@ephemushroom/opencode-claude-mem 0.6.2 → 0.7.1
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.
- package/README.md +145 -562
- package/dist/capture-status.d.ts +26 -0
- package/dist/cli.js +370 -352
- package/dist/official-sync.d.ts +29 -0
- package/dist/server.d.ts +70 -0
- package/dist/server.js +1299 -0
- package/dist/sidebar-model.d.ts +33 -5
- package/dist/tui.js +280 -352
- package/dist/worker-client.d.ts +52 -90
- package/dist/worker-start.d.ts +46 -0
- package/dist/worker-tools.d.ts +33 -0
- package/package.json +10 -23
- package/dist/file-context.d.ts +0 -17
- package/dist/index.d.ts +0 -20
- package/dist/index.js +0 -13844
- package/dist/memory-options.d.ts +0 -12
- package/dist/memory-session.d.ts +0 -22
- package/dist/memory-turn.d.ts +0 -10
- package/dist/memory-worker.d.ts +0 -21
- package/dist/package-server.d.ts +0 -7
- package/dist/package-server.js +0 -10
- package/dist/shared.d.ts +0 -14
- package/dist/tui-registration.d.ts +0 -16
- package/dist/v2.d.ts +0 -22
- package/dist/v2.js +0 -5133
package/README.md
CHANGED
|
@@ -1,625 +1,208 @@
|
|
|
1
1
|
# opencode-claude-mem
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The **Memory sidebar** for [OpenCode](https://opencode.ai), backed by
|
|
4
4
|
[Claude-Mem](https://github.com/thedotmack/claude-mem).
|
|
5
5
|
|
|
6
|
-
**Supports OpenCode 1 and OpenCode 2 with the same package name from v0.5.0.**
|
|
7
|
-
No `/v2` or `/cli` suffix is required. Existing version-specific entries remain compatible.
|
|
8
|
-
|
|
9
|
-
**v0.6.1** updates the OpenCode 2 TUI adapter for the `@opencode/plugin` 2.0.16
|
|
10
|
-
plugin contract. **v0.6.0** adds per-turn memory tracking, `mem-save`, file history and opt-in semantic
|
|
11
|
-
injection, and fixes the OpenCode 2 sidebar's `No renderer found` crash.
|
|
12
|
-
|
|
13
|
-
Share the same Claude-Mem worker, database, and memory across your coding
|
|
14
|
-
agents: memories written by Claude Code are visible to OpenCode, and vice
|
|
15
|
-
versa. Previous observations and summaries are injected into new OpenCode
|
|
16
|
-
sessions automatically.
|
|
17
|
-
|
|
18
|
-
```mermaid
|
|
19
|
-
flowchart LR
|
|
20
|
-
CC[Claude Code] -->|writes as<br/>platform_source=claude| W
|
|
21
|
-
OC[OpenCode<br/>+ this plugin] -->|writes as<br/>platform_source=opencode| W
|
|
22
|
-
W[Claude-Mem Worker<br/>127.0.0.1:37777] --> DB[(SQLite +<br/>ChromaDB)]
|
|
23
|
-
W -->|shared project memory| CC
|
|
24
|
-
W -->|shared project memory| OC
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
> **Note:** This plugin is a thin OpenCode adapter for an existing Claude-Mem
|
|
28
|
-
> installation. It does **not** install Claude-Mem, manage slash commands, or
|
|
29
|
-
> register Claude Code MCP servers for you.
|
|
30
|
-
|
|
31
|
-
## Quick Start
|
|
32
|
-
|
|
33
|
-
1. Install and configure Claude-Mem in Claude Code.
|
|
34
|
-
2. Add this plugin to your `opencode.json` — pick the section matching your
|
|
35
|
-
OpenCode version:
|
|
36
|
-
|
|
37
|
-
### OpenCode 1
|
|
38
|
-
|
|
39
|
-
```json
|
|
40
|
-
{
|
|
41
|
-
"plugin": ["@ephemushroom/opencode-claude-mem"]
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
### OpenCode 2
|
|
46
|
-
|
|
47
|
-
```json
|
|
48
|
-
{
|
|
49
|
-
"plugins": ["@ephemushroom/opencode-claude-mem"]
|
|
50
|
-
}
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
3. Restart OpenCode.
|
|
54
|
-
4. Start a session — memory context is injected automatically, the `mem-*`
|
|
55
|
-
tools become available, and a collapsible **Memory** section appears in the
|
|
56
|
-
sidebar (both versions).
|
|
57
|
-
|
|
58
|
-
Using [oh-my-openagent](https://github.com/code-yeongyu/oh-my-openagent)?
|
|
59
|
-
See [Disable the Claude Code bridge](#using-with-oh-my-openagent-disable-the-claude-code-bridge)
|
|
60
|
-
to avoid running two claude-mem integrations at once.
|
|
61
|
-
|
|
62
|
-
## OpenCode 1 and 2
|
|
63
|
-
|
|
64
|
-
OpenCode 1 and OpenCode 2 install side by side (`opencode` vs `opencode2`) and
|
|
65
|
-
their plugin APIs are incompatible. This package exposes **one bare package
|
|
66
|
-
name for both runtimes**, with thin bridges that select the existing adapter
|
|
67
|
-
contract. No `/v2` or `/cli` suffix is needed:
|
|
68
|
-
|
|
69
|
-
| | OpenCode 1 | OpenCode 2 |
|
|
70
|
-
|---|---|---|
|
|
71
|
-
| **Binary** | `opencode` | `opencode2` |
|
|
72
|
-
| **Server plugin config** | `opencode.json` → `plugin` | `opencode.json` → `plugins` |
|
|
73
|
-
| **Server plugin entry** | `@ephemushroom/opencode-claude-mem` | `@ephemushroom/opencode-claude-mem` |
|
|
74
|
-
| **Sidebar config** | `~/.config/opencode/tui.json` → `plugin` (self-healed) | `~/.config/opencode/cli.json` → `plugins` (self-healed) |
|
|
75
|
-
| **Sidebar config entry** | `@ephemushroom/opencode-claude-mem` | `@ephemushroom/opencode-claude-mem` |
|
|
76
|
-
| **Sidebar resolution** | package `./tui` export, `tui()` | package `./tui` export, `setup()` |
|
|
77
|
-
|
|
78
|
-
Both adapters talk to the same Claude-Mem worker, so memory written from V1,
|
|
79
|
-
V2, and Claude Code is shared. The V2 entrypoint covers the same behavior —
|
|
80
|
-
context injection, tool observation capture, the `mem-search`/`mem-timeline`/
|
|
81
|
-
`mem-get-observations`/`mem-save` tools, per-user-message registration and session summarize/cleanup via the event
|
|
82
|
-
stream.
|
|
83
|
-
|
|
84
|
-
The bare package is tested with `opencode 1.18.29` and
|
|
85
|
-
`opencode2 0.0.0-beta-19151`; v0.6.0 also passes server and real
|
|
86
|
-
sidebar interaction checks on `0.0.0-beta-19192`. The V2 SDK is pinned because preview APIs can
|
|
87
|
-
change. Unified routing requires **v0.5.0 or later**; the older `0.4.4` package
|
|
88
|
-
does not provide it. Upgrade the package in both server and sidebar configurations.
|
|
89
|
-
Existing `/server`, `/tui`, `/v2`, and `/cli` exports remain supported; replace
|
|
90
|
-
an old config entry rather than adding the bare name beside it.
|
|
91
|
-
|
|
92
|
-
After upgrading, finish active tasks, close the client, and restart the V2
|
|
93
|
-
background service with `opencode2 service restart` before reopening `opencode2`.
|
|
94
|
-
For V1, restart `opencode`. Verify server activation with `opencode2 plugin list`.
|
|
95
|
-
|
|
96
|
-
In V2, installing the server plugin
|
|
97
|
-
(`"plugins": ["@ephemushroom/opencode-claude-mem"]`) auto-appends the same
|
|
98
|
-
bare package to `~/.config/opencode/cli.json` on first load. Restart OpenCode
|
|
99
|
-
after that first load if the sidebar is not yet present. Beta `19151` still
|
|
100
|
-
uses a separate CLI config; this is not a promise of same-launch discovery
|
|
101
|
-
from the server config alone. To register manually, use:
|
|
102
|
-
|
|
103
|
-
```json
|
|
104
|
-
{
|
|
105
|
-
"plugins": ["@ephemushroom/opencode-claude-mem"]
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## What You Get
|
|
110
|
-
|
|
111
|
-
| Surface | What it looks like |
|
|
112
|
-
|---|---|
|
|
113
|
-
| **System prompt** | `<claude-mem-context>` block with recent observations + session summaries for the current project |
|
|
114
|
-
| **Tools** | `mem-search` → `mem-timeline` → `mem-get-observations`, plus explicit `mem-save` (no MCP server needed) |
|
|
115
|
-
| **Read history** | Bounded supplementary file history after eligible file reads; original file output is preserved |
|
|
116
|
-
| **Optional semantic context** | Relevant project memories for the current real user prompt; **off by default** |
|
|
117
|
-
| **Sidebar** | `▶ Memory (online, 11.7k obs)` — click to expand recent sessions and latest observations |
|
|
118
|
-
| **Background** | Every tool call, assistant message, and file edit captured as observations; sessions summarized on idle |
|
|
119
|
-
|
|
120
|
-
### Sidebar
|
|
121
|
-
|
|
122
|
-
The plugin registers a sidebar section styled after OpenCode's native
|
|
123
|
-
MCP/Context sections — borderless, click-to-toggle:
|
|
124
|
-
|
|
125
6
|
```text
|
|
126
|
-
▶ Memory (online,
|
|
127
|
-
```
|
|
7
|
+
▶ Memory (online, 549 obs) ← collapsed (default): this project's observations
|
|
128
8
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
•
|
|
9
|
+
▼ Memory opencode-claude-mem ← click the header to expand
|
|
10
|
+
• obs 549 · sum 51 · ses 13
|
|
11
|
+
• all 54.0k obs ← every project, muted
|
|
132
12
|
Recent sessions
|
|
133
|
-
•
|
|
134
|
-
|
|
13
|
+
• 发布 0.7.0 前核查与侧边栏项目统计…
|
|
14
|
+
12m ago
|
|
135
15
|
Latest
|
|
136
|
-
◆
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
- Summary line turns **yellow** while the worker is processing (`(queue N)`)
|
|
142
|
-
and **red** when offline (`(offline)`).
|
|
143
|
-
- Observation icons match the injected context legend: ◆ feature · ● bugfix ·
|
|
144
|
-
⚖ decision · ○ discovery · ↻ refactor · ✓ change · ⚠/⚷ security.
|
|
145
|
-
- Recent items are only fetched while expanded, keeping the collapsed poll
|
|
146
|
-
loop cheap (stats every 5s).
|
|
147
|
-
- Fails open: worker offline → shows the offline state, never blocks the TUI.
|
|
148
|
-
|
|
149
|
-
The sidebar loads via the package's `./tui` bridge in both versions (OpenCode 2
|
|
150
|
-
registers the bare name in `~/.config/opencode/cli.json`). On startup
|
|
151
|
-
the plugin **self-heals the TUI config**: if it is registered as a server
|
|
152
|
-
plugin but missing from the TUI plugin list, it appends itself — no manual
|
|
153
|
-
configuration. OpenCode 1 writes into `tui.json` (symlinked files are written
|
|
154
|
-
through, preserving dotfiles setups); OpenCode 2 appends
|
|
155
|
-
`@ephemushroom/opencode-claude-mem` to `cli.json`'s `plugins` array.
|
|
156
|
-
Existing bare, `/cli`, or `/tui` sidebar entries (including versions and
|
|
157
|
-
object-form options) are left untouched, without adding another entry.
|
|
158
|
-
Malformed or comment-bearing CLI config is left untouched; add the bare name
|
|
159
|
-
manually in that case.
|
|
160
|
-
|
|
161
|
-
### Memory Tools
|
|
162
|
-
|
|
163
|
-
Three native OpenCode tools cover the same 3-step search workflow as the upstream
|
|
164
|
-
Claude-Mem MCP server — no MCP server or stdio subprocess required:
|
|
165
|
-
|
|
166
|
-
```mermaid
|
|
167
|
-
flowchart LR
|
|
168
|
-
A["mem-search<br/><i>find IDs by query</i>"] --> B["mem-timeline<br/><i>context around an ID</i>"]
|
|
169
|
-
B --> C["mem-get-observations<br/><i>full details for IDs</i>"]
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
| Tool | Worker endpoint | Use it for |
|
|
173
|
-
|---|---|---|
|
|
174
|
-
| `mem-search` | `GET /api/search` | Formatted index with query, project, source, type, date, pagination, and ordering filters |
|
|
175
|
-
| `mem-timeline` | `GET /api/timeline` | Chronological records around an `anchor` ID (or auto-located via `query`) |
|
|
176
|
-
| `mem-get-observations` | `POST /api/observations/batch` | Full details for IDs — e.g. the IDs shown in the injected context |
|
|
177
|
-
| `mem-save` | `POST /api/memory/save` | Explicitly save required `text`, optional `title` and `project` (defaults to current project) |
|
|
178
|
-
|
|
179
|
-
`mem-save` strips `<private>` and `<claude-mem-context>` material from text/title,
|
|
180
|
-
rejects empty/fully stripped content and values above 24 KiB, and reports success
|
|
181
|
-
only for a valid Worker acknowledgement. It never retries automatically: after
|
|
182
|
-
a timeout, check with search before retrying because the write may have succeeded.
|
|
183
|
-
Manual saves do not require an observation-model inference pass, but the Worker
|
|
184
|
-
still performs asynchronous vector indexing; this is **not** a promise of zero
|
|
185
|
-
embedding cost. Native and namespaced `mem-save` calls are excluded from automatic
|
|
186
|
-
observation capture.
|
|
187
|
-
|
|
188
|
-
### Memory configuration (both runtimes)
|
|
189
|
-
|
|
190
|
-
The per-turn registration, `mem-save`, file history, and semantic options described
|
|
191
|
-
here require **v0.6.0 or later**. Upgrade both server and sidebar package entries;
|
|
192
|
-
`0.5.0` does not include these features or the renderer fix.
|
|
193
|
-
|
|
194
|
-
Configuration is read once when the server plugin is set up. Quit and restart
|
|
195
|
-
OpenCode after changing options, environment, or settings; on V2 also restart the
|
|
196
|
-
background service. No semantic feature is enabled globally by this plugin.
|
|
197
|
-
|
|
198
|
-
**OpenCode 1** uses a tuple in `opencode.json`:
|
|
199
|
-
|
|
200
|
-
```json
|
|
201
|
-
{
|
|
202
|
-
"plugin": [["@ephemushroom/opencode-claude-mem", {
|
|
203
|
-
"semanticInjection": { "enabled": true, "limit": 5, "maxChars": 6000, "timeoutMs": 2000 },
|
|
204
|
-
"fileContext": { "enabled": true, "limit": 15, "maxChars": 6000, "timeoutMs": 1500 }
|
|
205
|
-
}]]
|
|
206
|
-
}
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
**OpenCode 2** uses a package/options object (not a V1 tuple):
|
|
210
|
-
|
|
211
|
-
```json
|
|
212
|
-
{
|
|
213
|
-
"plugins": [{
|
|
214
|
-
"package": "@ephemushroom/opencode-claude-mem",
|
|
215
|
-
"options": {
|
|
216
|
-
"semanticInjection": { "enabled": true, "limit": 5, "maxChars": 6000, "timeoutMs": 2000 },
|
|
217
|
-
"fileContext": { "enabled": true, "limit": 15, "maxChars": 6000, "timeoutMs": 1500 }
|
|
218
|
-
}
|
|
219
|
-
}]
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
| Option | Semantic default | File-history default | Accepted values |
|
|
224
|
-
|---|---|---|---|
|
|
225
|
-
| `enabled` | `false` | `true` | Boolean |
|
|
226
|
-
| `limit` | `5` | `15` | Integer 1–50 |
|
|
227
|
-
| `maxChars` | `6000` | `6000` | Integer 256–24000; supplementary payload only |
|
|
228
|
-
| `timeoutMs` | `2000` | `1500` | Integer 100–10000 |
|
|
229
|
-
|
|
230
|
-
Per-field precedence for semantic `enabled` and `limit` is **explicit plugin
|
|
231
|
-
options > environment > `~/.claude-mem/settings.json` > defaults**. The environment
|
|
232
|
-
and settings keys are `CLAUDE_MEM_SEMANTIC_INJECT` (`true`/`false` or `1`/`0`) and
|
|
233
|
-
`CLAUDE_MEM_SEMANTIC_INJECT_LIMIT` (integer 1–50). Settings may use booleans/numbers
|
|
234
|
-
or their string equivalents. Explicit `false` overrides environment `true`.
|
|
235
|
-
Invalid values fall through to the next valid source; other controls use explicit
|
|
236
|
-
options then defaults. Settings are read-only and never logged.
|
|
237
|
-
|
|
238
|
-
Semantic retrieval uses `POST /api/context/semantic` with `{q, project, limit}`
|
|
239
|
-
and reads JSON `{context, count}`. `q` is the sanitized real current prompt,
|
|
240
|
-
at least 20 characters; media-only, fully private, and identifiable internal
|
|
241
|
-
messages are excluded. No `platformSource` filter is sent, so Claude Code and
|
|
242
|
-
OpenCode memories remain shared. Each real prompt identity gets at most one
|
|
243
|
-
retrieval attempt, including failure/timeout, reused across tool-loop dispatches.
|
|
244
|
-
The system block is replaced rather than accumulated. Old Workers, malformed
|
|
245
|
-
responses and offline retrieval fail open.
|
|
246
|
-
|
|
247
|
-
File history uses `GET /api/observations/by-file` with repeated `path` parameters
|
|
248
|
-
(absolute and project-relative, normalized to forward slashes), `projects` and `limit`. Supported read arguments
|
|
249
|
-
include V1 `filePath`, V2 `path`, and `file_path`/`filePaths`/`file_paths` aliases.
|
|
250
|
-
Only existing regular files of at least 1500 bytes qualify, at most 10 paths per
|
|
251
|
-
read. Lookups run concurrently within one configured per-read deadline (including
|
|
252
|
-
file metadata lookup), not ten serial timeout periods. Rows are deduplicated by
|
|
253
|
-
memory session and the displayed text is bounded; a file whose mtime is at least
|
|
254
|
-
the newest observation timestamp gets no history. Delivered history is deduplicated per
|
|
255
|
-
session/file revision (mtime and size); failures and timeouts may retry on a later read.
|
|
256
|
-
Editing the file or starting a new session also permits another lookup. Supplementary history is explicitly
|
|
257
|
-
labeled and wrapped in memory tags, appended without replacing/truncating the
|
|
258
|
-
original read result, and never included in the automatic tool observation.
|
|
259
|
-
Known child sessions (`parentID` when supplied by the host) skip file-history
|
|
260
|
-
enrichment; V1 resumed sessions without that metadata cannot reliably be identified
|
|
261
|
-
as subagents and are not guessed from the agent's name.
|
|
262
|
-
|
|
263
|
-
### Prompt lifecycle and Worker limitations
|
|
264
|
-
|
|
265
|
-
V1 registers stable `chat.message` IDs; V2 records admission IDs without writing,
|
|
266
|
-
then registers only IDs present in delivered `session.context` records at model
|
|
267
|
-
dispatch. Thus queued V2 prompts do not advance the Worker's current prompt.
|
|
268
|
-
Resumed sessions without local admission history use the latest delivered real
|
|
269
|
-
user turn, not a synthetic `SESSION_START`, and tool callbacks do not reread the
|
|
270
|
-
whole history. Registrations are serialized per session and successful IDs are
|
|
271
|
-
deduplicated locally; a failed registration retains its real prompt for retry.
|
|
272
|
-
Media-only turns use `[media prompt]`. Fully private or identifiable synthetic
|
|
273
|
-
turns suppress automatic observations, summaries and semantic retrieval locally,
|
|
274
|
-
including when the Worker reports a skipped/private registration.
|
|
275
|
-
|
|
276
|
-
**Upstream v13.24.1 still deduplicates identical prompt text within its own time
|
|
277
|
-
window and has no consumed external prompt-ID contract.** This plugin submits
|
|
278
|
-
distinct IDs even if their text is identical, without prefixing/changing the text,
|
|
279
|
-
but cannot guarantee distinct database prompt rows. A `duplicate` acknowledgement
|
|
280
|
-
is accepted; other skipped registrations do not authorize automatic capture.
|
|
281
|
-
V1 exposes submission callbacks rather than V2's delivered/inbox distinction;
|
|
282
|
-
it cannot provide the same queued-consumption guarantee. A restart cannot restore
|
|
283
|
-
the plugin's in-memory ID dedupe ledger, so upstream dedupe remains relevant.
|
|
284
|
-
|
|
285
|
-
Base context is session-isolated, limited to 24000 characters, with a two-second
|
|
286
|
-
request timeout. It is refreshed at V1 compaction start/end and V2 compaction
|
|
287
|
-
requests/completed events or changed compaction records. Failed reads are retryable;
|
|
288
|
-
an invalidated or deleted session cannot be repopulated by an older in-flight read.
|
|
289
|
-
|
|
290
|
-
## How It Works
|
|
291
|
-
|
|
292
|
-
```mermaid
|
|
293
|
-
sequenceDiagram
|
|
294
|
-
participant OC as OpenCode
|
|
295
|
-
participant P as Plugin
|
|
296
|
-
participant W as Claude-Mem Worker
|
|
297
|
-
|
|
298
|
-
OC->>P: plugin loads
|
|
299
|
-
P->>P: self-heal tui.json / cli.json
|
|
300
|
-
P->>W: health check (auto-start via bunx if down)
|
|
301
|
-
OC->>P: each real user prompt (chat.message / delivered context)
|
|
302
|
-
P->>W: POST /api/sessions/init
|
|
303
|
-
OC->>P: system prompt transform / context hook
|
|
304
|
-
W-->>P: GET /api/context/inject (cached per session)
|
|
305
|
-
P-->>OC: inject <claude-mem-context> into system prompt
|
|
306
|
-
loop during the session
|
|
307
|
-
OC->>P: tool.execute.after / assistant text / file.edited
|
|
308
|
-
P->>W: POST /api/sessions/observations
|
|
309
|
-
end
|
|
310
|
-
OC->>P: session idle / execution succeeded / compaction ended
|
|
311
|
-
P->>W: POST /api/sessions/summarize
|
|
312
|
-
OC->>P: session.deleted
|
|
313
|
-
P->>P: flush pending observations and release local state
|
|
16
|
+
◆ TUI 动态坐标重算修复后连续 4 次…
|
|
17
|
+
3m ago · #55670
|
|
18
|
+
Click an item for details ← opens the full summary or observation
|
|
314
19
|
```
|
|
315
20
|
|
|
316
|
-
|
|
317
|
-
Claude-Mem worker HTTP API. All indexing, summarization, memory search, and
|
|
318
|
-
storage stay in upstream Claude-Mem.
|
|
21
|
+
One package brings claude-mem to OpenCode 2, installed and updated like any other plugin:
|
|
319
22
|
|
|
320
|
-
|
|
23
|
+
- **Capture and context injection** run the **official claude-mem OpenCode plugin**. This
|
|
24
|
+
package downloads it at the running Worker's version (from the `claude-mem` npm release,
|
|
25
|
+
checked against the registry's sha512) and loads it, so capture always matches the
|
|
26
|
+
Worker's API and no file has to be copied by hand.
|
|
27
|
+
- **Memory tools** beyond the official plugin's search: `save_memory`, `work_state_write`,
|
|
28
|
+
`work_state_read`, `dumb_search`, `get_tool_uses` and the six corpus tools, served straight
|
|
29
|
+
from the Worker's HTTP API. No MCP server is needed.
|
|
30
|
+
- **The Worker is started** when nothing answers on its port.
|
|
31
|
+
- **The Memory sidebar**, below.
|
|
321
32
|
|
|
322
|
-
|
|
323
|
-
|
|
33
|
+
- Counts are for the current project (the directory name), matching the Worker's own
|
|
34
|
+
project filter: case-insensitive, merged projects included. They are read from the Worker's
|
|
35
|
+
database in read-only mode, because its HTTP API reports only global totals. When the
|
|
36
|
+
database is not on this machine or cannot be read, the sidebar shows global totals and
|
|
37
|
+
labels them `all ·`.
|
|
38
|
+
- Titles are truncated by display width with an ellipsis, so wide CJK text fits; the
|
|
39
|
+
project's own name is dropped from titles, since every row belongs to it.
|
|
40
|
+
- Clicking a recent session or observation opens its details in a dialog; observations show
|
|
41
|
+
the `get_observations([id])` call that fetches them through MCP.
|
|
42
|
+
- Summary turns yellow while the Worker is processing (`(queue N)`) and red when offline.
|
|
43
|
+
- Icons follow the injected context legend: ◆ feature · ● bugfix · ⚖ decision ·
|
|
44
|
+
○ discovery · ↻ refactor · ✓ change · ⚠/⚷ security.
|
|
45
|
+
- Recent rows are fetched only while expanded; collapsed, it polls stats every 5s.
|
|
46
|
+
- Read-only and fail-open: an offline Worker shows the offline state, never blocks the TUI.
|
|
324
47
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
| Refresh memory on compaction | `experimental.session.compacting` + `session.compacted` | compaction model requests/events + delivered compaction records |
|
|
329
|
-
| Register each real user prompt | `chat.message` (message ID) | `ctx.session.hook('context')` (`ctx.session.context` delivered IDs; not inbox admission) |
|
|
330
|
-
| Capture tool observations | `tool.execute.after` | `ctx.tool.hook('execute.after')` |
|
|
331
|
-
| Custom memory tools | `tool` (`mem-search`, …) | `ctx.tool.transform` (`tools.add`) |
|
|
332
|
-
| Assistant text capture | `event` (`message.updated`, debounced 250ms) | `session.text.ended` event (complete text) |
|
|
333
|
-
| File edit observations | `event` (`file.edited`) | `ctx.tool.hook('execute.after')` |
|
|
334
|
-
| Summarize on idle | `event` (`session.idle`) | `session.execution.succeeded` event |
|
|
335
|
-
| Summarize after compaction | `event` (`session.compacted`) | `session.compaction.ended` event |
|
|
336
|
-
| Release session tracking | `event` (`session.deleted`) | `session.deleted` event |
|
|
337
|
-
| Sidebar slot | `api.slots.register` (`sidebar_content`) | `ctx.ui.slot({ append: 'sidebar.content', render })` |
|
|
48
|
+
Verified on macOS with OpenCode **2.3.0** (built against `@opencode/plugin` 2.2.7,
|
|
49
|
+
`@opentui/solid` 0.8.1). The Windows paths follow claude-mem's own launcher location but
|
|
50
|
+
have not been run on Windows yet.
|
|
338
51
|
|
|
339
|
-
|
|
52
|
+
## Setup (OpenCode 2)
|
|
340
53
|
|
|
341
|
-
|
|
54
|
+
1. **Install claude-mem** once per machine. This installs the Worker and its launcher:
|
|
342
55
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
| Claude Code writes | Stored as `platform_source=claude` |
|
|
347
|
-
| Either reads (inject/search) | Sees **all** memory for the project, regardless of source |
|
|
56
|
+
```bash
|
|
57
|
+
npx claude-mem install
|
|
58
|
+
```
|
|
348
59
|
|
|
349
|
-
|
|
350
|
-
|
|
60
|
+
2. **Add the plugin.** This installs the package and lists it in
|
|
61
|
+
`~/.config/opencode/opencode.json`:
|
|
351
62
|
|
|
352
|
-
|
|
63
|
+
```bash
|
|
64
|
+
opencode plugin add @ephemushroom/opencode-claude-mem
|
|
65
|
+
```
|
|
353
66
|
|
|
354
|
-
|
|
67
|
+
3. **Add the sidebar** to `~/.config/opencode/cli.json`:
|
|
355
68
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
- A running Claude-Mem worker (default `127.0.0.1:37777`)
|
|
69
|
+
```json
|
|
70
|
+
{ "plugins": ["@ephemushroom/opencode-claude-mem"] }
|
|
71
|
+
```
|
|
360
72
|
|
|
361
|
-
|
|
73
|
+
Restart OpenCode. The first start downloads the official files (about 10 MB) in the
|
|
74
|
+
background; the memory tools work at once, and capture begins when the download finishes.
|
|
362
75
|
|
|
363
|
-
|
|
76
|
+
### Updating
|
|
364
77
|
|
|
365
|
-
```
|
|
366
|
-
|
|
367
|
-
/plugin install claude-mem
|
|
78
|
+
```bash
|
|
79
|
+
opencode plugin update # this package: server part and sidebar
|
|
368
80
|
```
|
|
369
81
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
### Step 2: Add the OpenCode Plugin
|
|
373
|
-
|
|
374
|
-
Add this plugin to your project or global `opencode.json`:
|
|
375
|
-
|
|
376
|
-
**OpenCode 1** (`opencode`):
|
|
377
|
-
|
|
378
|
-
```json
|
|
379
|
-
{
|
|
380
|
-
"plugin": ["@ephemushroom/opencode-claude-mem"]
|
|
381
|
-
}
|
|
382
|
-
```
|
|
82
|
+
OpenCode does not update plugins by itself. The official claude-mem files need no command:
|
|
83
|
+
after a Worker upgrade, the next OpenCode start fetches the matching version.
|
|
383
84
|
|
|
384
|
-
|
|
85
|
+
### Options
|
|
385
86
|
|
|
386
87
|
```json
|
|
387
88
|
{
|
|
388
|
-
"plugins": ["@ephemushroom/opencode-claude-mem"]
|
|
89
|
+
"plugins": [{ "package": "@ephemushroom/opencode-claude-mem", "options": { "mcp": true } }]
|
|
389
90
|
}
|
|
390
91
|
```
|
|
391
92
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
Then restart OpenCode.
|
|
93
|
+
- `mcp: true` registers claude-mem's own MCP server (every tool it has, including the
|
|
94
|
+
`smart_*` code-outline tools) in a separate process, instead of this package's tools.
|
|
95
|
+
A `claude-mem` entry you wrote under `mcp.servers` is left as it is.
|
|
396
96
|
|
|
397
|
-
|
|
97
|
+
claude-mem's settings apply as usual (its `settings.json`, in `~/.claude-mem` or
|
|
98
|
+
`CLAUDE_MEM_DATA_DIR`, or the environment):
|
|
398
99
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
100
|
+
- `CLAUDE_MEM_WORKER_HOST` / `CLAUDE_MEM_WORKER_PORT` select the Worker. Without a port,
|
|
101
|
+
claude-mem's own default applies (37700 plus the last two digits of the user id).
|
|
102
|
+
- `CLAUDE_MEM_LOCAL_API_TOKEN` is sent to a Worker on this machine that requires it. This
|
|
103
|
+
package's own requests refuse redirects; the official plugin's capture requests are
|
|
104
|
+
claude-mem's code and follow them (as of 15.18.3).
|
|
105
|
+
- `CLAUDE_MEM_WORKER_AUTOSTART=false` keeps this package from starting the Worker.
|
|
106
|
+
- `CLAUDE_MEM_WORK_STATE_ENABLED=false` removes the two work-state tools.
|
|
107
|
+
- `CLAUDE_MEM_WORKER_URL` is not supported: the official OpenCode plugin addresses the
|
|
108
|
+
Worker by host and port only, so the sidebar reports it and nothing is captured.
|
|
402
109
|
|
|
403
|
-
|
|
404
|
-
OpenCode 1 also shows a `Memory active · <project>` toast when a session
|
|
405
|
-
starts (OpenCode 2 only toasts a warning when the worker is offline).
|
|
110
|
+
### Tools
|
|
406
111
|
|
|
407
|
-
|
|
112
|
+
OpenCode lists them as the `claude_mem` namespace (`tools.claude_mem.save_memory(...)` in
|
|
113
|
+
Code Mode, `claude_mem_save_memory` as a direct tool call). The official plugin adds
|
|
114
|
+
`claude_mem_search`, `claude_mem_timeline` and `claude_mem_get_observations`.
|
|
408
115
|
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
116
|
+
| Tool | Purpose |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `save_memory` | Save a durable note |
|
|
119
|
+
| `work_state_write` / `work_state_read` | Per-project to-do lists and working state, shown at session start |
|
|
120
|
+
| `dumb_search` | One-call lookup by title overlap |
|
|
121
|
+
| `get_tool_uses` | Raw tool input/output for selected ids |
|
|
122
|
+
| `build_corpus`, `list_corpora`, `prime_corpus`, `query_corpus`, `rebuild_corpus`, `reprime_corpus` | Knowledge corpora |
|
|
413
123
|
|
|
414
|
-
|
|
415
|
-
- duplicate context injection and toasts
|
|
416
|
-
- bridged MCP tools (`search`, `timeline`, `get_observations`) shadowing the
|
|
417
|
-
native `mem-*` tools
|
|
124
|
+
### Share memory across Claude Code and OpenCode
|
|
418
125
|
|
|
419
|
-
|
|
126
|
+
The official plugin injects only OpenCode-recorded memory by default. To see every source,
|
|
127
|
+
add this to `~/.claude-mem/settings.json` (it also applies to Claude Code's session start):
|
|
420
128
|
|
|
421
|
-
```
|
|
422
|
-
{
|
|
423
|
-
"claude_code": {
|
|
424
|
-
"plugins_override": {
|
|
425
|
-
"claude-mem@thedotmack": false
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
129
|
+
```json
|
|
130
|
+
{ "CLAUDE_MEM_SESSION_START_INCLUDE_ALL_SOURCES": "true" }
|
|
429
131
|
```
|
|
430
132
|
|
|
431
|
-
|
|
432
|
-
itself keeps using claude-mem normally, and memory stays shared through the
|
|
433
|
-
worker. Everything the bridge provided is covered natively by this plugin:
|
|
434
|
-
|
|
435
|
-
| Bridged (before) | Native (this plugin) |
|
|
436
|
-
|---|---|
|
|
437
|
-
| MCP `search` | `mem-search` tool |
|
|
438
|
-
| MCP `timeline` | `mem-timeline` tool |
|
|
439
|
-
| MCP `get_observations` | `mem-get-observations` tool |
|
|
440
|
-
| `SessionStart` context hook | `system.transform` injection |
|
|
441
|
-
| `PostToolUse` observation hook | `tool.execute.after` capture |
|
|
442
|
-
|
|
443
|
-
## Reference
|
|
444
|
-
|
|
445
|
-
### Hook Mapping
|
|
446
|
-
|
|
447
|
-
Claude Code hooks → this plugin's adapters (see [Hook Mapping (V1 ↔ V2)](#hook-mapping-v1--v2)
|
|
448
|
-
for the per-runtime API):
|
|
449
|
-
|
|
450
|
-
| Claude Code | OpenCode (both runtimes) | Purpose |
|
|
451
|
-
|---|---|---|
|
|
452
|
-
| `SessionStart` | system prompt injection (`system.transform` / `context` hook) | Inject memory context |
|
|
453
|
-
| `SessionStart` | compaction injection (`session.compacting` / context hook) | Preserve memory during compaction |
|
|
454
|
-
| `UserPromptSubmit` | session init (`chat.message` / context hook) | Initialize session with real user prompt |
|
|
455
|
-
| `PostToolUse` | observation capture (`tool.execute.after` / `execute.after` hook) | Capture tool observations |
|
|
456
|
-
| Claude-Mem MCP `search` | `mem-search` tool | Search memory from OpenCode |
|
|
457
|
-
| Claude-Mem MCP `timeline` | `mem-timeline` tool | Chronological context around an observation |
|
|
458
|
-
| Claude-Mem MCP `get_observations` | `mem-get-observations` tool | Fetch full observation details by ID |
|
|
459
|
-
| _(streaming)_ | assistant text (`message.updated` / `session.text.ended`) | Capture assistant text |
|
|
460
|
-
| _(streaming)_ | file edits (`file.edited` / tool hook) | Record file edit observations |
|
|
461
|
-
| _(compaction)_ | `session.compacted` / `session.compaction.ended` | Summarize after OpenCode compacts |
|
|
462
|
-
| `Stop` | `session.idle` / `session.execution.succeeded` | Flush + summarize |
|
|
463
|
-
| `SessionEnd` | `session.deleted` | Flush observations and release local state; Worker self-completes |
|
|
464
|
-
|
|
465
|
-
### Worker API Endpoints Used
|
|
466
|
-
|
|
467
|
-
| Method | Endpoint | Purpose |
|
|
468
|
-
|---|---|---|
|
|
469
|
-
| `GET` | `/api/health` | Health check |
|
|
470
|
-
| `GET` | `/api/context/inject?project={name}` | Fetch formatted memory context |
|
|
471
|
-
| `POST` | `/api/sessions/init` | Initialize session |
|
|
472
|
-
| `POST` | `/api/sessions/observations` | Store tool observation |
|
|
473
|
-
| `POST` | `/api/sessions/summarize` | Trigger summarization |
|
|
474
|
-
| `GET` | `/api/search?query=...&project=...&dateStart=...&dateEnd=...` | `mem-search`; also supports `limit`, `platformSource`, `type`, `obs_type`, `offset`, and `orderBy` |
|
|
475
|
-
| `GET` | `/api/timeline?project={name}&anchor={id}` | `mem-timeline` |
|
|
476
|
-
| `POST` | `/api/observations/batch` | `mem-get-observations` |
|
|
477
|
-
| `POST` | `/api/memory/save` | Explicit `mem-save`, nested `metadata.platformSource` attribution |
|
|
478
|
-
| `POST` | `/api/context/semantic` | Opt-in semantic context; JSON `{context,count}` response |
|
|
479
|
-
| `GET` | `/api/observations/by-file?path=...&path=...&projects=...&limit=...` | Supplementary file history |
|
|
480
|
-
| `GET` | `/api/stats` + `/api/processing-status` | Sidebar status |
|
|
481
|
-
| `GET` | `/api/summaries` + `/api/observations` | Sidebar recent items (expanded only) |
|
|
482
|
-
|
|
483
|
-
The worker endpoint is resolved in this order: `CLAUDE_MEM_WORKER_HOST` /
|
|
484
|
-
`CLAUDE_MEM_WORKER_PORT` environment variables → `~/.claude-mem/settings.json`
|
|
485
|
-
→ `127.0.0.1:37777`.
|
|
486
|
-
|
|
487
|
-
### Key Implementation Details
|
|
488
|
-
|
|
489
|
-
- **Dual-runtime architecture** — `src/index.ts` is the OpenCode 1 plugin,
|
|
490
|
-
`src/v2.ts` the OpenCode 2 plugin (`Plugin.define`), `src/tui.ts` the V1
|
|
491
|
-
sidebar, `src/cli.ts` the V2 sidebar; `src/shared.ts` and
|
|
492
|
-
`src/sidebar-model.ts` hold the shared pure helpers; `src/worker-client.ts`
|
|
493
|
-
is a static HTTP client; `src/tui-registration.ts` self-heals `tui.json`
|
|
494
|
-
(V1) and `cli.json` (V2).
|
|
495
|
-
- **Static package bridges** — `src/package-server.ts` exposes `{ id, server,
|
|
496
|
-
setup }` at both `.` and `./server`; `src/package-tui.ts` exposes `{ id, tui,
|
|
497
|
-
setup }` at `./tui`. V1 reads `server`/`tui`; V2 reads `setup`. Neither bridge
|
|
498
|
-
invokes both adapters. Both installed server loaders prefer `./server`, so
|
|
499
|
-
routing only the root export to V2 is insufficient. Never combine `server`
|
|
500
|
-
and `tui` in one object: V1 rejects that shape.
|
|
501
|
-
- **Host renderer ownership** — the built TUI bridge uses explicit `.js`
|
|
502
|
-
relative imports so the host discovers both adapter modules and routes their
|
|
503
|
-
OpenTUI/Solid imports to its own runtime. Extensionless bridge imports can bypass
|
|
504
|
-
that prescan and crash the sidebar with `No renderer found`.
|
|
505
|
-
- **Zero runtime dependencies for server plugins** — the OpenCode plugin SDK
|
|
506
|
-
is bundled into `dist/` (V1 `index.js` ~490 KB, V2 `v2.js` ~160 KB including
|
|
507
|
-
bounded-response validation, using a deep SDK import that skips effect). The TUI entrypoints keep
|
|
508
|
-
`@opentui/solid` external (provided by the host TUI).
|
|
509
|
-
- **Reactive sidebar** — collapse state and view data are solid-js signals
|
|
510
|
-
(shared with OpenCode's own solid instance via `--external solid-js`), so
|
|
511
|
-
clicking the header re-renders reliably; falls back to plain closures if
|
|
512
|
-
solid-js cannot be resolved.
|
|
513
|
-
- **No console logging** — `console.*` output corrupts the OpenCode TUI;
|
|
514
|
-
the plugin never logs and never throws from hooks.
|
|
515
|
-
- **Deferred toast** — health toasts only happen after hook execution begins,
|
|
516
|
-
avoiding startup crashes caused by early TUI access.
|
|
517
|
-
- **Auto-start** — if the worker is down on load, spawns
|
|
518
|
-
`bunx claude-mem start` once per OpenCode process (skipped if `bun` is not
|
|
519
|
-
on `PATH`). Health is rechecked on subsequent hooks, so a recovered Worker
|
|
520
|
-
does not require restarting OpenCode.
|
|
521
|
-
- **Context caching** — base memory context is reused per session until a
|
|
522
|
-
compaction boundary invalidates it. Failed fetches are not cached.
|
|
523
|
-
- **Circular memory protection** — injected context is wrapped in
|
|
524
|
-
`<claude-mem-context>` tags, Claude-Mem search tools are skipped from
|
|
525
|
-
observation capture, and memory tags are stripped before storage.
|
|
526
|
-
- **Observation hardening** — low-value meta tools skipped; oversized payloads
|
|
527
|
-
truncated by UTF-8 byte size (24 KB cap).
|
|
528
|
-
- **Field name correctness** — worker payloads use `contentSessionId`, not
|
|
529
|
-
`claudeSessionId` (the wrong name fails silently).
|
|
530
|
-
- **Session lifecycle hygiene** — `session.deleted` flushes pending observations
|
|
531
|
-
and releases local tracking. Claude-Mem self-completes processing; the removed
|
|
532
|
-
`/api/sessions/complete` endpoint is not called.
|
|
533
|
-
- **Attribution** — observations include the OpenCode call ID as `tool_use_id`;
|
|
534
|
-
summaries include the latest assistant's `observedModel` when available.
|
|
535
|
-
- **Write status** — failed HTTP writes return failure without throwing; a summary
|
|
536
|
-
toast is shown only after the Worker accepts the request, not after generation.
|
|
537
|
-
|
|
538
|
-
## Troubleshooting
|
|
539
|
-
|
|
540
|
-
### No memory appears in OpenCode
|
|
541
|
-
|
|
542
|
-
- Confirm the worker is running:
|
|
133
|
+
### Verify
|
|
543
134
|
|
|
544
135
|
```bash
|
|
545
|
-
|
|
136
|
+
opencode plugin list # opencode-claude-mem 0.7.1 @ephemushroom/opencode-claude-mem
|
|
546
137
|
```
|
|
547
138
|
|
|
548
|
-
|
|
549
|
-
|
|
139
|
+
Open a session: the sidebar shows `▶ Memory (online, …)`, and new observations carry
|
|
140
|
+
canonical tool names (`Read`, `Edit`, `Bash`) with `files_modified` filled in.
|
|
550
141
|
|
|
551
|
-
###
|
|
142
|
+
### Where files go
|
|
552
143
|
|
|
553
|
-
|
|
554
|
-
|
|
144
|
+
`~/.cache/opencode-claude-mem/` (or `$XDG_CACHE_HOME/opencode-claude-mem/`): the official
|
|
145
|
+
files under `official/<version>/` (about 1.5 MB per claude-mem version; earlier versions are
|
|
146
|
+
kept, because another OpenCode process may still run from them) and `status/`, which carries
|
|
147
|
+
the server part's state to the sidebar. Deleting the directory while OpenCode is closed is
|
|
148
|
+
safe.
|
|
555
149
|
|
|
556
|
-
|
|
557
|
-
- Confirm `claude-mem` is installed for `bunx` — run
|
|
558
|
-
`bunx claude-mem --version` once to populate the cache.
|
|
559
|
-
- On Windows after a forced kill, port `37777` may stay in `TIME_WAIT` for
|
|
560
|
-
30-120 seconds; wait it out or restart Claude Code.
|
|
561
|
-
- Restart Claude Code to bring Claude-Mem back up via its own supervisor.
|
|
150
|
+
## Migrating
|
|
562
151
|
|
|
563
|
-
|
|
152
|
+
**From v0.7.0's manual setup.** Remove what the manual steps installed, then follow Setup:
|
|
564
153
|
|
|
565
|
-
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
`@ephemushroom/opencode-claude-mem` in its `plugins` array — self-healed
|
|
570
|
-
the same way (comment-bearing cli.json files are left untouched, so remove
|
|
571
|
-
the comments or add the entry manually).
|
|
572
|
-
- The sidebar requires OpenCode's `@opentui/solid` runtime; if unavailable the
|
|
573
|
-
section is skipped silently while hooks and tools keep working.
|
|
154
|
+
- delete `~/.config/opencode/plugins/claude-mem.js`. While that file exists it keeps
|
|
155
|
+
capturing, this package does not load a second copy, and that file is not kept up to date;
|
|
156
|
+
- delete the `claude-mem` entry under `mcp.servers` in `opencode.json`, unless you want
|
|
157
|
+
the MCP server; in that case use `options.mcp` instead.
|
|
574
158
|
|
|
575
|
-
|
|
159
|
+
**From v0.6.x.** Its own capture adapter is gone; capture is the official plugin's.
|
|
160
|
+
`mem-search` / `mem-timeline` / `mem-get-observations` are now `claude_mem_search` /
|
|
161
|
+
`claude_mem_timeline` / `claude_mem_get_observations`, and `mem-save` is `save_memory`.
|
|
162
|
+
Read-file history and opt-in semantic injection are not available.
|
|
576
163
|
|
|
577
|
-
|
|
578
|
-
|
|
164
|
+
**OpenCode 1.** The server part needs OpenCode 2. On OpenCode 1 use
|
|
165
|
+
`npx claude-mem install --ide opencode`; the sidebar still loads from `tui.json`.
|
|
579
166
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
- You are likely running both this plugin and a Claude Code compatibility
|
|
583
|
-
bridge for claude-mem. See
|
|
584
|
-
[Disable the Claude Code bridge](#using-with-oh-my-openagent-disable-the-claude-code-bridge).
|
|
585
|
-
|
|
586
|
-
### Observations are missing or incomplete
|
|
167
|
+
## Troubleshooting
|
|
587
168
|
|
|
588
|
-
-
|
|
589
|
-
-
|
|
169
|
+
- **`(offline)`**: the Worker is not running and could not be started. Run
|
|
170
|
+
`npx claude-mem start`; if that command is missing, `npx claude-mem install`.
|
|
171
|
+
- **`(capture off)`**: nothing records this OpenCode's sessions. Expand the sidebar: the
|
|
172
|
+
first row says why (claude-mem not installed, the Worker did not start, the download
|
|
173
|
+
failed, or a `plugins/claude-mem.js` file that OpenCode has not loaded) and what to do.
|
|
174
|
+
The package looks again every minute.
|
|
175
|
+
- **Sidebar missing**: check `~/.config/opencode/cli.json` lists the package; the sidebar
|
|
176
|
+
needs OpenCode's `@opentui/solid` runtime and is skipped silently without it.
|
|
177
|
+
- **Duplicate observations**: two capture integrations are active. Remove
|
|
178
|
+
`~/.config/opencode/plugins/claude-mem.js` or this package, and disable any Claude Code
|
|
179
|
+
compatibility bridge for claude-mem. In Code Mode one call is recorded as `execute` plus
|
|
180
|
+
the tool it ran; that is one call, not a duplicate.
|
|
181
|
+
- **Behind a registry mirror**: the download uses `CLAUDE_MEM_NPM_REGISTRY`, then
|
|
182
|
+
`npm_config_registry`, then `https://registry.npmjs.org`. The mirror must be HTTPS (or on
|
|
183
|
+
this machine): it names both the tarball and its checksum, so it is trusted like the
|
|
184
|
+
registry itself.
|
|
590
185
|
|
|
591
186
|
## Development
|
|
592
187
|
|
|
593
188
|
```bash
|
|
594
189
|
bun install
|
|
595
|
-
bun run build
|
|
596
|
-
bun test
|
|
597
|
-
bun run lint
|
|
598
|
-
bun
|
|
599
|
-
bun src/test-fixtures/
|
|
600
|
-
bun src/test-fixtures/
|
|
601
|
-
bun src/test-fixtures/
|
|
602
|
-
bun src/test-fixtures/tui-runtime.ts
|
|
603
|
-
bun
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
local registry, and ask the installed host to resolve the bare npm name in an
|
|
612
|
-
isolated home/cache. Registry access is needed for package dependencies. Server
|
|
613
|
-
QA drives base/opt-in semantic injection, exactly-once tool capture, all four memory tools,
|
|
614
|
-
private-save rejection, file-history enrichment without capture pollution, and
|
|
615
|
-
summarization. HTTP regression fixtures also cover repeated/distinct IDs, queued
|
|
616
|
-
V2 admission versus consumption, private turns, retries and compaction invalidation.
|
|
617
|
-
The V2 TUI probe uses ConPTY and xterm terminal cells to open a real session and
|
|
618
|
-
capture collapsed, expanded, and re-collapsed states with actual mouse events.
|
|
619
|
-
It checks online/offline operation, unchanged CLI config, and zero model requests.
|
|
620
|
-
Set `MEM_TUI_EVIDENCE_DIR` to retain text and truecolor ANSI captures. The separate
|
|
621
|
-
OpenTUI driver covers component behavior. V1's interactive host remains outside
|
|
622
|
-
this check; its server runtime is verified. Browser PNG fidelity is not claimed.
|
|
190
|
+
bun run build # server part + sidebar adapters + TUI bridge + declarations
|
|
191
|
+
bun test # build first: export tests import dist artifacts
|
|
192
|
+
bun run typecheck && bun run lint && bun run fmt:check
|
|
193
|
+
bun src/test-fixtures/server-runtime.ts # installed opencode: download, capture, tools
|
|
194
|
+
bun src/test-fixtures/server-runtime.ts mcp # options.mcp registers the MCP server
|
|
195
|
+
bun src/test-fixtures/server-runtime.ts start # no Worker: the launcher is run (macOS/Linux)
|
|
196
|
+
bun src/test-fixtures/server-runtime.ts standalone # plugins/claude-mem.js present: one capture
|
|
197
|
+
bun src/test-fixtures/tui-runtime.ts # installed opencode: real PTY, render + mouse toggle
|
|
198
|
+
bun src/test-fixtures/tui-runtime.ts offline # offline state renders and toggles
|
|
199
|
+
bun --conditions=browser src/test-fixtures/cli-driver.ts render # OpenTUI component driver
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
The runtime checks pack the current build, serve it from a temporary local registry, and run
|
|
203
|
+
the installed `opencode` in an isolated home with a fake Worker and model. They never touch
|
|
204
|
+
your config or memory database. The server check downloads the real `claude-mem` release. Set `MEM_TUI_EVIDENCE_DIR` to keep the captured
|
|
205
|
+
collapsed, expanded, detail-dialog and re-collapsed frames.
|
|
623
206
|
|
|
624
207
|
## License
|
|
625
208
|
|