@bcmyguest/openmem 0.0.0-stage → 0.8.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.
Files changed (230) hide show
  1. package/.agents/skills/openmem/SKILL.md +34 -0
  2. package/LICENSE +190 -0
  3. package/README.md +140 -2
  4. package/bin/hindsight-project-index +530 -0
  5. package/cli/coding-agent/access-policy.mjs +38 -0
  6. package/cli/coding-agent/agents.mjs +34 -0
  7. package/cli/coding-agent/bank-from-cwd.mjs +140 -0
  8. package/cli/coding-agent/capabilities.mjs +34 -0
  9. package/cli/coding-agent/context-store.mjs +81 -0
  10. package/cli/coding-agent/context-trim.mjs +897 -0
  11. package/cli/coding-agent/file-io.mjs +72 -0
  12. package/cli/coding-agent/hook-harnesses.mjs +88 -0
  13. package/cli/coding-agent/hook-runner.mjs +284 -0
  14. package/cli/coding-agent/install-access.mjs +119 -0
  15. package/cli/coding-agent/install-context-proxy.mjs +333 -0
  16. package/cli/coding-agent/install-rtk.mjs +60 -0
  17. package/cli/coding-agent/install-shim.mjs +201 -0
  18. package/cli/coding-agent/opencode-config.mjs +107 -0
  19. package/cli/coding-agent/opencode-plugin.mjs +132 -0
  20. package/cli/coding-agent/opencode2-plugin/index.js +299 -0
  21. package/cli/coding-agent/recall-frame.mjs +29 -0
  22. package/cli/coding-agent/remove-upstream-access.mjs +122 -0
  23. package/cli/coding-agent/runtime.mjs +40 -0
  24. package/cli/coding-agent/session-db.mjs +626 -0
  25. package/cli/coding-agent/session-facade.mjs +86 -0
  26. package/cli/coding-agent/toml-edit.mjs +161 -0
  27. package/cli/cognee-mcp.mjs +260 -0
  28. package/cli/context-management.mjs +254 -0
  29. package/cli/feed-sync.mjs +27 -0
  30. package/cli/install-coding-agent.mjs +298 -0
  31. package/cli/install-memory-mcp.mjs +426 -0
  32. package/cli/is-main.mjs +18 -0
  33. package/cli/mcp/context-sql-runner.mjs +58 -0
  34. package/cli/mcp/context-store.mjs +670 -0
  35. package/cli/mcp/context.mjs +61 -0
  36. package/cli/mcp/export/cognee-dataset-name.mjs +12 -0
  37. package/cli/mcp/export/cognee.mjs +119 -0
  38. package/cli/mcp/export/hindsight.mjs +48 -0
  39. package/cli/mcp/export/index.mjs +26 -0
  40. package/cli/mcp/export/mem0.mjs +31 -0
  41. package/cli/mcp/knowledge.mjs +333 -0
  42. package/cli/mcp/llm-synthesize.mjs +50 -0
  43. package/cli/mcp/mem0-scope-id.mjs +22 -0
  44. package/cli/mcp/memory-facade.mjs +521 -0
  45. package/cli/mcp/memory-reflect-consolidate.mjs +120 -0
  46. package/cli/mcp/notebooklm-banks.mjs +21 -0
  47. package/cli/mcp/notebooklm-hindsight-rest.mjs +45 -0
  48. package/cli/mcp/notebooklm-provider.mjs +225 -0
  49. package/cli/mcp/pmm-records.mjs +23 -0
  50. package/cli/mcp/portability.mjs +158 -0
  51. package/cli/mcp/stdio.mjs +65 -0
  52. package/cli/mcp/unified-mcp-install.mjs +65 -0
  53. package/cli/mem0-mcp.mjs +108 -0
  54. package/cli/notebooklm-mcp.mjs +236 -0
  55. package/cli/openmem-mcp.mjs +38 -0
  56. package/cli/openmem.mjs +222 -0
  57. package/cli/roots.mjs +85 -0
  58. package/cli/schedule.mjs +176 -0
  59. package/cli/stack.mjs +438 -0
  60. package/cli/switch-memory-provider.mjs +358 -0
  61. package/cli/wiring-report.mjs +125 -0
  62. package/compose.bench.yaml +12 -0
  63. package/compose.yaml +227 -0
  64. package/config/coding-agent.json +13 -0
  65. package/config/hindsight.env.example +26 -0
  66. package/config/index.yml +54 -0
  67. package/config/litellm.lemond.yaml +40 -0
  68. package/config/litellm.ollama.yaml +33 -0
  69. package/config/notebooklm.yml +33 -0
  70. package/config/openmem.toml.example +124 -0
  71. package/docs/OPENMEM.md +23 -0
  72. package/docs/architecture.md +245 -0
  73. package/docs/assets/README.md +10 -0
  74. package/docs/assets/setup-demo.gif +0 -0
  75. package/docs/coding-agent-hooks.md +75 -0
  76. package/docs/coding-agent-scopes.md +22 -0
  77. package/docs/coding-agents.md +71 -0
  78. package/docs/cognee.md +37 -0
  79. package/docs/compatibility.md +80 -0
  80. package/docs/concepts.md +135 -0
  81. package/docs/context-management.md +255 -0
  82. package/docs/context-proxy.md +115 -0
  83. package/docs/context-research.md +215 -0
  84. package/docs/context-store.md +277 -0
  85. package/docs/hindsight.md +77 -0
  86. package/docs/index-sources-roadmap.md +38 -0
  87. package/docs/index-sources.md +39 -0
  88. package/docs/indexer-sinks.md +122 -0
  89. package/docs/indexing.md +57 -0
  90. package/docs/manual-stack-setup.md +74 -0
  91. package/docs/mcp-install-guide.md +4 -0
  92. package/docs/mcp-setup.md +104 -0
  93. package/docs/mem0.md +141 -0
  94. package/docs/memory-portability.md +73 -0
  95. package/docs/memory-providers.md +246 -0
  96. package/docs/meridian-litellm.md +198 -0
  97. package/docs/model-configuration.md +106 -0
  98. package/docs/notebooklm.md +83 -0
  99. package/docs/npx-install.md +172 -0
  100. package/docs/openmem-config.md +194 -0
  101. package/docs/provider-wizard-hooks.md +222 -0
  102. package/docs/quickstart.md +107 -0
  103. package/docs/setup-wizard.md +117 -0
  104. package/docs/sources-feeds.md +39 -0
  105. package/docs/sources-readwise.md +23 -0
  106. package/docs/sources-zotero.md +22 -0
  107. package/glama.json +4 -0
  108. package/indexer/Dockerfile +38 -0
  109. package/indexer/code_outline.py +146 -0
  110. package/indexer/feed_sync.py +107 -0
  111. package/indexer/index_config.py +290 -0
  112. package/indexer/pytest.ini +5 -0
  113. package/indexer/sinks/__init__.py +148 -0
  114. package/indexer/sinks/_http.py +44 -0
  115. package/indexer/sinks/cognee.py +329 -0
  116. package/indexer/sinks/hindsight.py +107 -0
  117. package/indexer/sinks/mem0.py +247 -0
  118. package/indexer/watch.py +240 -0
  119. package/package.json +96 -4
  120. package/providers/_template/compose.yaml +52 -0
  121. package/providers/cognee/OPERATOR.md +82 -0
  122. package/providers/cognee/compose.yaml +89 -0
  123. package/providers/cognee/lib/clack.mjs +157 -0
  124. package/providers/cognee/lib/coding-agent.mjs +26 -0
  125. package/providers/cognee/lib/cognee-mcp-install.mjs +153 -0
  126. package/providers/cognee/lib/config.mjs +98 -0
  127. package/providers/cognee/lib/env-file.mjs +194 -0
  128. package/providers/cognee/lib/env-setup.mjs +83 -0
  129. package/providers/cognee/lib/llm-env.mjs +382 -0
  130. package/providers/cognee/lib/ports.mjs +25 -0
  131. package/providers/cognee/lib/smoke.mjs +246 -0
  132. package/providers/cognee/lib/stack-env.mjs +134 -0
  133. package/providers/cognee/lib/state.mjs +101 -0
  134. package/providers/cognee/lib/summary.mjs +56 -0
  135. package/providers/cognee/lib/validate.mjs +97 -0
  136. package/providers/cognee/manifest.json +56 -0
  137. package/providers/cognee/wizard.mjs +134 -0
  138. package/providers/graphiti/manifest.json +15 -0
  139. package/providers/hindsight/lib/clack.mjs +347 -0
  140. package/providers/hindsight/lib/coding-agent.mjs +204 -0
  141. package/providers/hindsight/lib/config.mjs +79 -0
  142. package/providers/hindsight/lib/env-setup.mjs +72 -0
  143. package/providers/hindsight/lib/litellm-routes.mjs +196 -0
  144. package/providers/hindsight/lib/meridian.mjs +307 -0
  145. package/providers/hindsight/lib/model-backend.mjs +243 -0
  146. package/providers/hindsight/lib/notebooklm-mcp-install.mjs +127 -0
  147. package/providers/hindsight/lib/ollama-compose.mjs +51 -0
  148. package/providers/hindsight/lib/ports.mjs +30 -0
  149. package/providers/hindsight/lib/probe.mjs +54 -0
  150. package/providers/hindsight/lib/stack-env.mjs +125 -0
  151. package/providers/hindsight/lib/state.mjs +80 -0
  152. package/providers/hindsight/lib/summary.mjs +57 -0
  153. package/providers/hindsight/lib/validate.mjs +81 -0
  154. package/providers/hindsight/manifest.json +58 -0
  155. package/providers/hindsight/wizard.mjs +150 -0
  156. package/providers/letta/manifest.json +29 -0
  157. package/providers/mem0/OPERATOR.md +143 -0
  158. package/providers/mem0/compose.yaml +79 -0
  159. package/providers/mem0/lib/coding-agent.mjs +58 -0
  160. package/providers/mem0/lib/config.mjs +45 -0
  161. package/providers/mem0/lib/configure.mjs +201 -0
  162. package/providers/mem0/lib/dotenv.mjs +71 -0
  163. package/providers/mem0/lib/env-file.mjs +110 -0
  164. package/providers/mem0/lib/http.mjs +69 -0
  165. package/providers/mem0/lib/litellm.mjs +457 -0
  166. package/providers/mem0/lib/mcp-install.mjs +165 -0
  167. package/providers/mem0/lib/secret.mjs +30 -0
  168. package/providers/mem0/lib/smoke.mjs +179 -0
  169. package/providers/mem0/lib/stack-env.mjs +255 -0
  170. package/providers/mem0/lib/state.mjs +67 -0
  171. package/providers/mem0/lib/summary.mjs +88 -0
  172. package/providers/mem0/lib/url.mjs +106 -0
  173. package/providers/mem0/lib/validate.mjs +158 -0
  174. package/providers/mem0/manifest.json +47 -0
  175. package/providers/mem0/wizard.mjs +146 -0
  176. package/providers/zep/manifest.json +29 -0
  177. package/proxy/config.yaml +33 -0
  178. package/proxy/openmem_context/__init__.py +6 -0
  179. package/proxy/openmem_context/adapters.py +504 -0
  180. package/proxy/openmem_context/compress.py +53 -0
  181. package/proxy/openmem_context/core.py +606 -0
  182. package/proxy/openmem_context/embed.py +212 -0
  183. package/proxy/openmem_context/recall.py +49 -0
  184. package/proxy/openmem_context/session.py +70 -0
  185. package/proxy/openmem_context/sessiondb.py +276 -0
  186. package/proxy/openmem_context/settings.py +134 -0
  187. package/proxy/openmem_context/store.py +129 -0
  188. package/proxy/openmem_context/tokens.py +123 -0
  189. package/proxy/openmem_context/ttl.py +78 -0
  190. package/proxy/openmem_context_hook.py +34 -0
  191. package/scripts/check-pack.mjs +219 -0
  192. package/scripts/gen-masks.mjs +83 -0
  193. package/scripts/gen-masks.sh +4 -0
  194. package/scripts/promotion-provider-smoke.mjs +34 -0
  195. package/scripts/run-setup.sh +30 -0
  196. package/scripts/setup.mjs +107 -0
  197. package/scripts/setup.sh +5 -0
  198. package/scripts/spin-up.sh +45 -0
  199. package/scripts/wizard.sh +5 -0
  200. package/server.json +34 -0
  201. package/sync/Dockerfile +27 -0
  202. package/sync/memory_backend.py +87 -0
  203. package/sync/notebooklm_sync.py +664 -0
  204. package/wizard/bin/pm.mjs +97 -0
  205. package/wizard/bin/setup.mjs +33 -0
  206. package/wizard/lib/compose-version.mjs +32 -0
  207. package/wizard/lib/compose.mjs +70 -0
  208. package/wizard/lib/context-step.mjs +140 -0
  209. package/wizard/lib/curl.mjs +103 -0
  210. package/wizard/lib/docker-build.mjs +148 -0
  211. package/wizard/lib/exec.mjs +41 -0
  212. package/wizard/lib/indexer.mjs +6 -0
  213. package/wizard/lib/litellm-env.mjs +55 -0
  214. package/wizard/lib/load-machine-env.mjs +4 -0
  215. package/wizard/lib/log.mjs +32 -0
  216. package/wizard/lib/notebooklm-agent-access.mjs +92 -0
  217. package/wizard/lib/notebooklm.mjs +214 -0
  218. package/wizard/lib/parse-args.mjs +87 -0
  219. package/wizard/lib/paths.mjs +39 -0
  220. package/wizard/lib/pm-config.mjs +371 -0
  221. package/wizard/lib/ports.mjs +94 -0
  222. package/wizard/lib/prompts.mjs +85 -0
  223. package/wizard/lib/provider-wizard/helpers.mjs +98 -0
  224. package/wizard/lib/provider-wizard/run-steps.mjs +129 -0
  225. package/wizard/lib/providers/registry.mjs +262 -0
  226. package/wizard/lib/run-clack.mjs +108 -0
  227. package/wizard/lib/run-wizard.mjs +750 -0
  228. package/wizard/lib/validate-setup.mjs +62 -0
  229. package/wizard/lib/wizard-action.mjs +34 -0
  230. package/wizard/lib/wizard-conf.mjs +71 -0
@@ -0,0 +1,245 @@
1
+ # Architecture
2
+
3
+ OpenMem connects coding agents and a shared indexer to one active [memory provider](provider-status.md). Agents use the stable `memory_*` MCP and session hooks; the indexer writes sources to the same provider. This page shows the full runtime paths and optional integrations. Setup (`npx @bcmyguest/openmem`) configures them but is outside the runtime data path. Switching providers does not migrate memories.
4
+
5
+ ## Overview
6
+
7
+ Two paths. **A, memory:** sources go through the indexer into one active provider, which agents reach through the `memory_*` MCP and session hooks. **B, context management:** the context proxy (OpenCode 2: a native plugin) keeps each session under `trim_at_tokens` by moving older turns to a local session store that the agent searches; no model call summarizes them. OpenMem parts are tinted.
8
+
9
+ <p align="center">
10
+ <picture>
11
+ <source media="(prefers-color-scheme: dark)" srcset="https://bcmyguest.github.io/openmem/media/overview-memory-dark.png" />
12
+ <img src="https://bcmyguest.github.io/openmem/media/overview-memory.png" alt="A, memory: sources, OpenMem indexer, one active provider, OpenMem MCP, coding agents with session hooks" width="360" />
13
+ </picture>
14
+ <picture>
15
+ <source media="(prefers-color-scheme: dark)" srcset="https://bcmyguest.github.io/openmem/media/overview-context-dark.png" />
16
+ <img src="https://bcmyguest.github.io/openmem/media/overview-context.png" alt="B, context management: coding agent, context proxy, model API, session store read back over MCP; OpenCode 2 uses a native plugin" width="360" />
17
+ </picture>
18
+ <br />
19
+ <sub>A, memory · B, context management</sub>
20
+ </p>
21
+
22
+ The sections below show every runtime path and optional integration.
23
+
24
+ ## Runtime data flow
25
+
26
+ Two paths share one **active provider API** (Hindsight, mem0, or Cognee — never more than one). Setup (`npx @bcmyguest/openmem`) is not on this diagram; see [How openmem interfaces with providers](#how-openmem-interfaces-with-providers).
27
+
28
+ ```mermaid
29
+ flowchart TB
30
+ subgraph disk["Sources on disk"]
31
+ GIT[Git repos]
32
+ OBS[Obsidian vaults]
33
+ MD[notes · papers · bookmarks]
34
+ FEED[Feed cache]
35
+ end
36
+
37
+ subgraph compose["Docker Compose"]
38
+ IDX[indexer]
39
+ PROV[(Active provider API)]
40
+ IDX -->|retain / update via sink| PROV
41
+ LIT[LiteLLM]
42
+ NLM[NotebookLM sync]
43
+ LIT -.->|Hindsight stack only| PROV
44
+ NLM -.->|opt-in profile| PROV
45
+ end
46
+
47
+ LIT --> LLM[(Local or cloud LLM)]
48
+
49
+ subgraph host["Host — IDE / coding agents"]
50
+ AG[Coding agents]
51
+ UMCP["openmem MCP\n(memory_*)"]
52
+ SHIM["Session hooks\n(all providers)"]
53
+ PLG["Hindsight plugin\n(--provider-plugin, replaces hooks)"]
54
+ PMCP["Provider MCP\nmem0 or Cognee, optional"]
55
+ NLMCP["NotebookLM MCP\noptional, separate server"]
56
+ end
57
+
58
+ GIT --> IDX
59
+ OBS --> IDX
60
+ MD --> IDX
61
+ FEED --> IDX
62
+ AG <-->|stdio| UMCP
63
+ AG <-->|hooks| SHIM
64
+ AG <-->|optional| PLG
65
+ SHIM -->|memory_*| UMCP
66
+ AG <-->|stdio| PMCP
67
+ AG <-->|stdio| NLMCP
68
+ UMCP -->|loopback HTTP| PROV
69
+ PLG -->|loopback HTTP| PROV
70
+ PMCP -->|loopback HTTP| PROV
71
+ NLMCP -->|loopback HTTP| PROV
72
+ ```
73
+
74
+ | Path | What moves |
75
+ | --- | --- |
76
+ | **Indexing** | Git, Obsidian, markdown trees, feed cache → indexer → provider HTTP sink (`MEMORY_SINK` from manifest) |
77
+ | **Agents** | Cursor/Claude/Codex → session hooks and/or MCP → same provider API |
78
+ | **Unified MCP** | `install-mcp` registers `openmem` on the host; tools delegate to the active provider |
79
+ | **LiteLLM** | Optional sidecar on Hindsight stacks; also used for **cross-provider reflect synthesis** when `PM_LLM_URL` / stack LiteLLM is reachable (`memory_reflect` on mem0/Cognee) |
80
+ | **NotebookLM sync** | **Opt-in, any active provider.** Background sync writes into `notebooklm::*` via the same indexer sinks (Hindsight / mem0 / Cognee); not the same as the NotebookLM MCP |
81
+ | **Provider MCP** | Native mem0 or Cognee tool names (`install-mcp --provider-only`); same API as unified MCP, different stdio server |
82
+ | **NotebookLM MCP** | Read-only list/search over synced notebooks; separate entry in `mcp.json`, not a memory provider |
83
+
84
+ Only **one provider** is active at a time (`MEMORY_PROVIDER`). The indexer uses that provider’s HTTP sink (`MEMORY_SINK` / manifest).
85
+
86
+ ## How openmem interfaces with providers
87
+
88
+ Product framing: [Concepts](concepts.md).
89
+
90
+ OpenMem connects the indexer, Compose, wizard, and MCP to the selected provider through its manifest and adapter. Provider support levels come from [Provider status](provider-status.md).
91
+
92
+ ```mermaid
93
+ flowchart TB
94
+ MAN["providers/*/manifest.json"]
95
+ HOOK["providers/*/wizard.mjs"]
96
+
97
+ subgraph cli["openmem CLI"]
98
+ W[setup / switch / doctor]
99
+ IM[install-mcp]
100
+ end
101
+
102
+ subgraph compose["Compose runtime"]
103
+ IDX[indexer container]
104
+ API[(Active provider HTTP API)]
105
+ IDX -->|sink driver| API
106
+ end
107
+
108
+ subgraph host["Host runtime"]
109
+ MCPJ["~/.cursor/mcp.json"]
110
+ UMCP[openmem-mcp\nmemory-facade]
111
+ AG[Agents]
112
+ end
113
+
114
+ MAN --> W
115
+ MAN --> IDX
116
+ HOOK --> W
117
+ W -->|env · compose up| compose
118
+ IM -->|merge server entry| MCPJ
119
+ MCPJ --> UMCP
120
+ AG <-->|stdio| UMCP
121
+ UMCP -->|fetch active provider| API
122
+ ```
123
+
124
+ ### Integration layers
125
+
126
+ | Layer | What it is | Repo location |
127
+ | --- | --- | --- |
128
+ | **Manifest** | Status, compose services, ports, indexer sink id, smoke HTTP templates | `providers/<id>/manifest.json` |
129
+ | **Wizard hooks** | Provider-specific env, keys, smoke, coding-agent notes | `providers/<id>/wizard.mjs` |
130
+ | **Indexer sink** | Poll/vault → retain/update/delete on the provider API | `indexer/` (driver id in manifest, e.g. `hindsight-rest-v1`, `mem0-rest`) |
131
+ | **Unified MCP** | Stable `memory_*` tools → provider HTTP | `cli/mcp/memory-facade.mjs`, `cli/openmem-mcp.mjs` |
132
+ | **Native agent paths** | Session hooks or provider plugin (`[agents] integration`) + optional MCP | `cli/coding-agent/hook-runner.mjs`; optional Hindsight plugin; `cli/mem0-mcp.mjs`, `cli/cognee-mcp.mjs`, NotebookLM |
133
+
134
+ Adding a provider means a new manifest + hooks + sink driver; agents can keep using **`memory_*`** once the facade implements that backend.
135
+
136
+ ### Runtime wiring (env and config)
137
+
138
+ | Input | Resolves |
139
+ | --- | --- |
140
+ | `MEMORY_PROVIDER` | Active provider (`wizard.conf`, optional `config.toml`) |
141
+ | Stack `.env` | API URLs, ports, `MEMORY_SINK`, indexer → provider URL |
142
+ | Provider secret files | e.g. `~/.config/personal-memory/mem0.env` (never committed; not written to `mcp.json`) |
143
+ | `~/.config/hindsight/index.yml` | What the indexer watches |
144
+
145
+ `npx @bcmyguest/openmem switch <id>` updates provider selection and restarts compose; it does **not** migrate memories ([export/import](memory-portability.md) is for that).
146
+
147
+ ### Example: unified MCP on mem0
148
+
149
+ 1. `npx @bcmyguest/openmem switch mem0 --yes` — compose and env point the indexer and unified MCP at `MEM0_API_URL`.
150
+ 2. `npx @bcmyguest/openmem install-mcp --yes` — merges the `openmem` server into `~/.cursor/mcp.json` (NotebookLM MCP only if you enabled sync or pass `--notebooklm`).
151
+ 3. The agent calls `memory_add` with `{ content: "…", bank: "my-project" }`. The facade sends `POST /memories` with `user_id=my-project` and `infer: false`.
152
+
153
+ `install-mcp --provider-only` is a **different** stdio server: same mem0 API, but upstream mem0 tool names from `@yeyuan98/mem0-mcp`. NotebookLM MCP is **different again** — search over notebooks synced into Hindsight, not a substitute for mem0/Cognee/Hindsight memory.
154
+
155
+ ### Unified MCP → provider HTTP
156
+
157
+ The `openmem` MCP server delegates each tool to the **active** provider:
158
+
159
+ | Unified tool | Hindsight (`HINDSIGHT_URL`) | mem0 (`MEM0_API_URL` + key file) | Cognee (`COGNEE_API_URL`) |
160
+ | --- | --- | --- | --- |
161
+ | `memory_add` | `POST /v1/default/banks/{bank}/memories` | `POST /memories` (`infer: false`, `user_id` from `bank` arg) | `POST /api/v1/add` |
162
+ | `memory_search` / `memory_recall` | `POST /v1/default/banks/{bank}/memories/recall` | `POST /search` with `filters.user_id` | `POST /api/v1/search` |
163
+ | `memory_reflect` | Same recall path | Search + optional LiteLLM synthesis | Search + optional LiteLLM synthesis |
164
+ | `memory_consolidate` | LiteLLM / Hindsight consolidate routes | Skipped (no equivalent) | `POST /api/v1/cognify` |
165
+ | `memory_forget` | `DELETE /v1/default/banks/{bank}` (bank scope) | `DELETE /memories/{id}` | Not exposed yet |
166
+ | `memory_provider_status` | Returns provider id + loopback URL | Same | Same |
167
+ | `memory_export` / `memory_import` | PMM envelope; mem0 list/add — see [Portable memory (PMM)](memory-portability.md) | | |
168
+
169
+ Default scope key for MCP-created rows: bank / `user_id` **`openmem-mcp`** unless the tool passes `bank`.
170
+
171
+ ### Native agent paths (optional, alongside unified MCP)
172
+
173
+ | Provider | Session / tools | Install |
174
+ | --- | --- | --- |
175
+ | **All providers** | In-repo session hooks → unified `memory_*` (`[agents] integration = "openmem"`, default) | `install-coding-agent --yes` |
176
+ | **Hindsight (optional)** | `@vectorize-io/hindsight-coding-agents` plugin instead of the session hooks (`integration = "provider"`) | `install-coding-agent --provider-plugin` |
177
+ | **mem0** | `@yeyuan98/mem0-mcp` tools | `install-mcp --provider-only` |
178
+ | **Cognee** | `cognee_health`, `cognee_search` | `install-mcp --provider-only` |
179
+ | **NotebookLM** | `notebooklm_list_banks`, `notebooklm_search` | `install-mcp` when sync enabled or `--notebooklm` |
180
+
181
+ `install-mcp` merges the **unified** `openmem` server by default (`--no-unified-mcp` to skip).
182
+
183
+ ## How file changes become memory
184
+
185
+ The indexer does not watch your editor — it watches **configured sources** on disk (poll, inotify, or periodic re-list).
186
+
187
+ | Source | Detection | What gets sent to the provider |
188
+ | --- | --- | --- |
189
+ | Git repo | Poll every `poll_seconds` (default 60): `HEAD` + tracked-file status | Tree-sitter outlines + text for changed files → **retain** on the active sink |
190
+ | Obsidian vault | inotify; re-index after `vault_quiet_seconds` (default 30) without edits | Vault documents → provider-specific banks |
191
+ | Notes / papers / bookmarks | `notes.paths`, `papers.paths`, `bookmarks.paths`; inotify on `.md` (bookmarks also `.html`, `.txt`) | Markdown (and bookmark exports) → `notes::`, `papers::`, `bookmarks::` banks |
192
+ | Feed cache | `feeds.out_dir` after `npx @bcmyguest/openmem feed-sync` (RSS / OpenAlex) | Generated markdown → `feed::` banks |
193
+ | New sources under scan roots | Re-list every `relist_seconds` (default 600) | Picked up without restarting the stack |
194
+
195
+ Configuration: `~/.config/hindsight/index.yml` (wizard writes this on first setup). Full source list and examples: [index-sources.md](index-sources.md) · [sources-feeds.md](sources-feeds.md) · [sources-zotero.md](sources-zotero.md) · [sources-readwise.md](sources-readwise.md). Filters such as `optInPaths` in `~/.hindsight/coding-agent.json` can limit which discovered sources are indexed.
196
+
197
+ Bank prefixes include `coding-agent::`, `obsidian::`, `notes::`, `papers::`, `bookmarks::`, `feed::`, and optional `notebooklm::*`. mem0 uses `user_id` / `agent_id` / `run_id`; Cognee uses **datasets** mapped from indexer banks.
198
+
199
+ ## Industry context
200
+
201
+ There is **no** cross-vendor standard for agent memory APIs. MCP standardizes tool transport, not memory semantics — each product exposes different tool names and shapes. openmem’s answer is a **stable facade** on your chosen backend so agents keep the same verbs when you switch providers.
202
+
203
+ ## Unified openmem MCP (beta)
204
+
205
+ `cli/openmem-mcp.mjs` registers as the `openmem` server in `~/.cursor/mcp.json` when you run `install-mcp` (unless `--no-unified-mcp`). It delegates to the active provider:
206
+
207
+ | Tool | Purpose |
208
+ | --- | --- |
209
+ | `memory_add` | Store text (Hindsight bank, mem0 user scope, Cognee dataset add) |
210
+ | `memory_search` / `memory_recall` | Query memories on the active backend |
211
+ | `memory_reflect` | Session-style context (recall or search + optional LiteLLM) |
212
+ | `memory_consolidate` | Cognee cognify; Hindsight notes; mem0 skip |
213
+ | `memory_forget` | Delete by id (mem0) or drop a Hindsight bank |
214
+ | `memory_provider_status` | Active provider and loopback URL (no secrets) |
215
+ | `memory_export` / `memory_import` | PMM portable format — [Portable memory (PMM)](memory-portability.md) |
216
+ | `memory_project_scope` | Resolve a workspace's bank and hook access (local) |
217
+ | `memory_pages_list` / `memory_pages_search` / `memory_pages_read` | List, search, and read curated knowledge pages (Hindsight; others return `supported: false`) |
218
+ | `memory_capture_initiative` | Record an approved feature plan as a tracked initiative page plus marker memory (Hindsight) |
219
+ | `memory_status` | Async ingest drain state and operation status (Hindsight; mem0 always ready) |
220
+ | `smart_compact_search` | Search a session's SQLite store of every message (FTS5 BM25 `query`, merged with embeddings when present, or a `pattern` regex), filtered by `role` and `in_context`, with `context` neighbouring rows (local files, every provider) — [Context store](context-store.md) |
221
+ | `smart_compact_sql` | One read-only SELECT against a session database, for counts and aggregates (2 s, 200 rows) |
222
+ | `smart_compact_get` | Return the full text of a compressed tool result by blob id, paged at 100k chars (local files, every provider) |
223
+
224
+ **Session hooks** (all providers) call the unified MCP via `cli/coding-agent/hook-runner.mjs`. Optional [`@vectorize-io/hindsight-coding-agents`](https://www.npmjs.com/package/@vectorize-io/hindsight-coding-agents) replaces them on Hindsight stacks: `--provider-plugin` sets `[agents] integration = "provider"`, removes OpenMem's hooks and keeps the unified MCP; `--no-provider-plugin` switches back. `--hindsight-plugin` was renamed to `--provider-plugin`. See [Coding-agent hooks](coding-agent-hooks.md).
225
+
226
+ ### Other MCP integrations
227
+
228
+ | Integration | Tools / path | Role |
229
+ | --- | --- | --- |
230
+ | Session hooks | SessionStart / prompt / Stop → `memory_*` | Default in-IDE session memory (all providers) |
231
+ | Hindsight plugin (optional) | Upstream retain / recall / reflect, instead of the session hooks | `--provider-plugin` only |
232
+ | `notebooklm` (`install-mcp`) | `notebooklm_list_banks`, `notebooklm_search` | Opt-in synced notebooks |
233
+ | `mem0` (`--provider-only`) | mem0 REST tools via `@yeyuan98/mem0-mcp` | Native mem0 tool names |
234
+ | `cognee` (`--provider-only`) | `cognee_health`, `cognee_search` | Native Cognee read-only MCP |
235
+
236
+ ## Related
237
+
238
+ - [Portable memory (PMM)](memory-portability.md) — export/import
239
+ - [MCP setup](mcp-setup.md) — unified and provider-native MCP
240
+ - [Provider status](provider-status.md) — manifest status and ports
241
+ - [mem0 operator guide](mem0.md) — URL-only mem0 setup
242
+ - [Cognee operator guide](cognee.md) — loopback container + LLM env
243
+ - [Configuration file](openmem-config.md) — `config.toml` for provider and stack defaults
244
+
245
+ Contributor-only guides (wizard phases, hooks, manual compose, [indexer sinks](indexer-sinks.md), [pluggable providers](memory-providers.md)) live under `docs/` in git and are not all published on the site. Day-to-day MCP install is on [MCP setup](mcp-setup.md).
@@ -0,0 +1,10 @@
1
+ # Docs assets
2
+
3
+ Regenerate the setup demo GIF after wizard output changes:
4
+
5
+ ```sh
6
+ uv run --with pillow python scripts/render-setup-gif.py
7
+ cp docs/assets/setup-demo.gif site/public/setup-demo.gif
8
+ ```
9
+
10
+ The capture uses stubbed `docker`/`curl` and `npx @bcmyguest/openmem setup --dry-run` (via `wizard/bin/setup.mjs`).
Binary file
@@ -0,0 +1,75 @@
1
+ # Coding-agent session hooks (parity)
2
+
3
+ Hindsight ships session retain/recall/reflect through
4
+ [`@vectorize-io/hindsight-coding-agents`](https://www.npmjs.com/package/@vectorize-io/hindsight-coding-agents).
5
+ openmem routes session work through the **unified MCP** (`memory_*`) for all three backends.
6
+
7
+ ## Capability matrix
8
+
9
+ | Capability | Hindsight (default shim) | mem0 (session shim) | Cognee (session shim) |
10
+ | --- | --- | --- | --- |
11
+ | retain | yes for supported agent transcripts | yes for supported agent transcripts (`memory_add`) | yes for supported agent transcripts |
12
+ | recall / search | yes | yes (prompt hook → `memory_recall`) | yes |
13
+ | reflect | yes (`memory_reflect` → Hindsight reflect) | search + optional LiteLLM synthesis | search + optional LiteLLM synthesis; raw hits if unavailable |
14
+ | consolidate | yes (Hindsight/LiteLLM routes) | no | yes (`memory_consolidate` → cognify) |
15
+ | bank / scope | Hindsight banks | mem0 `user_id` | Cognee dataset |
16
+
17
+ Flags live in `cli/coding-agent/capabilities.mjs`; `doctor wiring` and
18
+ `install-coding-agent` read the same table. `npx @bcmyguest/openmem wiring` prints
19
+ which session features work for the active provider.
20
+
21
+ ## Install per agent
22
+
23
+ ```sh
24
+ npx @bcmyguest/openmem install-coding-agent --yes
25
+ ```
26
+
27
+ - **All providers:** unified MCP and [shared skill](../.agents/skills/openmem/SKILL.md), plus session hooks (`cli/coding-agent/hook-runner.mjs`) for Claude Code, Codex, Cursor Agent, and a JavaScript OpenCode plugin: `cli/coding-agent/opencode-plugin.mjs` for OpenCode 1, `cli/coding-agent/opencode2-plugin/` for OpenCode 2 (the installer picks one from `opencode --version`).
28
+ - **Exclusive hook sets:** `[agents] integration` in `~/.config/personal-memory/config.toml` picks one. `openmem` (default) installs the hooks above and removes the upstream Hindsight install: hook entries (commands under `hindsight-coding-agents` / `.hindsight/coding-agents`), the matching OpenCode `plugin` entry, the `hindsight` MCP server when it runs the upstream `dist/mcp-server.js` (Claude Code `~/.claude.json`, Codex `config.toml`, Cursor `mcp.json`), and the `hindsight-coding-agent` skill copies. Upstream writes no MCP or skill for OpenCode. `provider` (`--provider-plugin`, Hindsight only) removes OpenMem's hooks, keeps the unified MCP, and runs `@vectorize-io/hindsight-coding-agents install`. `--no-provider-plugin` switches back; `--hindsight-plugin` was renamed to `--provider-plugin`. Other providers always get OpenMem hooks.
29
+
30
+ SessionStart output starts with a two-line banner: provider, bank, and the tools to use. It names `memory_pages_search` and `memory_capture_initiative` only when `PROVIDER_CAPABILITIES` marks `knowledge_pages` / `initiatives` for the provider. The same hook writes `sessions/<sid>.json` per [context store](context-store.md); a write failure is ignored. Denied workspaces get no registration.
31
+
32
+ `/smart-compact`: the installer writes `~/.claude/commands/smart-compact.md`. The prompt hook (Claude Code, Codex, Cursor) and the OpenCode plugin write `sessions/<sid>.force` when the prompt starts with `/smart-compact`, contains `<command-name>/smart-compact</command-name>`, or contains the command body's `openmem:smart-compact` marker; that prompt skips recall. The flag is written even when memory hooks are denied. Claude Code's hook docs say UserPromptSubmit receives the typed `/command args` text; the other two forms cover expanded deliveries.
33
+
34
+ Cursor hooks live under `hooks` in `~/.cursor/hooks.json` with `version: 1`, as Cursor documents; reinstall moves entries older OpenMem versions wrote at the top level.
35
+
36
+ See [MCP setup](mcp-setup.md) and [coding agents](coding-agents.md).
37
+
38
+ Claude Code Stop retention parses ordinary message and tool-use rows. Codex Stop retention is best effort because Codex does not guarantee a stable transcript format. Cursor Stop retention has a bounded adapter for the observed local agent-transcripts JSONL shape (top-level user/assistant role and `message.content` parts). Live Cursor Hook `transcript_path` linkage to that format remains unverified; unknown row shapes are skipped. Cursor recall and explicit `memory_add` remain available. OpenCode retention uses its plugin's session messages API.
39
+
40
+ ### OpenCode 2 plugin
41
+
42
+ OpenCode 2 does not run OpenCode 1 plugins ([migration guide](https://opencode.ai/v2/docs/build/plugins/migrate-v1/)). `cli/coding-agent/opencode2-plugin/index.js` default-exports a plain `{ id: "openmem", setup }` object. `Plugin.define` from `@opencode/plugin` 2.2.1 returns its argument unchanged, and OpenCode reads the default export's `id` and `setup()` ([Support V1](https://opencode.ai/v2/docs/build/plugins/server/#support-v1)), so the plugin adds no runtime dependency. `setup(ctx)` registers:
43
+
44
+ | Feature | OpenCode 2 API | Behaviour |
45
+ | --- | --- | --- |
46
+ | Registration | `prompt` / `context` hooks, `session.created` event | Writes `sessions/<sid>.json` on the first hook call per session. In OpenCode 2.2.1 a location's plugins loaded after `opencode run` had created the session, so `session.created` never arrived |
47
+ | Prompt recall | `ctx.session.hook("prompt")` | First prompt: `memory_reflect`; later prompts: `memory_recall` |
48
+ | System context | `ctx.session.hook("context")` | Pushes the session banner onto `event.system`; puts `Personal memory for <bank>:` and the framed recall block in a leading text part of the user message the prompt belongs to, never in `event.system` |
49
+ | Native trim | `ctx.session.hook("context")` | Replaces `event.messages` per [context proxy](context-proxy.md) rules (`cli/coding-agent/context-trim.mjs`) |
50
+ | Native compaction | `ctx.session.hook("compaction")` | Sets `event.result.summary` to the pointer + recall; `[compaction] native = false` disables it |
51
+ | `/smart-compact` | `prompt` hook; `ctx.command.transform` adds a `smart-compact` command | Writes `sessions/<sid>.force`; no recall for that prompt |
52
+ | Retention | `ctx.session.hook("experimental.idle")`; `session.execution.succeeded`, `session.status` idle and `session.idle` events as fallbacks | Reads `ctx.session.context()` and retains the new user/assistant text once per turn |
53
+
54
+ The access policy matches OpenCode 1: denied workspaces get no registration, recall or retention, but `/smart-compact`, trimming and compression still run. As with the proxy, a trim pointer carries recall only when the session's registration names a bank.
55
+
56
+ Hindsight Stop hooks submit retains with `async: true` so model extraction runs after the hook returns. A successful queue response advances the transcript cursor; later extraction failures must be checked through Hindsight operations. MCP `memory_add` defaults to async; pass `async: false` to wait for extraction.
57
+ SessionStart hooks use recall instead of reflect. Hindsight startup recall requests `budget: low` and `max_tokens: 1200`; all hook recall output is limited to eight hits and 8000 characters. Explicit `memory_reflect` remains available through the MCP.
58
+
59
+ Every hook and plugin recall (SessionStart and prompt hooks for Claude Code, Codex and Cursor; the OpenCode 1 and 2 per-prompt recall) is framed as untrusted data with the trim pointer's frame ([format](context-store.md#proxy-inserted-text)): the fixed sentence, then the text in an `<openmem-recall untrusted="true">` block whose inner `openmem-recall` tags are escaped. The 8000-character cap includes the 147-character frame; the SessionStart banner and the OpenCode `Personal memory for <bank>:` label sit outside it. `hookRecallBlock` in `cli/coding-agent/session-facade.mjs` builds it from the shared `recallBlock` (`cli/coding-agent/recall-frame.mjs`). `[compaction] recall` does not affect hook recall.
60
+
61
+ ## Session scopes
62
+
63
+ Indexer banks map to provider scopes (`coding-agent::repo`, `obsidian::vault`, mem0 `user_id`, Cognee dataset names). Default MCP scope key: `openmem-mcp`. See [coding-agent-scopes.md](coding-agent-scopes.md).
64
+
65
+ Hook access is configured in `~/.config/personal-memory/coding-agent.json`. With no file,
66
+ hooks are enabled for all workspaces and use the bank derived from the workspace name. A
67
+ malformed or unreadable config denies hook access, as does an event with no workspace path.
68
+ Set `disabled: true` to turn hooks off, or set `optInOnly: true` and list allowed absolute
69
+ workspace prefixes in `optInPaths`. Project banks resolve in this order: longest matching
70
+ prefix in active `index.yml` `banks`, longest matching prefix in this openmem
71
+ config, then the legacy Hindsight `~/.hindsight/coding-agent.json` mapping. Without
72
+ a match, the literal repository directory name is used in `coding-agent::<name>` (case
73
+ preserved). Nested workspace paths resolve to their Git repository root, and linked
74
+ worktrees share the common repository identity. The openmem config owns current
75
+ access and mapping policy; the legacy mapping remains supported for compatibility.
@@ -0,0 +1,22 @@
1
+ # Session scopes (banks, user_id, datasets)
2
+
3
+ One **scope key** is reused across indexer, unified MCP, and (where supported) the coding-agent path.
4
+
5
+ | Provider | Indexer bank example | MCP `bank` argument | Notes |
6
+ | --- | --- | --- | --- |
7
+ | Hindsight | `coding-agent::my-repo` | same bank string | Personal-memory hooks and MCP use Hindsight banks |
8
+ | mem0 | same bank string | maps to `user_id` | `memory_add` sets `user_id=bank` |
9
+ | Cognee | same bank string | maps to dataset name | See `cognee-dataset-name` in export code |
10
+
11
+ Default when tools omit `bank`: **`openmem-mcp`**.
12
+
13
+ Configure what gets indexed in `~/.config/hindsight/index.yml`. Optional filters in
14
+ `~/.hindsight/coding-agent.json` (`optInPaths`) limit which discovered sources are indexed.
15
+ Project bank routing is shared by the indexer and session integrations: the longest
16
+ matching `banks` prefix in the active index config wins, followed by
17
+ `~/.config/personal-memory/coding-agent.json` `mapPathToBank`, then the legacy
18
+ `~/.hindsight/coding-agent.json` mapping. The fallback uses the literal repository
19
+ directory name, preserving case; nested paths resolve to the repository root, and linked
20
+ worktrees use their common repository identity.
21
+
22
+ Future: `[session]` section in `~/.config/personal-memory/config.toml` may pin a default scope per repo; not required today.
@@ -0,0 +1,71 @@
1
+ # Coding agents and MCP
2
+
3
+ Prerequisite: run the wizard (`npx @bcmyguest/openmem`) so a provider stack is up. The MCP server and hooks only forward to that stack. Per-agent support and evidence levels: [Compatibility matrix](compatibility.md).
4
+
5
+ One entry point for session wiring on **every** provider (unified MCP + in-repo session hooks):
6
+
7
+ ```sh
8
+ npx @bcmyguest/openmem install-coding-agent --yes
9
+ # --provider-plugin / --no-provider-plugin: upstream Hindsight hooks instead of openmem's (saved in config)
10
+ # --no-rtk: skip rtk wiring; --context-proxy / --no-context-proxy: local context proxy (saved in config)
11
+ # same flags: --dry-run, --agents claude-code,codex,opencode,cursor-cli,hermes,gemini-cli,amp,cline
12
+ ```
13
+
14
+ Persisted choices live in `~/.config/personal-memory/config.toml`:
15
+
16
+ | Table | Key | Default | Flag |
17
+ | --- | --- | --- | --- |
18
+ | `[agents]` | `integration` = `openmem` \| `provider` | `openmem` | `--provider-plugin`, `--no-provider-plugin` |
19
+ | `[context_proxy]` | `enabled` | `false` | `--context-proxy`, `--no-context-proxy` |
20
+ | `[context_proxy]` | `port` | `4100` | edit the file |
21
+ | `[compaction]` | `native` | `true` | edit the file; OpenCode 2 only (see below) |
22
+
23
+ The two hook sets are exclusive; see [hook parity](coding-agent-hooks.md#install-per-agent).
24
+
25
+ **rtk.** When [`rtk`](https://github.com/rtk-ai/rtk) is on `PATH`, the installer runs rtk's own setup per selected agent: `rtk init -g --auto-patch` (Claude Code), `rtk init -g --codex`, `rtk init -g --agent cursor`, `rtk init -g --opencode`. rtk adds PreToolUse-style command rewriting and keeps other hooks; OpenMem's reinstall keeps rtk's entries. `rtk init` is idempotent. `--no-rtk` skips it.
26
+
27
+ **Context proxy.** `--context-proxy` creates `~/.config/personal-memory/context-proxy.env` (mode 600) with `LITELLM_MASTER_KEY` once and reuses it. Claude Code gets `env.ANTHROPIC_BASE_URL = http://127.0.0.1:<port>` and `env.ANTHROPIC_CUSTOM_HEADERS = x-litellm-api-key: Bearer <key>` in `~/.claude/settings.json`; OpenCode gets `provider.anthropic.options.baseURL = http://127.0.0.1:<port>/v1` and the same header ([OpenCode providers](https://opencode.ai/docs/providers/#base-url)). Claude Code then fails until the proxy runs. The proxy trims long sessions and compresses tool results; typing `/smart-compact` makes the prompt hook flag the next request for a trim. See [Context proxy](context-proxy.md). `--no-context-proxy` removes those keys when they still point at the loopback proxy; the key file stays. Codex stays hook-only. OpenCode 2 is never pointed at the proxy, even with `--context-proxy`; see below.
28
+
29
+ **OpenCode 1 or 2.** The installer runs `opencode --version`; output naming major 2 or later (OpenCode 2.2.1 prints `opencode v2.2.1`) selects OpenCode 2, and any failure or other output selects OpenCode 1. OpenCode 1 gets the file entry `cli/coding-agent/opencode-plugin.mjs` under `"plugin"`. OpenCode 2 gets the runtime directory `cli/coding-agent/opencode2-plugin` under `"plugins"` ([OpenCode 2 plugin config](https://opencode.ai/v2/docs/plugins/); configured local paths must be directories). Each install removes OpenMem's entry of the other shape, so only one OpenMem plugin loads. On OpenCode 2 the plugin trims context itself in its `context` hook, with the proxy's rules, thresholds (`CONTEXT_TRIM_AT_TOKENS`, `CONTEXT_COMPRESS_OVER_TOKENS`, `CONTEXT_COMPACTION_MAX_CHARS`, read from the environment OpenCode runs in), standing system-prompt instruction (`CONTEXT_STANDING_INSTRUCTION`) and [context store](context-store.md) files: every message goes into the session database `sessions/<sid>.db` through `node:sqlite` (Node ≥ 24). The installer therefore removes any earlier `provider.anthropic` proxy settings and says so in its summary. When OpenCode 2 compacts a session itself, the plugin's `compaction` hook marks every stored message out of context and supplies the `smart_compact_search` pointer plus bounded recall as the summary, so no model call is made. `[compaction] native = false` returns compaction to OpenCode's own summary.
30
+
31
+ This stages a persistent runtime under `~/.local/share/personal-memory/agent-runtime`, registers the unified MCP globally in Claude Code, Codex, Cursor Agent, and OpenCode, and installs their session hooks. It also copies the [openmem skill](../.agents/skills/openmem/SKILL.md) into each agent's global skill directory. The runtime path stays valid after an `npx` cache cleanup. Re-run the command after upgrading this package to refresh the runtime and skill. See [hook parity](coding-agent-hooks.md).
32
+
33
+ For Codex, installation sets `sandbox_mode = "workspace-write"` and enables `features.hooks` and `sandbox_workspace_write.network_access` when unset, and preserves explicit values. Codex otherwise defaults to a read-only sandbox without network, which breaks `curl` and package installs. For OpenCode, the plugin and MCP entry go into the existing `opencode.jsonc` or `opencode.json`; unrelated settings and JSONC comments outside the updated fields are retained.
34
+
35
+ Codex requires review of new or changed non-managed hooks in `/hooks` before they run. [Codex hook documentation](https://developers.openai.com/codex/hooks) describes this trust step.
36
+
37
+ The command keeps existing agent settings and other MCP servers. With `integration = "openmem"` it removes what the upstream Hindsight plugin installed: its hook entries, its `hindsight` MCP server (`~/.claude.json`, `~/.codex/config.toml`, `~/.cursor/mcp.json`) and its `hindsight-coding-agent` skill (`~/.claude/skills`, `~/.agents/skills`, `~/.cursor/skills`). An MCP entry goes only when it runs the upstream `hindsight-coding-agents/dist/mcp-server.js`; a skill only when its `SKILL.md` declares `name: hindsight-coding-agent`. A `hindsight` MCP entry of your own that points elsewhere stays. `--dry-run` lists the removals; `provider` mode removes none of these.
38
+
39
+ Wizard step 8 (Coding agents) offers the same `install-coding-agent --yes` for detected CLIs.
40
+
41
+ Use a **real** `~/.hindsight/coding-agent.json` on disk (seed from `config/coding-agent.json`). Do not symlink into the repo — machine fields such as `optInPaths` and `notebooklmAccess` must not live in the checkout. The indexer reads this file through the `$HOME` mount. If it is missing, the indexer logs a warning and still indexes everything under `$HOME`.
42
+
43
+ ### Memory MCP servers (`~/.cursor/mcp.json`)
44
+
45
+ To register **only** Cursor's memory-related MCP entries (NotebookLM, mem0, Cognee, and unified `openmem`) without re-running full setup:
46
+
47
+ ```sh
48
+ npx @bcmyguest/openmem install-mcp --yes
49
+ # checkout: node cli/openmem.mjs install-mcp --yes
50
+
51
+ # mem0 self-hosted REST → @yeyuan98/mem0-mcp via cli/mem0-mcp.mjs
52
+ MEMORY_PROVIDER=mem0 npx @bcmyguest/openmem install-mcp --yes --provider-only
53
+
54
+ # Cognee read-only health/search → cli/cognee-mcp.mjs
55
+ MEMORY_PROVIDER=cognee npx @bcmyguest/openmem install-mcp --yes --provider-only
56
+ ```
57
+
58
+ Provider comes from `MEMORY_PROVIDER`, else `~/.config/hindsight/wizard.conf`, else `hindsight`. NotebookLM MCP is installed when `~/.config/hindsight/notebooklm.yml` has `enabled: true`, or with `--notebooklm`. Flags: `--dry-run`, `--notebooklm-only`, `--provider-only`. Existing `hindsight` / `codegraph` / `notebooklm` / sibling provider entries are merged, not clobbered. For mem0, `mcp.json` gets `MEM0_API_URL` / `MEM0_BASE_URL` and the path to `mem0.env` — never the API key ([mem0 operator guide](https://github.com/bcmyguest/openmem/blob/main/providers/mem0/OPERATOR.md)). For Cognee, `mcp.json` gets `COGNEE_API_URL` only — never `COGNEE_API_KEY` ([Cognee operator guide](https://github.com/bcmyguest/openmem/blob/main/providers/cognee/OPERATOR.md); tools `cognee_health` / `cognee_search`). Manual JSON edits remain a fallback.
59
+
60
+ Restart the Cursor Agent (or other coding agent) after install so it loads the new wiring. With `optInOnly: true`, only paths listed in `optInPaths` get memory — `/tmp` workspaces and other unlisted directories stay opted out.
61
+
62
+ ### Switch memory provider
63
+
64
+ To change `MEMORY_PROVIDER` (updates `~/.config/hindsight/wizard.conf`, optionally restarts the stack and refreshes provider MCP) without a full interactive setup:
65
+
66
+ ```sh
67
+ npx @bcmyguest/openmem switch mem0 --yes
68
+ # checkout: node cli/openmem.mjs switch cognee --yes
69
+ ```
70
+
71
+ Flags: `--dry-run`, `--no-stack` (skip compose down/up), `--no-mcp` (skip `install-mcp --provider-only`). Switching does **not** migrate memories between backends. After a switch: restart Cursor Agent, then `npx @bcmyguest/openmem doctor`.
package/docs/cognee.md ADDED
@@ -0,0 +1,37 @@
1
+ # Cognee (loopback container)
2
+
3
+ Self-hosted graph/RAG memory via a pinned `cognee/cognee` image on a loopback port (`COGNEE_PORT`, default **8766**). Auth is off in this stack. Cognify defaults to local GLiNER + FastEmbed (no API key); optional LLM keys live in env files under `~/.config/personal-memory/`, not in stack `.env` or `mcp.json`.
4
+
5
+ ## Coding agents
6
+
7
+ No plugin package. Agents use REST (`/docs`, `/health`, `/api/v1/add`, `/cognify`, `/search`) or the **read-only** MCP in this repo.
8
+
9
+ ### Cursor MCP
10
+
11
+ When `MEMORY_PROVIDER=cognee`:
12
+
13
+ ```sh
14
+ npx @bcmyguest/openmem install-mcp --yes --provider-only
15
+ ```
16
+
17
+ Registers `cli/cognee-mcp.mjs` with `COGNEE_API_URL` only — **never** `COGNEE_API_KEY` in `mcp.json`. If you enable auth, export the key in the agent environment.
18
+
19
+ | Tool | Purpose |
20
+ | --- | --- |
21
+ | `cognee_health` | `GET /health` |
22
+ | `cognee_search` | `POST /api/v1/search` |
23
+
24
+ Ingest and cognify stay with the indexer or direct API calls; the MCP is search/health only.
25
+
26
+ Restart Cursor Agent after install.
27
+
28
+ ## Switch provider
29
+
30
+ ```sh
31
+ npx @bcmyguest/openmem switch cognee --yes
32
+ # later: npx @bcmyguest/openmem switch hindsight --yes
33
+ ```
34
+
35
+ Updates active provider config, restarts the stack (unless `--no-stack`), runs MCP install (unless `--no-mcp`). Does **not** migrate memories.
36
+
37
+ See also [Architecture](architecture.md), [Hindsight](hindsight.md), and [Provider status](provider-status.md).
@@ -0,0 +1,80 @@
1
+ # Compatibility matrix
2
+
3
+ What OpenMem supports per coding agent and per memory provider, as of branch `feat/openmem-context-layer` (2026-10-29). Each cell records the strongest evidence that exists, not intent.
4
+
5
+ | Mark | Meaning |
6
+ | --- | --- |
7
+ | ✅ | Verified live against a real agent or server |
8
+ | 🧪 | Implemented and covered by automated tests; not yet verified live |
9
+ | ◐ | Partial or best effort; see the note |
10
+ | ❌ | Not supported |
11
+
12
+ ## Coding agents
13
+
14
+ `install-coding-agent` wires the first five columns. Hermes, Gemini CLI, Amp and Cline get the unified MCP through `install-mcp` and their own MCP configuration; nothing else.
15
+
16
+ | Feature | Claude Code | Codex CLI | Cursor CLI | OpenCode 1.x | OpenCode 2.x |
17
+ | --- | --- | --- | --- | --- | --- |
18
+ | Unified `memory_*` MCP | 🧪 ¹⁴ | 🧪 | 🧪 ¹⁴ | 🧪 ¹⁴ | ❌ ¹ |
19
+ | OpenMem skill | 🧪 | 🧪 | 🧪 | 🧪 | ❌ ¹ |
20
+ | Startup banner + recall | 🧪 | 🧪 ² | 🧪 ³ | 🧪 ²² | 🧪 ¹⁵ ²² |
21
+ | Session registration (`sessions/<sid>.json`) | 🧪 | 🧪 | 🧪 ³ | 🧪 ⁴ | ✅ ¹⁵ ¹⁶ |
22
+ | Per-prompt recall | 🧪 | 🧪 | 🧪 ³ | 🧪 | ✅ ¹⁵ |
23
+ | Turn retention (Stop / idle) | 🧪 | ◐ ⁵ | ◐ ⁶ | 🧪 | ✅ ¹⁵ ¹⁷ |
24
+ | `/smart-compact` trim flag | 🧪 ⁷ | 🧪 | 🧪 | 🧪 | ✅ ¹⁵ ¹⁸ |
25
+ | Context proxy (trim, tool-result compression) | ✅ ⁸ | ✅ ⁹ | ❌ ¹⁰ | ◐ ¹¹ | ✅ native ¹⁵ ¹⁹ |
26
+ | Agent compaction replaced by pointer + recall | ❌ | ❌ | ❌ | ❌ | ✅ ¹⁵ (`[compaction] native`) |
27
+ | `[agents] integration` toggle | 🧪 ²¹ | 🧪 ²¹ | 🧪 ²¹ | 🧪 ²¹ | 🧪 ²⁰ |
28
+ | rtk command rewriting (`rtk init`) | 🧪 ¹² | 🧪 ¹² | 🧪 ¹² | 🧪 ¹² | ❌ ¹³ |
29
+
30
+ 1. Not built for OpenCode 2. OpenCode 2 replaced the plugin API ([migration guide](https://opencode.ai/v2/docs/build/plugins/migrate-v1/)) and its config shape (`"plugins"`, `"providers"`); the installer's MCP and skill wiring for OpenCode was written for OpenCode 1 and has not been checked against OpenCode 2.
31
+ 2. Codex runs non-managed hooks only after review in `/hooks` ([Codex hooks](https://developers.openai.com/codex/hooks)).
32
+ 3. Cursor hooks now go under `"hooks"` in `~/.cursor/hooks.json` (Cursor's documented shape). Earlier OpenMem releases wrote them at the top level, where Cursor does not read them.
33
+ 4. The plugin registers on `session.created` and, when `context-proxy.env` exists, sends `x-openmem-session-id` through `chat.headers`, so the proxy keys OpenCode trims by the real session id. Neither is verified in a live OpenCode session.
34
+ 5. Codex does not guarantee a stable transcript format; unknown rows are skipped.
35
+ 6. Cursor Stop retention parses the observed local `agent-transcripts` JSONL shape; live hook `transcript_path` linkage is unverified.
36
+ 7. Detects the typed `/smart-compact`, the expanded `<command-name>` tag, and an `openmem:smart-compact` marker; which form Claude Code passes to UserPromptSubmit is unverified.
37
+ 8. Verified with `claude -p` on a Claude subscription through LiteLLM v1.106.6: OAuth forwarding, streaming, signed thinking blocks, trims on resumed sessions, compressed tool results, recall injection, prompt-cache reads after a trim. Wiring through `install-coding-agent --context-proxy` (settings.json `env`) is test-covered only.
38
+ 9. The `context-proxy` service is pinned to the dev build `ghcr.io/berriai/litellm:v1.109.0-dev.1`, the only LiteLLM release with PR #41522 (ChatGPT-subscription pass-through, `/backend-api/codex/{models,responses}`); v1.106.6 and v1.108.0-rc.1 lack it. Codex keeps its ChatGPT login through a custom `[model_providers.openmem]` (`requires_openai_auth = true`, `base_url = http://127.0.0.1:<port>/backend-api/codex`, the LiteLLM key in `http_headers`); `openai_base_url` alone cannot work, because the pass-through requires `x-litellm-api-key` beside the ChatGPT bearer and Codex 0.162.0 ignores header overrides on the built-in `openai` provider (`merge_configured_model_providers`, `codex-rs/model-provider-info/src/lib.rs`). Verified once live (2026-10-29): Codex 0.162.0 with ChatGPT login, a temp `CODEX_HOME` wired by `installContextProxy`, one `codex exec "reply with OK"` against a throwaway container built from compose.yaml. Codex answered `OK`; the proxy logged `GET /backend-api/codex/models` and `POST /backend-api/codex/responses` (200); the hook stored the turn in `sessions/<codex session id>.db` (`prompt_cache_key` is the session id) and recorded the reported 13,876 prompt tokens. Trims, tool-result compression and recall were not exercised live (one short turn); they ran in the dev image against a fake upstream (`proxy/tests/image/run.py`). Remote compaction is off for a custom provider (`ProviderCapabilities`, `codex-rs/model-provider/src/capabilities.rs`), so Codex compacts locally. Wiring through `install-coding-agent` is test-covered only.
39
+ 10. Whether Cursor CLI accepts a custom model base URL is unverified.
40
+ 11. The installer sets `provider.anthropic.options.baseURL` and `headers`; whether OpenCode applies `headers` to its built-in Anthropic provider is unverified. Chat Completions and Responses trimming is unit-tested only.
41
+ 12. Tested with a fake `rtk` that records its arguments; flags taken from rtk's README and source. No real rtk binary was run.
42
+ 13. Tracked upstream in [rtk-ai/rtk#3463](https://github.com/rtk-ai/rtk/issues/3463).
43
+ 14. MCP connection checks recorded in `REVAMP.md` (Claude Code, OpenCode; Cursor listed nine tools) ran against the earlier nine-tool list. The current 18 tools add the page, status, initiative and `smart_compact_*` tools, which were checked through the facade only, not listed or called inside any agent.
44
+ 15. Checked once live with OpenCode 2.2.1 (`@opencode/cli-linux-x64`, run from a temp directory with temp `HOME`/XDG dirs and `opencode run --standalone`) against a loopback fake OpenAI-compatible model and a fake Hindsight API. Requests reached the fake model with the memory system part, the trimmed messages, the pointer plus recall plus ingest note, and the byte-identical sticky prefix on later turns. A sandbox helper plugin triggered compaction through `ctx.session.compact`; OpenCode stored the plugin's summary as a completed compaction and made no summary model call. Hindsight was a fake server: recall content, retention and the ingest note never touched a real Hindsight. Not checked against a real model provider either. `scripts/tests/test_opencode2_plugin.mjs` and `test_context_trim.mjs` cover the same paths with a fake `ctx`.
45
+ 16. OpenCode 2.2.1 loaded the location's plugins after `opencode run` had created the session, so no `session.created` event arrived. The plugin registers on the first `prompt` or `context` hook call instead.
46
+ 17. Retention runs from the `experimental.idle` session hook (typed in `@opencode/plugin` 2.2.1; not in the server docs), with `session.execution.succeeded`, `session.status` idle and `session.idle` events as fallbacks. OpenCode 2.2.1 published neither `session.status` nor `session.idle` to the plugin.
47
+ 18. Typed `/smart-compact` through `opencode run` arrived as prompt text, and the next request was trimmed. The plugin also registers a `smart-compact` command through `ctx.command.transform`; that path is test-covered only.
48
+ 19. OpenCode 2 is never pointed at the context proxy; the plugin trims in its `context` hook ([context proxy](context-proxy.md)). The trim was checked live (footnote 15); tool-result compression is test-covered only, including byte parity with the proxy's `compress_text`.
49
+ 20. The installer runs `opencode --version` (major 2 → `"plugins"` directory entry, anything else → `"plugin"` file entry), removes the other shape and skips proxy wiring for OpenCode 2. Tested with a fake `opencode` on `PATH`. The installer itself was not run against a real OpenCode 2 install; the live check configured the plugin directory by hand.
50
+ 21. `openmem` mode removes the upstream Hindsight hooks, OpenCode plugin entry, `hindsight` MCP server (only when it runs the upstream `dist/mcp-server.js`) and `hindsight-coding-agent` skill. Locations come from reading `@vectorize-io/hindsight-coding-agents` 0.8.3 `dist/installer.js`; tested against seeded files, not a live upstream install.
51
+ 22. At 2c1a245 neither OpenCode plugin emitted a startup banner; banners are being added on this branch and are not yet verified live. For OpenCode 2, per-prompt recall through the prompt hook reached the model live (footnote 15).
52
+
53
+ Copilot and Pi are not in OpenMem's agent registry. rtk supports both; Pi can point at the context proxy only if it accepts a custom Anthropic base URL (unverified).
54
+
55
+ ## Memory providers
56
+
57
+ | Capability | Hindsight | mem0 | Cognee |
58
+ | --- | --- | --- | --- |
59
+ | `memory_recall` / `memory_search` | ✅ | 🧪 | 🧪 |
60
+ | `memory_add` | 🧪 | 🧪 | 🧪 |
61
+ | `memory_reflect` | ✅ native `/reflect` | 🧪 search + optional LiteLLM synthesis | 🧪 search + optional LiteLLM synthesis |
62
+ | `memory_consolidate` | 🧪 | ❌ no-op | 🧪 cognify |
63
+ | `memory_pages_list` / `search` / `read` | ✅ | ❌ `supported: false` | ❌ `supported: false` |
64
+ | `memory_capture_initiative` | 🧪 | ❌ `supported: false` | ❌ `supported: false` |
65
+ | `memory_status` (ingest drained, per-operation) | ✅ | 🧪 always ready (synchronous ingest) | ❌ `supported: false` |
66
+ | `smart_compact_search` / `smart_compact_get` | 🧪 local files, provider-independent | 🧪 | 🧪 |
67
+ | Proxy recall injection after a trim | ✅ | ❌ | ❌ |
68
+ | `memory_export` / `memory_import` (PMM) | 🧪 | 🧪 | 🧪 |
69
+
70
+ "✅" for Hindsight means the call succeeded against the live server on this machine (28 banks, 41,701 facts); `memory_recall` and `memory_reflect` evidence is from `REVAMP.md`, the page and status tools from this branch. mem0 and Cognee rows are covered by facade tests with stubbed HTTP.
71
+
72
+ ## Hindsight model backends (wizard step 3)
73
+
74
+ | Backend | Status |
75
+ | --- | --- |
76
+ | Ollama in Compose (profile `ollama`) | ✅ retain, reflect and consolidate answered through LiteLLM v1.106.6 |
77
+ | Ollama on the host | 🧪 |
78
+ | lemond on the host | 🧪 |
79
+ | Custom OpenAI-compatible URL | 🧪 |
80
+ | Claude subscription via Meridian | 🧪 stub server only; see [Meridian guide](meridian-litellm.md) |