@zilliz/memsearch-opencode 0.2.1 → 0.3.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 CHANGED
@@ -62,6 +62,7 @@ OpenCode Session
62
62
  ├── chat.message hook ──→ Detect turn completion
63
63
  │ │
64
64
  │ ├── Extract last turn from SQLite
65
+ │ ├── Persist turn metadata to .memsearch/opencode-turns.db
65
66
  │ ├── Summarize via LLM (third-person notes)
66
67
  │ └── Append to .memsearch/memory/YYYY-MM-DD.md
67
68
  │ │
@@ -106,7 +107,11 @@ We discussed the authentication flow before, what was the approach?
106
107
  |------|-------------|
107
108
  | `memory_search` | Semantic search over past memories. Returns ranked chunks. |
108
109
  | `memory_get` | Expand a chunk hash to see the full markdown section. |
109
- | `memory_transcript` | Read original conversation from OpenCode SQLite DB. |
110
+ | `memory_transcript` | Read original conversation from OpenCode SQLite DB, optionally centered on a turn cursor. |
111
+
112
+ `<project>/.memsearch/opencode-turns.db` stores derived capture checkpoints and
113
+ turn ordering only. It is rebuildable state, not the source of truth for
114
+ transcript recall.
110
115
 
111
116
  ## Memory Files
112
117
 
@@ -127,7 +132,7 @@ Each file contains timestamped entries with bullet-point summaries:
127
132
  ## Session 14:30
128
133
 
129
134
  ### 14:30
130
- <!-- session:ses_abc123 db:~/.local/share/opencode/opencode.db -->
135
+ <!-- session:ses_abc123 turn:msg_123abc db:~/.local/share/opencode/opencode.db -->
131
136
  - User asked about the authentication flow.
132
137
  - Assistant explained the OAuth2 implementation in auth.ts.
133
138
  - Assistant modified the token refresh logic in refresh.ts.
@@ -143,13 +148,22 @@ memsearch config set embedding.provider openai
143
148
  export OPENAI_API_KEY=sk-...
144
149
  ```
145
150
 
146
- To override only the OpenCode capture summarization model:
151
+ To override only the OpenCode native capture summarization model:
147
152
 
148
153
  ```bash
149
154
  memsearch config set plugins.opencode.summarize.model anthropic/claude-haiku
150
155
  ```
151
156
 
152
- Leave it empty or unset to keep the current `small_model` / plugin default behavior. This setting does not fall back to `llm.model`.
157
+ To use a memsearch-managed API provider instead:
158
+
159
+ ```bash
160
+ memsearch config set llm.providers.openai.type openai
161
+ memsearch config set llm.providers.openai.model gpt-4o-mini
162
+ memsearch config set llm.providers.openai.api_key env:OPENAI_API_KEY
163
+ memsearch config set plugins.opencode.summarize.provider openai
164
+ ```
165
+
166
+ Leave `plugins.opencode.summarize.provider` empty or set it to `native` to keep the current `small_model` / plugin default behavior. This setting does not fall back to `llm.model`.
153
167
 
154
168
  ## How It Works
155
169
 
@@ -157,7 +171,7 @@ Leave it empty or unset to keep the current `small_model` / plugin default behav
157
171
 
158
172
  2. **Index**: The markdown files are indexed by memsearch into a Milvus collection (Milvus Lite by default, runs in-process).
159
173
 
160
- 3. **Recall**: When the assistant needs historical context, it calls `memory_search` to find relevant chunks. Results can be expanded with `memory_get` or drilled into with `memory_transcript`.
174
+ 3. **Recall**: When the assistant needs historical context, it calls `memory_search` to find relevant chunks. Results can be expanded with `memory_get` or drilled into with `memory_transcript`, which reads the original transcript from OpenCode SQLite.
161
175
 
162
176
  4. **Cold-start**: At session start, recent memory bullets are injected into the system prompt so the assistant has immediate context.
163
177
 
package/index.ts CHANGED
@@ -285,11 +285,14 @@ const MemsearchPlugin: Plugin = async ({ project, directory, worktree }) => {
285
285
  description:
286
286
  "Retrieve the original conversation from a past OpenCode session. " +
287
287
  "Use after memory_get when the expanded result contains a session anchor " +
288
- "(<!-- session:ID db:PATH -->). Returns the formatted " +
289
- "dialogue with [Human] and [Assistant] labels.",
288
+ "(<!-- session:ID turn:ID db:PATH -->). Returns the formatted " +
289
+ "dialogue with [Human] and [Assistant] labels. When turn_id is present, " +
290
+ "the tool returns the target turn plus surrounding context.",
290
291
  args: {
291
292
  session_id: tool.schema.string().describe("The session ID from the anchor comment"),
292
- limit: tool.schema.number().optional().describe("Max number of messages to return (default: 20)"),
293
+ turn_id: tool.schema.string().optional().describe("Optional turn ID from the anchor comment"),
294
+ context: tool.schema.number().optional().describe("Turns before/after the target turn (default: 3)"),
295
+ limit: tool.schema.number().optional().describe("Max number of turns to return when no turn_id is provided (default: 20)"),
293
296
  },
294
297
  async execute(args, context) {
295
298
  const dir = context?.directory || projectDir;
@@ -297,11 +300,25 @@ const MemsearchPlugin: Plugin = async ({ project, directory, worktree }) => {
297
300
  if (autoCapture) startCaptureDaemon(dir, col, memsearchCmd);
298
301
  try {
299
302
  const scriptPath = join(PLUGIN_DIR, "scripts", "parse-transcript.py");
300
- const result = spawnSync(
301
- "python3",
302
- [scriptPath, args.session_id, ...(args.limit ? ["--limit", String(args.limit)] : [])],
303
- { encoding: "utf-8", timeout: 15000 }
304
- );
303
+ const scriptArgs = [
304
+ scriptPath,
305
+ args.session_id,
306
+ "--project-dir",
307
+ dir,
308
+ ];
309
+ if (args.turn_id) {
310
+ scriptArgs.push("--turn", args.turn_id);
311
+ }
312
+ if (typeof args.context === "number") {
313
+ scriptArgs.push("--context", String(args.context));
314
+ }
315
+ if (typeof args.limit === "number") {
316
+ scriptArgs.push("--limit", String(args.limit));
317
+ }
318
+ const result = spawnSync("python3", scriptArgs, {
319
+ encoding: "utf-8",
320
+ timeout: 15000,
321
+ });
305
322
  return result.stdout?.trim() || result.stderr || "No transcript content found.";
306
323
  } catch (e: any) {
307
324
  return `Transcript parse failed: ${e.message}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zilliz/memsearch-opencode",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "memsearch plugin for OpenCode — semantic memory search across sessions",
5
5
  "type": "module",
6
6
  "main": "index.ts",