Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,12 @@ plugins/
│ ├── skills/ # memory-recall SKILL.md (decision guide)
│ └── scripts/ # derive-collection.sh, parse-transcript.sh
├── opencode/ # OpenCode plugin (TypeScript npm plugin)
│ ├── index.ts # Tools + experimental hooks
│ ├── scripts/ # capture-daemon.py (SQLite polling), parse-transcript.py
│ └── skills/ # memory-recall SKILL.md
│ ├── index.ts # Plugin.define setup, execution events, prompt/context hooks
│ ├── capture.ts # Capture/recovery coordinator and native inference bridge
│ ├── tools.ts # memory_search/get/transcript registration
│ ├── skills.ts # Packaged Skill registration
│ ├── scripts/ # capture.py (durable capture), opencode_turns.py, parse-transcript.py
│ └── skills/ # memory-recall, memory-config, memory-to-skill
└── codex/ # Codex plugin (shell hooks + SKILL.md)
├── hooks/ # SessionStart, Stop, UserPromptSubmit
├── skills/ # memory-recall skill
Expand Down Expand Up @@ -130,12 +133,26 @@ TypeScript is loaded via jiti — no compilation step needed.

### OpenCode

Prepare the source dependencies:

```bash
mkdir -p ~/.config/opencode/plugins
ln -sf $(pwd)/plugins/opencode/index.ts ~/.config/opencode/plugins/memsearch.ts
# Restart opencode to load
bash plugins/opencode/install.sh
```

The script prints the absolute plugin directory to add to the `plugins`
array in `opencode.json`:

```json
{
"plugins": ["/absolute/path/to/memsearch/plugins/opencode"]
}
```

Use this directory as the only MemSearch entry, retaining other plugins.
Restart OpenCode and verify the loaded path, three memory tools, and packaged
Skills. See the [plugin README](plugins/opencode/README.md) for development checks
and capture/recovery behavior.

### Codex

```bash
Expand Down
16 changes: 5 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,21 +181,15 @@ We discussed batch size limits before, what did we decide?
<details>
<summary><h3>For OpenCode Users</h3></summary>

**Plugin 0.4.0 supports OpenCode V2 `>=2.0.32 <3`.** Install with `opencode plugin add @zilliz/memsearch-opencode@0.4.0`, or add it to the V2 configuration:
MemSearch gives OpenCode persistent memory across sessions. Install the plugin:

```json
{ "plugins": ["@zilliz/memsearch-opencode@0.4.0"] }
```bash
opencode plugin add @zilliz/memsearch-opencode
```

Use exactly one MemSearch source. The three tools and Skills register at runtime. Completed turns are captured immediately; durable pending work recovers before recall after a short exit. Markdown remains under `.memsearch/memory/`.

**V1 users pin the published 0.3.17 plugin** using their existing V1 configuration:

```json
{ "plugin": ["@zilliz/memsearch-opencode@0.3.17"] }
```
Completed turns are summarized into `.memsearch/memory/` and indexed for recall. Pending work resumes after an interruption.

Ask about previous decisions to use `memory_search` → `memory_get` → `memory_transcript`, or invoke the `memory-recall` Skill. Existing Markdown and transcript anchors are preserved; OpenCode's database migration remains user-owned.
Ask about previous decisions or debugging sessions, and OpenCode can search memory, expand relevant notes, and look up the original conversation. The `memory-recall`, `memory-config`, and `memory-to-skill` Skills are included.

> 📖 [OpenCode Plugin docs](https://zilliztech.github.io/memsearch/platforms/opencode/)

Expand Down
2 changes: 1 addition & 1 deletion docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ model = "" # empty = Codex plugin default

[plugins.opencode.summarize]
provider = "" # empty/native = OpenCode native summarizer
model = "" # empty = OpenCode small_model/default behavior
model = "" # native: empty = title-agent model, then host default

[plugins.openclaw.summarize]
provider = "" # empty/native = OpenClaw native summarizer
Expand Down
2 changes: 1 addition & 1 deletion docs/home/for-users.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Pick your platform, install the plugin, and you're done. memsearch captures conv
| [**Codex**](../platforms/codex/index.md) | `bash install.sh` | Stable |
| [**DeepSeek Harness**](../platforms/dsh/index.md) | `dsh plugin --profile <name> add @zilliz/memsearch-dsh` | Stable |
| [**OpenClaw**](../platforms/openclaw/index.md) | `openclaw plugins install --force` + hook permissions | Stable |
| [**OpenCode**](../platforms/opencode/index.md) | Add to `opencode.json` plugin array | Stable |
| [**OpenCode**](../platforms/opencode/index.md) | `opencode plugin add @zilliz/memsearch-opencode` | Stable |

## What Happens Automatically

Expand Down
8 changes: 4 additions & 4 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ Three tools (`memory_search`, `memory_get`, `memory_transcript`) with per-worksp

### OpenCode Plugin

OpenCode V2 plugin with immediate session-event capture and durable SQLite recovery before recall. V1 users pin the published `@zilliz/memsearch-opencode@0.3.17`.
Persistent memory for OpenCode. Completed turns are summarized into Markdown, ready to recall in future sessions.

```bash
bash memsearch/plugins/opencode/install.sh
opencode plugin add @zilliz/memsearch-opencode
```

[:octicons-arrow-right-24: OpenCode Plugin docs](platforms/opencode/index.md){ .md-button }
Expand All @@ -91,9 +91,9 @@ All platforms share the same markdown memory format and derive collection names
| | [Claude Code](platforms/claude-code/index.md) | [Codex](platforms/codex/index.md) | [DeepSeek Harness](platforms/dsh/index.md) | [OpenClaw](platforms/openclaw/index.md) | [OpenCode](platforms/opencode/index.md) |
|---|:---:|:---:|:---:|:---:|:---:|
| **Plugin type** | Shell hooks | Shell hooks | Native ESM plugin | TS plugin | TS plugin |
| **Capture** | Stop hook + Haiku | Stop hook + Codex | DSH turn events + headless agent | agent_end hook | SQLite daemon |
| **Capture** | Stop hook + Haiku | Stop hook + Codex | DSH turn events + headless agent | agent_end hook | Execution events + SQLite recovery |
| **Recall** | SKILL.md (fork) | SKILL.md | Native skill | memory_search tool | memory_search tool |
| **Install** | Plugin marketplace | `install.sh` | `dsh plugin add` | `openclaw plugins install --force` + hook permissions | npm + opencode.json |
| **Install** | Plugin marketplace | `install.sh` | `dsh plugin add` | `openclaw plugins install --force` + hook permissions | `opencode plugin add` |

[:octicons-arrow-right-24: Platform comparison](platforms/index.md){ .md-button }

Expand Down
6 changes: 3 additions & 3 deletions docs/platforms/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ memsearch provides plugins for 5 AI coding agent platforms. All plugins share th
| Feature | [Claude Code](claude-code/index.md) | [Codex](codex/index.md) | [DeepSeek Harness](dsh/index.md) | [OpenClaw](openclaw/index.md) | [OpenCode](opencode/index.md) |
|---------|:---:|:---:|:---:|:---:|:---:|
| **Plugin type** | Shell hooks | Shell hooks | Native ESM + web client | TS registerTool | TS npm plugin |
| **Capture method** | Stop hook (async) | Stop hook (async) | `session/event` turn end | agent_end hook | SQLite daemon |
| **Summarization** | `claude -p --model haiku` | `codex exec` | DSH headless agent | OpenClaw agent | `opencode run` |
| **Capture method** | Stop hook (async) | Stop hook (async) | `session/event` turn end | agent_end hook | Execution events + SQLite recovery |
| **Summarization** | `claude -p --model haiku` | `codex exec` | DSH headless agent | OpenClaw agent | Native `ctx.generate.text` |
| **Recall mechanism** | SKILL.md (context: fork) | SKILL.md | Native skill | memory_search tool | memory_search tool |
| **L3 transcript format** | Claude Code JSONL | Codex rollout JSONL | DSH session database | OpenClaw JSONL | OpenCode SQLite |
| **Isolation** | Per-project collection | Per-project collection | Per-project collection | Per-workspace collection | Per-project collection |
| **Install method** | Plugin marketplace | `install.sh` | `dsh plugin add` | `openclaw plugins install --force` + hook permissions | npm + opencode.json |
| **Install method** | Plugin marketplace | `install.sh` | `dsh plugin add` | `openclaw plugins install --force` + hook permissions | `opencode plugin add` |
| **Embedding default** | ONNX bge-m3 (CPU) | ONNX bge-m3 (CPU) | ONNX bge-m3 (CPU) | ONNX bge-m3 (CPU) | ONNX bge-m3 (CPU) |
| **API key required** | No (ONNX default) | No (ONNX default) | No (ONNX default) | No (ONNX default) | No (ONNX default) |

Expand Down
12 changes: 6 additions & 6 deletions docs/platforms/opencode/how-it-works.md
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
# How It Works

The V2 plugin combines host execution events with a read-only SQLite projection reader. Events trigger immediate work; the database determines what can safely be captured. One finite helper handles a serialized batch, and a project file lock coordinates concurrent host instances.
The plugin combines host execution events with a read-only SQLite projection reader. Events trigger immediate work; the database determines what can safely be captured. One finite helper handles a serialized batch, and a project file lock coordinates concurrent host instances.

## Completion and ownership

The reader uses `session_v2` and `session_message`, ordered by the per-session `seq` column. It requires completed assistant messages, settled tools, and a terminal boundary. A streamed response alone does not qualify. Persisted failed/interrupted runs advance without a summary; host shutdown without an idle boundary remains pending for resumption.

Officially migrated V2 history has completed messages without streamed timestamps or idle rows. The pinned migration's settled message shape permits historical baselining and anchor replay before continuing in V2. A following user message alone does not qualify a live turn; retrying, unfinished, or failed final responses cannot become successful summaries.
A following user message alone does not qualify a live turn; retrying, unfinished, or failed final responses cannot become successful summaries.

Capture, requesting-session checks and L3 use the canonical physical checkout root (or exact non-Git directory) plus workspace. Host project IDs may change and are diagnostic metadata, not ownership or durable cursor keys. Git subdirectories and symlink aliases resolve to their checkout; nested repositories, separate worktrees and unrelated same-name directories stay separate. Session metadata is filtered before selecting message content, and location-switch boundaries exclude prior-location payloads from the query. Subagents and copied fork history are excluded from capture. Synthetic, compaction, reasoning and raw tool content are omitted.

## Durable capture

The helper stores a pending turn before inference. Once summarized, it durably stores the intended append and its file offset/hash, appends and fsyncs the Markdown, commits the sequence cursor, and indexes. It can complete its own partial append or recognize a finished append after a checkpoint failure. Conflicting journal edits stop automatic repair. A failed index remains dirty for retry without appending the summary again.

New V2 tables in `.memsearch/opencode-turns.db` leave old sidecar tables intact. Markdown remains the source of truth, with the existing `<!-- session:... turn:... db:... -->` anchor format. On first activation, existing settled history is baselined atomically; incomplete turns remain eligible. Setup establishes the baseline without inference, then registers tools, Skills and hooks before subscribing to execution events. Subsequent recovery scans replay missed work, including events that arrived during setup.
Capture state lives in `.memsearch/opencode-turns.db`. Markdown is the source of truth, with `<!-- session:... turn:... db:... -->` anchors linking summaries to original conversations. On first activation, existing settled history is baselined atomically; incomplete turns remain eligible. Setup establishes the baseline without inference, then registers tools, Skills and hooks before subscribing to execution events. Subsequent recovery scans replay missed work, including events that arrived during setup.

Completion events wake capture immediately. A 15-second scan covers lost or early events. Recovery also runs before prompts, context injection, search and expansion. Host shutdown has a three-second limit: the plugin gives its helper a short grace period, then cancels it. **Normal capture is immediate, and pending work recovers before recall; exit-time inference is not guaranteed.** SIGKILL cannot guarantee a flush. There is no detached daemon or inactivity threshold, and old daemon processes are not managed.
Completion events wake capture immediately. A 15-second scan covers lost or early events. Recovery also runs before prompts, context injection, search and expansion. Host shutdown has a three-second limit: the plugin gives its helper a short grace period, then cancels it. Pending inference and indexing resume on the next activation before recall. A forced exit can leave work pending.

Search and expansion use a query mode of the same finite helper. It takes the capture/index project lock and revalidates the requesting session after waiting, then runs the CLI query. All plugin-owned index/search/expand commands acquire `~/.memsearch/.opencode-cli.lock` after the project lock, coordinating different checkouts that share HOME and the default Milvus Lite database. The HOME lock is released when the CLI operation completes or is cancelled; it does not cover summaries or optional maintenance. CLI access from other programs is outside this coordination.

## Inference and maintenance

`plugins.opencode.summarize.provider` selects native or a named shared API provider. Native inference calls `ctx.generate.text` with only the bounded summary prompt. It creates no session, invokes no tools and does not include current session history. It never uses `ctx.session.generate`.

Native model precedence is task override → resolved title-agent model → host default. The default applies when title-agent lookup succeeds without a model; lookup failure produces an unavailable note without invoking a different model. This consumes V2's migrated `small_model` choice without parsing or modifying host config. Named providers retain `memsearch summarize --plugin opencode --agent-name OpenCode`, including provider endpoint, environment-key and model overrides.
Native model precedence is task override → resolved title-agent model → host default. The default applies when title-agent lookup succeeds without a model; lookup failure produces an unavailable note without invoking a different model. Named providers use `memsearch summarize --plugin opencode --agent-name OpenCode`, including provider endpoint, environment-key and model overrides.

Custom `prompts.summarize` overrides the packaged shared prompt. Genuine failures write the established unavailable note; cancellation leaves pending work. Raw dialogue is never a fallback. Disabling summarization prevents calls to either route.

Enabled PROJECT.md/USER.md maintenance and Skill distillation reuse shared Python prompts, provider resolution, due-state and digest logic. A separate finite background helper runs maintenance after capture, without holding the capture lock or delaying prompt/context/search recovery. Shutdown cancels it. Native maintenance uses its task override or host default, via stateless inference. It has no transcript tools; candidate Skills must not invent exact commands requiring L3 verification. Candidates are installed only after an explicit user request.

## Context and recall

The context hook preserves host `SystemPart` metadata while idempotently adding recent daily journal excerpts and recall/candidate hints. Tools and Skills use the requesting session's checkout, and collection defaults never override explicit collection config. See [memory tools](memory-tools.md) for progressive disclosure and migration diagnostics.
The context hook preserves host `SystemPart` metadata while idempotently adding recent daily journal excerpts and recall/candidate hints. Tools and Skills use the requesting session's checkout, and collection defaults never override explicit collection config. See [memory tools](memory-tools.md) for the recall workflow.
12 changes: 8 additions & 4 deletions docs/platforms/opencode/index.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
# OpenCode Plugin

MemSearch captures completed OpenCode V2 turns as Markdown and retrieves them through semantic search, section expansion, and original transcript lookup. Daily journals remain readable and usable by the other MemSearch integrations.
MemSearch gives OpenCode persistent memory across sessions. It captures completed turns as Markdown and retrieves them through semantic search, section expansion, and original transcript lookup. Daily journals are readable and usable by the other MemSearch integrations.

**Plugin 0.4.0 supports OpenCode V2 `>=2.0.32 <3`.** Standalone TUI capture/recall/recovery has been validated on official CLI **2.0.32 and 2.1.0**. Development types remain pinned to SDK 2.0.32. **V1 users pin `@zilliz/memsearch-opencode@0.3.17`.**
Install the plugin and start a conversation:

Completion events trigger a finite capture helper immediately. SQLite sequence cursors and durable pending appends support recovery after interruption. Recall waits for recovery, then uses the project's configured collection. A short host shutdown may leave work pending; it is recovered on the next activation before recall.
```bash
opencode plugin add @zilliz/memsearch-opencode
```

The plugin registers `memory_search`, `memory_get`, `memory_transcript`, and the three Skills `memory-recall`, `memory-config`, `memory-to-skill`. Native summaries use independent host inference; existing named API-provider overrides, shared prompts and optional maintenance remain available.
Completed turns are summarized and indexed automatically. In a later session, ask about a past decision or debugging problem: OpenCode can search the notes and follow their references to the original conversation. Pending capture and indexing resume after an interruption, before recall.

The plugin includes `memory_search`, `memory_get`, and `memory_transcript`, plus the Skills `memory-recall`, `memory-config`, and `memory-to-skill`. Summaries use OpenCode's native inference by default; shared settings let you choose a model or API provider and enable optional memory maintenance.

Continue with [installation](installation.md), [capture and recovery](how-it-works.md), or the [memory tools](memory-tools.md).
Loading
Loading