@zilliz/memsearch-opencode 0.2.1 → 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.
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.
@@ -157,7 +162,7 @@ Leave it empty or unset to keep the current `small_model` / plugin default behav
157
162
 
158
163
  2. **Index**: The markdown files are indexed by memsearch into a Milvus collection (Milvus Lite by default, runs in-process).
159
164
 
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`.
165
+ 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
166
 
162
167
  4. **Cold-start**: At session start, recent memory bullets are injected into the system prompt so the assistant has immediate context.
163
168
 
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.0",
4
4
  "description": "memsearch plugin for OpenCode — semantic memory search across sessions",
5
5
  "type": "module",
6
6
  "main": "index.ts",