@mathew-cf/opencode-memory 0.3.1 → 1.0.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
@@ -2,7 +2,7 @@
2
2
 
3
3
  Persistent cross-session memory for [OpenCode](https://opencode.ai).
4
4
 
5
- This plugin gives the agent a durable knowledge base rooted at `~/opencode-memory/` — a git-tracked tree of markdown notes — plus read access to its own past sessions. A hybrid keyword + semantic search layer surfaces relevant notes before work starts, and a guard hook nudges the agent to save reusable discoveries as it goes.
5
+ A durable knowledge base rooted at `~/opencode-memory/` — a git-tracked tree of markdown notes — paired with a hybrid keyword + semantic search layer. The OpenCode plugin provides tools, hooks, auto-applied config, and a bundled skill.
6
6
 
7
7
  ## Why
8
8
 
@@ -13,29 +13,31 @@ LLM agents forget everything between sessions. That means rediscovering the same
13
13
  | Category | Additions |
14
14
  | ------------------ | ------------------------------------------------------------------------- |
15
15
  | **Memory tools** | `memory_search`, `memory_list`, `memory_save`, `memory_access`, `memory_setup` |
16
- | **Session tools** | `session_search`, `session_read`, `session_list` |
17
- | **Hooks** | Search-first nudge at 8 tool calls; discovery nudge on subagent outputs; retrospective reminder at compaction time |
18
- | **Skill** | `opencode-memory` (auto-registered via the `skills.paths` config) |
19
- | **Agent prompts** | Built-in subagents (`general`, `explore`, `research`, `review`, `investigator`) get a memory-aware prompt prepended non-destructively |
16
+ | **Session tools** | `session_search`, `session_read`, `session_list` (OpenCode only — read OpenCode's SQLite history) |
17
+ | **Hooks** | Search-first nudge at 8 tool calls; discovery nudge on subagent outputs; retrospective reminder at compaction time (OpenCode only) |
18
+ | **Skill** | `opencode-memory` auto-registered in OpenCode, dropped at `~/.agents/skills/opencode-memory` for Zed & Pi |
19
+ | **Agent prompts** | Built-in subagents (`general`, `explore`, `research`, `review`, `investigator`) get a memory-aware prompt prepended non-destructively (OpenCode only) |
20
20
 
21
21
  ## Installation
22
22
 
23
+ ### OpenCode
24
+
23
25
  ```jsonc
24
26
  // opencode.jsonc
25
27
  {
26
- "plugin": ["@mathew-cf/opencode-memory@0.3.1"]
28
+ "plugin": ["@mathew-cf/opencode-memory@1.0.0"]
27
29
  }
28
30
  ```
29
31
 
30
- Then bootstrap the memory directory + embedding model:
32
+ Then bootstrap the memory directory + embedding model + skill:
31
33
 
32
34
  ```bash
33
35
  bunx @mathew-cf/opencode-memory init
34
36
  ```
35
37
 
36
- This creates `~/opencode-memory/` (git repo, 7 category subdirs) and downloads the ~90MB embedding model. Idempotent — safe to re-run. Pass `--skip-model` to defer the download.
38
+ This creates `~/opencode-memory/` (git repo, 7 category subdirs), downloads the ~90MB embedding model, and symlinks the bundled skill into `~/.agents/skills/opencode-memory` (where Zed and Pi look). Idempotent — safe to re-run. Pass `--skip-model` to defer the download, `--skip-skills` to skip the symlink.
37
39
 
38
- The plugin auto-registers:
40
+ The plugin also auto-registers (OpenCode only):
39
41
 
40
42
  - its bundled skill under `config.skills.paths`
41
43
  - edit + external-directory permissions for `~/opencode-memory/**`
@@ -68,7 +70,7 @@ If either dependency fails to install (unusual — usually indicates an unsuppor
68
70
  bunx @mathew-cf/opencode-memory init
69
71
  ```
70
72
 
71
- Creates `~/opencode-memory/` (or `$MEMORY_DIR`), runs `git init`, scaffolds the 7 advisory category subdirs (`preferences/`, `repos/`, `technical/`, `people/`, `workflows/`, `snippets/`, `notes/`), and pre-caches the embedding model for semantic search.
73
+ Creates `~/opencode-memory/` (or `$OPENCODE_MEMORY_DIR`), runs `git init`, scaffolds the 7 advisory category subdirs (`preferences/`, `repos/`, `technical/`, `people/`, `workflows/`, `snippets/`, `notes/`), and pre-caches the embedding model for semantic search.
72
74
 
73
75
  Subcommands:
74
76
 
package/dist/cli.d.ts CHANGED
@@ -38,6 +38,18 @@
38
38
  interface InitOptions {
39
39
  /** Skip the rag download step. Useful in CI or for offline first-runs. */
40
40
  skipModel?: boolean;
41
+ /**
42
+ * Skip installing the bundled skill into `~/.agents/skills/`. By
43
+ * default `init` symlinks the skill there so Zed (`crates/agent_skills`)
44
+ * and Pi (`packages/coding-agent/docs/skills.md`) — both of which
45
+ * auto-discover that path — pick the skill up on next launch.
46
+ */
47
+ skipSkills?: boolean;
48
+ /**
49
+ * Override the directory where `installSkill` drops the symlink.
50
+ * Defaults to `~/.agents/skills`. Test-only escape hatch.
51
+ */
52
+ skillLinkDir?: string;
41
53
  /** Suppress success lines (errors still print). For embedding in scripts. */
42
54
  quiet?: boolean;
43
55
  }
@@ -55,7 +67,58 @@ export interface InitResult {
55
67
  modelDownloadAttempted: boolean;
56
68
  /** Whatever rag download printed, if it ran. */
57
69
  modelDownloadOutput?: string;
70
+ /**
71
+ * Outcome of the optional skill-symlink step. `null` when
72
+ * `skipSkills` was set. Otherwise see `SkillInstallResult` for the
73
+ * three valid resting states.
74
+ */
75
+ skillInstall: SkillInstallResult | null;
58
76
  }
77
+ /**
78
+ * Result of installing the bundled `opencode-memory` skill into
79
+ * `~/.agents/skills/`. Captures the three valid resting states:
80
+ * - `"created"`: a fresh symlink was placed at the target path
81
+ * - `"already-installed"`: the target was already a symlink to our skill dir
82
+ * - `"skipped-existing"`: a non-matching file/dir/symlink was already there
83
+ * (we never overwrite — user-owned content wins)
84
+ * - `"unavailable"`: the bundled skill dir wasn't resolvable on disk
85
+ * (unusual; usually means the package layout was tampered with)
86
+ */
87
+ export interface SkillInstallResult {
88
+ status: "created" | "already-installed" | "skipped-existing" | "unavailable";
89
+ /** Absolute path of the link we attempted to create. */
90
+ linkPath: string;
91
+ /** Absolute path the link points at (or would point at). */
92
+ targetPath: string;
93
+ }
94
+ /**
95
+ * Locate the bundled skills directory next to this file's package root.
96
+ *
97
+ * In src layout: `src/cli.ts` → `<repo>/skills`.
98
+ * In dist layout: `dist/cli.js` → `<pkg>/skills` (the `skills` folder
99
+ * is shipped in the npm package via `package.json` `files`).
100
+ *
101
+ * Exported so tests can monkey-patch the lookup if needed.
102
+ */
103
+ export declare function resolveBundledSkillsDir(): string | undefined;
104
+ /**
105
+ * Install (idempotent) the bundled `opencode-memory` skill into
106
+ * `~/.agents/skills/opencode-memory` — the directory Zed and Pi both
107
+ * auto-discover. Never overwrites a non-matching entry already at the
108
+ * target; users who manually placed something there keep ownership.
109
+ *
110
+ * Implementation: symlink rather than copy. Symlinks let plugin upgrades
111
+ * (`bun add @mathew-cf/opencode-memory@latest`) pick up new skill content
112
+ * without re-running `init`. The link points at the bundled skill
113
+ * directory inside the installed package.
114
+ *
115
+ * `linkDir` defaults to `~/.agents/skills` but is parameterised so tests
116
+ * can target a temp directory.
117
+ */
118
+ export declare function installSkill(options: {
119
+ bundledSkillsDir: string | undefined;
120
+ linkDir?: string;
121
+ }): Promise<SkillInstallResult>;
59
122
  /**
60
123
  * Pure-ish init: takes an explicit memoryDir so tests can target a temp
61
124
  * path. The CLI wrapper passes `resolveMemoryDir()`.
@@ -69,10 +132,35 @@ export declare function usage(): string;
69
132
  * Parse argv tail into a simple options bag. Exported for tests.
70
133
  * Recognised flags:
71
134
  * --skip-model | -s InitOptions.skipModel = true
135
+ * --skip-skills InitOptions.skipSkills = true
72
136
  * --quiet | -q InitOptions.quiet = true
73
137
  */
74
138
  export declare function parseInitFlags(argv: string[]): InitOptions;
75
- /** CLI dispatcher. Exported so tests can drive it without exec(). */
76
- export declare function dispatch(argv: string[]): Promise<number>;
139
+ /**
140
+ * Writer functions for `dispatch`. Each receives a chunk of text exactly
141
+ * as it would be passed to `process.stdout.write` / `process.stderr.write`
142
+ * — including any trailing newlines. Callers must include their own
143
+ * newlines so passing `process.stdout.write.bind(process.stdout)` reads
144
+ * naturally.
145
+ *
146
+ * Exists primarily so tests can silence the CLI output without
147
+ * monkey-patching `process.stdout`, but the same shape lets embedders
148
+ * (e.g. a wrapping daemon) capture or redirect output cleanly.
149
+ */
150
+ export interface DispatchIO {
151
+ /** Defaults to `process.stdout.write` bound to stdout. */
152
+ out?: (chunk: string) => void;
153
+ /** Defaults to `process.stderr.write` bound to stderr. */
154
+ err?: (chunk: string) => void;
155
+ }
156
+ /**
157
+ * CLI dispatcher. Exported so tests can drive it without exec().
158
+ *
159
+ * Output is routed through the optional `io.out` / `io.err` writers so
160
+ * tests (and any embedder) can capture or silence the chatter without
161
+ * having to monkey-patch global stdio. Defaults preserve the standalone
162
+ * bin behaviour exactly.
163
+ */
164
+ export declare function dispatch(argv: string[], io?: DispatchIO): Promise<number>;
77
165
  export {};
78
166
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAUH,UAAU,WAAW;IACnB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;IACxB,kFAAkF;IAClF,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,yCAAyC;IACzC,sBAAsB,EAAE,OAAO,CAAC;IAChC,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,WAAgB,EACzB,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAgD,GACrE,OAAO,CAAC,UAAU,CAAC,CAuDrB;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,MAAM,CAiB9B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAO1D;AAED,qEAAqE;AACrE,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiC9D"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAaH,UAAU,WAAW;IACnB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,cAAc,EAAE,OAAO,CAAC;IACxB,kFAAkF;IAClF,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,yCAAyC;IACzC,sBAAsB,EAAE,OAAO,CAAC;IAChC,gDAAgD;IAChD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAC;CACzC;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,aAAa,CAAC;IAC7E,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,SAAS,CAc5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAC1C,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA8C9B;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,WAAgB,EACzB,GAAG,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAgD,GACrE,OAAO,CAAC,UAAU,CAAC,CAkFrB;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,MAAM,CAyB9B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,WAAW,CAQ1D;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,UAAU;IACzB,0DAA0D;IAC1D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,0DAA0D;IAC1D,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCnF"}