@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,222 @@
1
+ # Provider wizard hooks (sub-wizards)
2
+
3
+ The meta wizard (`./setup`, `./pm`) owns cross-provider steps. Each **provider plugin** ships a
4
+ **`providers/<id>/wizard.mjs`** module, the same relationship as asdf/mise plugins: the core tool
5
+ runs the plugin's hooks; it does not reimplement Node, Rust, mem0, or a model router.
6
+
7
+ The meta wizard knows nothing about any one provider. `wizard/lib/run-wizard.mjs`,
8
+ `wizard/lib/ports.mjs` and `wizard/lib/validate-setup.mjs` contain no provider names (a test greps
9
+ for this). A provider that exports no hook for a phase gets a clean no-op for that phase: there is
10
+ no default provider and no fallback implementation.
11
+
12
+ ## Hook API version
13
+
14
+ `helpers.apiVersion` is `2`. It is bumped when a helper is removed or changes meaning; adding a
15
+ helper does not bump it. Version 1 (the `chooseBackend` helper and `fallback:` argument) is gone.
16
+ The v1 phase names still work unchanged.
17
+
18
+ ## Package root vs stack root
19
+
20
+ | Field | Env | Meaning | Used for |
21
+ | --- | --- | --- | --- |
22
+ | `ctx.repoRoot` | `PM_STACK_ROOT` | Mutable stack root | compose project dir (`cwd` of every `docker compose` call), `.env`, `compose.override.yaml`, `.build-hash`, generated files |
23
+ | `ctx.packageRoot` | `PM_PACKAGE_ROOT` (default: `repoRoot`) | Read-only code root | `providers/` manifests and hook modules, `scripts/setup.mjs`, `scripts/gen-masks.mjs` |
24
+
25
+ For a git checkout they are the same directory. For an installed package the integrator passes the
26
+ stack root as `repoRoot` (`runWizard(stackRoot, argv)`) and the package directory through
27
+ `PM_PACKAGE_ROOT`. `runWizard` exports `PM_PACKAGE_ROOT` so child code sees it.
28
+ `PM_PROVIDERS_DIR` overrides the providers directory entirely (tests use it for fake providers).
29
+ Provider code must write only under `ctx.repoRoot` and read bundled files only under
30
+ `ctx.packageRoot`.
31
+
32
+ ## Execution order
33
+
34
+ ```
35
+ meta.preflight
36
+ meta.provider pick memory provider (Clack / TOML / --yes)
37
+ provider.init quiet: seed ctx defaults (also runs before preflight)
38
+ provider.resolvePorts host ports (also after the provider is chosen)
39
+ provider.afterProvider
40
+ provider.configureModelRouting models, keys, logins
41
+ meta.wizardConf written unless the provider already saved it
42
+ meta.setupEnv indexer state dir, then provider.setupEnv or scripts/setup.mjs
43
+ meta.index index.yml
44
+ meta.notebooklm optional profile
45
+ provider.beforeStack compose fragments, migrations
46
+ meta.stack build, up, health, provider.afterStackHealthy, then smoke
47
+ meta.codingAgent generic npx plugin, then provider.setupCodingAgent
48
+ meta.validate generic checks, then provider.extendValidation
49
+ meta.syncConfig config.toml (provider.configToml sections)
50
+ meta.summary provider.summary
51
+ ```
52
+
53
+ **Stack-only actions** (`./setup --up`, `./pm up`) skip the configure phases:
54
+
55
+ ```
56
+ meta.preflight -> meta.provider -> hydrate -> provider.resolvePorts -> provider.beforeStack
57
+ -> meta.stack -> meta.validate -> meta.summary
58
+ ```
59
+
60
+ **Down** runs `meta.preflight -> meta.stackDown -> meta.summary`. There are no down hooks yet.
61
+
62
+ ## Hook module contract
63
+
64
+ Path: `providers/<id>/wizard.mjs` (ESM), found through the manifest:
65
+
66
+ ```json
67
+ "wizardHooks": { "module": "wizard.mjs" }
68
+ ```
69
+
70
+ The path must stay inside the provider directory. Every export is an optional
71
+ `async function(ctx, helpers)`; implement only what you need. Hooks marked announced print
72
+ `provider <id>: <phase>` when they run; quiet hooks return a value to the meta wizard.
73
+
74
+ | Export | Kind | Return | When it runs |
75
+ | --- | --- | --- | --- |
76
+ | `init` | quiet | ignored | Seed provider defaults on `ctx` before anything reads them |
77
+ | `hydrate` | quiet | ignored | Restore provider state from the saved `wizard.conf` |
78
+ | `afterProvider` | announced | ignored | Right after the provider is selected |
79
+ | `configureModelRouting` | announced | ignored | Model backend, API keys, logins. Honor `ctx.skipBackendStep` (Clack already asked) |
80
+ | `resolvePorts` | announced | ignored | Choose free host ports (`helpers.choosePort`, `helpers.resolveHostPort`) |
81
+ | `stackEnv` | quiet | `{ description?, env? }` | What the generic `scripts/setup.mjs` run should print and receive |
82
+ | `setupEnv` | announced | ignored | Replace the generic secrets/env step; call `helpers.runStackSetup` to still run `scripts/setup.mjs` |
83
+ | `beforeStack` | announced | ignored | After env and index, before `docker compose up` |
84
+ | `apiBase` | quiet | string | HTTP base URL when it is not `http://127.0.0.1:<compose.hostPortEnv>` |
85
+ | `smoke` | announced | ignored | Replace the manifest HTTP smoke test |
86
+ | `afterStackHealthy` | announced | ignored | After health, before smoke (e.g. pull compose Ollama models) |
87
+ | `setupCodingAgent` | announced | ignored | After the generic coding-agent plugin step |
88
+ | `extendValidation` | announced | ignored | Push to `ctx.validationErrors` / `ctx.validationChecks`; runs after the generic checks |
89
+ | `configToml` | quiet | `{ stack?, memory?, <table>: {...} }` | Sections for `config.toml`: `stack` merges into `[stack]`, `memory` sub-tables (for example `memory.mem0`) merge into `[memory]` and `provider` there is always set by the wizard, every other key is a table |
90
+ | `summary` | quiet | `{ running?, configFiles?, notes?, logServices? }` | Lines for the closing summary |
91
+ | `clackSetup` | none | `{ env }` | Called by the Clack front end as `(ctxStub, ui, helpers)` |
92
+ | `prepareStackEnv` | script | `{ entries, drop, report }` | Called by `scripts/setup.mjs`; `.env` always gets `HOST_UID`/`HOST_GID` |
93
+ | `migrateEnv` | script | n/a | `scripts/setup.mjs --migrate-env` |
94
+ | `setupNotices` | script | `string[]` | Lines `scripts/setup.mjs` prints at the end |
95
+
96
+ `prepareStackEnv`, `migrateEnv` and `setupNotices` receive `{ repo, home, env }` (`repo` is the
97
+ stack root) and run in a separate Node process, so they may not use `helpers`.
98
+
99
+ Unrecognised exports are ignored. Providers must not import `wizard/lib/run-wizard.mjs`; it
100
+ imports them. Everything the meta wizard owns reaches a hook through `helpers`.
101
+
102
+ ## Helpers
103
+
104
+ `createHelpers()` in `wizard/lib/provider-wizard/helpers.mjs` returns a frozen object. Functions
105
+ that take `ctx` honor `--dry-run` (they print instead of acting).
106
+
107
+ | Helper | Purpose |
108
+ | --- | --- |
109
+ | `apiVersion` | `2` |
110
+ | `step`, `info`, `ok`, `warn`, `die` | Logging; `die` exits 1 |
111
+ | `problem(ctx, msg)` | `die`, or `warn` in a dry run |
112
+ | `ask`, `confirm` | Prompts (answers come from `ctx.yes` and `PM_*` env when non-interactive) |
113
+ | `act(ctx, desc, cmd, args, {env, cwd})`, `actWithEnv` | Run a command, printed only in a dry run |
114
+ | `commandExists(name)` | PATH lookup |
115
+ | `envValue(file, key)`, `expandHome`, `ensureConfigDir(ctx)` | Paths and wizard.conf reads |
116
+ | `curlGet`, `curlJson`, `curlRequest` | HTTP via curl |
117
+ | `portFree`, `choosePort(ctx, label, port, {envVars})`, `resolveHostPort(ctx, label)` | Ports; `resolveHostPort` reads the manifest `compose.hostPortEnv` and `defaultHostPort` |
118
+ | `composeArgs(ctx, ...rest)` | `docker compose` argv: project, optional `-f` files, optional `--profile` |
119
+ | `saveWizardConf(ctx, extra, {pmSections})` | Write `wizard.conf` (and `config.toml` sections); no-op in a dry run. Always includes `MEMORY_PROVIDER` |
120
+ | `runStackSetup(ctx, opts)` | Run `<packageRoot>/scripts/setup.mjs` against the stack root |
121
+ | `apiBase(ctx)` | The provider's resolved HTTP base URL |
122
+
123
+ ## Manifest fields the meta wizard reads
124
+
125
+ ```json
126
+ "compose": {
127
+ "profile": "mem0",
128
+ "files": ["compose.mem0.yaml"],
129
+ "hostPortEnv": "MEM0_PORT",
130
+ "defaultHostPort": 8000,
131
+ "healthService": "mem0",
132
+ "logServices": ["mem0"]
133
+ },
134
+ "wizard": { "recallHint": "check the server ({compose} logs mem0)" }
135
+ ```
136
+
137
+ - `compose.profile` adds `--profile <name>`; `compose.files` adds `-f` flags after `compose.yaml`
138
+ and after `compose.override.yaml` when that exists. Both apply to every compose call: `up`,
139
+ `down`, `build`, `ps`, and the indexer run. Files must be inside the stack root (no absolute
140
+ paths, no `..`). With neither field the command text is exactly what it was before.
141
+ - `compose.services` is documentation only: `up` is scoped by the profile, not by service list.
142
+ - The API base URL comes from `compose.hostPortEnv` and `defaultHostPort`, or from an `apiBase`
143
+ hook. `ctx.apiUrl` (`--api-url`) wins over both.
144
+ - `wizard.recallHint` is the error hint when the smoke recall fails. `{compose}` expands to the
145
+ full compose command prefix and `{project}` to the project name. Without it the generic
146
+ message uses `compose.logServices` or `compose.healthService`.
147
+ - A provider with no model backend sets none of `MEMORY_BACKEND`, `MEMORY_MODEL`, ...; generic
148
+ validation does not require them.
149
+
150
+ ## Delegated commands (asdf-style)
151
+
152
+ A manifest may declare commands the provider owns outright:
153
+
154
+ ```json
155
+ "wizardHooks": {
156
+ "module": "wizard.mjs",
157
+ "delegates": {
158
+ "mem0-login": { "description": "Run mem0 CLI login", "run": ["mem0", "login"] }
159
+ }
160
+ }
161
+ ```
162
+
163
+ `./pm mem0-login` runs `run` with inherited stdio when that provider is active. Prefer delegates
164
+ over reimplementing provider CLIs in Node.
165
+
166
+ ## Hindsight
167
+
168
+ Everything about LiteLLM routes, lemond, Ollama, custom OpenAI-compatible backends and the Clack
169
+ model prompts lives in `providers/hindsight/`:
170
+
171
+ | File | Role |
172
+ | --- | --- |
173
+ | `wizard.mjs` | Thin hook exports; re-exports `prepareStackEnv`, `migrateEnv`, `setupNotices` |
174
+ | `lib/state.mjs` | `ensureState`, backend defaults, `wizard.conf` reads |
175
+ | `lib/model-backend.mjs` | Backend choice (lemond / ollama / custom), reflect model, model pulls |
176
+ | `lib/litellm-routes.mjs` | Write the LiteLLM route file and `hindsight.env`; saves `wizard.conf` |
177
+ | `lib/probe.mjs` | Probe lemond/ollama endpoints and list models |
178
+ | `lib/config.mjs` | `defaultsFromConfig`, `applyConfigEnv`, `configToml` (`[stack]` ports, `[model]`) |
179
+ | `lib/ports.mjs` | `resolvePorts` for the API and control-plane ports |
180
+ | `lib/env-setup.mjs` | `stackEnv`, `setupEnv` (secrets, LiteLLM env) |
181
+ | `lib/stack-env.mjs` | `prepareStackEnv`, `migrateEnv`, `setupNotices` for `scripts/setup.mjs` |
182
+ | `lib/validate.mjs` | Hindsight validation (model backend, route file, ports) |
183
+ | `lib/summary.mjs` | Closing summary lines |
184
+ | `lib/coding-agent.mjs` | seed/materialize `~/.hindsight/coding-agent.json` (real file) and opt-in paths check |
185
+ | `lib/clack.mjs` | `clackSetup`: backend and model prompts for the Clack front end |
186
+
187
+ Its `wizard.conf` keeps `MEMORY_PROVIDER`, `MEMORY_BACKEND`, `MEMORY_MODEL`, `MEMORY_API_BASE` and
188
+ `MEMORY_REFLECT_MODEL`. The manifest sets `compose.profile: "hindsight"`, so a
189
+ non-Hindsight provider never starts its services.
190
+
191
+ `configureModelRouting` takes `ctx.skipBackendStep` (`WIZARD_SKIP_BACKEND_STEP=1`) to skip the
192
+ prompts when Clack has already collected the answers.
193
+
194
+ ## Loader
195
+
196
+ `wizard/lib/provider-wizard/run-steps.mjs`:
197
+
198
+ - `loadProviderWizard(manifest)`: import `providers/<id>/wizard.mjs`, cached per file; `{}` when absent
199
+ - `callProviderHook(ctx, phase, helpers)`: returns `{ ran, value }`; announces the announced phases
200
+ - `runProviderPhase(ctx, phase, helpers)`: the same, returning whether the hook ran
201
+ - `runDelegatedCommand`, `listDelegateCommands`: manifest `delegates`
202
+
203
+ ## Tests
204
+
205
+ - `scripts/tests/test_provider_wizard_hooks.mjs`: helpers `apiVersion`, frozen helpers, hook loader,
206
+ stubbed-helpers tests of the Hindsight `configureModelRouting` (`--yes`, `skipBackendStep`, the
207
+ three backends), static checks (no provider imports `run-wizard.mjs`; no provider names in the
208
+ meta files)
209
+ - `scripts/tests/test_provider_manifests.mjs`: manifest schema incl. `compose.profile`/`files`
210
+ - `scripts/tests/test_wizard.sh`: dry-run and real-run scenarios with a docker stub, including a
211
+ provider with no hooks, a provider with every v2 hook (fixtures in
212
+ `scripts/tests/fixtures/providers/`, selected with `PM_PROVIDERS_DIR`), and a package-root /
213
+ stack-root split
214
+
215
+ ## Adding hooks (checklist)
216
+
217
+ 1. Add `wizardHooks.module` (and `compose.*`) to `manifest.json`
218
+ 2. Create `providers/<id>/wizard.mjs`; implement only the phases you need
219
+ 3. Keep provider state on `ctx` through `init`/`hydrate`; return `configToml`/`summary` data instead of writing in the meta files
220
+ 4. Add `delegates` only when a native CLI must run on the host
221
+ 5. Document native vs meta ownership in manifest `settings`
222
+ 6. Extend the tests and the [add-memory-provider](../.agents/skills/add-memory-provider/SKILL.md) skill
@@ -0,0 +1,107 @@
1
+ # Quickstart
2
+
3
+ Get from zero to a running stack in one wizard run. **Choose your memory provider** in the wizard (Hindsight by default; mem0 or Cognee if you prefer) — same CLI either way. Cloning the repo is optional; **`npx @bcmyguest/openmem`** is the usual path. For why OpenMem exists (interface layer, not a memory engine), see [Concepts](concepts.md).
4
+
5
+ ## Before you start
6
+
7
+ | Requirement | Why |
8
+ | --- | --- |
9
+ | Docker + Compose v2 | Runs the stack; your user must run `docker` without sudo |
10
+ | Node.js ≥ 24 | CLI, setup wizard, and the session context store (`node:sqlite` with FTS5) |
11
+ | LLM for Hindsight (default provider) | lemond, Ollama, OpenAI-compatible, or a Claude subscription through [Meridian](meridian-litellm.md) — wizard wires LiteLLM |
12
+ | git, curl | Wizard preflight |
13
+
14
+ Default stack is [Hindsight](hindsight.md). Other providers: wizard or `npx @bcmyguest/openmem providers` ([provider status](provider-status.md)).
15
+
16
+ ## 1. Run the wizard
17
+
18
+ **From npm (recommended):**
19
+
20
+ ```sh
21
+ npx @bcmyguest/openmem
22
+ ```
23
+
24
+ **From a git checkout** (repo directory is the stack root):
25
+
26
+ ```sh
27
+ git clone https://github.com/bcmyguest/openmem.git
28
+ cd openmem
29
+ npm install
30
+ npm run setup
31
+ ```
32
+
33
+ Run other commands from the checkout with `node cli/openmem.mjs <command>`.
34
+
35
+ The wizard asks for a memory provider, provider settings, what to index, then starts Docker and runs a smoke test.
36
+
37
+ Useful variants:
38
+
39
+ ```sh
40
+ npx @bcmyguest/openmem setup --dry-run # plan only, no writes
41
+ npx @bcmyguest/openmem configure --yes # defaults + start, no prompts
42
+ ```
43
+
44
+ Wizard dry-run (what first setup plans — no writes):
45
+
46
+ <p align="center">
47
+ <img src="https://bcmyguest.github.io/openmem/setup-demo.gif" alt="Terminal recording of the setup wizard dry run: preflight checks, memory provider, model backend, secrets, sources and stack steps, each planned write printed as a [dry-run] line" width="720" />
48
+ </p>
49
+
50
+ ## 2. Confirm it is up
51
+
52
+ ```sh
53
+ npx @bcmyguest/openmem doctor
54
+ curl -fsS http://127.0.0.1:8888/health # Hindsight default; see wizard output for other providers
55
+ ```
56
+
57
+ ## 3. Wire your coding agent (optional)
58
+
59
+ **Session memory** (after step 1 — MCP and hooks need the running stack): `npx @bcmyguest/openmem install-coding-agent --yes` — unified MCP **plus** session hooks for Claude Code, Codex, OpenCode, Cursor CLI (any active provider). On Hindsight, `--provider-plugin` uses the upstream Hindsight plugin hooks instead (one hook set at a time). Not the same as `install-mcp` alone.
60
+
61
+ **`install-mcp`** merges the **`openmem` unified MCP** (`memory_add`, `memory_search`, `memory_recall`, `memory_reflect`, `memory_consolidate`, `memory_forget` on whichever provider you picked) and, when NotebookLM sync is on, the **NotebookLM MCP**:
62
+
63
+ ```sh
64
+ npx @bcmyguest/openmem install-mcp --yes
65
+ npx @bcmyguest/openmem install-mcp --yes --notebooklm # force NotebookLM entry
66
+ ```
67
+
68
+ Session hooks use the in-repo shim by default (`[agents] integration = "openmem"`); `--provider-plugin` replaces them with the upstream Hindsight plugin and `--no-provider-plugin` switches back. Optional native mem0/Cognee MCP: `install-mcp --provider-only`. Full guide: [MCP setup](mcp-setup.md).
69
+
70
+ Restart Cursor Agent after MCP changes. Move memories between providers with [Portable memory (PMM)](memory-portability.md) — `switch` alone does not migrate data.
71
+
72
+ ## Day-2
73
+
74
+ ```sh
75
+ npx @bcmyguest/openmem up
76
+ npx @bcmyguest/openmem down
77
+ npx @bcmyguest/openmem switch mem0 --yes
78
+ npx @bcmyguest/openmem doctor
79
+ ```
80
+
81
+ | Command | Purpose |
82
+ | --- | --- |
83
+ | `up` / `down` | Start or stop the stack (down keeps data volumes) |
84
+ | `switch <id> --yes` | Change provider (no memory migration) |
85
+ | `doctor` | Validate config without the smoke test |
86
+ | `schedule install` | Refresh configured RSS/OpenAlex feeds hourly with the OS scheduler |
87
+
88
+ In a checkout, use `npx .` instead of `npx @bcmyguest/openmem`.
89
+
90
+ ## Where files live
91
+
92
+ | Install | Stack root (compose, `.env`) |
93
+ | --- | --- |
94
+ | `npx @bcmyguest/openmem` | `~/.local/share/personal-memory/stack` (override: `PM_STACK_ROOT`) |
95
+ | Git checkout | The clone directory |
96
+
97
+ Secrets and index config: `~/.config/hindsight/` (and optional `~/.config/personal-memory/config.toml`).
98
+
99
+ ## Next
100
+
101
+ - [MCP setup](mcp-setup.md) — unified `memory_*`, provider-native, NotebookLM
102
+ - [Portable memory (PMM)](memory-portability.md) — export/import
103
+ - [Architecture](architecture.md) — data flow, indexing, MCP by provider
104
+ - [Index sources](index-sources.md) — git, Obsidian, notes/papers/bookmarks, feed cache
105
+ - [Feed sync](sources-feeds.md) — configure RSS/OpenAlex and schedule refreshes
106
+ - [Install with npx](npx-install.md) — upgrades, troubleshooting
107
+ - [Configuration file](openmem-config.md) — declarative `config.toml`
@@ -0,0 +1,117 @@
1
+ # Setup wizard
2
+
3
+ The wizard is a Node program (`wizard/bin/setup.mjs`). It is exposed as:
4
+
5
+ | How you run it | When |
6
+ | --- | --- |
7
+ | `npx @bcmyguest/openmem` / `npx @bcmyguest/openmem setup` | Normal install ([Install with npx](npx-install.md)) |
8
+ | `npm run setup` / `./setup` | Git checkout (stack root stays in the repo); other commands: `node cli/openmem.mjs <command>` |
9
+
10
+ Interactive runs use [@clack/prompts](https://github.com/bombshell-dev/clack). `--yes` and `--dry-run` skip Clack.
11
+
12
+ ## Stack actions
13
+
14
+ Before provider questions, pick what the run should do (Clack or `PM_WIZARD_ACTION`):
15
+
16
+ | Action | Flag | Behavior |
17
+ | --- | --- | --- |
18
+ | Configure | default | Full wizard: provider, env, index sources, start stack, optional coding-agent step |
19
+ | Start | `--up` | Requires existing `~/.config/hindsight/wizard.conf`; starts stack and validates |
20
+ | Stop | `--down` | `docker compose down` for the project |
21
+
22
+ Non-interactive shortcuts:
23
+
24
+ ```sh
25
+ npx @bcmyguest/openmem configure --yes # setup --yes
26
+ npx @bcmyguest/openmem up # wizard --up (after first configure)
27
+ npx @bcmyguest/openmem down # wizard --down
28
+ ```
29
+
30
+ ## Wizard phases
31
+
32
+ Configure runs these steps in order (provider hooks replace or extend some steps):
33
+
34
+ | Step | Title | What happens |
35
+ | --- | --- | --- |
36
+ | 1 | Preflight | `git`, `curl`, `docker`, Compose v2; host UID/GID; API/control-plane ports |
37
+ | 2 | Memory provider | Hindsight, mem0, or Cognee ([Provider status](provider-status.md)) |
38
+ | 3 | Provider config | See table below |
39
+ | 4 | Secrets and env | Files under `~/.config/hindsight/` (mode 600); runs `scripts/setup.mjs` for stack `.env` and `compose.override.yaml` |
40
+ | 5 | Sources to index | Writes `~/.config/hindsight/index.yml`; lists sources with a dry indexer run |
41
+ | 6 | NotebookLM sync | Opt-in; Google login when enabled |
42
+ | 7 | Start the stack | Build indexer image if inputs changed; health wait; smoke retain/recall (unless `--no-smoke`) |
43
+ | 8 | Context management (smart compaction) | Multi-select of the installed agents (Claude Code, OpenCode 1, OpenCode 2). Defaults: saved `[context_proxy.agents]` keys, else `[context_proxy] enabled`, else OpenCode 2 on and the proxy-routed agents off. Saves all four keys to `config.toml`. Claude Code or OpenCode 1 on: writes the proxy key file and store directories, then starts the `context-proxy` compose service. Neither on: stops a running `context-proxy` after step 9, unless an agent still points at it ([Context management](context-management.md)) |
44
+ | 9 | Coding agents (optional) | For detected CLIs (claude, codex, opencode, cursor-agent), offers `install-coding-agent --yes`: unified MCP, OpenMem skill, session hooks; honours `[agents] integration` (OpenMem hooks or the provider plugin) and `[context_proxy.agents]`. Default answer is no |
45
+ | 10 | Validate memory setup | Provider checks + shared validation |
46
+
47
+ The last line is `wizard: changed=N` (files and containers this run touched). An unchanged re-run prints `changed=0`.
48
+
49
+ ## Step 3 by provider
50
+
51
+ | Provider | Step 3 asks for |
52
+ | --- | --- |
53
+ | Hindsight | Model backend: lemond, Ollama (host or compose profile), custom OpenAI-compatible URL, or a Claude subscription through a running Meridian ([guide](meridian-litellm.md#with-the-wizard)); LiteLLM routes for `memory-retain`, `memory-reflect`, `memory-consolidate` |
54
+ | mem0 | Self-hosted REST base URL and API key file path |
55
+ | Cognee | Loopback port and `LLM_API_KEY` for graph build |
56
+
57
+ Details: [Model configuration](model-configuration.md) (Hindsight), `providers/mem0/OPERATOR.md`, `providers/cognee/OPERATOR.md`.
58
+
59
+ ## Where configuration lives
60
+
61
+ | Path | Written by | Purpose |
62
+ | --- | --- | --- |
63
+ | Stack root `.env`, `.build-hash`, `compose.override.yaml` | `scripts/setup.mjs` | Compose project; indexer UID; secret-path masks |
64
+ | `~/.config/hindsight/wizard.conf` | Wizard | Provider id, backend choice, ports |
65
+ | `~/.config/hindsight/hindsight.env`, `litellm.env` | Setup / Hindsight hooks | Hindsight + LiteLLM secrets |
66
+ | `~/.config/hindsight/index.yml` | Wizard step 5 | Index roots, repos, vaults; optional `notes` / `papers` / `bookmarks` / `feeds` ([index-sources.md](index-sources.md)) |
67
+ | `~/.config/hindsight/notebooklm.yml` | Wizard step 6 | NotebookLM sync toggles |
68
+ | `~/.config/personal-memory/config.toml` | Optional; synced on configure | Declarative overrides ([Configuration file](openmem-config.md)) |
69
+ | `~/.hindsight/coding-agent.json` | Wizard / install-mcp | **Real file on disk** — do not symlink to the repo template |
70
+
71
+ ### Stack root (npx installs)
72
+
73
+ When the CLI is not running from a git checkout, mutable compose files live under:
74
+
75
+ ```text
76
+ ${PM_STACK_ROOT:-${XDG_DATA_HOME:-~/.local/share}/personal-memory/stack}
77
+ ```
78
+
79
+ Wizard code and provider hooks still run from the npm package. See [Install with npx](npx-install.md#stack-root).
80
+
81
+ ## Wizard flags
82
+
83
+ | Flag | Effect |
84
+ | --- | --- |
85
+ | `--yes` / `-y` | Accept defaults; no prompts |
86
+ | `--dry-run` | Plan only; read-only checks; no writes or containers |
87
+ | `--no-smoke` | Skip retain/recall smoke test |
88
+ | `--rebuild` | Rebuild indexer image even if sources unchanged |
89
+ | `--up` / `--down` | Start or stop only (see stack actions) |
90
+
91
+ Environment (common):
92
+
93
+ | Variable | Meaning |
94
+ | --- | --- |
95
+ | `MEMORY_PROVIDER` | Default provider id |
96
+ | `PM_BACKEND` | Hindsight backend default (`lemond`, `ollama`, `custom`) |
97
+ | `PM_PROJECT` | Docker Compose project name |
98
+ | `PM_STACK_ROOT` / `PM_USE_CHECKOUT` | Stack root location |
99
+ | `HINDSIGHT_PORT`, `HINDSIGHT_CP_PORT` | Host API and control-plane ports |
100
+
101
+ Run `./setup --help` in a checkout for the full list.
102
+
103
+ ## Indexer image builds
104
+
105
+ The wizard rebuilds the indexer image only when its inputs change (Dockerfile, `compose.yaml`, copied sources). The hash is stored in `.build-hash` at the stack root. If nothing changed, it uses `up -d --no-build` so containers are not recreated unnecessarily.
106
+
107
+ ## Related docs
108
+
109
+ | Topic | Doc |
110
+ | --- | --- |
111
+ | npx, stack root, upgrades | [npx-install.md](npx-install.md) |
112
+ | `config.toml` and day-2 tasks | [openmem-config.md](openmem-config.md) |
113
+ | Manual compose without the wizard | [manual-stack-setup.md](manual-stack-setup.md) |
114
+ | LiteLLM routes and models | [model-configuration.md](model-configuration.md) |
115
+ | Index sources and `index.yml` | [indexing.md](indexing.md) |
116
+ | NotebookLM sync and MCP | [notebooklm.md](notebooklm.md) |
117
+ | Plugins and MCP install | [coding-agents.md](coding-agents.md) |
@@ -0,0 +1,39 @@
1
+ # RSS and OpenAlex feeds
2
+
3
+ Configure `feeds` in `index.yml`, run sync, then the indexer watches `feeds.out_dir` as kind **feed** (`feed::*` banks).
4
+
5
+ ```yaml
6
+ feeds:
7
+ out_dir: ~/.local/share/personal-memory/feeds
8
+ rss:
9
+ - url: https://rss.arxiv.org/rss/cs.AI
10
+ slug: arxiv-cs-ai
11
+ openalex_queries:
12
+ - url: https://api.openalex.org/works?search=machine%20learning&per_page=25
13
+ slug: openalex-ml
14
+ ```
15
+
16
+ ```sh
17
+ npx @bcmyguest/openmem feed-sync
18
+ # checkout: npm run feed-sync
19
+ ```
20
+
21
+ Then ensure the stack indexer is running. Each run writes markdown files under `out_dir`; the watcher indexes new/changed files.
22
+
23
+ Network use: feed-sync calls public RSS/OpenAlex URLs from the host (not from CI by default).
24
+
25
+ `feed-sync` needs Python 3 with PyYAML on the host. On Windows it uses `py -3`, then `python`; on macOS and Linux it uses `python3`, then `python`. Set `PYTHON` to choose a specific executable.
26
+
27
+ ## Schedule feed sync (optional)
28
+
29
+ Install an hourly job with the current user's native scheduler. The GitHub npx source works before the next npm release includes `schedule`:
30
+
31
+ ```sh
32
+ npx --yes github:bcmyguest/openmem schedule install --dry-run
33
+ npx --yes github:bcmyguest/openmem schedule install
34
+ npx --yes github:bcmyguest/openmem schedule remove
35
+ ```
36
+
37
+ After that release, `npx @bcmyguest/openmem schedule ...` runs the same command from npm.
38
+
39
+ OpenMem installs a systemd user timer on Linux, a launchd agent on macOS, or a Task Scheduler task on Windows. The job calls the published npm package through a stable runner in your user config directory. Installation records the Python interpreter with PyYAML, so the job does not depend on your interactive shell's PATH. It runs when your user scheduler is active; the Linux timer catches up after downtime. Re-run `schedule install` if you move or upgrade Node.js or Python.
@@ -0,0 +1,23 @@
1
+ # Readwise → indexer
2
+
3
+ Export highlights from [Readwise Reader](https://readwise.io/read) or the legacy export as **Markdown**.
4
+
5
+ 1. Export to a directory (Readwise → Export → Markdown).
6
+ 2. Add to `notes.paths` or `papers.paths` depending on how you split reading vs research:
7
+
8
+ ```yaml
9
+ notes:
10
+ paths:
11
+ - ~/Readwise/Full-Sync
12
+ ```
13
+
14
+ 3. Re-run indexing; chunks retain with bank `notes::full-sync` (slug from folder name).
15
+
16
+ Optional stable bank id:
17
+
18
+ ```yaml
19
+ banks:
20
+ ~/Readwise/Full-Sync: readwise::full-sync
21
+ ```
22
+
23
+ For automatic sync, use Readwise’s scheduled export + the same path (filesystem watcher picks up changes).
@@ -0,0 +1,22 @@
1
+ # Zotero → indexer
2
+
3
+ **Assumption:** use export-to-disk first; no Zotero API key in the stack yet.
4
+
5
+ 1. Install [Better BibTeX](https://retorque.re/zotero-better-bibtex/) (optional) for stable cite keys.
6
+ 2. Export markdown or JSON notes to a folder, e.g. `~/Zotero/export-md`.
7
+ 3. Point `papers.paths` at that folder in `~/.config/hindsight/index.yml`:
8
+
9
+ ```yaml
10
+ papers:
11
+ paths:
12
+ - ~/Zotero/export-md
13
+ ```
14
+
15
+ 4. Restart the indexer container or run `bin/hindsight-project-index --apply --papers ~/Zotero/export-md`.
16
+
17
+ Banks default to `papers::<folder-name>` unless overridden under `banks:`:
18
+
19
+ ```yaml
20
+ banks:
21
+ ~/Zotero/export-md: papers::zotero
22
+ ```
package/glama.json ADDED
@@ -0,0 +1,4 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "maintainers": ["bcmyguest"]
4
+ }
@@ -0,0 +1,38 @@
1
+ # Project indexer: one pass at startup, then re-index each source after it stops changing.
2
+ FROM python:3.12-slim
3
+
4
+ RUN apt-get update \
5
+ && apt-get install -y --no-install-recommends git ca-certificates \
6
+ && rm -rf /var/lib/apt/lists/*
7
+
8
+ # Tree-sitter grammars are prefetched here, so the runtime never downloads and can run with no network and a
9
+ # read-only $HOME. The directory is world-readable because the container runs as the host UID.
10
+ ENV TREE_SITTER_GRAMMAR_DIR=/opt/tree-sitter-grammars
11
+ RUN pip install --no-cache-dir watchfiles==1.3.0 pyyaml==6.0.3 tree-sitter-language-pack==1.22.1 \
12
+ && python3 -c "import os; from tree_sitter_language_pack import PackConfig, download, init; \
13
+ init(PackConfig(cache_dir=os.environ['TREE_SITTER_GRAMMAR_DIR'])); \
14
+ download(['python', 'javascript', 'typescript', 'tsx', 'go', 'rust', 'java', 'c', 'cpp', 'csharp', 'ruby', 'lua', 'bash', 'php'])" \
15
+ && chmod -R a+rX /opt/tree-sitter-grammars
16
+
17
+ # The compose user is the host's UID/GID, which may have no passwd entry here. Trust every repository owner, since
18
+ # the indexer only reads them and the owner is the host user.
19
+ RUN git config --system safe.directory '*'
20
+
21
+ COPY bin/hindsight-project-index /usr/local/bin/hindsight-project-index
22
+ COPY indexer/watch.py indexer/index_config.py indexer/code_outline.py indexer/feed_sync.py /opt/indexer/
23
+ # Memory sinks (one module per provider). A new indexer/sinks/<name>.py needs no Dockerfile edit.
24
+ COPY indexer/sinks/ /opt/indexer/sinks/
25
+ # Shipped default config. index_config.py finds it at ../config/index.yml relative to itself.
26
+ COPY config/index.yml /opt/config/index.yml
27
+ RUN chmod 0755 /usr/local/bin/hindsight-project-index /opt/indexer/watch.py \
28
+ && chmod -R a+rX /opt/indexer
29
+
30
+ # $HOME is bind-mounted, so ignore the host's ~/.local site-packages (they would shadow the pinned packages).
31
+ # PYTHONPATH makes index_config, code_outline and the sinks package importable from both the indexer script and
32
+ # watch.py.
33
+ ENV PYTHONUNBUFFERED=1 \
34
+ PYTHONNOUSERSITE=1 \
35
+ PYTHONPATH=/opt/indexer \
36
+ HINDSIGHT_URL=http://hindsight:8888
37
+
38
+ CMD ["python3", "/opt/indexer/watch.py"]