@jsperson

OpenClaw Logkeeper

Turn-by-turn conversation logger for OpenClaw. Appends every agent exchange to daily markdown files across all surfaces — Discord, TUI, webchat, cron — regardless of model.

Current version
v1.0.4
code-pluginCommunitysource-linked

openclaw-logkeeper

Turn-by-turn conversation logger for OpenClaw. Appends every completed agent exchange to daily markdown files — across Discord, TUI, webchat, cron, and any other surface — regardless of which model is running.

Unlike the built-in session-memory hook (which saves a snapshot only when you issue /new or /reset), Scribe writes continuously: one entry per turn, every turn, to a configurable directory.

Output is plain markdown, compatible with QMD and other local search tools.

Install

From ClawHub (recommended):

openclaw plugins install clawhub:openclaw-logkeeper

From npm:

npm install -g openclaw-logkeeper
openclaw plugins install ./node_modules/openclaw-logkeeper

From source:

git clone https://github.com/jsperson/openclaw-logkeeper.git
cd openclaw-logkeeper
npm install && npm run build
openclaw plugins install ./

Required configuration

Scribe requires two things in your ~/.openclaw/openclaw.json:

1. Grant conversation access (required for agent_end hook to fire):

{
  "plugins": {
    "entries": {
      "openclaw-logkeeper": {
        "enabled": true,
        "hooks": {
          "allowConversationAccess": true
        },
        "config": {
          "logDir": "~/your/log/directory"
        }
      }
    }
  }
}

Without allowConversationAccess: true, the hook is silently blocked by OpenClaw and no logs will be written.

2. Set logDir — the directory where daily files are written. Supports ~/ expansion. This field is required; the plugin will not start without it.

Verify it's working: Send a message in any channel, then check your logDir for a file named YYYY-MM-DD-discord.md (or YYYY-MM-DD-tui.md for TUI sessions). It should appear within 30 seconds.

Configuration reference

All options go under plugins.entries.openclaw-logkeeper.config in openclaw.json.

OptionTypeDefaultDescription
logDirstring~/.openclaw/logsDirectory for log files. Supports ~/.
filenamestring"{date}-{channel}.md"Filename template. Variables: {date} (YYYY-MM-DD), {channel} (provider name or tui), {agent} (agentId).
channelsobject{}Per-channel filename overrides. Key: provider name (discord, telegram, etc.) or tui. Value: filename template.
userAliasstring"user"Speaker label for the user.
assistantAliasstring"assistant"Fallback label for the assistant. Scribe first reads the agent name from IDENTITY.md — set this only if you want to override that.
maxLengthinteger4000Maximum characters written for the assistant response. 0 = unlimited. Truncated entries include a note with the original character count.
includeCronbooleanfalseInclude cron/heartbeat turns in logs.
metadatabooleanfalseAppend a metadata line after the timestamp: · {model} · {input}↑ {output}↓. Silently omitted if model or token data is unavailable.

Full example

{
  "plugins": {
    "entries": {
      "openclaw-logkeeper": {
        "enabled": true,
        "hooks": {
          "allowConversationAccess": true
        },
        "config": {
          "logDir": "~/ai-logs",
          "filename": "{date}-{channel}.md",
          "channels": {
            "discord": "{date}-discord.md",
            "tui": "{date}-tui.md"
          },
          "userAlias": "scott",
          "maxLength": 4000,
          "includeCron": false,
          "metadata": false
        }
      }
    }
  }
}

QMD integration

If you use QMD to search your logs, point logDir at the directory QMD's daily-logs collection scans. QMD's **/*.md pattern picks up any filename suffix automatically — no QMD config changes needed.

Example output

~/ai-logs/2026-05-07-discord.md:

# 2026-05-07

### 14:32
**scott:** What's on my calendar today?

**jomama:** You have three items: standup at 09:30, PT at 14:00, and Jason's soccer game at 18:00.

### 15:01
**scott:** Set a reminder to call Mom at 19:00.

**jomama:** Done — reminder added to Apple Reminders.

~/ai-logs/2026-05-07-tui.md:

# 2026-05-07

### 09:15
**scott:** Show me last week's summary.

**jomama:** Here's what happened last week: ...

With metadata: true:

### 14:32
· claude-opus-4-7 · 312↑ 87↓
**scott:** What's on my calendar today?

**jomama:** You have three items: ...

How it works

Scribe uses OpenClaw's agent_end plugin hook, which fires after every completed agent turn — regardless of surface, model, or channel. This makes it:

  • Model-agnostic: works with Claude, Qwen, local models, anything OpenClaw supports
  • Surface-complete: Discord, TUI, webchat, cron, and future channels all produce logs
  • Continuous: one entry per turn, no manual /reset required

The assistant's display name is read from your workspace IDENTITY.md automatically (- Name: YourAgentName).

Compatibility

  • OpenClaw 2026.x+ (plugin API >=2026.3.24-beta.2)
  • Node.js 22+

Contributing

Bug reports and PRs welcome at github.com/jsperson/openclaw-logkeeper.

License

MIT © Scott Person

Source and release

Source repository

jsperson/openclaw-logkeeper

Open repo

Source commit

672c3ab805d5820ff5ebd5db1c0e26f52e5795a1

View commit

Install command

openclaw plugins install clawhub:openclaw-logkeeper

Metadata

  • Package: openclaw-logkeeper
  • Created: 2026/05/07
  • Updated: 2026/05/07
  • Executes code: Yes
  • Source tag: v1.0.4

Compatibility

  • Built with OpenClaw: 2026.5.6
  • Plugin API range: >=2026.3.24-beta.2
  • Tags: latest
  • Files: 25