@jonathangu/openclawbrain 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +412 -0
  3. package/bin/openclawbrain.js +15 -0
  4. package/docs/END_STATE.md +244 -0
  5. package/docs/EVIDENCE.md +128 -0
  6. package/docs/RELEASE_CONTRACT.md +91 -0
  7. package/docs/agent-tools.md +106 -0
  8. package/docs/architecture.md +224 -0
  9. package/docs/configuration.md +178 -0
  10. package/docs/evidence/2026-03-16/3188b50c4ed30f07dea111e35ce52aabefaced63/brain-teach-session-bound/status.json +87 -0
  11. package/docs/evidence/2026-03-16/3188b50c4ed30f07dea111e35ce52aabefaced63/brain-teach-session-bound/summary.md +16 -0
  12. package/docs/evidence/2026-03-16/3188b50c4ed30f07dea111e35ce52aabefaced63/brain-teach-session-bound/trace.json +273 -0
  13. package/docs/evidence/2026-03-16/3188b50c4ed30f07dea111e35ce52aabefaced63/brain-teach-session-bound/validation-report.json +652 -0
  14. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/channels-status.txt +31 -0
  15. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/config-snapshot.json +66 -0
  16. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/doctor.json +14 -0
  17. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/gateway-probe.txt +34 -0
  18. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/gateway-status.txt +41 -0
  19. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/logs.txt +428 -0
  20. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/status-all.txt +60 -0
  21. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/status.json +223 -0
  22. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/summary.md +13 -0
  23. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/trace.json +4 -0
  24. package/docs/evidence/2026-03-16/4941429588810da5d6f7ef1509f229f83fa08031/validation-report.json +334 -0
  25. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/channels-status.txt +25 -0
  26. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/config-snapshot.json +91 -0
  27. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/doctor.json +14 -0
  28. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/gateway-probe.txt +36 -0
  29. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/gateway-status.txt +44 -0
  30. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/logs.txt +428 -0
  31. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/short-static-classification/preflight-doctor.json +10 -0
  32. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/short-static-classification/preflight-sdk-probe.json +11 -0
  33. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/short-static-classification/preflight-setup-only.json +12 -0
  34. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/short-static-classification/summary.md +30 -0
  35. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/short-static-classification/validation-report.json +72 -0
  36. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/status-all.txt +63 -0
  37. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/status.json +200 -0
  38. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/summary.md +13 -0
  39. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/trace.json +4 -0
  40. package/docs/evidence/2026-03-16/7f8dbcb27e741abdeefd5656c210639d0acdd440/validation-report.json +311 -0
  41. package/docs/evidence/README.md +16 -0
  42. package/docs/fts5.md +161 -0
  43. package/docs/tui.md +506 -0
  44. package/index.ts +1372 -0
  45. package/openclaw.plugin.json +136 -0
  46. package/package.json +66 -0
  47. package/src/assembler.ts +804 -0
  48. package/src/brain-cli.ts +316 -0
  49. package/src/brain-core/decay.ts +35 -0
  50. package/src/brain-core/episode.ts +82 -0
  51. package/src/brain-core/graph.ts +321 -0
  52. package/src/brain-core/health.ts +116 -0
  53. package/src/brain-core/mutator.ts +281 -0
  54. package/src/brain-core/pack.ts +117 -0
  55. package/src/brain-core/policy.ts +153 -0
  56. package/src/brain-core/replay.ts +1 -0
  57. package/src/brain-core/teacher.ts +105 -0
  58. package/src/brain-core/trace.ts +40 -0
  59. package/src/brain-core/traverse.ts +230 -0
  60. package/src/brain-core/types.ts +405 -0
  61. package/src/brain-core/update.ts +123 -0
  62. package/src/brain-harvest/human.ts +46 -0
  63. package/src/brain-harvest/scanner.ts +98 -0
  64. package/src/brain-harvest/self.ts +147 -0
  65. package/src/brain-runtime/assembler-extension.ts +230 -0
  66. package/src/brain-runtime/evidence-detectors.ts +68 -0
  67. package/src/brain-runtime/graph-io.ts +72 -0
  68. package/src/brain-runtime/harvester-extension.ts +98 -0
  69. package/src/brain-runtime/service.ts +659 -0
  70. package/src/brain-runtime/tools.ts +109 -0
  71. package/src/brain-runtime/worker-state.ts +106 -0
  72. package/src/brain-runtime/worker-supervisor.ts +169 -0
  73. package/src/brain-store/embedding.ts +179 -0
  74. package/src/brain-store/init.ts +347 -0
  75. package/src/brain-store/migrations.ts +188 -0
  76. package/src/brain-store/store.ts +816 -0
  77. package/src/brain-worker/child-runner.ts +321 -0
  78. package/src/brain-worker/jobs.ts +12 -0
  79. package/src/brain-worker/mutation-job.ts +5 -0
  80. package/src/brain-worker/promotion-job.ts +5 -0
  81. package/src/brain-worker/protocol.ts +79 -0
  82. package/src/brain-worker/teacher-job.ts +5 -0
  83. package/src/brain-worker/update-job.ts +5 -0
  84. package/src/brain-worker/worker.ts +422 -0
  85. package/src/compaction.ts +1332 -0
  86. package/src/db/config.ts +265 -0
  87. package/src/db/connection.ts +72 -0
  88. package/src/db/features.ts +42 -0
  89. package/src/db/migration.ts +561 -0
  90. package/src/engine.ts +1995 -0
  91. package/src/expansion-auth.ts +351 -0
  92. package/src/expansion-policy.ts +303 -0
  93. package/src/expansion.ts +383 -0
  94. package/src/integrity.ts +600 -0
  95. package/src/large-files.ts +527 -0
  96. package/src/openclaw-bridge.ts +22 -0
  97. package/src/retrieval.ts +357 -0
  98. package/src/store/conversation-store.ts +748 -0
  99. package/src/store/fts5-sanitize.ts +29 -0
  100. package/src/store/full-text-fallback.ts +74 -0
  101. package/src/store/index.ts +29 -0
  102. package/src/store/summary-store.ts +918 -0
  103. package/src/summarize.ts +847 -0
  104. package/src/tools/common.ts +53 -0
  105. package/src/tools/lcm-conversation-scope.ts +76 -0
  106. package/src/tools/lcm-describe-tool.ts +234 -0
  107. package/src/tools/lcm-expand-query-tool.ts +594 -0
  108. package/src/tools/lcm-expand-tool.delegation.ts +556 -0
  109. package/src/tools/lcm-expand-tool.ts +448 -0
  110. package/src/tools/lcm-expansion-recursion-guard.ts +286 -0
  111. package/src/tools/lcm-grep-tool.ts +200 -0
  112. package/src/transcript-repair.ts +301 -0
  113. package/src/types.ts +149 -0
package/docs/fts5.md ADDED
@@ -0,0 +1,161 @@
1
+ # Optional: enable FTS5 for fast full-text search
2
+
3
+ OpenClawBrain's inherited LCM substrate works without FTS5 as of the current release. When FTS5 is unavailable in the
4
+ Node runtime that runs the OpenClaw gateway, the plugin:
5
+
6
+ - keeps persisting messages and summaries
7
+ - falls back from `"full_text"` search to a slower `LIKE`-based search
8
+ - loses FTS ranking/snippet quality
9
+
10
+ If you want native FTS5 search performance and ranking, the **exact Node runtime that runs the
11
+ gateway** must have SQLite FTS5 compiled in.
12
+
13
+ ## Probe the gateway runtime
14
+
15
+ Run this with the same `node` binary your gateway uses:
16
+
17
+ ```bash
18
+ node --input-type=module - <<'NODE'
19
+ import { DatabaseSync } from 'node:sqlite';
20
+ const db = new DatabaseSync(':memory:');
21
+ const options = db.prepare('pragma compile_options').all().map((row) => row.compile_options);
22
+
23
+ console.log(options.filter((value) => value.includes('FTS')).join('\n') || 'no fts compile options');
24
+
25
+ try {
26
+ db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
27
+ console.log("fts5: ok");
28
+ } catch (err) {
29
+ console.log("fts5: fail");
30
+ console.log(err instanceof Error ? err.message : String(err));
31
+ }
32
+ NODE
33
+ ```
34
+
35
+ Expected output:
36
+
37
+ ```text
38
+ ENABLE_FTS5
39
+ fts5: ok
40
+ ```
41
+
42
+ If you get `fts5: fail`, build or install an FTS5-capable Node and point the gateway at that runtime.
43
+
44
+ ## Build an FTS5-capable Node on macOS
45
+
46
+ This workflow was verified with Node `v22.15.0`.
47
+
48
+ ```bash
49
+ cd ~/Projects
50
+ git clone --depth 1 --branch v22.15.0 https://github.com/nodejs/node.git node-fts5
51
+ cd node-fts5
52
+ ```
53
+
54
+ Edit `deps/sqlite/sqlite.gyp` and add `SQLITE_ENABLE_FTS5` to the `defines` list for the `sqlite`
55
+ target:
56
+
57
+ ```diff
58
+ 'defines': [
59
+ 'SQLITE_DEFAULT_MEMSTATUS=0',
60
+ + 'SQLITE_ENABLE_FTS5',
61
+ 'SQLITE_ENABLE_MATH_FUNCTIONS',
62
+ 'SQLITE_ENABLE_SESSION',
63
+ 'SQLITE_ENABLE_PREUPDATE_HOOK'
64
+ ],
65
+ ```
66
+
67
+ Important:
68
+
69
+ - patch `deps/sqlite/sqlite.gyp`, not only `node.gyp`
70
+ - `node:sqlite` uses the embedded SQLite built from `deps/sqlite/sqlite.gyp`
71
+
72
+ Build the runtime:
73
+
74
+ ```bash
75
+ ./configure --prefix="$PWD/out-install"
76
+ make -j8 node
77
+ ```
78
+
79
+ Expose the binary under a Node-compatible basename that OpenClaw recognizes:
80
+
81
+ ```bash
82
+ mkdir -p ~/Projects/node-fts5/bin
83
+ ln -sfn ~/Projects/node-fts5/out/Release/node ~/Projects/node-fts5/bin/node-22.15.0
84
+ ```
85
+
86
+ Use a basename like `node-22.15.0`, `node`, or `nodejs`. Names like
87
+ `node-v22.15.0-fts5` may not be recognized correctly by OpenClaw's CLI/runtime parsing.
88
+
89
+ Verify the new runtime:
90
+
91
+ ```bash
92
+ ~/Projects/node-fts5/bin/node-22.15.0 --version
93
+ ~/Projects/node-fts5/bin/node-22.15.0 --input-type=module - <<'NODE'
94
+ import { DatabaseSync } from 'node:sqlite';
95
+ const db = new DatabaseSync(':memory:');
96
+ db.exec("CREATE VIRTUAL TABLE t USING fts5(content)");
97
+ console.log("fts5: ok");
98
+ NODE
99
+ ```
100
+
101
+ ## Point the OpenClaw gateway at that runtime on macOS
102
+
103
+ Back up the existing LaunchAgent plist first:
104
+
105
+ ```bash
106
+ cp ~/Library/LaunchAgents/ai.openclaw.gateway.plist \
107
+ ~/Library/LaunchAgents/ai.openclaw.gateway.plist.bak-$(date +%Y%m%d-%H%M%S)
108
+ ```
109
+
110
+ Replace the runtime path, then reload the agent:
111
+
112
+ ```bash
113
+ /usr/libexec/PlistBuddy -c 'Set :ProgramArguments:0 /Users/youruser/Projects/node-fts5/bin/node-22.15.0' \
114
+ ~/Library/LaunchAgents/ai.openclaw.gateway.plist
115
+
116
+ launchctl bootout gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist 2>/dev/null || true
117
+ launchctl bootstrap gui/$UID ~/Library/LaunchAgents/ai.openclaw.gateway.plist
118
+ launchctl kickstart -k gui/$UID/ai.openclaw.gateway
119
+ ```
120
+
121
+ Verify the live runtime:
122
+
123
+ ```bash
124
+ launchctl print gui/$UID/ai.openclaw.gateway | sed -n '1,80p'
125
+ ```
126
+
127
+ You should see:
128
+
129
+ ```text
130
+ program = /Users/youruser/Projects/node-fts5/bin/node-22.15.0
131
+ ```
132
+
133
+ ## Verify the OpenClawBrain plugin
134
+
135
+ Check the logs:
136
+
137
+ ```bash
138
+ tail -n 60 ~/.openclaw/logs/gateway.log
139
+ tail -n 60 ~/.openclaw/logs/gateway.err.log
140
+ ```
141
+
142
+ You want:
143
+
144
+ - `[gateway] [lcm] Plugin loaded ...`
145
+ - no new `no such module: fts5`
146
+
147
+ Then force one turn through the gateway and verify the DB fills:
148
+
149
+ ```bash
150
+ /Users/youruser/Projects/node-fts5/bin/node-22.15.0 \
151
+ /path/to/openclaw/dist/index.js \
152
+ agent --session-id fts5-smoke --message 'Reply with exactly: ok' --timeout 60
153
+
154
+ sqlite3 ~/.openclaw/lcm.db '
155
+ select count(*) as conversations from conversations;
156
+ select count(*) as messages from messages;
157
+ select count(*) as summaries from summaries;
158
+ '
159
+ ```
160
+
161
+ Those counts should increase after a real turn.
package/docs/tui.md ADDED
@@ -0,0 +1,506 @@
1
+ # TUI Reference
2
+
3
+ The OpenClawBrain TUI (`lcm-tui`) is an interactive terminal application for inspecting, debugging, and maintaining the inherited LCM substrate. It provides direct visibility into what the model sees (context assembly), how summaries are structured (DAG hierarchy), and tools for surgical repairs when things go wrong.
4
+
5
+ ## Installation
6
+
7
+ **From GitHub releases:**
8
+
9
+ Download the latest binary for your platform from the OpenClawBrain release surface that ships this repo's TUI assets.
10
+
11
+ **Build from source:**
12
+
13
+ ```bash
14
+ cd tui
15
+ go build -o lcm-tui .
16
+ # or: make build
17
+ # or: go install github.com/Martian-Engineering/lossless-claw/tui@latest
18
+ ```
19
+
20
+ Requires Go 1.24+.
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ lcm-tui # default: ~/.openclaw/lcm.db
26
+ lcm-tui --db /path/to/lcm.db # custom database path
27
+ ```
28
+
29
+ The TUI auto-discovers agent session directories from `~/.openclaw/agents/`.
30
+
31
+ ## Navigation Model
32
+
33
+ The TUI is organized as a drill-down hierarchy. You navigate deeper with Enter and back with `b`/Backspace.
34
+
35
+ ```
36
+ Agents → Sessions → Conversation → [Summary DAG | Context View | Large Files]
37
+ ```
38
+
39
+ ### Screen 1: Agent List
40
+
41
+ Lists all agents discovered under `~/.openclaw/agents/`. Select an agent to see its sessions.
42
+
43
+ | Key | Action |
44
+ |-----|--------|
45
+ | `↑`/`↓` or `k`/`j` | Move cursor |
46
+ | `Enter` | Open agent's sessions |
47
+ | `r` | Reload agent list |
48
+ | `q` | Quit |
49
+
50
+ ### Screen 2: Session List
51
+
52
+ Shows JSONL session files for the selected agent, sorted by last modified time. Each entry shows the filename, last update time, message count, conversation ID (if LCM-tracked), summary count, and large file count.
53
+
54
+ Sessions load in batches of 50. Scrolling near the bottom automatically loads more.
55
+
56
+ | Key | Action |
57
+ |-----|--------|
58
+ | `↑`/`↓` or `k`/`j` | Move cursor |
59
+ | `Enter` | Open conversation |
60
+ | `b`/`Backspace` | Back to agents |
61
+ | `r` | Reload sessions |
62
+ | `q` | Quit |
63
+
64
+ ### Screen 3: Conversation View
65
+
66
+ A scrollable, color-coded view of the raw session messages. Each message shows its timestamp, role (user/assistant/system/tool), and content. Roles are color-coded:
67
+
68
+ - **Green** — user messages
69
+ - **Blue** — assistant messages
70
+ - **Yellow** — system messages
71
+ - **Gray** — tool calls and results
72
+
73
+ This is the raw session data, not the LCM-managed context. Use it to understand what actually happened in the conversation.
74
+
75
+ For sessions with an LCM `conv_id`, the conversation view uses keyset-paged windows by `message_id` (newest window first) instead of hydrating full history.
76
+
77
+ | Key | Action |
78
+ |-----|--------|
79
+ | `↑`/`↓` or `k`/`j` | Scroll one line |
80
+ | `PgUp`/`PgDn` | Scroll half page |
81
+ | `g` | Jump to top |
82
+ | `G` | Jump to bottom |
83
+ | `[` | Load older message window |
84
+ | `]` | Load newer message window |
85
+ | `l` | Open **Summary DAG** view |
86
+ | `c` | Open **Context** view |
87
+ | `f` | Open **Large Files** view |
88
+ | `b`/`Backspace` | Back to sessions |
89
+ | `r` | Reload messages |
90
+ | `q` | Quit |
91
+
92
+ ## Summary DAG View
93
+
94
+ The core inspection tool. Shows the full hierarchy of LCM summaries for a conversation as an expandable tree.
95
+
96
+ Each row shows:
97
+ ```
98
+ [marker] summary_id [kind, tokens] content preview
99
+ ```
100
+
101
+ - **Marker**: `>` (collapsed, has children), `v` (expanded), `-` (leaf, no children)
102
+ - **Kind**: `leaf` for depth-0 summaries, `d1`/`d2`/`d3` for condensed summaries at each depth
103
+ - **Tokens**: token count of the summary content
104
+
105
+ The bottom panel shows the detail view for the selected summary: full content text and source messages (the raw messages that were summarized to create this node).
106
+
107
+ ### When to Use
108
+
109
+ - **Verify summarization quality** — read what the model will actually see
110
+ - **Check DAG structure** — ensure the depth hierarchy is balanced
111
+ - **Find corrupted nodes** — look for suspiciously short content, "[LCM fallback summary]" markers, or raw tool output that leaked into summaries
112
+ - **Understand temporal coverage** — each summary's source messages show exactly which conversation segment it covers
113
+
114
+ ### Navigation
115
+
116
+ | Key | Action |
117
+ |-----|--------|
118
+ | `↑`/`↓` or `k`/`j` | Move cursor in list |
119
+ | `Enter`/`l`/`Space` | Expand/collapse node |
120
+ | `h` | Collapse current node |
121
+ | `g` | Jump to first summary |
122
+ | `G` | Jump to last summary |
123
+ | `Shift+J` | Scroll detail panel down |
124
+ | `Shift+K` | Scroll detail panel up |
125
+ | `w` | **Rewrite** selected summary |
126
+ | `W` | **Subtree rewrite** (selected + all descendants) |
127
+ | `d` | **Dissolve** selected condensed summary |
128
+ | `r` | Reload DAG |
129
+ | `b`/`Backspace` | Back to conversation |
130
+ | `q` | Quit |
131
+
132
+ ## Context View
133
+
134
+ Shows exactly what the model sees: the ordered list of context items (summaries + fresh tail messages) that LCM assembles for the next turn. This is the ground truth for "what does the agent know right now?"
135
+
136
+ Each row shows:
137
+ ```
138
+ ordinal kind [id, tokens] content_preview
139
+ ```
140
+
141
+ - **Summaries** show as `leaf`, `d1`, `d2`, etc. with their summary ID
142
+ - **Messages** show their role (user/assistant/system/tool) with message ID
143
+
144
+ The status bar shows totals: how many summaries, how many messages, total items, and total tokens.
145
+
146
+ ### When to Use
147
+
148
+ - **Debug context overflow** — see total token count and identify what's consuming the budget
149
+ - **Verify assembly order** — summaries should appear before fresh tail messages, ordered chronologically
150
+ - **Check after dissolve/rewrite** — confirm your changes are reflected in what the model sees
151
+ - **Compare with raw conversation** — the conversation view shows everything; the context view shows what survives compaction
152
+
153
+ | Key | Action |
154
+ |-----|--------|
155
+ | `↑`/`↓` or `k`/`j` | Move cursor |
156
+ | `g` | Jump to first item |
157
+ | `G` | Jump to last item |
158
+ | `Shift+J` | Scroll detail panel down |
159
+ | `Shift+K` | Scroll detail panel up |
160
+ | `r` | Reload context |
161
+ | `b`/`Backspace` | Back to conversation |
162
+ | `q` | Quit |
163
+
164
+ ## Large Files View
165
+
166
+ Lists files that exceeded the large file threshold (default 25k tokens) and were intercepted by LCM. Shows file ID, display name, MIME type, byte size, and creation time. The detail panel shows the exploration summary that was generated as a lightweight stand-in.
167
+
168
+ | Key | Action |
169
+ |-----|--------|
170
+ | `↑`/`↓` or `k`/`j` | Move cursor |
171
+ | `g`/`G` | Jump to first/last |
172
+ | `r` | Reload files |
173
+ | `b`/`Backspace` | Back to conversation |
174
+ | `q` | Quit |
175
+
176
+ ## Operations
177
+
178
+ ### Rewrite (`w`)
179
+
180
+ Re-summarizes a single summary node using the current depth-aware prompt templates. The process:
181
+
182
+ 1. **Preview** — shows the prompt that will be sent, including source material, target token count, previous context, and time range
183
+ 2. **API call** — sends to the configured provider API (Anthropic by default)
184
+ 3. **Review** — shows old and new content side-by-side with token delta. Toggle unified diff view with `d`. Scroll with `j`/`k`.
185
+
186
+ | Key (Preview) | Action |
187
+ |-----|--------|
188
+ | `Enter` | Send to API |
189
+ | `Esc` | Cancel |
190
+
191
+ | Key (Review) | Action |
192
+ |-----|--------|
193
+ | `y`/`Enter` | Apply rewrite to database |
194
+ | `n`/`Esc` | Discard |
195
+ | `d` | Toggle unified diff view |
196
+ | `j`/`k` | Scroll content |
197
+
198
+ **When to use:** A summary has poor quality (too verbose, missing key details, or was generated before the depth-aware prompts were implemented). Rewriting regenerates it from its original source material using the current prompts.
199
+
200
+ ### Subtree Rewrite (`W`)
201
+
202
+ Rewrites the selected summary and all its descendants, bottom-up. Leaves are rewritten first so that condensed parents pick up the improved content. Nodes are processed one at a time through the same preview→API→review cycle.
203
+
204
+ | Key (additional) | Action |
205
+ |-----|--------|
206
+ | `A` | **Auto-accept** — apply current and all remaining automatically |
207
+ | `n` | Skip current node, advance to next |
208
+ | `Esc` | Abort entire subtree rewrite |
209
+
210
+ The status bar shows progress as `[N/total]`. Auto-accept pauses on errors so you can inspect failures.
211
+
212
+ **When to use:** A whole branch of the DAG has outdated formatting (e.g., pre-depth-aware summaries). Subtree rewrite regenerates everything from the leaves up.
213
+
214
+ ### Dissolve (`d`)
215
+
216
+ Reverses a condensation: removes a condensed summary from the active context and restores its parent summaries in its place. This is a surgical undo of a compaction step.
217
+
218
+ The confirmation screen shows:
219
+ - The target summary (kind, depth, tokens, context ordinal)
220
+ - Token impact (condensed tokens → total restored parent tokens)
221
+ - Ordinal shift (how many items after the target will be renumbered)
222
+ - Parent summaries that will be restored (with previews)
223
+
224
+ | Key | Action |
225
+ |-----|--------|
226
+ | `y`/`Enter` | Execute dissolve |
227
+ | `n`/`Esc` | Cancel |
228
+
229
+ **When to use:**
230
+ - A condensed summary is too lossy — you want the original finer-grained summaries back
231
+ - A corrupted condensed node needs to be removed so its parents can be individually repaired
232
+ - You want to re-do a condensation after improving the leaf summaries
233
+
234
+ **Important:** Dissolving increases the number of context items and total token count. Check the context view afterward to verify you haven't exceeded the context window threshold.
235
+
236
+ ## CLI Subcommands
237
+
238
+ Each interactive operation also has a standalone CLI equivalent for scripting and batch operations.
239
+
240
+ ### `lcm-tui repair`
241
+
242
+ Finds and fixes corrupted summaries (those containing the `[LCM fallback summary]` marker from failed summarization attempts).
243
+
244
+ ```bash
245
+ # Scan a specific conversation (dry run)
246
+ lcm-tui repair 44
247
+
248
+ # Scan all conversations
249
+ lcm-tui repair --all
250
+
251
+ # Apply repairs
252
+ lcm-tui repair 44 --apply
253
+
254
+ # Repair a specific summary
255
+ lcm-tui repair 44 --summary-id sum_abc123 --apply
256
+ ```
257
+
258
+ The repair process:
259
+ 1. Identifies corrupted summaries by scanning for the fallback marker
260
+ 2. Orders them bottom-up: leaves first (in context ordinal order), then condensed nodes by ascending depth
261
+ 3. Reconstructs source material from linked messages (leaves) or child summaries (condensed)
262
+ 4. Resolves `previous_context` for each node (for deduplication in the prompt)
263
+ 5. Sends to Anthropic API with the appropriate depth prompt
264
+ 6. Updates the database in a single transaction
265
+
266
+ | Flag | Description |
267
+ |------|-------------|
268
+ | `--apply` | Write repairs to database (default: dry run) |
269
+ | `--all` | Scan all conversations |
270
+ | `--summary-id <id>` | Target a specific summary |
271
+ | `--verbose` | Show content hashes and previews |
272
+
273
+ ### `lcm-tui rewrite`
274
+
275
+ Re-summarizes summaries using current depth-aware prompts. Unlike repair, this works on any summary, not just corrupted ones.
276
+
277
+ ```bash
278
+ # Rewrite a single summary (dry run)
279
+ lcm-tui rewrite 44 --summary sum_abc123
280
+
281
+ # Rewrite all depth-0 summaries
282
+ lcm-tui rewrite 44 --depth 0 --apply
283
+
284
+ # Rewrite everything bottom-up
285
+ lcm-tui rewrite 44 --all --apply --diff
286
+
287
+ # Rewrite with OpenAI Responses API
288
+ lcm-tui rewrite 44 --summary sum_abc123 --provider openai --model gpt-5.3-codex --apply
289
+
290
+ # Use custom prompt templates
291
+ lcm-tui rewrite 44 --all --apply --prompt-dir ~/.config/lcm-tui/prompts
292
+ ```
293
+
294
+ | Flag | Description |
295
+ |------|-------------|
296
+ | `--summary <id>` | Rewrite a single summary |
297
+ | `--depth <n>` | Rewrite all summaries at depth N |
298
+ | `--all` | Rewrite all summaries (bottom-up by depth, then timestamp) |
299
+ | `--apply` | Write changes to database |
300
+ | `--dry-run` | Show before/after without writing (default) |
301
+ | `--diff` | Show unified diff |
302
+ | `--provider <id>` | API provider (inferred from `--model` when omitted) |
303
+ | `--model <model>` | API model (default depends on provider) |
304
+ | `--prompt-dir <path>` | Custom prompt template directory |
305
+ | `--timestamps` | Inject timestamps into source text (default: true) |
306
+ | `--tz <timezone>` | Timezone for timestamps (default: system local) |
307
+
308
+ Exactly one of `--summary`, `--depth`, or `--all` is required.
309
+
310
+ ### `lcm-tui dissolve`
311
+
312
+ Reverses a condensation, restoring parent summaries to the active context.
313
+
314
+ ```bash
315
+ # Preview (dry run)
316
+ lcm-tui dissolve 44 --summary-id sum_abc123
317
+
318
+ # Execute
319
+ lcm-tui dissolve 44 --summary-id sum_abc123 --apply
320
+
321
+ # Keep the condensed summary record (don't purge from DB)
322
+ lcm-tui dissolve 44 --summary-id sum_abc123 --apply --purge=false
323
+ ```
324
+
325
+ | Flag | Description |
326
+ |------|-------------|
327
+ | `--summary-id <id>` | Condensed summary to dissolve (required) |
328
+ | `--apply` | Execute changes |
329
+ | `--purge` | Also delete the condensed summary record (default: true) |
330
+
331
+ ### `lcm-tui transplant`
332
+
333
+ Deep-copies a summary DAG from one conversation to another. Used when an agent gets a new conversation (session rollover) but you want to carry forward summaries from the old one.
334
+
335
+ ```bash
336
+ # Preview what would be copied
337
+ lcm-tui transplant 18 653
338
+
339
+ # Execute
340
+ lcm-tui transplant 18 653 --apply
341
+ ```
342
+
343
+ The transplant:
344
+ 1. Identifies all summary context items in the source conversation
345
+ 2. Recursively collects the full DAG (all ancestor summaries)
346
+ 3. Deep-copies every summary with new IDs, owned by the target conversation
347
+ 4. Deep-copies all linked messages and message_parts with new IDs
348
+ 5. Rewires summary_messages and summary_parents edges
349
+ 6. Prepends transplanted summaries to the target's context (existing items shift)
350
+ 7. Detects duplicates via content SHA256 and aborts if any match
351
+
352
+ Everything runs in a single transaction.
353
+
354
+ | Flag | Description |
355
+ |------|-------------|
356
+ | `--apply` | Execute transplant |
357
+ | `--dry-run` | Show what would be transplanted (default) |
358
+
359
+ ### `lcm-tui backfill`
360
+
361
+ Imports a pre-LCM JSONL session into `conversations/messages/context_items`, runs iterative depth-aware compaction with the configured provider + prompt templates, optionally forces a single-root fold, and can transplant the result to another conversation.
362
+
363
+ ```bash
364
+ # Preview import + compaction plan (no writes)
365
+ lcm-tui backfill my-agent session_abc123
366
+
367
+ # Import + compact
368
+ lcm-tui backfill my-agent session_abc123 --apply
369
+
370
+ # Re-run compaction for an already-imported session
371
+ lcm-tui backfill my-agent session_abc123 --apply --recompact
372
+
373
+ # Force a single summary root when possible
374
+ lcm-tui backfill my-agent session_abc123 --apply --recompact --single-root
375
+
376
+ # Import + compact + transplant into an active conversation
377
+ lcm-tui backfill my-agent session_abc123 --apply --transplant-to 653
378
+
379
+ # Backfill using OpenAI
380
+ lcm-tui backfill my-agent session_abc123 --apply --provider openai --model gpt-5.3-codex
381
+ ```
382
+
383
+ All write paths are transactional:
384
+ 1. Import transaction (conversation/messages/message_parts/context)
385
+ 2. Per-pass compaction transactions (leaf/condensed replacements)
386
+ 3. Optional transplant transaction (reuse of transplant command internals)
387
+
388
+ An idempotency guard prevents duplicate imports for the same `session_id`.
389
+
390
+ | Flag | Description |
391
+ |------|-------------|
392
+ | `--apply` | Execute import/compaction/transplant |
393
+ | `--dry-run` | Show what would run, without writes (default) |
394
+ | `--recompact` | Re-run compaction for already-imported sessions (message import remains idempotent) |
395
+ | `--single-root` | Force condensed folding until one summary remains when possible |
396
+ | `--transplant-to <conv_id>` | Transplant backfilled summaries into target conversation |
397
+ | `--title <text>` | Override imported conversation title |
398
+ | `--leaf-chunk-tokens <n>` | Max source tokens per leaf chunk |
399
+ | `--leaf-target-tokens <n>` | Target output tokens for leaf summaries |
400
+ | `--condensed-target-tokens <n>` | Target output tokens for condensed summaries |
401
+ | `--leaf-fanout <n>` | Min leaves required for d1 condensation |
402
+ | `--condensed-fanout <n>` | Min summaries required for d2+ condensation |
403
+ | `--hard-fanout <n>` | Min summaries for forced single-root passes |
404
+ | `--fresh-tail <n>` | Preserve freshest N raw messages from leaf compaction |
405
+ | `--provider <id>` | API provider (inferred from model when omitted) |
406
+ | `--model <id>` | API model (default depends on provider) |
407
+ | `--prompt-dir <path>` | Custom depth-prompt directory |
408
+
409
+ ### `lcm-tui prompts`
410
+
411
+ Manage and inspect depth-aware prompt templates. Templates control how the LLM summarizes at each depth level.
412
+
413
+ ```bash
414
+ # List active template sources (embedded vs filesystem override)
415
+ lcm-tui prompts --list
416
+
417
+ # Export default templates to filesystem for customization
418
+ lcm-tui prompts --export # default: ~/.config/lcm-tui/prompts/
419
+ lcm-tui prompts --export /path/to/my/prompts
420
+
421
+ # Show a specific template's content
422
+ lcm-tui prompts --show leaf
423
+
424
+ # Diff a filesystem override against the embedded default
425
+ lcm-tui prompts --diff condensed-d1
426
+
427
+ # Render a template with test variables
428
+ lcm-tui prompts --render leaf --target-tokens 800
429
+ ```
430
+
431
+ | Flag | Description |
432
+ |------|-------------|
433
+ | `--list` | Show which templates are active and their source |
434
+ | `--export [dir]` | Export embedded defaults to filesystem |
435
+ | `--show <name>` | Print the active template content |
436
+ | `--diff <name>` | Unified diff between override and embedded default |
437
+ | `--render <name>` | Render template with provided variables |
438
+ | `--prompt-dir <dir>` | Custom prompt template directory |
439
+
440
+ **Template names:** `leaf`, `condensed-d1`, `condensed-d2`, `condensed-d3` (`.tmpl` suffix optional).
441
+
442
+ **Customization workflow:**
443
+ 1. `lcm-tui prompts --export` to get the defaults
444
+ 2. Edit the templates in `~/.config/lcm-tui/prompts/`
445
+ 3. `lcm-tui prompts --diff condensed-d1` to verify changes
446
+ 4. Templates are automatically picked up by rewrite/repair operations
447
+
448
+ ## Depth-Aware Prompt Templates
449
+
450
+ The TUI uses four distinct prompt templates, one per depth level. This matches the plugin's depth-dispatched summarization strategy:
451
+
452
+ | Template | Depth | Strategy | Receives `previous_context` |
453
+ |----------|-------|----------|-----------------------------|
454
+ | `leaf.tmpl` | d0 | Narrative preservation with timestamps, file tracking | Yes |
455
+ | `condensed-d1.tmpl` | d1 | Chronological session narrative, delta-oriented (avoids repeating previous context) | Yes |
456
+ | `condensed-d2.tmpl` | d2 | Arc-focused: goal → outcome → what carries forward. Self-contained. | No |
457
+ | `condensed-d3.tmpl` | d3+ | Maximum abstraction. Durable context only. Self-contained. | No |
458
+
459
+ **d0/d1** summaries receive `previous_context` (the content of the preceding summary at the same depth) so they can avoid repeating information. **d2+** summaries are self-contained — they're designed to be independently useful for `lcm_expand_query` retrieval without requiring sibling context.
460
+
461
+ All templates end with an `"Expand for details about:"` footer listing topics available for deeper retrieval via the agent tools.
462
+
463
+ ## Authentication
464
+
465
+ The TUI resolves API keys by provider for rewrite, repair, and backfill compaction operations.
466
+
467
+ - Anthropic: `ANTHROPIC_API_KEY`
468
+ - OpenAI: `OPENAI_API_KEY`
469
+
470
+ Resolution order:
471
+ 1. Provider API key environment variable
472
+ 2. OpenClaw config (`~/.openclaw/openclaw.json`) — checks matching provider auth profile mode
473
+ 3. OpenClaw env file
474
+ 4. `~/.zshrc` export
475
+ 5. Credential file candidates under `~/.openclaw/`
476
+
477
+ If the provider auth profile mode is `oauth` (not `api_key`), set the provider API key environment variable explicitly.
478
+
479
+ Interactive rewrite (`w`/`W`) can be configured with:
480
+ - `LCM_TUI_SUMMARY_PROVIDER`
481
+ - `LCM_TUI_SUMMARY_MODEL`
482
+ - `LCM_TUI_CONVERSATION_WINDOW_SIZE` (default `200`)
483
+
484
+ It also honors `LCM_SUMMARY_PROVIDER` / `LCM_SUMMARY_MODEL` as fallback.
485
+
486
+ ## Database
487
+
488
+ The TUI operates directly on the SQLite database at `~/.openclaw/lcm.db`. All write operations (rewrite, dissolve, repair, transplant, backfill) use transactions. Changes take effect on the next conversation turn — the running OpenClaw instance picks up database changes automatically.
489
+
490
+ **Backup recommendation:** Before batch operations (repair `--all`, rewrite `--all`, transplant, backfill), copy the database:
491
+
492
+ ```bash
493
+ cp ~/.openclaw/lcm.db ~/.openclaw/lcm.db.bak-$(date +%Y%m%d)
494
+ ```
495
+
496
+ ## Troubleshooting
497
+
498
+ **"No LCM summaries found"** — The session may not have an associated conversation in the LCM database. Check that the `conv_id` column shows a non-zero value in the session list. Sessions without LCM tracking won't have summaries.
499
+
500
+ **Rewrite returns empty/bad content** — Check provider/model access and API key. If normalization still yields empty text, the TUI now returns diagnostics including `provider`, `model`, and response `block_types` to help pinpoint adapter mismatches.
501
+
502
+ **Dissolve fails with "not condensed"** — Only condensed summaries (depth > 0) can be dissolved. Leaf summaries have no parent summaries to restore.
503
+
504
+ **Transplant aborts with duplicates** — The target conversation already has summaries with identical content hashes. This prevents accidental double-transplants. If intentional, delete the duplicates from the target first.
505
+
506
+ **Token count discrepancies** — The TUI estimates tokens as `len(content) / 4`. This is a rough heuristic, not a precise tokenizer count. The plugin uses the same estimate for consistency.