@wipcomputer/memory-crystal 0.7.10

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 (157) hide show
  1. package/.env.example +20 -0
  2. package/CHANGELOG.md +367 -0
  3. package/LICENSE +21 -0
  4. package/README-ENTERPRISE.md +226 -0
  5. package/README.md +127 -0
  6. package/RELAY.md +199 -0
  7. package/TECHNICAL.md +628 -0
  8. package/_trash/RELEASE-NOTES-v0-7-4.md +64 -0
  9. package/_trash/RELEASE-NOTES-v0-7-5.md +19 -0
  10. package/cloud/README.md +116 -0
  11. package/cloud/docs/gpt-system-instructions.md +69 -0
  12. package/cloud/migrations/0001_init.sql +52 -0
  13. package/dist/bridge.d.ts +7 -0
  14. package/dist/bridge.js +14 -0
  15. package/dist/bulk-copy.d.ts +17 -0
  16. package/dist/bulk-copy.js +90 -0
  17. package/dist/cc-hook.d.ts +8 -0
  18. package/dist/cc-hook.js +368 -0
  19. package/dist/cc-poller.d.ts +1 -0
  20. package/dist/cc-poller.js +550 -0
  21. package/dist/chunk-25LXQJ4Z.js +110 -0
  22. package/dist/chunk-2DRXIRQW.js +97 -0
  23. package/dist/chunk-2ZNH5F6E.js +1281 -0
  24. package/dist/chunk-3G3SFYYI.js +288 -0
  25. package/dist/chunk-3RG5ZIWI.js +10 -0
  26. package/dist/chunk-3S6TI23B.js +97 -0
  27. package/dist/chunk-3VFIJYS4.js +818 -0
  28. package/dist/chunk-52QE3YI3.js +1169 -0
  29. package/dist/chunk-57RP3DIN.js +1205 -0
  30. package/dist/chunk-5HSZ4W2P.js +62 -0
  31. package/dist/chunk-645IPXW3.js +290 -0
  32. package/dist/chunk-7A7ELD4C.js +1205 -0
  33. package/dist/chunk-7FYY4GZM.js +1205 -0
  34. package/dist/chunk-7IUE7ODU.js +254 -0
  35. package/dist/chunk-7RMLKZIS.js +108 -0
  36. package/dist/chunk-AA3OPP4Z.js +432 -0
  37. package/dist/chunk-ASSZDR6I.js +108 -0
  38. package/dist/chunk-AYRJVWUC.js +1205 -0
  39. package/dist/chunk-CCYI5O3D.js +148 -0
  40. package/dist/chunk-D3I3ZSE2.js +411 -0
  41. package/dist/chunk-DACSKLY6.js +219 -0
  42. package/dist/chunk-DW5B4BL7.js +108 -0
  43. package/dist/chunk-EKSACBTJ.js +1070 -0
  44. package/dist/chunk-EXEZZADG.js +248 -0
  45. package/dist/chunk-F3Y7EL7K.js +83 -0
  46. package/dist/chunk-FHRZNOMW.js +1205 -0
  47. package/dist/chunk-IM7N24MT.js +129 -0
  48. package/dist/chunk-IPNYIXFK.js +1178 -0
  49. package/dist/chunk-J7MRSZIO.js +167 -0
  50. package/dist/chunk-JITKI2OI.js +106 -0
  51. package/dist/chunk-JWZXYVET.js +1068 -0
  52. package/dist/chunk-KCQUXVYT.js +108 -0
  53. package/dist/chunk-KOQ43OX6.js +1281 -0
  54. package/dist/chunk-KYVWO6ZM.js +1069 -0
  55. package/dist/chunk-L3VHARQH.js +413 -0
  56. package/dist/chunk-LBWDS6BE.js +288 -0
  57. package/dist/chunk-LOVAHSQV.js +411 -0
  58. package/dist/chunk-LQOYCAGG.js +446 -0
  59. package/dist/chunk-LWAIPJ2W.js +146 -0
  60. package/dist/chunk-M5DHKW7M.js +127 -0
  61. package/dist/chunk-MBKCIJHM.js +1328 -0
  62. package/dist/chunk-MK42FMEG.js +147 -0
  63. package/dist/chunk-MOBMYHKL.js +1205 -0
  64. package/dist/chunk-MPLTNMRG.js +67 -0
  65. package/dist/chunk-NIJCVN3O.js +147 -0
  66. package/dist/chunk-NZCFSZQ7.js +1205 -0
  67. package/dist/chunk-O2UITJGH.js +465 -0
  68. package/dist/chunk-OCRA44AZ.js +108 -0
  69. package/dist/chunk-P3KJR66H.js +117 -0
  70. package/dist/chunk-PEK6JH65.js +432 -0
  71. package/dist/chunk-PJ6FFKEX.js +77 -0
  72. package/dist/chunk-PLUBBZYR.js +800 -0
  73. package/dist/chunk-PNKVD2UK.js +26 -0
  74. package/dist/chunk-PSQZURHO.js +229 -0
  75. package/dist/chunk-SGL6ISBJ.js +1061 -0
  76. package/dist/chunk-SJABZZT5.js +97 -0
  77. package/dist/chunk-TD3P3K32.js +1199 -0
  78. package/dist/chunk-TMDZJJKV.js +288 -0
  79. package/dist/chunk-UNHVZB5G.js +411 -0
  80. package/dist/chunk-VAFTWSTE.js +1061 -0
  81. package/dist/chunk-VNFXFQBB.js +217 -0
  82. package/dist/chunk-X3GVFKSJ.js +1205 -0
  83. package/dist/chunk-XZ3S56RQ.js +1061 -0
  84. package/dist/chunk-Y72C7F6O.js +148 -0
  85. package/dist/chunk-YLICP577.js +1205 -0
  86. package/dist/chunk-YX6AXLVK.js +159 -0
  87. package/dist/chunk-ZCQYHTNU.js +146 -0
  88. package/dist/cli.d.ts +1 -0
  89. package/dist/cli.js +1105 -0
  90. package/dist/cloud-crystal.js +6 -0
  91. package/dist/core.d.ts +232 -0
  92. package/dist/core.js +12 -0
  93. package/dist/crypto.d.ts +20 -0
  94. package/dist/crypto.js +27 -0
  95. package/dist/crystal-capture.sh +29 -0
  96. package/dist/crystal-serve.d.ts +4 -0
  97. package/dist/crystal-serve.js +252 -0
  98. package/dist/dev-update-SZ2Z4WCQ.js +6 -0
  99. package/dist/discover.d.ts +30 -0
  100. package/dist/discover.js +177 -0
  101. package/dist/doctor.d.ts +9 -0
  102. package/dist/doctor.js +334 -0
  103. package/dist/dream-weaver.d.ts +8 -0
  104. package/dist/dream-weaver.js +56 -0
  105. package/dist/file-sync.d.ts +48 -0
  106. package/dist/file-sync.js +18 -0
  107. package/dist/installer.d.ts +61 -0
  108. package/dist/installer.js +618 -0
  109. package/dist/ldm-backup.sh +116 -0
  110. package/dist/ldm.d.ts +50 -0
  111. package/dist/ldm.js +32 -0
  112. package/dist/mcp-server.d.ts +1 -0
  113. package/dist/mcp-server.js +265 -0
  114. package/dist/migrate.d.ts +1 -0
  115. package/dist/migrate.js +89 -0
  116. package/dist/mirror-sync.d.ts +1 -0
  117. package/dist/mirror-sync.js +159 -0
  118. package/dist/oc-backfill.d.ts +19 -0
  119. package/dist/oc-backfill.js +74 -0
  120. package/dist/openclaw.d.ts +5 -0
  121. package/dist/openclaw.js +423 -0
  122. package/dist/pair.d.ts +4 -0
  123. package/dist/pair.js +75 -0
  124. package/dist/poller.d.ts +1 -0
  125. package/dist/poller.js +634 -0
  126. package/dist/role.d.ts +24 -0
  127. package/dist/role.js +13 -0
  128. package/dist/search-pipeline-4K4OJSSS.js +255 -0
  129. package/dist/search-pipeline-4PRS6LI7.js +280 -0
  130. package/dist/search-pipeline-7UJMXPLO.js +280 -0
  131. package/dist/search-pipeline-DQTRLGBH.js +74 -0
  132. package/dist/search-pipeline-HNG37REH.js +282 -0
  133. package/dist/search-pipeline-IZFPLBUB.js +280 -0
  134. package/dist/search-pipeline-MID6F26Q.js +73 -0
  135. package/dist/search-pipeline-N52JZFNN.js +282 -0
  136. package/dist/search-pipeline-OPB2PRQQ.js +280 -0
  137. package/dist/search-pipeline-VXTE5HAD.js +262 -0
  138. package/dist/staging.d.ts +29 -0
  139. package/dist/staging.js +21 -0
  140. package/dist/summarize.d.ts +19 -0
  141. package/dist/summarize.js +10 -0
  142. package/dist/worker-demo.js +186 -0
  143. package/dist/worker-mcp.js +404 -0
  144. package/dist/worker.js +137 -0
  145. package/migrations/0001_init.sql +51 -0
  146. package/migrations/0002_cloud_storage.sql +49 -0
  147. package/openclaw.plugin.json +11 -0
  148. package/package.json +57 -0
  149. package/scripts/crystal-capture 2.sh +29 -0
  150. package/scripts/crystal-capture.sh +29 -0
  151. package/scripts/deploy-cloud 2.sh +153 -0
  152. package/scripts/deploy-cloud.sh +153 -0
  153. package/scripts/ldm-backup.sh +116 -0
  154. package/scripts/migrate-lance-to-sqlite.mjs +217 -0
  155. package/skills/memory/SKILL.md +427 -0
  156. package/wrangler-demo.toml +8 -0
  157. package/wrangler-mcp.toml +24 -0
package/.env.example ADDED
@@ -0,0 +1,20 @@
1
+ # Memory Crystal — Environment Config
2
+ # Copy to ~/.openclaw/memory-crystal/.env and fill in your keys.
3
+ # Or skip this and use 1Password (keys auto-resolve from "Agent Secrets" vault).
4
+
5
+ # Embedding provider: openai (default), ollama, or google
6
+ # CRYSTAL_EMBEDDING_PROVIDER=openai
7
+
8
+ # OpenAI (required if provider is openai)
9
+ OPENAI_API_KEY=sk-...
10
+
11
+ # Google (required if provider is google)
12
+ # GOOGLE_API_KEY=AIza...
13
+
14
+ # Ollama (only if provider is ollama — runs locally, no key needed)
15
+ # CRYSTAL_OLLAMA_HOST=http://localhost:11434
16
+ # CRYSTAL_OLLAMA_MODEL=nomic-embed-text
17
+
18
+ # Cloud mirror (Phase 2)
19
+ # CRYSTAL_REMOTE_URL=https://memory-crystal.your-worker.workers.dev
20
+ # CRYSTAL_REMOTE_TOKEN=your-token
package/CHANGELOG.md ADDED
@@ -0,0 +1,367 @@
1
+ # Changelog
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+ ## 0.7.10 (2026-03-13)
13
+
14
+ # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
15
+
16
+ **Date:** 2026-03-13
17
+ **Author:** CC-Mini
18
+ **Session:** memory-db-fix
19
+
20
+ ---
21
+
22
+ ## What Happened
23
+
24
+ Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
25
+
26
+ ### Issue 1: Doctor False Positive
27
+
28
+ `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
29
+
30
+ **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
31
+
32
+ ### Issue 2: Orphaned Vectors and FTS Entries
33
+
34
+ On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
35
+
36
+ The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
37
+
38
+ **Impact:**
39
+ - 141,651 orphaned vectors (~875 MB)
40
+ - 141,652 orphaned FTS entries
41
+ - ~7% of search queries hit phantom results (silently filtered out)
42
+ - Database: 1.96 GB (should have been ~1 GB)
43
+
44
+ **Fix (three parts):**
45
+
46
+ 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
47
+ ```sql
48
+ CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
49
+ BEGIN
50
+ DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
51
+ INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
52
+ END;
53
+ ```
54
+
55
+ 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
56
+
57
+ 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
58
+
59
+ **Cleanup results:**
60
+ - 141,651 orphaned vectors removed
61
+ - FTS rebuilt from 73,813 chunks in 5.7s
62
+ - Database: 1.96 GB -> 1.45 GB (525 MB saved)
63
+ - Verification: chunks = FTS entries = 73,813. Match: YES
64
+ - Zero orphans remaining
65
+
66
+ ### Side Discovery: Plaintext SA Token
67
+
68
+ During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
69
+
70
+ ### Product Rule Established
71
+
72
+ Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
73
+
74
+ ## Files Changed
75
+
76
+ | File | Change |
77
+ |------|--------|
78
+ | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
79
+ | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
80
+ | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
81
+ | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
82
+
83
+ ## Related (wip-secrets-ios-private)
84
+
85
+ | File | What |
86
+ |------|------|
87
+ | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
88
+ | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
89
+
90
+ ## Status
91
+
92
+ - Code deployed and running (cleanup already executed)
93
+ - Not yet committed / PR'd / released
94
+ - Needs: branch, commit, PR, merge, `wip-release patch`
95
+
96
+ ## 0.7.9 (2026-03-13)
97
+
98
+ # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
99
+
100
+ **Date:** 2026-03-13
101
+ **Author:** CC-Mini
102
+ **Session:** memory-db-fix
103
+
104
+ ---
105
+
106
+ ## What Happened
107
+
108
+ Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
109
+
110
+ ### Issue 1: Doctor False Positive
111
+
112
+ `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
113
+
114
+ **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
115
+
116
+ ### Issue 2: Orphaned Vectors and FTS Entries
117
+
118
+ On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
119
+
120
+ The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
121
+
122
+ **Impact:**
123
+ - 141,651 orphaned vectors (~875 MB)
124
+ - 141,652 orphaned FTS entries
125
+ - ~7% of search queries hit phantom results (silently filtered out)
126
+ - Database: 1.96 GB (should have been ~1 GB)
127
+
128
+ **Fix (three parts):**
129
+
130
+ 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
131
+ ```sql
132
+ CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
133
+ BEGIN
134
+ DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
135
+ INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
136
+ END;
137
+ ```
138
+
139
+ 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
140
+
141
+ 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
142
+
143
+ **Cleanup results:**
144
+ - 141,651 orphaned vectors removed
145
+ - FTS rebuilt from 73,813 chunks in 5.7s
146
+ - Database: 1.96 GB -> 1.45 GB (525 MB saved)
147
+ - Verification: chunks = FTS entries = 73,813. Match: YES
148
+ - Zero orphans remaining
149
+
150
+ ### Side Discovery: Plaintext SA Token
151
+
152
+ During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
153
+
154
+ ### Product Rule Established
155
+
156
+ Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
157
+
158
+ ## Files Changed
159
+
160
+ | File | Change |
161
+ |------|--------|
162
+ | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
163
+ | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
164
+ | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
165
+ | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
166
+
167
+ ## Related (wip-secrets-ios-private)
168
+
169
+ | File | What |
170
+ |------|------|
171
+ | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
172
+ | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
173
+
174
+ ## Status
175
+
176
+ - Code deployed and running (cleanup already executed)
177
+ - Not yet committed / PR'd / released
178
+ - Needs: branch, commit, PR, merge, `wip-release patch`
179
+
180
+ ## 0.7.8 (2026-03-13)
181
+
182
+ # Dev Update: Orphan Cleanup, DELETE Trigger, Doctor Fix
183
+
184
+ **Date:** 2026-03-13
185
+ **Author:** CC-Mini
186
+ **Session:** memory-db-fix
187
+
188
+ ---
189
+
190
+ ## What Happened
191
+
192
+ Parker ran the Memory Crystal install prompt and `crystal doctor` reported "Embeddings: FAILING ... no provider configured in env." Investigation revealed two separate issues:
193
+
194
+ ### Issue 1: Doctor False Positive
195
+
196
+ `checkEmbeddingProvider()` in `doctor.ts` only checked `process.env.OPENAI_API_KEY`. But the cron job and hooks resolve the key from 1Password via the SA token at `~/.openclaw/secrets/op-sa-token`. The doctor didn't know about this path.
197
+
198
+ **Fix:** Added `checkOpEmbeddings()` helper to `doctor.ts` that checks for the SA token file, then does a live `op read` to verify it works. Doctor now reports `ok: openai (via 1Password)` instead of `fail`.
199
+
200
+ ### Issue 2: Orphaned Vectors and FTS Entries
201
+
202
+ On 2026-03-11, 141,652 bulk file-scan chunks were correctly deleted from the `chunks` table. Parker said: "Why are we indexing documents?" These were raw file scans (Python venv packages, TypeScript source, vendor code) with no conversational context.
203
+
204
+ The deletion used raw SQL (`DELETE FROM chunks WHERE agent_id = 'system'`). But Memory Crystal had no DELETE trigger. The corresponding entries in `chunks_vec` (sqlite-vec) and `chunks_fts` (FTS5) were left orphaned.
205
+
206
+ **Impact:**
207
+ - 141,651 orphaned vectors (~875 MB)
208
+ - 141,652 orphaned FTS entries
209
+ - ~7% of search queries hit phantom results (silently filtered out)
210
+ - Database: 1.96 GB (should have been ~1 GB)
211
+
212
+ **Fix (three parts):**
213
+
214
+ 1. **DELETE trigger** added to `initChunksTables()` in `core.ts`:
215
+ ```sql
216
+ CREATE TRIGGER IF NOT EXISTS chunks_cleanup AFTER DELETE ON chunks
217
+ BEGIN
218
+ DELETE FROM chunks_vec WHERE chunk_id = OLD.id;
219
+ INSERT INTO chunks_fts(chunks_fts, rowid, text) VALUES('delete', OLD.id, OLD.text);
220
+ END;
221
+ ```
222
+
223
+ 2. **`cleanOrphans()` method** added to Crystal class in `core.ts`. Counts orphaned vec/FTS entries, deletes vec orphans in batches of 1000, rebuilds FTS5 from scratch.
224
+
225
+ 3. **`crystal cleanup` CLI command** added to `cli.ts`. Handles the full workflow: backup, pause cron, clean orphans, VACUUM, resume cron. Supports `--dry-run`.
226
+
227
+ **Cleanup results:**
228
+ - 141,651 orphaned vectors removed
229
+ - FTS rebuilt from 73,813 chunks in 5.7s
230
+ - Database: 1.96 GB -> 1.45 GB (525 MB saved)
231
+ - Verification: chunks = FTS entries = 73,813. Match: YES
232
+ - Zero orphans remaining
233
+
234
+ ### Side Discovery: Plaintext SA Token
235
+
236
+ During investigation, discovered that `~/.openclaw/secrets/op-sa-token` is a plaintext 1Password SA token readable by any process running as `lesa`. This is the bootstrap credential that unlocks all secrets. Bug report filed. Long-term fix: Lesa iOS app with remote biometrics (product doc written).
237
+
238
+ ### Product Rule Established
239
+
240
+ Memory Crystal indexes conversations only. File content that appears in conversation turns (agent reads a file, discusses it) is captured as part of the conversation. Raw directory scanning without conversational context is not what Memory Crystal is for.
241
+
242
+ ## Files Changed
243
+
244
+ | File | Change |
245
+ |------|--------|
246
+ | `src/core.ts` | Added `chunks_cleanup` DELETE trigger, `cleanOrphans()` method |
247
+ | `src/cli.ts` | Added `crystal cleanup` command, updated imports and USAGE |
248
+ | `src/doctor.ts` | Added `checkOpEmbeddings()` for 1Password detection |
249
+ | `ai/product/bugs/2026-03-13--orphaned-vectors-and-fts-after-bulk-delete.md` | Bug report |
250
+
251
+ ## Related (wip-secrets-ios-private)
252
+
253
+ | File | What |
254
+ |------|------|
255
+ | `ai/product/product-ideas/lesa-app-remote-biometrics.md` | Lesa app: remote biometrics for agent computers |
256
+ | `ai/product/bugs/2026-03-13--plaintext-sa-token-on-disk.md` | Plaintext SA token bug report |
257
+
258
+ ## Status
259
+
260
+ - Code deployed and running (cleanup already executed)
261
+ - Not yet committed / PR'd / released
262
+ - Needs: branch, commit, PR, merge, `wip-release patch`
263
+
264
+ ## 0.7.7 (2026-03-13)
265
+
266
+ Update install prompt to new standard format. Replaces old 3-question prompt with 4 explain questions, installed check, and dry-run before install.
267
+
268
+ ## 0.7.6 (2026-03-13)
269
+
270
+ Update LDM delegation tips
271
+
272
+ ## 0.7.5 (2026-03-13)
273
+
274
+ # Release Notes: Memory Crystal v0.7.5
275
+
276
+ ## LDM OS Integration
277
+
278
+ Memory Crystal now works with LDM OS when it's available.
279
+
280
+ ### crystal init delegates to ldm install
281
+
282
+ When the `ldm` CLI exists on PATH, `crystal init` delegates generic deployment to it. LDM OS handles the scaffold, interface detection, and extension deployment. Memory Crystal keeps its own setup: database backup, role configuration, pairing, cron jobs.
283
+
284
+ When `ldm` isn't available, `crystal init` works standalone like it always has. No new dependencies. No breaking changes.
285
+
286
+ ### LDM OS tip
287
+
288
+ After install completes, Memory Crystal prints a tip: "Run `ldm install` to see more skills you can add." Helps users discover the rest of the ecosystem.
289
+
290
+ ### Part of LDM OS
291
+
292
+ README now includes a "Part of LDM OS" section linking back to the LDM OS repo. Memory Crystal installs into LDM OS, the local runtime for AI agents.
293
+
294
+ ## 0.7.4 (2026-03-11)
295
+
296
+ MCP fix (OPENCLAW_HOME env var), AgentId reads from LDM config instead of hardcoding, MCP registrations moved to user-level, 33 stale branches renamed, QMD v1.1.6 analysis documented
297
+
298
+ ## 0.7.3 (2026-03-10)
299
+
300
+ Fix MCP registration to include OPENCLAW_HOME env var for memory-crystal MCP server
301
+
302
+ ## 0.7.2 (2026-03-05)
303
+
304
+ Fix MCP detection in doctor and installer to check project-level and user-scope registrations
305
+
306
+ ## 0.7.1 (2026-03-05)
307
+
308
+ Database backup, verification, and import in installer
309
+
310
+ ## 0.7.0 (2026-03-05)
311
+
312
+ Delta sync, file sync, intelligent install & update
313
+
314
+ ## 0.6.1 (2026-03-05)
315
+
316
+ Search quality: deep search with LLM query expansion + re-ranking, MCP sampling design, updated docs
317
+
318
+ ## 0.6.0 (2026-03-04)
319
+
320
+ Dream Weaver integration, Crystal Core gateway, staging pipeline, commands channel.
321
+
322
+ - Dream Weaver narrative consolidation via `crystal dream-weave` (imports engine from dream-weaver-protocol)
323
+ - Crystal Core gateway (`crystal serve`) on localhost:18790, OpenAI-compatible endpoint
324
+ - Staging pipeline for new agents from relay (auto-detect, stage, backfill, dream-weave)
325
+ - Commands channel on relay Worker (nodes send commands to Core, Core sends results back)
326
+ - OpenClaw raw data sync to LDM after every agent_end turn (sessions, workspace, daily logs)
327
+ - Relay command support in cc-hook.ts (`sendCommand()` export)
328
+ - Harness-aware init flow (OpenClaw vs Claude Code, Core vs Node)
329
+ - Poller now detects new agents and routes to staging before live ingest
330
+
331
+ ## 0.5.0 (2026-03-04)
332
+
333
+ Init discovery, bulk copy, OpenClaw parser, backfill, CE migration. Reorganize ai/ to ai/product/.
334
+
335
+ - `crystal init` discovers session files on the current machine (Claude Code + OpenClaw)
336
+ - `crystal backfill` embeds raw transcript files from LDM (Core: local embed, Node: relay to Core)
337
+ - `crystal migrate-embeddings` migrates context-embeddings.sqlite chunks into crystal.db ($0, copies embeddings directly)
338
+ - `src/discover.ts` auto-detects installed harnesses and session file locations
339
+ - `src/bulk-copy.ts` copies raw files to LDM transcripts (idempotent, skip if same size)
340
+ - `src/oc-backfill.ts` parses OpenClaw JSONL format into standard message format
341
+ - Workspace path added to LDM (`~/.ldm/agents/{id}/memory/workspace/`)
342
+
343
+
344
+
345
+ ## 0.4.1 (2026-03-03)
346
+
347
+ Crystal Core/Node architecture, crystal doctor, crystal backup, crystal bridge, SKILL.md onboarding rewrite
348
+
349
+ ## 0.3.3 (2026-03-02)
350
+
351
+ Fix bin entries: crystal and crystal-mcp commands were missing from v0.3.2 due to npm stripping ./ prefix paths
352
+
353
+ ## 0.3.2 (2026-03-02)
354
+
355
+ Rewrite SKILL.md as complete agent install guide. Add crystal-mcp binary for clean MCP config. CLI search output matches MCP server (freshness icons, numbered results). Agents can now auto-detect and install for Claude Code CLI, Claude Desktop, and OpenClaw.
356
+
357
+ ## 0.3.1 (2026-03-02)
358
+
359
+ Fix npm package: exclude ai/ folder from published tarball
360
+
361
+ ## 0.3.0 (2026-03-02)
362
+
363
+ Phase 1 continuous capture, Cloud MCP server, QR pairing, crystal init, docs overhaul
364
+
365
+ ## 0.2.0 (2026-02-28)
366
+
367
+ README overhaul, relay encryption, QR pairing spec, Grok/Lesa feedback, disable auto dev-updates
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Parker Todd Brooks
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,226 @@
1
+ ###### WIP Computer
2
+
3
+ # Memory Crystal for Enterprise
4
+
5
+ Agent memory infrastructure. Local-first. Encrypted. Inspectable. *In testing.*
6
+
7
+ ## The Problem
8
+
9
+ Your organization runs AI agents across teams, departments, and tools. Each agent starts every session with no memory. No continuity. No shared context. Conversations with one agent are invisible to every other.
10
+
11
+ Your agents can't remember what your people told them. Your people keep re-explaining themselves. Context is lost between sessions, between tools, between teams.
12
+
13
+ This is not a convenience problem. It's a reliability problem. An auditability problem. A cost problem.
14
+
15
+ ## What Memory Crystal Does
16
+
17
+ Memory Crystal is a persistent context layer for AI agents. One shared database. Hybrid search. On your machines. Under your control.
18
+
19
+ - **Local-first.** All data stays on-prem. Nothing leaves your network unless you configure it to.
20
+ - **Inspectable.** One SQLite file. Open it with any SQLite tool. Audit it. Query it. Back it up with `cp`.
21
+ - **Deterministic search.** Hybrid retrieval (BM25 keyword + vector similarity + Reciprocal Rank Fusion). Same query, same results. No black-box ranking.
22
+ - **Encrypted sync.** Multi-site deployments use AES-256-GCM encryption with HMAC-SHA256 signing. The relay sees encrypted noise. Keys never leave your machines.
23
+ - **Agent isolation.** Each agent gets its own ID, its own transcript archive, its own session summaries. Shared search across agents, isolated storage per agent.
24
+ - **Zero cloud dependency.** Runs fully offline with local embeddings (Ollama). No API keys required. No data exfiltration risk.
25
+
26
+ ## Five-Layer Memory Stack
27
+
28
+ Memory Crystal implements a full memory pipeline, not just search.
29
+
30
+ | Layer | What | How |
31
+ |-------|------|-----|
32
+ | L1: Raw Transcripts | Every conversation archived as JSONL | Automatic. cc-poller (cron), cc-hook (Stop), openclaw.ts (agent_end) |
33
+ | L2: Vector Index | Chunks embedded into crystal.db | Automatic. Hybrid search (BM25 + vector + RRF) |
34
+ | L3: Structured Memory | Facts, preferences, decisions | `crystal_remember` / `crystal_forget` |
35
+ | L4: Narrative Consolidation | Dream Weaver journals, identity, soul | `crystal dream-weave` (imports engine from Dream Weaver Protocol) |
36
+ | L5: Active Working Context | Boot sequence files, shared context | Agent reads on startup |
37
+
38
+ L1-L3 are fully automated. L4 runs on-demand or via Crystal Core gateway. L5 is consumed by the agent's boot sequence.
39
+
40
+ ## Architecture
41
+
42
+ ```
43
+ sqlite-vec (vectors) + FTS5 (BM25) + SQLite (metadata)
44
+ | | |
45
+ core.ts ... pure logic, zero framework deps
46
+ |-- cli.ts -> crystal search, dream-weave, backfill, serve
47
+ |-- mcp-server.ts -> MCP protocol (any compatible client)
48
+ |-- openclaw.ts -> OpenClaw plugin + raw data sync to LDM
49
+ |-- cc-poller.ts -> Continuous capture (cron, primary)
50
+ |-- cc-hook.ts -> Claude Code Stop hook (redundancy) + relay commands
51
+ |-- crystal-serve.ts -> Crystal Core gateway (localhost:18790)
52
+ |-- dream-weaver.ts -> Dream Weaver integration (narrative consolidation)
53
+ |-- staging.ts -> New agent staging pipeline
54
+ |-- llm.ts -> LLM provider cascade (MLX > Ollama > OpenAI > Anthropic)
55
+ |-- search-pipeline.ts -> Deep search (expand, search, RRF, rerank, blend)
56
+ +-- worker.ts -> Encrypted relay (multi-site sync, 3 channels)
57
+ ```
58
+
59
+ One core module. Multiple interfaces. Every interface calls the same search engine. No inconsistency between access paths.
60
+
61
+ ## Security Model
62
+
63
+ **Data at rest:** Single SQLite file. Standard filesystem permissions. Encrypt the volume if your compliance requires it.
64
+
65
+ **Data in transit:** AES-256-GCM authenticated encryption. HMAC-SHA256 integrity verification. Shared symmetric key generated on-prem, never transmitted to the relay. The relay is a dead drop with no decryption capability.
66
+
67
+ **Agent boundaries:** `CRYSTAL_AGENT_ID` isolates each agent's transcript archive, session summaries, and daily logs. Search spans all agents by default, or filters by agent ID.
68
+
69
+ **Private mode:** Memory capture can be paused per-agent. When off, nothing is recorded. Resumes from where it left off when re-enabled.
70
+
71
+ **No background processes that move data.** No telemetry. No analytics. No phone-home. The code is open source. Audit it.
72
+
73
+ ## Retrieval Quality
74
+
75
+ Hybrid search is not "we added vectors." It's a two-tier retrieval engine with LLM-powered deep search.
76
+
77
+ ### Fast Path (Hybrid Search)
78
+ - **FTS5 BM25** for exact keyword matches (Porter stemming)
79
+ - **sqlite-vec cosine similarity** for semantic matches
80
+ - **Reciprocal Rank Fusion** merges both result lists (k=60, tiered weights: BM25 2x, vector 1x)
81
+ - **Recency weighting** ensures fresh context wins decisively: exponential decay `max(0.3, exp(-age_days * 0.1))`
82
+ - **Content deduplication** via SHA-256 hash prevents duplicate embeddings
83
+ - **Time-filtered search** ... restrict results to last 24h, 7d, 30d, or any date range
84
+
85
+ ### Deep Search (LLM-Powered, default)
86
+ - **Query expansion** ... LLM generates 3 search variations (lexical, semantic, hypothetical document). Each runs through hybrid search. Results merged via RRF.
87
+ - **Strong signal detection** ... BM25 probe skips expansion when the answer is obvious (saves latency).
88
+ - **LLM re-ranking** ... top 40 candidates scored by LLM for relevance to the original query.
89
+ - **Position-aware blending** ... trusts RRF for top positions, lets the reranker fix ordering in the tail.
90
+
91
+ Deep search runs by default. Falls back to fast path silently if no LLM provider is available. For air-gapped environments, MLX (Apple Silicon) or Ollama provides free, fully local deep search with no API keys and no network.
92
+
93
+ A search for "deployment policy" finds conversations containing those exact words (BM25), conversations about "shipping code to production" (vector similarity), and conversations about "release workflow" that the LLM recognizes as relevant. All three matter. All three surface.
94
+
95
+ ## What Gets Stored
96
+
97
+ Every agent conversation produces three artifacts:
98
+
99
+ | Artifact | Format | Location |
100
+ |----------|--------|----------|
101
+ | Raw transcript | JSONL | `~/.ldm/agents/{id}/memory/transcripts/` |
102
+ | Session summary | Markdown | `~/.ldm/agents/{id}/memory/sessions/` |
103
+ | Embeddings | sqlite-vec | `~/.ldm/memory/crystal.db` |
104
+
105
+ Additionally:
106
+ - **Explicit memories** stored via `crystal_remember` (facts, preferences, decisions)
107
+ - **Source files** indexed as collections (code, documentation, internal knowledge bases)
108
+ - **Daily logs** appended per-agent for audit trails
109
+ - **Dream Weaver journals** generated by narrative consolidation (identity, soul, context, reference)
110
+ - **Workspace files** synced from agent workspace to LDM (OpenClaw .md files)
111
+
112
+ ## Embedding Providers
113
+
114
+ | Provider | Model | Dimensions | Network Required |
115
+ |----------|-------|-----------|-----------------|
116
+ | Ollama (recommended for enterprise) | nomic-embed-text | 768 | No. Fully local. |
117
+ | OpenAI | text-embedding-3-small | 1536 | Yes. API calls. |
118
+ | Google | text-embedding-004 | 768 | Yes. API calls. |
119
+
120
+ For air-gapped environments, Ollama is the only option. No data leaves the machine. No API keys. No external dependencies.
121
+
122
+ ## Multi-Site Sync
123
+
124
+ For organizations with multiple offices or remote teams.
125
+
126
+ **Architecture:** One Crystal Core (the primary embedder), many Crystal Nodes (capture and sync). Core is the only machine that writes embeddings. Nodes capture raw conversations and send them to Core. Core embeds, then pushes deltas back.
127
+
128
+ **What syncs:**
129
+ 1. **Delta chunks** ... only new embeddings since last sync (not the full database)
130
+ 2. **Full file tree** ... the entire `~/.ldm/` directory: workspace files, daily logs, journals, media, everything an embedding references
131
+ 3. **Commands** ... bidirectional remote operations (run Dream Weaver, trigger backfill, request status)
132
+
133
+ **How it works:**
134
+ 1. Each site runs Memory Crystal locally
135
+ 2. Core embeds all conversations into crystal.db (one source of truth for embeddings)
136
+ 3. New chunks + changed files are encrypted (AES-256-GCM) and signed (HMAC-SHA256)
137
+ 4. Encrypted deltas are dropped at a relay (hosted or self-hosted)
138
+ 5. Other sites poll, decrypt, and insert into their local crystal.db + file tree
139
+ 6. The relay deletes blobs after pickup
140
+
141
+ **No cloud search.** Every node has the full database and full file tree. All search is local. The relay is pure transport. Nothing is stored or searchable in the cloud.
142
+
143
+ **Self-hosted relay:** Deploy the Cloudflare Worker on your own Cloudflare account. Full control. No third-party data exposure.
144
+
145
+ **Hosted relay:** Use our infrastructure. Free during beta. Your data is encrypted before it reaches us. We cannot read it.
146
+
147
+ ## Compliance
148
+
149
+ - **Data residency:** All primary data is local. Relay blobs are encrypted and ephemeral.
150
+ - **Auditability:** SQLite is inspectable. Every chunk has a timestamp, source, and SHA-256 hash.
151
+ - **Right to delete:** `crystal forget <id>` deprecates specific memories. Database can be wiped entirely with standard file operations.
152
+ - **Access control:** Filesystem permissions on the SQLite file. No built-in user auth (it's a local tool, not a SaaS).
153
+ - **No vendor lock-in:** MIT licensed (local code). Standard SQLite format. Export with any SQLite tool.
154
+
155
+ ## Database
156
+
157
+ One file: `crystal.db`. Contains:
158
+
159
+ | Table | Purpose |
160
+ |-------|---------|
161
+ | `chunks` | Chunk text, metadata, SHA-256 hash, timestamps |
162
+ | `chunks_vec` | sqlite-vec virtual table (vector search) |
163
+ | `chunks_fts` | FTS5 virtual table (keyword search) |
164
+ | `memories` | Explicit facts and preferences |
165
+ | `capture_state` | Watermarks for incremental ingestion |
166
+ | `source_collections` | Indexed directory collections |
167
+ | `source_files` | File records with content hashes |
168
+
169
+ No migrations server. No schema versioning service. It's SQLite. `sqlite3 crystal.db ".schema"` shows you everything.
170
+
171
+ ## Integration
172
+
173
+ | Platform | Integration | Auto-Capture |
174
+ |----------|------------|-------------|
175
+ | Claude Code | Cron poller (`cc-poller.ts`, primary) + Stop hook (`cc-hook.ts`, redundancy) | Yes. Every minute via cron, plus flush on session end. |
176
+ | OpenClaw | Plugin (`openclaw.ts`) + `agent_end` hook + raw data sync | Yes. Every turn. Also syncs sessions, workspace, daily logs to LDM. |
177
+ | Claude Desktop | MCP server (`mcp-server.ts`) | Search only. Manual capture. |
178
+ | Any MCP client | MCP server | Search only. Manual capture. |
179
+ | Any shell-accessible tool | CLI (`crystal search`) | Manual. |
180
+ | Custom agents | Node.js module (`import from 'memory-crystal'`) | Programmable. |
181
+
182
+ ## Crystal Core Gateway
183
+
184
+ Crystal Core runs an HTTP gateway (`crystal serve`) on localhost:18790. OpenAI-compatible endpoint for agent-to-agent communication and automated processing.
185
+
186
+ - `POST /v1/chat/completions` ... invoke `claude -p` through the gateway
187
+ - `POST /process` ... trigger backfill, dream-weave, or staging processing
188
+ - `GET /status` ... health check and crystal stats
189
+
190
+ Localhost-only binding. Never exposed to the network. Optional bearer token auth.
191
+
192
+ ## New Agent Onboarding
193
+
194
+ When a new agent connects via relay, Crystal Core automatically:
195
+ 1. Detects the unknown agent ID
196
+ 2. Routes to staging (`~/.ldm/staging/{agent_id}/`)
197
+ 3. Runs backfill (embed all transcripts)
198
+ 4. Runs Dream Weaver full mode (generate identity, soul, context, journals)
199
+ 5. Moves to live capture
200
+
201
+ No manual intervention. The staging pipeline handles the cold-start problem.
202
+
203
+ ## Deployment
204
+
205
+ ```bash
206
+ npm install memory-crystal
207
+ crystal init --agent your-agent-id
208
+ crystal status
209
+ ```
210
+
211
+ For enterprise deployments across multiple machines, see [Relay: Memory Sync](https://github.com/wipcomputer/memory-crystal/blob/main/RELAY.md).
212
+
213
+ For full technical details, see [Technical Documentation](https://github.com/wipcomputer/memory-crystal/blob/main/TECHNICAL.md).
214
+
215
+ ---
216
+
217
+ ## License
218
+
219
+ ```
220
+ src/, skills/, cli.ts, mcp-server.ts MIT (use anywhere, no restrictions)
221
+ worker/ AGPL (relay server)
222
+ ```
223
+
224
+ AGPL for personal use is free.
225
+
226
+ Built by Parker Todd Brooks, Lēsa (OpenClaw, Claude Opus 4.6), Claude Code CLI (Claude Opus 4.6).