om-memory-system 3.0.0 → 3.1.0-next.4

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.
Files changed (52) hide show
  1. package/{LICENSE → LICENSE.md} +4 -2
  2. package/README.md +108 -532
  3. package/dist/adapters/opencode/auto-capture-summary.js +23 -17
  4. package/dist/adapters/opencode/import-command.d.ts +42 -0
  5. package/dist/adapters/opencode/import-command.js +154 -0
  6. package/dist/adapters/pi/extension.js +4 -5
  7. package/dist/adapters/pi/import-command.d.ts +7 -19
  8. package/dist/adapters/pi/import-command.js +46 -161
  9. package/dist/adapters/pi/live-model.d.ts +17 -0
  10. package/dist/adapters/pi/live-model.js +86 -0
  11. package/dist/adapters/pi/profile.d.ts +7 -17
  12. package/dist/adapters/pi/profile.js +28 -66
  13. package/dist/adapters/pi/provider.d.ts +8 -1
  14. package/dist/adapters/pi/provider.js +34 -6
  15. package/dist/cli/index.d.ts +7 -0
  16. package/dist/cli/index.js +94 -0
  17. package/dist/config.d.ts +7 -20
  18. package/dist/config.js +24 -61
  19. package/dist/core/extraction.d.ts +2 -2
  20. package/dist/core/extraction.js +8 -3
  21. package/dist/core/profile-analysis.d.ts +16 -0
  22. package/dist/core/profile-analysis.js +47 -0
  23. package/dist/importer/import-args.d.ts +44 -0
  24. package/dist/importer/import-args.js +219 -0
  25. package/dist/importer/importer.d.ts +33 -9
  26. package/dist/importer/importer.js +153 -89
  27. package/dist/importer/ledger.d.ts +9 -2
  28. package/dist/importer/ledger.js +16 -2
  29. package/dist/importer/model-selection.d.ts +16 -0
  30. package/dist/importer/model-selection.js +84 -0
  31. package/dist/importer/opencode-import.d.ts +28 -0
  32. package/dist/importer/opencode-import.js +87 -0
  33. package/dist/importer/opencode-project.d.ts +11 -0
  34. package/dist/importer/opencode-project.js +38 -0
  35. package/dist/importer/opencode-reader.d.ts +19 -0
  36. package/dist/importer/opencode-reader.js +214 -0
  37. package/dist/importer/profile-import.d.ts +29 -0
  38. package/dist/importer/profile-import.js +111 -0
  39. package/dist/importer/run-import.d.ts +49 -0
  40. package/dist/importer/run-import.js +123 -0
  41. package/dist/index.d.ts +4 -0
  42. package/dist/index.js +37 -1
  43. package/dist/services/ai/internal-capture-sessions.d.ts +2 -0
  44. package/dist/services/ai/internal-capture-sessions.js +7 -0
  45. package/dist/services/ai/live-model-choice.d.ts +52 -0
  46. package/dist/services/ai/live-model-choice.js +83 -0
  47. package/dist/services/ai/profile-llm-client.js +7 -5
  48. package/dist/services/user-memory-learning.js +9 -8
  49. package/dist/services/user-profile/ai-cleanup.js +8 -5
  50. package/dist/services/user-profile/user-profile-manager.js +11 -10
  51. package/dist/v2/adapter.js +27 -0
  52. package/package.json +5 -2
package/README.md CHANGED
@@ -4,584 +4,160 @@
4
4
  [![npm downloads](https://img.shields.io/npm/dm/om-memory-system.svg)](https://www.npmjs.com/package/om-memory-system)
5
5
  [![license](https://img.shields.io/npm/l/om-memory-system.svg)](https://www.npmjs.com/package/om-memory-system)
6
6
 
7
- > **Fork notice.** This is [`cmdaltctr/omms`](https://github.com/cmdaltctr/omms), a fork of
8
- > [`tickernelz/opencode-mem`](https://github.com/tickernelz/opencode-mem), published on npm as **`om-memory-system`**, the Opinionated
9
- > Modular Memory System for coding agents. The fork adds first-class integration with the
10
- > [Pi coding agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent): the memory engine now runs as a
11
- > shared, host-neutral core behind a native Pi extension, so OpenCode and Pi read and write one memory store per
12
- > project. Existing OpenCode memory data migrates automatically and safely on first start; see
13
- > [docs/omms-migration.md](docs/omms-migration.md). All existing OpenCode behaviour, storage compatibility, and
14
- > configuration are preserved. See [docs/shared-core.md](docs/shared-core.md) for the boundary,
15
- > [docs/pi-adapter.md](docs/pi-adapter.md) for Pi installation and lifecycle details, and
16
- > [docs/pi-history-import.md](docs/pi-history-import.md) to import existing Pi session history.
7
+ ![OMMS banner](.github/banner.png)
17
8
 
18
- ![OpenCode Memory Banner](.github/banner.png)
9
+ OMMS gives your AI coding agent a long-term memory. As you work, it writes
10
+ short notes about what was done and decided in each project: fixes, design
11
+ choices, things that did not work. It brings the relevant notes back in later
12
+ sessions, so the agent does not start from zero every time. It also learns how
13
+ you like to work and keeps that as a user profile.
19
14
 
20
- A persistent memory system for AI coding agents that enables long-term context retention across sessions using local vector database technology.
15
+ It runs inside [OpenCode](https://opencode.ai) and the
16
+ [Pi coding agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent).
17
+ Both share one memory per project, so a note written in one is available in
18
+ the other. Everything is stored locally on your machine.
21
19
 
22
- ## Visual Overview
20
+ ## What it does
23
21
 
24
- **Project Memory Timeline:**
22
+ - **Remembers automatically.** After each piece of work, a background model
23
+ call summarises it into a memory. You do not have to ask.
24
+ - **Recalls when relevant.** Matching memories are added to the agent's
25
+ context: on every prompt in OpenCode v2 and Pi, at the start of a session in
26
+ OpenCode v1.
27
+ - **Learns your preferences.** A user profile of your habits builds up over
28
+ time and follows you across projects.
29
+ - **Imports your past sessions.** One command turns old OpenCode or Pi
30
+ history into memories and a profile.
31
+ - **Lets you look and edit.** A local web page shows every memory and your
32
+ profile.
33
+ - **Keeps private things private.** Text inside `<private>` tags is never
34
+ stored.
25
35
 
26
- ![Project Memory Timeline](.github/screenshot-project-memory.png)
36
+ ![Project memory timeline](.github/screenshot-project-memory.png)
27
37
 
28
- **User Profile Viewer:**
38
+ ![User profile viewer](.github/screenshot-user-profile.png)
29
39
 
30
- ![User Profile Viewer](.github/screenshot-user-profile.png)
40
+ ## Before you start
31
41
 
32
- ## Core Features
42
+ You need one of:
33
43
 
34
- Local Turso/libSQL database with native vector search, persistent project memories, automatic user profile learning, unified memory-prompt timeline, full-featured web UI, intelligent prompt-based memory extraction, multi-provider AI support (OpenAI, Anthropic), 12+ local embedding models, smart deduplication, and built-in privacy protection.
44
+ - **OpenCode** 1.18.29 or later (v1 plugin API) or OpenCode v2
45
+ - **Pi coding agent**
35
46
 
36
- ## Prerequisites
47
+ Nothing else is required. OMMS brings its own database. On first use it
48
+ downloads a small embedding model (the part that makes memories searchable),
49
+ so you need internet access once. The terminal import command also needs
50
+ Node.js 22.14 or later.
37
51
 
38
- This plugin uses embedded Turso/libSQL with native vector indexes (`F32_BLOB`, `vector_top_k`). No separate vector database or custom SQLite build is required.
52
+ ## Set up
39
53
 
40
- **Recommended runtime:**
54
+ ### 1. Install
41
55
 
42
- - Bun
43
- - Standard OpenCode plugin environment
44
- - Internet access on first use if you use the default local embedding model, because the model is downloaded by `@huggingface/transformers`.
45
- - For source/development installs, run `bun install` before building or testing. The published plugin package installs its runtime dependencies automatically through OpenCode.
46
-
47
- **CI-tested platforms:** Linux, Windows, macOS 15 and macOS 26 on both Intel (`darwin/x64`) and Apple Silicon (`darwin/arm64`). Older macOS releases are not excluded by that matrix; they are simply outside the current GitHub-hosted runner set.
48
-
49
- **Notes:**
50
-
51
- - Vector embeddings are stored and searched directly in Turso/libSQL; inserts update the vector index automatically.
52
- - Vector search uses libSQL's DiskANN index via `vector_top_k` (approximate nearest neighbors).
53
- - Auto-capture and user profile learning require an AI provider that can return structured/tool-call output. Memory search/add/list still work without auto-capture provider configuration.
54
-
55
- ### Upgrading from legacy SQLite shards
56
-
57
- On first startup after upgrading, omms automatically migrates existing memory shard databases to native Turso/libSQL vector format:
58
-
59
- - Each shard is backed up as `<shard>.db.legacy.bak` before rewrite
60
- - Progress is tracked per shard in `<shard>.db.turso-migrate.json`
61
- - A global marker `.turso-migrated` is written only after all shards verify successfully
62
- - Do not run multiple OpenCode instances against the same `storagePath` during migration; a lock file (`.turso-migrate.lock`) prevents concurrent migration
63
- - Manual dimension migrations use `.turso-operation.lock`; other plugin processes reject new memory writes until the migration finishes
64
-
65
- If migration is interrupted, the next startup resumes from the backup automatically.
66
-
67
- If a shard becomes incompatible (for example after changing `embeddingDimensions`), writes are blocked and the original database is left untouched. Use the Web UI's re-embed migration to build and verify a replacement before it is swapped into place. The previous shard remains available as `<shard>.db.pre-reembed-<pid>-<timestamp>.bak`.
68
-
69
- ## Install OMMS
70
-
71
- Install OMMS in the coding agent you use. You can install it in both OpenCode
72
- and Pi. They share one project memory store.
73
-
74
- ### OpenCode
75
-
76
- Add `om-memory-system` (the npm name for omms) to your OpenCode configuration. OpenCode downloads the package
77
- when you restart it. On OpenCode v2 you can instead run `opencode plugin add om-memory-system`,
78
- which installs the package and updates your global configuration for you.
79
-
80
- #### macOS
81
-
82
- Edit `~/.config/opencode/opencode.json`.
83
-
84
- For OpenCode v2, use the native `plugins` list:
56
+ **OpenCode.** Add `om-memory-system` to `~/.config/opencode/opencode.json`
57
+ (on Windows, `%USERPROFILE%\.config\opencode\opencode.json`):
85
58
 
86
59
  ```jsonc
87
- {
88
- "plugins": ["om-memory-system"],
89
- }
90
- ```
91
-
92
- For OpenCode v1 (1.18.29 or later), use the `plugin` list:
60
+ // OpenCode v2
61
+ { "plugins": ["om-memory-system"] }
93
62
 
94
- ```jsonc
95
- {
96
- "plugin": ["om-memory-system"],
97
- }
98
- ```
99
-
100
- Restart OpenCode after you save the file.
101
-
102
- #### Windows
103
-
104
- Edit `%USERPROFILE%\.config\opencode\opencode.json`, for example
105
- `C:\Users\<you>\.config\opencode\opencode.json`.
106
-
107
- For OpenCode v2, use:
108
-
109
- ```jsonc
110
- {
111
- "plugins": ["om-memory-system"],
112
- }
113
- ```
114
-
115
- For OpenCode v1 (1.18.29 or later), use:
116
-
117
- ```jsonc
118
- {
119
- "plugin": ["om-memory-system"],
120
- }
63
+ // OpenCode v1
64
+ { "plugin": ["om-memory-system"] }
121
65
  ```
122
66
 
123
- Restart OpenCode after you save the file. OMMS does not read `%APPDATA%` or
124
- `%LOCALAPPDATA%` for this setting.
67
+ On OpenCode v2 you can run `opencode plugin add om-memory-system` instead.
68
+ Restart OpenCode.
125
69
 
126
- ### Pi coding agent
127
-
128
- Run the following command in Terminal on macOS or PowerShell on Windows:
70
+ **Pi.** Run:
129
71
 
130
72
  ```bash
131
73
  pi install npm:om-memory-system
132
74
  ```
133
75
 
134
- Restart Pi after installation. The extension reads the same configuration and
135
- storage path as OpenCode, so memories remain available in both agents.
136
-
137
- See [docs/pi-adapter.md](docs/pi-adapter.md) for Pi lifecycle details and
138
- [docs/pi-history-import.md](docs/pi-history-import.md) to import existing Pi
139
- session history.
140
-
141
- Once OMMS is running, open the memory explorer web UI at
142
- `http://127.0.0.1:4747`. It ships with every release.
143
-
144
- ### Update OMMS
145
-
146
- Install OMMS without a version number, as shown above, so your agent can tell
147
- you when a new release is out. Neither agent installs updates by itself; you
148
- choose when to update.
149
-
150
- | Agent | How you hear about a new release | Update with |
151
- | ----------- | ------------------------------------------------------------- | ----------------------------------------------------------------------- |
152
- | Pi | Pi shows an update notice while you work | `pi update npm:om-memory-system` (or `pi update --extensions` for all) |
153
- | OpenCode v2 | Run `opencode plugin check` to list plugins with new versions | `opencode plugin update om-memory-system` (or `opencode plugin update`) |
154
-
155
- Restart the agent after updating.
156
-
157
- To stay on one version, install it with the version number instead:
158
- `pi install npm:om-memory-system@3.1.0` in Pi, or `opencode plugin add om-memory-system@3.1.0` in
159
- OpenCode. A pinned install is never updated or flagged; install without the
160
- number again to go back to receiving updates.
161
-
162
- Release notes for every version are in [CHANGELOG.md](CHANGELOG.md) and on the
163
- [GitHub Releases](https://github.com/cmdaltctr/omms/releases) page.
164
-
165
- Upgrading from an existing `opencode-mem` install? The store migrates to
166
- `~/.omms/data` automatically on first start, with a verified backup first.
167
- See [docs/omms-migration.md](docs/omms-migration.md).
168
-
169
- ## How to use day-to-day
170
-
171
- You do **not** need to ask OpenCode to “remember” things for the plugin to work. With the defaults, memory builds up as you work.
172
-
173
- ### Typical daily flow
174
-
175
- 1. Enable the plugin (see [Install OMMS](#install-omms)) and restart OpenCode.
176
- 2. Configure an AI provider for auto-capture — recommended: `opencodeProvider` + `opencodeModel` (or `"opencodeModel": "inherit"`). Details under [Auto-Capture AI Provider](#auto-capture-ai-provider).
177
- 3. Work normally in OpenCode. When a session goes idle, auto-capture extracts memorable technical context and stores it.
178
- 4. Relevant memories are injected into context automatically. On OpenCode v2 and Pi, every prompt runs a semantic search of the project memory and adds the matches as an `<omms-retrieval>` system section (never as a chat message). On OpenCode v1, the most recent memories are injected on the first message of a session (`chatMessage.injectOn`). After compaction, the session's own memories are restored. Browse or edit memories in the web UI at `http://127.0.0.1:4747`.
179
- 5. Use the `memory` tool when you want something stored or retrieved immediately (see [Usage Examples](#usage-examples)).
180
-
181
- ### Automatic vs manual memory
182
-
183
- | Approach | When it runs | What you do |
184
- | ------------------------------------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------ |
185
- | **Auto-capture** (`autoCaptureEnabled: true`, default) | After conversation turns when the session goes idle | Nothing — extraction is automatic |
186
- | **Manual** `memory` tool / commands | On demand | `add`, `search`, `list`, `profile`, `forget`, `list-shards`, `migrate`, `export`, `import` |
187
-
188
- Manual search/add/list still work even if auto-capture has no provider configured. Auto-capture and user profile learning need a provider that can return structured/tool-call output.
189
-
190
- ### Memory vs AGENTS.md / project docs
191
-
192
- | Store in **memory** | Store in **AGENTS.md** / static docs |
193
- | -------------------------------------------------------------------- | ----------------------------------------------------------- |
194
- | Project-specific decisions, bug patterns, “we tried X and it failed” | Stable rules and workflows that rarely change |
195
- | User preferences discovered over sessions | Always-on coding conventions and process |
196
- | Facts that should follow you across chats | Instructions every agent should see regardless of retrieval |
197
-
198
- Rule of thumb: if it is a lasting project instruction, put it in AGENTS.md; if it is context that grows from real work, let memory (or auto-capture) hold it.
199
-
200
- ### Intelligent prompt-based memory extraction
201
-
202
- That phrase in the feature list is **auto-capture**: after a conversation, a background AI request summarizes technical work and saves it as memory. No special prompt from you is required. It uses `opencodeProvider` / `opencodeModel` when set, otherwise the manual `memoryProvider` fallback.
203
-
204
- ### User profile
205
-
206
- The **User Profile** is a separate, cross-project summary of how you like to work (preferences, habits). It is updated on an interval (`userProfileAnalysisInterval`, default every 10 analyzed prompts), shown in the web UI’s profile view, and readable via `memory({ mode: "profile" })`. You do not populate it by hand for normal use — profile learning fills it when a provider is ready.
207
-
208
- ### Web UI
209
-
210
- Open `http://127.0.0.1:4747` to browse the memory–prompt timeline, inspect captures, and manage the user profile. If you bind the server beyond loopback, see [Web UI HTTP Basic Auth](#web-ui-http-basic-auth).
211
-
212
- ## Usage Examples
213
-
214
- ```typescript
215
- memory({ mode: "add", content: "Project uses microservices architecture" });
216
- memory({ mode: "search", query: "architecture decisions" });
217
- memory({ mode: "search", query: "architecture decisions", scope: "all-projects" });
218
- memory({ mode: "profile" });
219
- memory({ mode: "list", limit: 10 });
220
- memory({ mode: "list-shards" });
221
- memory({ mode: "migrate", fromPath: "/old/path/to/project" });
222
- memory({ mode: "export", outputPath: "./memories.json" });
223
- memory({ mode: "import", inputPath: "./memories.json" });
224
- ```
225
-
226
- Access the web interface at `http://127.0.0.1:4747` for visual memory browsing and management.
227
-
228
- **Network binding security:** Keep `webServerHost` on `127.0.0.1` unless you intentionally expose the UI. Binding to `0.0.0.0` (or any non-loopback host) requires `webServerApiToken`; all `/api/*` requests must then send `Authorization: Bearer <token>` or `X-Omms-Token` (the legacy `X-Opencode-Mem-Token` header is still accepted). Open the UI with `?apiToken=<token>` so the browser stores and sends it.
229
-
230
- Dimension migrations generate every new embedding first, import them into a temporary indexed shard, verify the row count, and only then replace the original file. Failed migrations leave the source shard untouched.
76
+ Restart Pi. You can install OMMS in both agents; they share the same memory.
231
77
 
232
- ## Configuration Essentials
78
+ ### 2. Choose which model writes memories (optional)
233
79
 
234
- Configure at `~/.config/omms/omms.jsonc`. While that file does not exist, omms still reads the legacy `~/.config/opencode/opencode-mem.jsonc` (it is never written), so existing installs keep working before you migrate settings. Per-project overrides go in `<project>/.opencode/omms.jsonc` (the legacy `.opencode/opencode-mem.jsonc` is still read when no `omms.jsonc` exists):
235
-
236
- **Windows:** `%USERPROFILE%\.config\omms\omms.jsonc` (not AppData). Default storage resolves to `%USERPROFILE%\.omms\data` (the `~` form in the example below expands to your user home on Windows as well). A legacy `~/.opencode-mem/data` store migrates to the new path automatically on first start.
237
-
238
- The plugin creates a full commented template at this path on first startup (only when no config exists at all). This trimmed example shows the most common settings:
80
+ With no settings, OMMS uses the model of the session you are working in. To
81
+ use a different one, add it to `~/.config/omms/omms.jsonc`. If you have no
82
+ config file yet, OMMS creates this one with comments on first start.
239
83
 
240
84
  ```jsonc
241
85
  {
242
- "storagePath": "~/.omms/data",
243
- "userEmailOverride": "user@example.com",
244
- "userNameOverride": "John Doe",
245
- "embeddingModel": "Xenova/nomic-embed-text-v1",
246
- // Optional Nomic task prefixes (search_document: / search_query:). After enabling,
247
- // re-index existing memories so store and query vectors stay aligned.
248
- // "embeddingUseTaskPrefixes": true,
249
- // Optional OpenAI-compatible embedding endpoint:
250
- // "embeddingApiUrl": "https://api.openai.com/v1",
251
- // "embeddingApiKey": "env://OPENAI_API_KEY",
252
- // "embeddingModel": "text-embedding-3-small",
253
-
254
- "memory": {
255
- "defaultScope": "project",
256
- },
257
- "webServerEnabled": true,
258
- "webServerPort": 4747,
259
- // Required when webServerHost is not 127.0.0.1/localhost:
260
- // "webServerHost": "0.0.0.0",
261
- // "webServerApiToken": "env://OMMS_WEB_TOKEN",
262
-
263
- "autoCaptureEnabled": true,
264
- "autoCaptureLanguage": "auto",
265
-
266
- "opencodeProvider": "anthropic",
267
- "opencodeModel": "claude-haiku-4-5-20251001",
268
-
269
- // Manual fallback if you do not use opencodeProvider:
270
- // "memoryProvider": "openai-chat",
271
- // "memoryModel": "gpt-4o-mini",
272
- // "memoryApiUrl": "https://api.openai.com/v1",
273
- // "memoryApiKey": "env://OPENAI_API_KEY",
274
-
275
- "showAutoCaptureToasts": true,
276
- "showUserProfileToasts": true,
277
- "showErrorToasts": true,
278
-
279
- "userProfileAnalysisInterval": 10,
280
- "userProfileMaxContextBytes": 32768,
281
- "maxMemories": 10,
282
-
283
- "compaction": {
284
- "enabled": true,
285
- "memoryLimit": 10,
286
- },
287
- "chatMessage": {
288
- "enabled": true,
289
- "maxMemories": 3,
290
- "excludeCurrentSession": true,
291
- "maxAgeDays": undefined,
292
- "injectOn": "first", // OpenCode v1 only; v2 and Pi search on every prompt
293
- },
86
+ // A model you are already signed in to in OpenCode or Pi.
87
+ // Use "inherit" to always follow the session's model.
88
+ "opencodeProvider": "openai",
89
+ "opencodeModel": "gpt-5.6-luna",
90
+ "piProvider": "openai-codex",
91
+ "piModel": "gpt-5.6-luna",
294
92
  }
295
93
  ```
296
94
 
297
- ### Choosing / configuring embeddings
298
-
299
- Embeddings power similarity search for memories and the user profile. Configure them in the same file (`~/.config/omms/omms.jsonc`). There is **no MLX backend** — local embeddings use `@huggingface/transformers` with ONNX, not Apple MLX.
300
-
301
- **Local (default):** set only `embeddingModel`. On first use the model is downloaded from Hugging Face and cached under `{storagePath}/.cache` (default `~/.omms/data/.cache`).
95
+ You can also use any OpenAI-compatible or Anthropic API with your own key.
96
+ See [Configuration](docs/configuration.md#choosing-the-model).
302
97
 
303
- **Remote (OpenAI-compatible):** set both `embeddingApiUrl` and `embeddingApiKey`. The plugin then calls `{embeddingApiUrl}/embeddings` with a Bearer token. `embeddingApiKey` accepts the same secret formats as `memoryApiKey` (`literal`, `env://…`, `file://…`).
98
+ ### 3. Check it works
304
99
 
305
- | Key | Role |
306
- | --------------------- | ----------------------------------------------------------------------------------------- |
307
- | `embeddingModel` | Hugging Face id (local) or API model name (remote). Default: `Xenova/nomic-embed-text-v1` |
308
- | `embeddingDimensions` | Optional override; usually omit — dimensions are looked up from a built-in map |
309
- | `embeddingApiUrl` | Base URL for an OpenAI-compatible embeddings API (no trailing path beyond `/v1`) |
310
- | `embeddingApiKey` | API key for that endpoint (required together with `embeddingApiUrl`) |
100
+ Work normally for a few turns, then open `http://127.0.0.1:4747` in your
101
+ browser (OpenCode serves this page). New memories appear on the timeline.
102
+ You can also ask the agent: "search memory for what we changed today".
311
103
 
312
- Recommended local models:
104
+ ## Import your past history
313
105
 
314
- | Model | Dims | Notes |
315
- | ------------------------------------ | ---- | ----------------------------------- |
316
- | `Xenova/nomic-embed-text-v1` | 768 | Default; multilingual, 8192 context |
317
- | `Xenova/jina-embeddings-v2-base-en` | 768 | English-only, 8192 context |
318
- | `Xenova/jina-embeddings-v2-small-en` | 512 | Faster, 8192 context |
319
- | `Xenova/all-MiniLM-L6-v2` | 384 | Very fast, 512 context |
320
- | `Xenova/all-mpnet-base-v2` | 768 | Good quality, 512 context |
106
+ To turn earlier sessions into memories, preview first and then run it inside
107
+ the agent:
321
108
 
322
- Example — remote OpenAI embeddings:
323
-
324
- ```jsonc
325
- {
326
- "embeddingApiUrl": "https://api.openai.com/v1",
327
- "embeddingApiKey": "env://OPENAI_API_KEY",
328
- "embeddingModel": "text-embedding-3-small",
329
- }
330
- ```
331
-
332
- Changing `embeddingModel` (or dimensions) can trigger re-embedding of stored memories on next startup. Prefer picking a model once and sticking with it for a given data directory.
333
-
334
- **Intel Mac (`darwin/x64`):** `onnxruntime-node@1.21.0` through `1.23.2` can crash OpenCode's embedded Bun `1.3.14` during process exit after successful local embeddings (`Ort::Env` teardown / SIGILL). The fix shipped in `1.24.1`, but fixed releases still lack an x64 native binding. `omms` therefore pins `onnxruntime-node@1.20.1` and loads transformers through a CJS resolve shim so OpenCode nested installs keep that binding. Transformers is resolved to an absolute path before that shim is installed so OpenCode's Bun `--compile` host does not fail with `Cannot find module '@huggingface/transformers' from ''`. After upgrading, clear OpenCode's nested plugin cache (`~/.cache/opencode/packages/om-memory-system@*`, or `opencode-mem@*` on pre-migration installs) and reinstall, or use a remote endpoint via `embeddingApiUrl` + `embeddingApiKey` (example above). This pin stays until onnxruntime publishes a post-teardown-fix darwin/x64 build.
335
-
336
- ### Memory Scope
337
-
338
- - `scope: "project"`: query only the current project. This is the default.
339
- - `scope: "all-projects"`: query `search` / `list` across all project shards.
340
- - `memory.defaultScope` sets the default query scope when no explicit scope is provided.
341
-
342
- ### Web UI HTTP Basic Auth
343
-
344
- When `webServerHost` is set to anything other than loopback (for example `0.0.0.0`), the web UI is reachable by anyone on the network. To keep your memories off the LAN, gate the web server with HTTP Basic Auth via the same config file used for everything else:
345
-
346
- ```jsonc
347
- {
348
- "webServerHost": "0.0.0.0", // optional: reach the UI from the LAN
349
- "webServerAuthPassword": "pick-a-strong-one",
350
- "webServerAuthUsername": "admin", // optional, defaults to the current OS user
351
- }
352
- ```
353
-
354
- | Field | Default | Effect |
355
- | ----------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- |
356
- | `webServerAuthPassword` | _(empty)_ | When set, the server demands HTTP Basic Auth credentials on every request. Leave empty to keep the open-by-default behavior. |
357
- | `webServerAuthUsername` | OS user (`$USER`) | Username required by the Basic Auth challenge. |
358
-
359
- `webServerAuthPassword` accepts the same secret formats as `memoryApiKey`:
360
-
361
- - a literal string (simple, fine for personal machines),
362
- - `env://SOME_ENV_VAR` to pull the value from the environment at startup,
363
- - `file:///path/to/secret` to read it from a file (`chmod 600` recommended — the plugin will warn if the file is world-readable).
364
-
365
- The browser will pop its native Basic Auth dialog and remember the credentials for the current session; closing all browser windows discards them, so reopening the browser requires signing in again. Credentials are compared with a constant-time check, and the unauthenticated 401 response carries `Cache-Control: no-store` so no intermediate cache will replay it. CORS is also relaxed once auth is on, so other tools on the same LAN can talk to the API after authenticating.
366
-
367
- ### Sharing One Project Memory Across Nested Repos
368
-
369
- By default a project is identified by its enclosing git repository, so every
370
- physical git repo gets its own isolated memory store. That is wrong for
371
- multi-repo workspaces — trees managed by Google [`repo`](https://gerrit.googlesource.com/git-repo/+/HEAD/Docs/manual-repo.md),
372
- monorepos, or any layout where several nested git repositories belong to one
373
- logical project — because each sub-repository would be siloed.
374
-
375
- Drop an empty **`.omms-project`** marker file at the workspace root (the legacy
376
- `.opencode-mem-project` marker is still honoured and gives the same project identity):
377
-
378
- ```
379
- my-workspace/
380
- ├── .omms-project ← workspace root
381
- ├── kernel/ (own git repo)
382
- ├── userspace/ (own git repo)
383
- └── tools/ (own git repo)
384
- ```
385
-
386
- Every session started anywhere underneath the marker then resolves onto that
387
- root and shares one memory store, regardless of which sub-repo the working
388
- directory lives in:
389
-
390
- ```sh
391
- touch ~/my-workspace/.omms-project
392
- ```
393
-
394
- The marker is looked up by walking up from the working directory that every
395
- code path already passes in (the plugin's working directory, the web API's
396
- `process.cwd()`), so identity is **directory-driven and process-independent**.
397
- It does not rely on environment variables or a global config value, which
398
- would be unreliable here: omms runs across multiple opencode processes
399
- that share a single web server, and only some of those processes carry a
400
- given env var. With the marker, the project root is always derived from where
401
- the session actually runs.
402
-
403
- The marker takes precedence over git detection. When it is present, the
404
- sub-repo's own git remote is intentionally ignored (it would describe only one
405
- nested repository). Without a marker, behavior is unchanged (git-based
406
- identity).
407
-
408
- ### Moving or Recovering Project Memories
409
-
410
- omms keys project shards by a hash of the project identity. Moving a
411
- repository (OS migration, path reorganization, switching from a Windows mount
412
- to a native path) can therefore orphan the old shard under
413
- `~/.omms/data/projects/` while a new empty shard is created for the
414
- new path.
415
-
416
- These are OpenCode `memory` tool calls with JSON arguments, not commands to
417
- run in a terminal. The issue-style `memory migrate --from ...` notation maps
418
- to `memory({ mode: "migrate", fromPath: "..." })`.
419
-
420
- **1. Local move when you still know the old path**
421
-
422
- Open OpenCode in the **new** project directory. The target project must not
423
- already contain memories (migration aborts unchanged on conflict). Preview the
424
- detected source, destination, and file actions before changing anything:
425
-
426
- ```typescript
427
- memory({ mode: "migrate", fromPath: "/old/path/to/project", dryRun: true });
428
- memory({ mode: "migrate", fromPath: "/old/path/to/project" });
429
- ```
430
-
431
- For safety, migration refuses a source whose stored project directory still
432
- exists. If you intentionally want to move an active source, inspect the dry-run
433
- output first and then pass `allowLinkedSource: true`. Original source shard
434
- files are retained as timestamped `*.pre-path-migrate-*.bak` backups.
435
-
436
- **2. Old path is gone — discover the orphaned shard first**
437
-
438
- ```typescript
439
- memory({ mode: "list-shards" });
440
- memory({ mode: "migrate", fromHash: "fa645294d88bbae2" });
441
- ```
442
-
443
- `list-shards` reports each project hash, stored `projectPath`, memory count,
444
- and status (`current`, `linked`, `orphaned`, `missing-file`, `empty`, or
445
- `ambiguous`). `fromHash` is the 16-character lowercase hexadecimal `scopeHash`
446
- returned by this call. Prefer it when the old directory no longer exists or
447
- multiple shards contain the same stored path, because git-based identities
448
- cannot always be recomputed from a missing path.
449
-
450
- **3. Cross-machine backup / restore**
451
-
452
- ```typescript
453
- // on the source machine / old checkout
454
- memory({ mode: "export", outputPath: "./memories.json" });
455
-
456
- // on the destination machine / new checkout
457
- memory({ mode: "import", inputPath: "./memories.json", dryRun: true });
458
- memory({ mode: "import", inputPath: "./memories.json" });
459
- ```
460
-
461
- Export writes a versioned JSON document without vectors. Import remaps the
462
- memories onto the current project and recomputes embeddings with the currently
463
- configured model. Import adds memories to an existing project, but duplicate
464
- memory IDs abort the whole import before writing; this differs from `migrate`,
465
- which requires an empty target.
466
-
467
- Export files are plaintext and can contain memory content, user names/email
468
- addresses, repository URLs, and absolute project paths. Store them like other
469
- sensitive backups and delete them when no longer needed. Fully private entries
470
- are omitted, and user profiles and prompt history are not included. The
471
- document contains `schemaVersion: 1`; imports reject newer unsupported schema
472
- versions rather than guessing.
473
-
474
- ### Auto-Capture AI Provider
475
-
476
- Auto-capture runs a background AI request to summarize technical work and save it as memory. It needs one of the provider configurations below.
477
-
478
- **Recommended:** Use a provider that is already authenticated in opencode and supports structured output:
479
-
480
- ```jsonc
481
- "opencodeProvider": "anthropic",
482
- "opencodeModel": "claude-haiku-4-5-20251001",
483
- ```
484
-
485
- The plugin issues structured-output requests to opencode's session API instead of calling provider endpoints directly, so opencode owns the auth, token refresh, and provider routing. The provider name must match an entry from `opencode providers list`, and the selected model must support structured JSON output through opencode.
486
-
487
- Supported providers: any provider listed by `opencode providers list` (e.g. `anthropic`, `openai`, `github-copilot`, ...).
488
-
489
- If `opencodeProvider` and `opencodeModel` are set, they take precedence over the manual `memoryProvider` settings below.
490
-
491
- **Follow the session model:** set `"opencodeModel": "inherit"` to use a concrete OpenCode model at call time instead of a pinned id. For **auto-capture**, each prompt is recorded via the `chat.params` hook and the capture request reuses that prompt's provider/model. For **profile learning** and other structured-output paths (which are not tied to a single user message), `inherit` falls back to the most recent model in OpenCode's `model.json` recent list (preferring the configured `opencodeProvider`). Sending the literal model id `inherit` is never valid and previously caused `ProviderModelNotFoundError: Model not found: <provider>/inherit` on those paths. `opencodeProvider` is still required as the normal config gate.
492
-
493
- **Fallback:** Manual API configuration (if not using opencodeProvider):
494
-
495
- ```jsonc
496
- "memoryProvider": "openai-chat",
497
- "memoryModel": "gpt-4o-mini",
498
- "memoryApiUrl": "https://api.openai.com/v1",
499
- "memoryApiKey": "sk-...",
500
- ```
501
-
502
- **API Key Formats:**
503
-
504
- ```jsonc
505
- "memoryApiKey": "sk-..."
506
- "memoryApiKey": "file://~/.config/opencode/api-key.txt"
507
- "memoryApiKey": "env://OPENAI_API_KEY"
109
+ ```text
110
+ /memory-import-opencode-history --dry-run
111
+ /memory-import-pi-history --dry-run
508
112
  ```
509
113
 
510
- Manual `memoryProvider` modes:
511
-
512
- - `openai-chat`: OpenAI Chat Completions compatible API with tool/function calling. This can work with compatible proxies such as LiteLLM only when the selected upstream model and proxy preserve tool calls.
513
- - `openai-responses`: OpenAI Responses API with function-call output.
514
- - `anthropic`: Anthropic Messages API with tool use.
515
- - `minimax`: MiniMax Anthropic Messages-compatible endpoint. Set `memoryApiUrl` to the global endpoint (`https://api.minimax.io`) or the China endpoint (`https://api.minimaxi.com`); the `/anthropic/v1/messages` path and `x-api-key` header are applied automatically. MiniMax text models such as `MiniMax-M3` support the adaptive thinking modes used by this plugin via `memoryExtraParams`.
516
- - `orcarouter`: OpenAI-compatible model gateway with namespaced model IDs. `memoryApiUrl` and `memoryModel` are optional — they default to `https://api.orcarouter.ai/v1` and `orcarouter/auto` (a routing alias that selects a capable model per request). If you set `memoryModel`, use a namespaced ID such as `openai/gpt-5.5` or `deepseek/deepseek-v4-flash`; OrcaRouter rejects bare model names. Example:
517
- ```jsonc
518
- "memoryProvider": "orcarouter",
519
- "memoryApiKey": "<OrcaRouter API key>",
520
- ```
521
- [OrcaRouter](https://www.orcarouter.ai) also runs gateway-level, zero-trust security for AI agents on the same endpoint — screening every prompt/response and governing every tool call on a default-deny basis, with no application code changes.
522
-
523
- Troubleshooting:
524
-
525
- - Auto-capture failures do not block manual `memory` tool usage.
526
- - If auto-capture reports that a provider is not connected, confirm the provider name with `opencode providers list` and configure that provider in opencode first.
527
- - If a proxy or custom provider returns plain text instead of structured/tool output, choose another model/provider or use one of the manual provider modes above.
528
- - For models that reject `temperature`, add `"memoryTemperature": false` when using manual API configuration.
529
- - **Intel Mac (darwin/x64) local embedding:** if embedding init fails or OpenCode exits with SIGILL after local memory use, clear `~/.cache/opencode/packages/om-memory-system@*` (or `opencode-mem@*` on pre-migration installs) after upgrading so the nested install picks up the pinned `onnxruntime-node@1.20.1`, or switch to a remote embedding endpoint via `embeddingApiUrl` + `embeddingApiKey`. See [Choosing / configuring embeddings](#choosing-configuring-embeddings). MLX is not supported.
530
-
531
- ## Public Subpath Exports
114
+ The preview shows how many model calls a real import needs. It uses the
115
+ session's model; add `--model provider/id` for a cheaper one. There is also a
116
+ terminal version, `npx om-memory-system`, that uses an API key. See the
117
+ [OpenCode](docs/opencode-history-import.md) and [Pi](docs/pi-history-import.md)
118
+ import guides, and the [CLI reference](docs/cli.md).
532
119
 
533
- In addition to the main plugin entry, `omms` exposes one stable subpath
534
- that other opencode plugins can import directly. This avoids having to
535
- reverse-engineer container-tag conventions when writing third-party tools that
536
- read or write into the same memory store.
120
+ ## Keeping OMMS up to date
537
121
 
538
- ### `om-memory-system/tags`
122
+ Pi shows a notice when a new version is out; update with
123
+ `pi update npm:om-memory-system`. On OpenCode v2, run `opencode plugin check`
124
+ and `opencode plugin update om-memory-system`. Restart the agent afterwards.
125
+ Coming from `opencode-mem`? Your memories move over automatically, with a
126
+ backup first. See [Updating and upgrading](docs/upgrading.md) and
127
+ [CHANGELOG.md](CHANGELOG.md).
539
128
 
540
- Canonical container-tag helpers. The same functions omms itself uses
541
- to scope auto-captured memories.
129
+ ## Documentation
542
130
 
543
- ```ts
544
- import { getProjectTagInfo, getUserTagInfo, getTags } from "om-memory-system/tags";
131
+ | Read this | To learn about |
132
+ | ---------------------------------------------------------- | ---------------------------------------------------------------- |
133
+ | [Using memory day to day](docs/using-memory.md) | How capture and recall work, the `memory` tool, the user profile |
134
+ | [Configuration](docs/configuration.md) | Settings, choosing the model, embeddings, troubleshooting |
135
+ | [Web UI](docs/web-ui.md) | The memory explorer, opening it on a network safely |
136
+ | [Moving projects](docs/moving-projects.md) | Nested repositories, moved folders, backup and restore |
137
+ | [Updating and upgrading](docs/upgrading.md) | Updates, pinning a version, older stores |
138
+ | [OpenCode adapter](docs/opencode-adapter.md) | How the OpenCode plugin hooks in |
139
+ | [Pi adapter](docs/pi-adapter.md) | How the Pi extension hooks in |
140
+ | [OpenCode history import](docs/opencode-history-import.md) | Importing past OpenCode sessions |
141
+ | [Pi history import](docs/pi-history-import.md) | Importing past Pi sessions, moving machines |
142
+ | [CLI reference](docs/cli.md) | The `om-memory-system` terminal command |
143
+ | [Migrating from opencode-mem](docs/omms-migration.md) | What changes when upgrading from the original plugin |
144
+ | [For developers](docs/developers.md) | Building, testing, the public `tags` export, architecture |
145
+ | [Contributing](CONTRIBUTING.md) | How to set up, test, and send a pull request |
545
146
 
546
- // Canonical project tag derived from cwd (git remote URL if present, else
547
- // the project root path). Format: `omms_project_<sha16>`; rows written by
548
- // older versions are migrated automatically on first start.
549
- const projectTag = getProjectTagInfo(process.cwd()).tag;
550
-
551
- // Canonical user tag derived from `git config user.email`.
552
- // Format: `omms_user_<sha16>`.
553
- const userTag = getUserTagInfo().tag;
554
-
555
- // Both at once.
556
- const { user, project } = getTags(process.cwd());
557
- ```
558
-
559
- Tags produced by these helpers match what auto-capture writes, so third-party
560
- plugins that call `POST /api/memories` will land in the same shards the rest
561
- of the system already understands. Hand-rolled tags whose substring isn't
562
- `_project_` or `_user_` end up in shadow shards that `/api/stats` and
563
- `/api/memories` silently filter out — using these helpers avoids that pitfall.
564
-
565
- ## Development & Contribution
566
-
567
- Build and test locally:
568
-
569
- ```bash
570
- bun install
571
- bun run build
572
- bun run typecheck
573
- bun run format
574
- ```
147
+ ## About this fork
575
148
 
576
- This project is actively seeking contributions to become the definitive memory plugin for AI coding agents. Whether you are fixing bugs, adding features, improving documentation, or expanding embedding model support, your contributions are critical. The codebase is well-structured and ready for enhancement. If you hit a blocker or have improvement ideas, submit a pull request - we review and merge contributions quickly.
149
+ OMMS is [`cmdaltctr/omms`](https://github.com/cmdaltctr/omms), a fork of
150
+ [`tickernelz/opencode-mem`](https://github.com/tickernelz/opencode-mem),
151
+ published on npm as `om-memory-system`. The fork runs the memory engine as a
152
+ shared core for both OpenCode and Pi (see [shared core](docs/shared-core.md)).
153
+ Existing OpenCode memories and settings keep working.
577
154
 
578
- ## License & Links
155
+ ## License and links
579
156
 
580
- MIT License - see LICENSE file
157
+ MIT License. See [LICENSE.md](LICENSE.md).
581
158
 
582
- - **Repository**: https://github.com/cmdaltctr/omms (fork)
583
- - **Upstream**: https://github.com/tickernelz/opencode-mem
584
- - **Issues**: https://github.com/cmdaltctr/omms/issues
585
- - **OpenCode Platform**: https://opencode.ai
159
+ - Repository: https://github.com/cmdaltctr/omms
160
+ - Upstream: https://github.com/tickernelz/opencode-mem
161
+ - Issues: https://github.com/cmdaltctr/omms/issues
586
162
 
587
- Inspired by [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory)
163
+ Inspired by [opencode-supermemory](https://github.com/supermemoryai/opencode-supermemory).