pi-obsidian-memory 0.0.1 → 0.1.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 (572) hide show
  1. package/README.md +173 -7
  2. package/package.json +41 -11
  3. package/skills/obsidian-memory/SKILL.md +101 -0
  4. package/src/domain/capture/constants.ts +5 -0
  5. package/src/domain/capture/index.ts +6 -0
  6. package/src/domain/capture/input-problems.ts +9 -0
  7. package/src/domain/capture/schemas.ts +92 -0
  8. package/src/domain/capture/tally.ts +26 -0
  9. package/src/domain/capture/types.ts +49 -0
  10. package/src/domain/capture/validate.ts +75 -0
  11. package/src/domain/command-flags/constants.ts +141 -0
  12. package/src/domain/command-flags/index.ts +1 -0
  13. package/src/domain/config/change.ts +105 -0
  14. package/src/domain/config/constants.ts +25 -0
  15. package/src/domain/config/diagnostics.ts +35 -0
  16. package/src/domain/config/disclosures.ts +8 -0
  17. package/src/domain/config/fields.ts +7 -0
  18. package/src/domain/config/index.ts +11 -0
  19. package/src/domain/config/inspection.ts +43 -0
  20. package/src/domain/config/invariants.ts +68 -0
  21. package/src/domain/config/legacy-capture.ts +17 -0
  22. package/src/domain/config/observations.ts +109 -0
  23. package/src/domain/config/parse.ts +25 -0
  24. package/src/domain/config/paths.ts +61 -0
  25. package/src/domain/config/registration.ts +34 -0
  26. package/src/domain/config/repair.ts +36 -0
  27. package/src/domain/config/resources.ts +65 -0
  28. package/src/domain/config/rules.ts +49 -0
  29. package/src/domain/config/schemas.ts +155 -0
  30. package/src/domain/config/settings.ts +23 -0
  31. package/src/domain/config/types.ts +239 -0
  32. package/src/domain/decision-model/constants.ts +7 -0
  33. package/src/domain/decision-model/cutoffs.ts +8 -0
  34. package/src/domain/decision-model/endpoint.ts +11 -0
  35. package/src/domain/decision-model/failure-detail.ts +8 -0
  36. package/src/domain/decision-model/index.ts +6 -0
  37. package/src/domain/decision-model/rank.ts +36 -0
  38. package/src/domain/decision-model/types.ts +77 -0
  39. package/src/domain/embeddings/constants.ts +55 -0
  40. package/src/domain/embeddings/identity.ts +30 -0
  41. package/src/domain/embeddings/index.ts +5 -0
  42. package/src/domain/embeddings/schemas.ts +25 -0
  43. package/src/domain/embeddings/types.ts +52 -0
  44. package/src/domain/embeddings/vectors.ts +53 -0
  45. package/src/domain/folder-index/constants.ts +9 -0
  46. package/src/domain/folder-index/display.ts +22 -0
  47. package/src/domain/folder-index/index.ts +5 -0
  48. package/src/domain/folder-index/listing.ts +58 -0
  49. package/src/domain/folder-index/render.ts +114 -0
  50. package/src/domain/folder-index/types.ts +41 -0
  51. package/src/domain/index.ts +22 -0
  52. package/src/domain/lifecycle/index.ts +2 -0
  53. package/src/domain/lifecycle/lifecycle.ts +39 -0
  54. package/src/domain/lifecycle/types.ts +17 -0
  55. package/src/domain/loaded-memory/budget.ts +14 -0
  56. package/src/domain/loaded-memory/constants.ts +9 -0
  57. package/src/domain/loaded-memory/index.ts +4 -0
  58. package/src/domain/loaded-memory/render.ts +30 -0
  59. package/src/domain/loaded-memory/types.ts +19 -0
  60. package/src/domain/memory/draft.ts +12 -0
  61. package/src/domain/memory/index.ts +4 -0
  62. package/src/domain/memory/schemas.ts +15 -0
  63. package/src/domain/memory/target.ts +27 -0
  64. package/src/domain/memory/types.ts +20 -0
  65. package/src/domain/memory-agent/index.ts +5 -0
  66. package/src/domain/memory-agent/input-problems.ts +9 -0
  67. package/src/domain/memory-agent/refusal.ts +6 -0
  68. package/src/domain/memory-agent/schemas.ts +112 -0
  69. package/src/domain/memory-agent/types.ts +25 -0
  70. package/src/domain/memory-agent/validate.ts +67 -0
  71. package/src/domain/names/constants.ts +32 -0
  72. package/src/domain/names/index.ts +2 -0
  73. package/src/domain/names/names.ts +83 -0
  74. package/src/domain/note/check.ts +68 -0
  75. package/src/domain/note/constants.ts +15 -0
  76. package/src/domain/note/frontmatter-fields.ts +175 -0
  77. package/src/domain/note/frontmatter.ts +138 -0
  78. package/src/domain/note/index.ts +9 -0
  79. package/src/domain/note/parse.ts +41 -0
  80. package/src/domain/note/render.ts +27 -0
  81. package/src/domain/note/schema-errors.ts +41 -0
  82. package/src/domain/note/schemas.ts +38 -0
  83. package/src/domain/note/types.ts +53 -0
  84. package/src/domain/note/validate.ts +19 -0
  85. package/src/domain/path-platform/index.ts +2 -0
  86. package/src/domain/path-platform/path-module.ts +11 -0
  87. package/src/domain/path-platform/types.ts +1 -0
  88. package/src/domain/search-catalog/constants.ts +1 -0
  89. package/src/domain/search-catalog/coverage.ts +35 -0
  90. package/src/domain/search-catalog/dont-forget.ts +10 -0
  91. package/src/domain/search-catalog/fingerprint.ts +9 -0
  92. package/src/domain/search-catalog/index.ts +10 -0
  93. package/src/domain/search-catalog/inspection.ts +47 -0
  94. package/src/domain/search-catalog/plan.ts +68 -0
  95. package/src/domain/search-catalog/ranking.ts +27 -0
  96. package/src/domain/search-catalog/schemas.ts +49 -0
  97. package/src/domain/search-catalog/types.ts +103 -0
  98. package/src/domain/search-catalog/vector-refresh.ts +22 -0
  99. package/src/domain/shell-edit/command-segments.ts +28 -0
  100. package/src/domain/shell-edit/command-words.ts +22 -0
  101. package/src/domain/shell-edit/constants.ts +125 -0
  102. package/src/domain/shell-edit/executed-files.ts +154 -0
  103. package/src/domain/shell-edit/index.ts +6 -0
  104. package/src/domain/shell-edit/powershell-files.ts +38 -0
  105. package/src/domain/shell-edit/rules.ts +19 -0
  106. package/src/domain/shell-edit/types.ts +75 -0
  107. package/src/domain/tool-flags/constants.ts +178 -0
  108. package/src/domain/tool-flags/index.ts +2 -0
  109. package/src/domain/tool-flags/types.ts +7 -0
  110. package/src/domain/validation/constants.ts +1 -0
  111. package/src/domain/validation/describe.ts +137 -0
  112. package/src/domain/validation/index.ts +3 -0
  113. package/src/domain/validation/types.ts +3 -0
  114. package/src/domain/vault-access/absolute-candidate.ts +81 -0
  115. package/src/domain/vault-access/argument-tokens.ts +22 -0
  116. package/src/domain/vault-access/command-mentions-vault.ts +115 -0
  117. package/src/domain/vault-access/constants.ts +54 -0
  118. package/src/domain/vault-access/index.ts +7 -0
  119. package/src/domain/vault-access/types.ts +18 -0
  120. package/src/domain/vault-access/vault-access-refusal.ts +36 -0
  121. package/src/domain/vault-access/vault-location.ts +22 -0
  122. package/src/domain/vault-assets/index.ts +2 -0
  123. package/src/domain/vault-assets/render.ts +51 -0
  124. package/src/domain/vault-assets/types.ts +36 -0
  125. package/src/domain/vault-catalog/analyze.ts +37 -0
  126. package/src/domain/vault-catalog/classify.ts +37 -0
  127. package/src/domain/vault-catalog/dont-forget.ts +6 -0
  128. package/src/domain/vault-catalog/export-entries.ts +10 -0
  129. package/src/domain/vault-catalog/index.ts +5 -0
  130. package/src/domain/vault-catalog/types.ts +114 -0
  131. package/src/domain/vault-diagnosis/diagnose.ts +79 -0
  132. package/src/domain/vault-diagnosis/index.ts +2 -0
  133. package/src/domain/vault-diagnosis/types.ts +31 -0
  134. package/src/domain/vault-path/constants.ts +13 -0
  135. package/src/domain/vault-path/index.ts +2 -0
  136. package/src/domain/vault-path/vault-path.ts +65 -0
  137. package/src/pi/capture/cadence.ts +49 -0
  138. package/src/pi/capture/completion.ts +26 -0
  139. package/src/pi/capture/constants.ts +5 -0
  140. package/src/pi/capture/handlers.ts +30 -0
  141. package/src/pi/capture/index.ts +8 -0
  142. package/src/pi/capture/runtime.ts +83 -0
  143. package/src/pi/capture/schemas.ts +8 -0
  144. package/src/pi/capture/tool-calls.ts +6 -0
  145. package/src/pi/capture/transcript.ts +55 -0
  146. package/src/pi/capture/types.ts +46 -0
  147. package/src/pi/change-report/constants.ts +15 -0
  148. package/src/pi/change-report/index.ts +3 -0
  149. package/src/pi/change-report/report.ts +54 -0
  150. package/src/pi/change-report/types.ts +8 -0
  151. package/src/pi/context/constants.ts +5 -0
  152. package/src/pi/context/index.ts +3 -0
  153. package/src/pi/context/status.ts +15 -0
  154. package/src/pi/context/types.ts +98 -0
  155. package/src/pi/extension.ts +100 -0
  156. package/src/pi/index.ts +26 -0
  157. package/src/pi/memory-add/constants.ts +13 -0
  158. package/src/pi/memory-add/index.ts +5 -0
  159. package/src/pi/memory-add/memory-add.ts +31 -0
  160. package/src/pi/memory-add/respond.ts +55 -0
  161. package/src/pi/memory-add/schemas.ts +29 -0
  162. package/src/pi/memory-add/types.ts +15 -0
  163. package/src/pi/memory-archive/constants.ts +8 -0
  164. package/src/pi/memory-archive/index.ts +4 -0
  165. package/src/pi/memory-archive/memory-archive.ts +29 -0
  166. package/src/pi/memory-archive/schemas.ts +15 -0
  167. package/src/pi/memory-archive/types.ts +8 -0
  168. package/src/pi/memory-block/block.ts +75 -0
  169. package/src/pi/memory-block/constants.ts +24 -0
  170. package/src/pi/memory-block/index.ts +4 -0
  171. package/src/pi/memory-block/render.ts +54 -0
  172. package/src/pi/memory-block/types.ts +24 -0
  173. package/src/pi/memory-doctor/constants.ts +43 -0
  174. package/src/pi/memory-doctor/index.ts +4 -0
  175. package/src/pi/memory-doctor/memory-doctor.ts +135 -0
  176. package/src/pi/memory-doctor/report.ts +101 -0
  177. package/src/pi/memory-doctor/types.ts +13 -0
  178. package/src/pi/memory-export/constants.ts +15 -0
  179. package/src/pi/memory-export/index.ts +4 -0
  180. package/src/pi/memory-export/memory-export.ts +57 -0
  181. package/src/pi/memory-export/name.ts +9 -0
  182. package/src/pi/memory-export/types.ts +4 -0
  183. package/src/pi/memory-get/constants.ts +12 -0
  184. package/src/pi/memory-get/index.ts +5 -0
  185. package/src/pi/memory-get/memory-get.ts +23 -0
  186. package/src/pi/memory-get/respond.ts +38 -0
  187. package/src/pi/memory-get/schemas.ts +13 -0
  188. package/src/pi/memory-get/types.ts +10 -0
  189. package/src/pi/memory-init/constants.ts +17 -0
  190. package/src/pi/memory-init/index.ts +2 -0
  191. package/src/pi/memory-init/memory-init.ts +63 -0
  192. package/src/pi/memory-search/constants.ts +16 -0
  193. package/src/pi/memory-search/index.ts +5 -0
  194. package/src/pi/memory-search/memory-search.ts +22 -0
  195. package/src/pi/memory-search/respond.ts +62 -0
  196. package/src/pi/memory-search/schemas.ts +11 -0
  197. package/src/pi/memory-search/types.ts +10 -0
  198. package/src/pi/memory-session/constants.ts +7 -0
  199. package/src/pi/memory-session/index.ts +4 -0
  200. package/src/pi/memory-session/keeper.ts +101 -0
  201. package/src/pi/memory-session/respond.ts +6 -0
  202. package/src/pi/memory-session/types.ts +23 -0
  203. package/src/pi/memory-settings/constants.ts +69 -0
  204. package/src/pi/memory-settings/edits.ts +46 -0
  205. package/src/pi/memory-settings/index.ts +9 -0
  206. package/src/pi/memory-settings/lines.ts +119 -0
  207. package/src/pi/memory-settings/models.ts +81 -0
  208. package/src/pi/memory-settings/projects.ts +46 -0
  209. package/src/pi/memory-settings/providers.ts +77 -0
  210. package/src/pi/memory-settings/save.ts +16 -0
  211. package/src/pi/memory-settings/screen.ts +27 -0
  212. package/src/pi/memory-settings/types.ts +87 -0
  213. package/src/pi/memory-setup/constants.ts +33 -0
  214. package/src/pi/memory-setup/disclosure.ts +22 -0
  215. package/src/pi/memory-setup/index.ts +4 -0
  216. package/src/pi/memory-setup/memory-setup.ts +153 -0
  217. package/src/pi/memory-setup/types.ts +6 -0
  218. package/src/pi/memory-succeed/constants.ts +10 -0
  219. package/src/pi/memory-succeed/index.ts +4 -0
  220. package/src/pi/memory-succeed/memory-succeed.ts +34 -0
  221. package/src/pi/memory-succeed/schemas.ts +30 -0
  222. package/src/pi/memory-succeed/types.ts +8 -0
  223. package/src/pi/memory-update/constants.ts +8 -0
  224. package/src/pi/memory-update/index.ts +4 -0
  225. package/src/pi/memory-update/memory-update.ts +29 -0
  226. package/src/pi/memory-update/schemas.ts +24 -0
  227. package/src/pi/memory-update/types.ts +8 -0
  228. package/src/pi/paths/constants.ts +7 -0
  229. package/src/pi/paths/index.ts +2 -0
  230. package/src/pi/paths/paths.ts +15 -0
  231. package/src/pi/paths/platform.ts +7 -0
  232. package/src/pi/registrar.ts +25 -0
  233. package/src/pi/registration-report/constants.ts +13 -0
  234. package/src/pi/registration-report/index.ts +2 -0
  235. package/src/pi/registration-report/report.ts +26 -0
  236. package/src/pi/relevant-memory/constants.ts +3 -0
  237. package/src/pi/relevant-memory/index.ts +4 -0
  238. package/src/pi/relevant-memory/prompt.ts +23 -0
  239. package/src/pi/relevant-memory/runtime.ts +88 -0
  240. package/src/pi/relevant-memory/types.ts +14 -0
  241. package/src/pi/semantic/constants.ts +3 -0
  242. package/src/pi/semantic/index.ts +2 -0
  243. package/src/pi/semantic/runtime.ts +59 -0
  244. package/src/pi/session-start/constants.ts +7 -0
  245. package/src/pi/session-start/index.ts +3 -0
  246. package/src/pi/session-start/session-start.ts +48 -0
  247. package/src/pi/session-start/types.ts +5 -0
  248. package/src/pi/shell-edit-guard/guard.ts +41 -0
  249. package/src/pi/shell-edit-guard/index.ts +3 -0
  250. package/src/pi/shell-edit-guard/prompt.ts +30 -0
  251. package/src/pi/shell-edit-guard/types.ts +13 -0
  252. package/src/pi/types.ts +44 -0
  253. package/src/pi/vault-guard/constants.ts +1 -0
  254. package/src/pi/vault-guard/index.ts +4 -0
  255. package/src/pi/vault-guard/request.ts +39 -0
  256. package/src/pi/vault-guard/types.ts +5 -0
  257. package/src/pi/vault-guard/vault-guard.ts +21 -0
  258. package/src/services/capture-cadence/domain-rules.ts +8 -0
  259. package/src/services/capture-cadence/index.ts +1 -0
  260. package/src/services/clock/clock.ts +7 -0
  261. package/src/services/clock/index.ts +1 -0
  262. package/src/services/config/canonicalize.ts +163 -0
  263. package/src/services/config/constants.ts +1 -0
  264. package/src/services/config/fully-qualified-path.ts +14 -0
  265. package/src/services/config/index.ts +12 -0
  266. package/src/services/config/path-identity.ts +65 -0
  267. package/src/services/config/publication.ts +75 -0
  268. package/src/services/config/read.ts +47 -0
  269. package/src/services/config/registration.ts +26 -0
  270. package/src/services/config/resolve-input.ts +27 -0
  271. package/src/services/config/snapshot.ts +26 -0
  272. package/src/services/config/target.ts +2 -0
  273. package/src/services/config/types.ts +97 -0
  274. package/src/services/config/vault-access.ts +2 -0
  275. package/src/services/config/volume-namespace.ts +5 -0
  276. package/src/services/config/write.ts +63 -0
  277. package/src/services/decision-model/constants.ts +16 -0
  278. package/src/services/decision-model/decide.ts +42 -0
  279. package/src/services/decision-model/diagnostics.ts +6 -0
  280. package/src/services/decision-model/endpoint.ts +1 -0
  281. package/src/services/decision-model/failure-detail.ts +1 -0
  282. package/src/services/decision-model/index.ts +7 -0
  283. package/src/services/decision-model/interruption.ts +29 -0
  284. package/src/services/decision-model/jev.ts +61 -0
  285. package/src/services/decision-model/laya-batch.ts +64 -0
  286. package/src/services/decision-model/laya-http-failure.ts +41 -0
  287. package/src/services/decision-model/laya-response.ts +95 -0
  288. package/src/services/decision-model/laya.ts +35 -0
  289. package/src/services/decision-model/preflight.ts +24 -0
  290. package/src/services/decision-model/prompts.ts +36 -0
  291. package/src/services/decision-model/schemas.ts +43 -0
  292. package/src/services/decision-model/score-candidates.ts +41 -0
  293. package/src/services/decision-model/types.ts +182 -0
  294. package/src/services/embeddings/asset-download.ts +45 -0
  295. package/src/services/embeddings/asset-fetch.ts +39 -0
  296. package/src/services/embeddings/asset-inspection.ts +36 -0
  297. package/src/services/embeddings/batch.ts +32 -0
  298. package/src/services/embeddings/chunks.ts +80 -0
  299. package/src/services/embeddings/configuration.ts +8 -0
  300. package/src/services/embeddings/constants.ts +24 -0
  301. package/src/services/embeddings/errors.ts +11 -0
  302. package/src/services/embeddings/google.ts +90 -0
  303. package/src/services/embeddings/http.ts +64 -0
  304. package/src/services/embeddings/index.ts +17 -0
  305. package/src/services/embeddings/inference.ts +35 -0
  306. package/src/services/embeddings/local.ts +138 -0
  307. package/src/services/embeddings/model-asset.ts +68 -0
  308. package/src/services/embeddings/model-cache.ts +30 -0
  309. package/src/services/embeddings/openai.ts +64 -0
  310. package/src/services/embeddings/operation.ts +31 -0
  311. package/src/services/embeddings/responses.ts +41 -0
  312. package/src/services/embeddings/runtime.ts +13 -0
  313. package/src/services/embeddings/schemas.ts +53 -0
  314. package/src/services/embeddings/types.ts +116 -0
  315. package/src/services/id/id.ts +5 -0
  316. package/src/services/id/index.ts +1 -0
  317. package/src/services/index.ts +11 -0
  318. package/src/services/llm/capture.ts +19 -0
  319. package/src/services/llm/check-chat-models.ts +38 -0
  320. package/src/services/llm/complete.ts +57 -0
  321. package/src/services/llm/constants.ts +32 -0
  322. package/src/services/llm/domain-rules.ts +2 -0
  323. package/src/services/llm/index.ts +6 -0
  324. package/src/services/llm/lifetime.ts +16 -0
  325. package/src/services/llm/retrieve.ts +19 -0
  326. package/src/services/llm/schemas.ts +9 -0
  327. package/src/services/llm/types.ts +94 -0
  328. package/src/services/search-index/catalog-query.ts +34 -0
  329. package/src/services/search-index/catalog-statements.ts +33 -0
  330. package/src/services/search-index/catalog.ts +19 -0
  331. package/src/services/search-index/cleanup.ts +13 -0
  332. package/src/services/search-index/close.ts +5 -0
  333. package/src/services/search-index/constants.ts +102 -0
  334. package/src/services/search-index/dont-forget.ts +1 -0
  335. package/src/services/search-index/fingerprint.ts +17 -0
  336. package/src/services/search-index/folder-index-statements.ts +17 -0
  337. package/src/services/search-index/folder-index-storage.ts +54 -0
  338. package/src/services/search-index/folder-indexes.ts +13 -0
  339. package/src/services/search-index/index.ts +14 -0
  340. package/src/services/search-index/inspection.ts +1 -0
  341. package/src/services/search-index/inventory.ts +67 -0
  342. package/src/services/search-index/legacy.ts +64 -0
  343. package/src/services/search-index/location.ts +12 -0
  344. package/src/services/search-index/open.ts +46 -0
  345. package/src/services/search-index/query.ts +39 -0
  346. package/src/services/search-index/ranking.ts +12 -0
  347. package/src/services/search-index/reconcile.ts +93 -0
  348. package/src/services/search-index/recovery.ts +56 -0
  349. package/src/services/search-index/refusals.ts +21 -0
  350. package/src/services/search-index/schema.ts +42 -0
  351. package/src/services/search-index/schemas.ts +181 -0
  352. package/src/services/search-index/search.ts +5 -0
  353. package/src/services/search-index/statements.ts +18 -0
  354. package/src/services/search-index/storage.ts +207 -0
  355. package/src/services/search-index/types.ts +113 -0
  356. package/src/services/search-index/vector-statements.ts +18 -0
  357. package/src/services/search-index/vector-storage.ts +169 -0
  358. package/src/services/search-index/vectors.ts +18 -0
  359. package/src/services/search-index/write.ts +9 -0
  360. package/src/services/shell-edit/ask.ts +53 -0
  361. package/src/services/shell-edit/domain-rules.ts +2 -0
  362. package/src/services/shell-edit/index.ts +4 -0
  363. package/src/services/shell-edit/schemas.ts +23 -0
  364. package/src/services/shell-edit/types.ts +61 -0
  365. package/src/services/shell-scripts/constants.ts +1 -0
  366. package/src/services/shell-scripts/files.ts +16 -0
  367. package/src/services/shell-scripts/index.ts +5 -0
  368. package/src/services/shell-scripts/package-scripts.ts +74 -0
  369. package/src/services/shell-scripts/schemas.ts +3 -0
  370. package/src/services/shell-scripts/scripts.ts +27 -0
  371. package/src/services/shell-scripts/types.ts +11 -0
  372. package/src/services/vault/archive.ts +31 -0
  373. package/src/services/vault/bootstrap/ensure.ts +50 -0
  374. package/src/services/vault/bootstrap/index.ts +2 -0
  375. package/src/services/vault/bootstrap/paths.ts +57 -0
  376. package/src/services/vault/bootstrap/types.ts +17 -0
  377. package/src/services/vault/bootstrap/write.ts +47 -0
  378. package/src/services/vault/catalog/bytes.ts +51 -0
  379. package/src/services/vault/catalog/dont-forget.ts +1 -0
  380. package/src/services/vault/catalog/enumerate.ts +69 -0
  381. package/src/services/vault/catalog/export.ts +21 -0
  382. package/src/services/vault/catalog/failures.ts +16 -0
  383. package/src/services/vault/catalog/index.ts +10 -0
  384. package/src/services/vault/catalog/inspect.ts +41 -0
  385. package/src/services/vault/catalog/observe.ts +35 -0
  386. package/src/services/vault/catalog/resolve.ts +94 -0
  387. package/src/services/vault/catalog/stat.ts +23 -0
  388. package/src/services/vault/catalog/types.ts +69 -0
  389. package/src/services/vault/catalog/visit.ts +58 -0
  390. package/src/services/vault/complete-blank.ts +66 -0
  391. package/src/services/vault/constants.ts +3 -0
  392. package/src/services/vault/context/index.ts +1 -0
  393. package/src/services/vault/context/types.ts +10 -0
  394. package/src/services/vault/create.ts +19 -0
  395. package/src/services/vault/display.ts +6 -0
  396. package/src/services/vault/domain-rules.ts +10 -0
  397. package/src/services/vault/draft.ts +2 -0
  398. package/src/services/vault/filesystem/failures.ts +53 -0
  399. package/src/services/vault/filesystem/hash.ts +5 -0
  400. package/src/services/vault/filesystem/index.ts +5 -0
  401. package/src/services/vault/filesystem/read.ts +61 -0
  402. package/src/services/vault/filesystem/types.ts +36 -0
  403. package/src/services/vault/filesystem/write.ts +80 -0
  404. package/src/services/vault/find.ts +27 -0
  405. package/src/services/vault/folder-contents.ts +31 -0
  406. package/src/services/vault/folder-index/index.ts +2 -0
  407. package/src/services/vault/folder-index/read.ts +87 -0
  408. package/src/services/vault/folder-index/types.ts +19 -0
  409. package/src/services/vault/folder-listing.ts +1 -0
  410. package/src/services/vault/index.ts +21 -0
  411. package/src/services/vault/inspect-folder.ts +13 -0
  412. package/src/services/vault/list.ts +121 -0
  413. package/src/services/vault/memory-folder.ts +24 -0
  414. package/src/services/vault/paths.ts +11 -0
  415. package/src/services/vault/publish.ts +52 -0
  416. package/src/services/vault/read.ts +46 -0
  417. package/src/services/vault/refresh-folders.ts +197 -0
  418. package/src/services/vault/refresh-plan.ts +79 -0
  419. package/src/services/vault/refresh.ts +8 -0
  420. package/src/services/vault/refusals.ts +23 -0
  421. package/src/services/vault/relocate.ts +131 -0
  422. package/src/services/vault/relocation-checks.ts +89 -0
  423. package/src/services/vault/resolve-stored-file.ts +43 -0
  424. package/src/services/vault/resolve.ts +109 -0
  425. package/src/services/vault/succeed.ts +45 -0
  426. package/src/services/vault/types.ts +199 -0
  427. package/src/services/vault/update-file.ts +58 -0
  428. package/src/services/vault/update.ts +22 -0
  429. package/src/services/vault/write-new-file.ts +37 -0
  430. package/src/shared/index.ts +1 -0
  431. package/src/shared/result/index.ts +1 -0
  432. package/src/shared/result/types.ts +17 -0
  433. package/src/usecases/add-memory/add-memory.ts +83 -0
  434. package/src/usecases/add-memory/index.ts +4 -0
  435. package/src/usecases/add-memory/maintenance.ts +23 -0
  436. package/src/usecases/add-memory/schemas.ts +12 -0
  437. package/src/usecases/add-memory/types.ts +47 -0
  438. package/src/usecases/archive-memory/archive-memory.ts +27 -0
  439. package/src/usecases/archive-memory/index.ts +3 -0
  440. package/src/usecases/archive-memory/schemas.ts +11 -0
  441. package/src/usecases/archive-memory/types.ts +17 -0
  442. package/src/usecases/capture-memory/apply.ts +73 -0
  443. package/src/usecases/capture-memory/capture-memory.ts +117 -0
  444. package/src/usecases/capture-memory/constants.ts +15 -0
  445. package/src/usecases/capture-memory/index.ts +5 -0
  446. package/src/usecases/capture-memory/observe.ts +122 -0
  447. package/src/usecases/capture-memory/settings.ts +20 -0
  448. package/src/usecases/capture-memory/types.ts +103 -0
  449. package/src/usecases/check-shell-edit/check-shell-edit.ts +28 -0
  450. package/src/usecases/check-shell-edit/index.ts +2 -0
  451. package/src/usecases/check-shell-edit/types.ts +30 -0
  452. package/src/usecases/check-vault-access/check-vault-access.ts +23 -0
  453. package/src/usecases/check-vault-access/constants.ts +7 -0
  454. package/src/usecases/check-vault-access/index.ts +4 -0
  455. package/src/usecases/check-vault-access/raw-device.ts +10 -0
  456. package/src/usecases/check-vault-access/targets.ts +49 -0
  457. package/src/usecases/check-vault-access/types.ts +33 -0
  458. package/src/usecases/complete-blank-memory/complete-blank-memory.ts +48 -0
  459. package/src/usecases/complete-blank-memory/constants.ts +3 -0
  460. package/src/usecases/complete-blank-memory/index.ts +4 -0
  461. package/src/usecases/complete-blank-memory/schemas.ts +14 -0
  462. package/src/usecases/complete-blank-memory/types.ts +28 -0
  463. package/src/usecases/diagnose-memory/constants.ts +3 -0
  464. package/src/usecases/diagnose-memory/decision.ts +36 -0
  465. package/src/usecases/diagnose-memory/diagnose-memory.ts +52 -0
  466. package/src/usecases/diagnose-memory/embeddings.ts +39 -0
  467. package/src/usecases/diagnose-memory/index.ts +5 -0
  468. package/src/usecases/diagnose-memory/types.ts +86 -0
  469. package/src/usecases/diagnose-memory/vault.ts +33 -0
  470. package/src/usecases/export-memory/collect.ts +20 -0
  471. package/src/usecases/export-memory/constants.ts +3 -0
  472. package/src/usecases/export-memory/export-memory.ts +84 -0
  473. package/src/usecases/export-memory/index.ts +3 -0
  474. package/src/usecases/export-memory/types.ts +28 -0
  475. package/src/usecases/get-memory/get-memory.ts +97 -0
  476. package/src/usecases/get-memory/index.ts +2 -0
  477. package/src/usecases/get-memory/types.ts +25 -0
  478. package/src/usecases/index.ts +25 -0
  479. package/src/usecases/list-memory/index.ts +2 -0
  480. package/src/usecases/list-memory/leased/index.ts +2 -0
  481. package/src/usecases/list-memory/leased/read.ts +16 -0
  482. package/src/usecases/list-memory/leased/types.ts +21 -0
  483. package/src/usecases/list-memory/list-memory.ts +33 -0
  484. package/src/usecases/list-memory/types.ts +8 -0
  485. package/src/usecases/load-dont-forget/index.ts +2 -0
  486. package/src/usecases/load-dont-forget/load-dont-forget.ts +111 -0
  487. package/src/usecases/load-dont-forget/types.ts +26 -0
  488. package/src/usecases/memory-change/change.ts +42 -0
  489. package/src/usecases/memory-change/index.ts +5 -0
  490. package/src/usecases/memory-change/maintenance.ts +11 -0
  491. package/src/usecases/memory-change/partial.ts +18 -0
  492. package/src/usecases/memory-change/receipt.ts +40 -0
  493. package/src/usecases/memory-change/types.ts +44 -0
  494. package/src/usecases/operation-context/context.ts +37 -0
  495. package/src/usecases/operation-context/index.ts +2 -0
  496. package/src/usecases/operation-context/types.ts +19 -0
  497. package/src/usecases/registration/check.ts +6 -0
  498. package/src/usecases/registration/entry.ts +33 -0
  499. package/src/usecases/registration/index.ts +8 -0
  500. package/src/usecases/registration/init.ts +94 -0
  501. package/src/usecases/registration/prepare-init.ts +43 -0
  502. package/src/usecases/registration/prepare.ts +35 -0
  503. package/src/usecases/registration/propose.ts +34 -0
  504. package/src/usecases/registration/publication.ts +90 -0
  505. package/src/usecases/registration/setup.ts +41 -0
  506. package/src/usecases/registration/types.ts +107 -0
  507. package/src/usecases/relevant-memory/agent.ts +55 -0
  508. package/src/usecases/relevant-memory/constants.ts +28 -0
  509. package/src/usecases/relevant-memory/cutoffs.ts +29 -0
  510. package/src/usecases/relevant-memory/decision.ts +102 -0
  511. package/src/usecases/relevant-memory/index.ts +11 -0
  512. package/src/usecases/relevant-memory/loaded.ts +31 -0
  513. package/src/usecases/relevant-memory/refresh.ts +30 -0
  514. package/src/usecases/relevant-memory/retrieve-memory.ts +62 -0
  515. package/src/usecases/relevant-memory/schemas.ts +20 -0
  516. package/src/usecases/relevant-memory/session-memory.ts +53 -0
  517. package/src/usecases/relevant-memory/track-dont-forget.ts +13 -0
  518. package/src/usecases/relevant-memory/types.ts +106 -0
  519. package/src/usecases/resolve-memory/index.ts +2 -0
  520. package/src/usecases/resolve-memory/leased/index.ts +2 -0
  521. package/src/usecases/resolve-memory/leased/resolve.ts +109 -0
  522. package/src/usecases/resolve-memory/leased/types.ts +35 -0
  523. package/src/usecases/resolve-memory/resolve-memory.ts +23 -0
  524. package/src/usecases/resolve-memory/types.ts +7 -0
  525. package/src/usecases/search-memory/constants.ts +1 -0
  526. package/src/usecases/search-memory/index.ts +3 -0
  527. package/src/usecases/search-memory/search-memory.ts +132 -0
  528. package/src/usecases/search-memory/types.ts +39 -0
  529. package/src/usecases/semantic/constants.ts +7 -0
  530. package/src/usecases/semantic/index.ts +5 -0
  531. package/src/usecases/semantic/prepare.ts +30 -0
  532. package/src/usecases/semantic/rank.ts +83 -0
  533. package/src/usecases/semantic/refresh-vectors.ts +95 -0
  534. package/src/usecases/semantic/types.ts +17 -0
  535. package/src/usecases/semantic-port/index.ts +1 -0
  536. package/src/usecases/semantic-port/types.ts +20 -0
  537. package/src/usecases/semantic-provider/constants.ts +6 -0
  538. package/src/usecases/semantic-provider/index.ts +5 -0
  539. package/src/usecases/semantic-provider/local.ts +33 -0
  540. package/src/usecases/semantic-provider/remote.ts +10 -0
  541. package/src/usecases/semantic-provider/size.ts +10 -0
  542. package/src/usecases/semantic-provider/types.ts +19 -0
  543. package/src/usecases/session/index.ts +2 -0
  544. package/src/usecases/session/lease.ts +70 -0
  545. package/src/usecases/session/receipts.ts +46 -0
  546. package/src/usecases/session/state.ts +106 -0
  547. package/src/usecases/session/types.ts +45 -0
  548. package/src/usecases/settings/change.ts +142 -0
  549. package/src/usecases/settings/index.ts +3 -0
  550. package/src/usecases/settings/prepare.ts +24 -0
  551. package/src/usecases/settings/types.ts +32 -0
  552. package/src/usecases/succeed-memory/index.ts +3 -0
  553. package/src/usecases/succeed-memory/schemas.ts +13 -0
  554. package/src/usecases/succeed-memory/succeed-memory.ts +34 -0
  555. package/src/usecases/succeed-memory/types.ts +18 -0
  556. package/src/usecases/synchronize-memory/index.ts +2 -0
  557. package/src/usecases/synchronize-memory/leased/aliases.ts +55 -0
  558. package/src/usecases/synchronize-memory/leased/folder-states.ts +58 -0
  559. package/src/usecases/synchronize-memory/leased/index.ts +2 -0
  560. package/src/usecases/synchronize-memory/leased/inspection.ts +32 -0
  561. package/src/usecases/synchronize-memory/leased/maintenance.ts +41 -0
  562. package/src/usecases/synchronize-memory/leased/publication.ts +55 -0
  563. package/src/usecases/synchronize-memory/leased/scan.ts +37 -0
  564. package/src/usecases/synchronize-memory/leased/synchronize.ts +102 -0
  565. package/src/usecases/synchronize-memory/leased/types.ts +60 -0
  566. package/src/usecases/synchronize-memory/synchronize-memory.ts +26 -0
  567. package/src/usecases/synchronize-memory/types.ts +5 -0
  568. package/src/usecases/update-memory/index.ts +3 -0
  569. package/src/usecases/update-memory/schemas.ts +14 -0
  570. package/src/usecases/update-memory/types.ts +16 -0
  571. package/src/usecases/update-memory/update-memory.ts +31 -0
  572. package/CHANGELOG.md +0 -21
@@ -0,0 +1,102 @@
1
+ import { Compile } from "typebox/compile"
2
+
3
+ import { CatalogEntrySchema, CatalogNoteSchema } from "#src/domain"
4
+ import { CatalogRowSchema } from "./schemas.ts"
5
+
6
+ export const CATALOG_VALIDATION_POLICY = "vault-note-analysis-v1"
7
+
8
+ export const INDEX_FILE_EXTENSION = ".sqlite"
9
+
10
+ export const INDEX_FILE_NAME_LENGTH = 16
11
+
12
+ export const STATEMENT_WEIGHT = 2
13
+
14
+ export const BODY_WEIGHT = 1
15
+
16
+ export const WORD_PATTERN = /[\p{L}\p{N}]+/gu
17
+
18
+ export const INDEX_SCHEMA_VERSION = 3
19
+
20
+ export const CatalogRowValidator = Compile(CatalogRowSchema)
21
+
22
+ export const CatalogEntryValidator = Compile(CatalogEntrySchema)
23
+
24
+ export const CatalogNoteValidator = Compile(CatalogNoteSchema)
25
+
26
+ export const SQLITE_PRIMARY_CODE_MASK = 0xff
27
+
28
+ export const SQLITE_ERROR = 1
29
+
30
+ export const SQLITE_CORRUPT = 11
31
+
32
+ export const SQLITE_NOTADB = 26
33
+
34
+ export const REBUILD_SCHEMA_SQL = `
35
+ DROP TABLE IF EXISTS notes_fts;
36
+ DROP TABLE IF EXISTS notes;
37
+ DROP TABLE IF EXISTS catalog_state;
38
+ DROP TABLE IF EXISTS vector_chunks;
39
+ DROP TABLE IF EXISTS vector_generation;
40
+ DROP TABLE IF EXISTS folder_indexes;
41
+ CREATE TABLE catalog_state (
42
+ singleton INTEGER PRIMARY KEY CHECK(singleton = 1),
43
+ revision INTEGER NOT NULL,
44
+ population TEXT NOT NULL
45
+ );
46
+ INSERT INTO catalog_state VALUES (1, 0, 'needs-population');
47
+ CREATE TABLE folder_indexes (
48
+ folder TEXT PRIMARY KEY,
49
+ fingerprint TEXT NOT NULL,
50
+ index_size INTEGER NOT NULL,
51
+ index_mtime_ms REAL NOT NULL,
52
+ index_ctime_ms REAL NOT NULL,
53
+ index_ino TEXT NOT NULL
54
+ );
55
+ CREATE TABLE vector_generation (
56
+ singleton INTEGER PRIMARY KEY CHECK(singleton = 1),
57
+ fingerprint TEXT NOT NULL,
58
+ dimensions INTEGER NOT NULL
59
+ );
60
+ CREATE TABLE vector_chunks (
61
+ content_fingerprint TEXT NOT NULL,
62
+ chunk INTEGER NOT NULL,
63
+ vector TEXT NOT NULL,
64
+ PRIMARY KEY(content_fingerprint, chunk)
65
+ );
66
+ CREATE TABLE notes (
67
+ rowid INTEGER PRIMARY KEY,
68
+ path TEXT NOT NULL UNIQUE,
69
+ id TEXT,
70
+ folder TEXT NOT NULL,
71
+ statement TEXT,
72
+ body TEXT,
73
+ type TEXT,
74
+ dont_forget INTEGER,
75
+ archived INTEGER,
76
+ size INTEGER NOT NULL,
77
+ modified_ms REAL NOT NULL,
78
+ hash TEXT NOT NULL,
79
+ content_fingerprint TEXT,
80
+ validation_fingerprint TEXT NOT NULL,
81
+ needs_fixing INTEGER NOT NULL
82
+ );
83
+ CREATE INDEX notes_id ON notes(id);
84
+ CREATE VIRTUAL TABLE notes_fts USING fts5(
85
+ statement, body,
86
+ content = 'notes', content_rowid = 'rowid',
87
+ tokenize = 'porter unicode61'
88
+ );
89
+ CREATE TRIGGER notes_insert AFTER INSERT ON notes BEGIN
90
+ INSERT INTO notes_fts(rowid, statement, body) VALUES (new.rowid, new.statement, new.body);
91
+ END;
92
+ CREATE TRIGGER notes_delete AFTER DELETE ON notes BEGIN
93
+ INSERT INTO notes_fts(notes_fts, rowid, statement, body)
94
+ VALUES ('delete', old.rowid, old.statement, old.body);
95
+ END;
96
+ CREATE TRIGGER notes_update AFTER UPDATE OF statement, body ON notes BEGIN
97
+ INSERT INTO notes_fts(notes_fts, rowid, statement, body)
98
+ VALUES ('delete', old.rowid, old.statement, old.body);
99
+ INSERT INTO notes_fts(rowid, statement, body) VALUES (new.rowid, new.statement, new.body);
100
+ END;
101
+ PRAGMA user_version = ${INDEX_SCHEMA_VERSION};
102
+ `
@@ -0,0 +1 @@
1
+ export { dontForgetCandidates } from "#src/domain"
@@ -0,0 +1,17 @@
1
+ import { createHash } from "node:crypto"
2
+
3
+ import type { MemoryConfig } from "#src/domain"
4
+ import { CATALOG_VALIDATION_POLICY } from "./constants.ts"
5
+
6
+ export function catalogValidationFingerprint(limits: MemoryConfig["limits"]): string {
7
+ return createHash("sha256")
8
+ .update(
9
+ JSON.stringify([
10
+ CATALOG_VALIDATION_POLICY,
11
+ limits.maxStatementChars,
12
+ limits.maxBodyChars,
13
+ limits.maxNotesPerFolder,
14
+ ]),
15
+ )
16
+ .digest("hex")
17
+ }
@@ -0,0 +1,17 @@
1
+ import type { DatabaseSync } from "node:sqlite"
2
+
3
+ export function prepareFolderIndexStatements(database: DatabaseSync) {
4
+ return {
5
+ all: database.prepare(
6
+ "SELECT folder, fingerprint, index_size, index_mtime_ms, index_ctime_ms, index_ino FROM folder_indexes ORDER BY folder",
7
+ ),
8
+ put: database.prepare(`
9
+ INSERT INTO folder_indexes (folder, fingerprint, index_size, index_mtime_ms, index_ctime_ms, index_ino)
10
+ VALUES (?, ?, ?, ?, ?, ?)
11
+ ON CONFLICT(folder) DO UPDATE SET fingerprint = excluded.fingerprint,
12
+ index_size = excluded.index_size, index_mtime_ms = excluded.index_mtime_ms,
13
+ index_ctime_ms = excluded.index_ctime_ms, index_ino = excluded.index_ino
14
+ `),
15
+ prune: database.prepare("DELETE FROM folder_indexes WHERE folder NOT IN (SELECT value FROM json_each(?))"),
16
+ }
17
+ }
@@ -0,0 +1,54 @@
1
+ import { Value } from "typebox/value"
2
+
3
+ import type { prepareFolderIndexStatements } from "./folder-index-statements.ts"
4
+ import { corruptCatalog } from "./inventory.ts"
5
+ import { invalidCatalog } from "./reconcile.ts"
6
+ import { FolderIndexRowSchema, FolderIndexWriteSchema } from "./schemas.ts"
7
+ import type { FolderIndexState, FolderIndexStatesResult, IndexWriteResult } from "./types.ts"
8
+
9
+ export function readStoredFolderIndexes(
10
+ statements: ReturnType<typeof prepareFolderIndexStatements>,
11
+ ): FolderIndexStatesResult {
12
+ const states: FolderIndexState[] = []
13
+ for (const row of statements.all.all()) {
14
+ if (
15
+ !Value.Check(FolderIndexRowSchema, row) ||
16
+ !Number.isFinite(row.index_mtime_ms) ||
17
+ !Number.isFinite(row.index_ctime_ms)
18
+ )
19
+ return corruptCatalog()
20
+ states.push({
21
+ folder: row.folder,
22
+ fingerprint: row.fingerprint,
23
+ indexSize: row.index_size,
24
+ indexMtimeMs: row.index_mtime_ms,
25
+ indexCtimeMs: row.index_ctime_ms,
26
+ indexIno: row.index_ino,
27
+ })
28
+ }
29
+ return { succeeded: true, output: states }
30
+ }
31
+
32
+ export function writeFolderIndexStates(
33
+ statements: ReturnType<typeof prepareFolderIndexStatements>,
34
+ states: FolderIndexState[],
35
+ keepFolders: string[],
36
+ ): IndexWriteResult {
37
+ const valid =
38
+ Value.Check(FolderIndexWriteSchema, { states, keepFolders }) &&
39
+ states.every((state) => Number.isFinite(state.indexMtimeMs) && Number.isFinite(state.indexCtimeMs))
40
+ if (!valid) return invalidCatalog("the folder index states are invalid")
41
+
42
+ for (const state of states) {
43
+ statements.put.run(
44
+ state.folder,
45
+ state.fingerprint,
46
+ state.indexSize,
47
+ state.indexMtimeMs,
48
+ state.indexCtimeMs,
49
+ state.indexIno,
50
+ )
51
+ }
52
+ statements.prune.run(JSON.stringify(keepFolders))
53
+ return { succeeded: true }
54
+ }
@@ -0,0 +1,13 @@
1
+ import type { FolderIndexState, FolderIndexStatesResult, IndexWriteResult, SearchIndex } from "./types.ts"
2
+
3
+ export function readFolderIndexStates(index: SearchIndex): FolderIndexStatesResult {
4
+ return index.folderIndexes()
5
+ }
6
+
7
+ export function recordFolderIndexStates(
8
+ index: SearchIndex,
9
+ states: FolderIndexState[],
10
+ keepFolders: string[],
11
+ ): IndexWriteResult {
12
+ return index.recordFolderIndexes(states, keepFolders)
13
+ }
@@ -0,0 +1,14 @@
1
+ export * from "./catalog.ts"
2
+ export * from "./close.ts"
3
+ export * from "./dont-forget.ts"
4
+ export * from "./fingerprint.ts"
5
+ export * from "./folder-indexes.ts"
6
+ export * from "./inspection.ts"
7
+ export * from "./location.ts"
8
+ export * from "./open.ts"
9
+ export * from "./ranking.ts"
10
+ export * from "./recovery.ts"
11
+ export * from "./search.ts"
12
+ export * from "./types.ts"
13
+ export * from "./vectors.ts"
14
+ export * from "./write.ts"
@@ -0,0 +1 @@
1
+ export { classifyAliasFailure, inspectedCatalogEntry, reusableCatalogEntry } from "#src/domain"
@@ -0,0 +1,67 @@
1
+ import { Value } from "typebox/value"
2
+
3
+ import type { CatalogEntry } from "#src/domain"
4
+ import type { prepareCatalogStatements } from "./catalog-statements.ts"
5
+ import { CatalogEntryValidator, CatalogNoteValidator, CatalogRowValidator } from "./constants.ts"
6
+ import { CatalogStateSchema } from "./schemas.ts"
7
+ import type { CatalogRow, InventoryResult, SearchIndexRefusal } from "./types.ts"
8
+
9
+ export function readInventory(statements: ReturnType<typeof prepareCatalogStatements>): InventoryResult {
10
+ const state = statements.state.get()
11
+ if (!Value.Check(CatalogStateSchema, state)) return corruptCatalog()
12
+
13
+ const entries: CatalogEntry[] = []
14
+ for (const row of statements.inventory.all()) {
15
+ if (!CatalogRowValidator.Check(row)) return corruptCatalog()
16
+ const entry = entryFromRow(row)
17
+ if (!entry || !validCatalogEntry(entry)) return corruptCatalog()
18
+ entries.push(entry)
19
+ }
20
+ return { succeeded: true, output: { ...state, entries } }
21
+ }
22
+
23
+ export function validCatalogEntry(entry: CatalogEntry): boolean {
24
+ if (!CatalogEntryValidator.Check(entry) || !Number.isFinite(entry.stat.mtimeMs)) return false
25
+ if (!entry.note) return !entry.contentFingerprint && entry.needsFixing
26
+ if (!entry.contentFingerprint) return false
27
+ return entry.note.archived || entry.path.split("/")[0]?.toLowerCase() !== "archive"
28
+ }
29
+
30
+ function entryFromRow(row: CatalogRow): CatalogEntry | null {
31
+ const entry: CatalogEntry = {
32
+ path: row.path,
33
+ stat: { size: row.size, mtimeMs: row.modified_ms },
34
+ rawHash: row.hash,
35
+ contentFingerprint: row.content_fingerprint,
36
+ validationFingerprint: row.validation_fingerprint,
37
+ needsFixing: row.needs_fixing === 1,
38
+ note: null,
39
+ }
40
+ if (!row.id) {
41
+ const columns = [row.type, row.statement, row.body, row.dont_forget, row.archived]
42
+ if (columns.some((value) => typeof value === "string" || typeof value === "number")) return null
43
+ return entry
44
+ }
45
+ const note = noteFromRow(row)
46
+ if (!note) return null
47
+ entry.note = note
48
+ return entry
49
+ }
50
+
51
+ function noteFromRow(row: CatalogRow): CatalogEntry["note"] {
52
+ if (typeof row.dont_forget !== "number" || typeof row.archived !== "number") return null
53
+ const note = {
54
+ id: row.id,
55
+ type: row.type,
56
+ statement: row.statement,
57
+ body: row.body,
58
+ dontForget: row.dont_forget === 1,
59
+ archived: row.archived === 1,
60
+ }
61
+ if (!CatalogNoteValidator.Check(note)) return null
62
+ return note
63
+ }
64
+
65
+ export function corruptCatalog(): SearchIndexRefusal {
66
+ return { succeeded: false, reason: "corrupted", problems: ["the catalog does not match its schema"] }
67
+ }
@@ -0,0 +1,64 @@
1
+ import { Value } from "typebox/value"
2
+
3
+ import { type CatalogEntry, semanticFingerprint } from "#src/domain"
4
+ import type { prepareCatalogStatements } from "./catalog-statements.ts"
5
+ import { validCatalogEntry } from "./inventory.ts"
6
+ import { invalidCatalog, writeCatalogEntry } from "./reconcile.ts"
7
+ import { IndexEntrySchema } from "./schemas.ts"
8
+ import type { prepareStatements } from "./statements.ts"
9
+ import type { IndexEntry, IndexWriteResult } from "./types.ts"
10
+
11
+ export function putLegacyEntry(
12
+ statements: ReturnType<typeof prepareStatements>,
13
+ catalog: ReturnType<typeof prepareCatalogStatements>,
14
+ entry: IndexEntry,
15
+ ): IndexWriteResult {
16
+ if (!Value.Check(IndexEntrySchema, entry) || !Number.isFinite(entry.modifiedMs)) {
17
+ return invalidCatalog("the entry does not match the index schema")
18
+ }
19
+ if (statements.byId.all(entry.id).length > 1) {
20
+ return invalidCatalog("duplicate ids require a path-keyed catalog mutation")
21
+ }
22
+ const converted = legacyEntry(entry)
23
+ if (!validCatalogEntry(converted)) return invalidCatalog("the entry does not have a valid catalog path")
24
+ statements.move.run(converted.path, entry.id)
25
+ writeCatalogEntry(catalog, converted)
26
+ statements.folder.run(entry.folder, converted.path)
27
+ catalog.prune.run()
28
+ catalog.advance.run("needs-population")
29
+ return { succeeded: true }
30
+ }
31
+
32
+ export function removeLegacyEntry(
33
+ statements: ReturnType<typeof prepareStatements>,
34
+ catalog: ReturnType<typeof prepareCatalogStatements>,
35
+ id: string,
36
+ ): IndexWriteResult {
37
+ if (statements.byId.all(id).length > 1) return invalidCatalog("duplicate ids require a path-keyed catalog mutation")
38
+ statements.remove.run({ id })
39
+ catalog.prune.run()
40
+ catalog.advance.run("needs-population")
41
+ return { succeeded: true }
42
+ }
43
+
44
+ function legacyEntry(entry: IndexEntry): CatalogEntry {
45
+ let path = `${entry.statement}.md`
46
+ if (entry.folder !== "") path = `${entry.folder}/${path}`
47
+ if (entry.archived && path.split("/")[0]?.toLowerCase() !== "archive") path = `archive/${path}`
48
+ return {
49
+ path,
50
+ stat: { size: entry.size, mtimeMs: entry.modifiedMs },
51
+ rawHash: entry.hash,
52
+ contentFingerprint: semanticFingerprint(entry),
53
+ validationFingerprint: "legacy-unvalidated",
54
+ needsFixing: false,
55
+ note: {
56
+ id: entry.id,
57
+ statement: entry.statement,
58
+ body: entry.body,
59
+ type: entry.type,
60
+ dontForget: entry.dontForget,
61
+ archived: entry.archived,
62
+ },
63
+ }
64
+ }
@@ -0,0 +1,12 @@
1
+ import { createHash } from "node:crypto"
2
+ import { join } from "node:path"
3
+
4
+ import { comparablePath, type PathPlatform } from "#src/domain"
5
+ import { INDEX_FILE_EXTENSION, INDEX_FILE_NAME_LENGTH } from "./constants.ts"
6
+
7
+ export function indexFileFor(indexFolder: string, vaultPath: string, platform: PathPlatform): string {
8
+ const vaultKey = comparablePath(vaultPath, platform)
9
+ const name = createHash("sha256").update(vaultKey).digest("hex").slice(0, INDEX_FILE_NAME_LENGTH)
10
+
11
+ return join(indexFolder, `${name}${INDEX_FILE_EXTENSION}`)
12
+ }
@@ -0,0 +1,46 @@
1
+ import { lstatSync, mkdirSync } from "node:fs"
2
+ import { dirname } from "node:path"
3
+ import { DatabaseSync } from "node:sqlite"
4
+
5
+ import { closeFailedIndex } from "./cleanup.ts"
6
+ import { indexFailure } from "./refusals.ts"
7
+ import { initializeSchema } from "./schema.ts"
8
+ import { SqliteSearchIndex } from "./storage.ts"
9
+ import type { OpenIndexResult } from "./types.ts"
10
+
11
+ export function openIndex(path: string): OpenIndexResult {
12
+ try {
13
+ for (const suffix of ["", "-journal", "-wal", "-shm"]) {
14
+ if (lstatSync(`${path}${suffix}`, { throwIfNoEntry: false })?.isSymbolicLink()) {
15
+ return {
16
+ succeeded: false,
17
+ reason: "unavailable",
18
+ problems: [`Index path must not be a link: ${path}${suffix}`],
19
+ }
20
+ }
21
+ }
22
+ mkdirSync(dirname(path), { recursive: true })
23
+ return initializeIndex(new DatabaseSync(path))
24
+ } catch (error) {
25
+ if (!(error instanceof Error)) {
26
+ throw error
27
+ }
28
+ return indexFailure(error)
29
+ }
30
+ }
31
+
32
+ function initializeIndex(database: DatabaseSync): OpenIndexResult {
33
+ try {
34
+ const schema = initializeSchema(database)
35
+ if (!schema.succeeded) {
36
+ return closeFailedIndex(database, schema)
37
+ }
38
+
39
+ return { succeeded: true, output: new SqliteSearchIndex(database), rebuilt: schema.output }
40
+ } catch (error) {
41
+ if (!(error instanceof Error)) {
42
+ throw error
43
+ }
44
+ return closeFailedIndex(database, indexFailure(error))
45
+ }
46
+ }
@@ -0,0 +1,39 @@
1
+ import type { StatementSync } from "node:sqlite"
2
+
3
+ import { eng, removeStopwords } from "stopword"
4
+ import { Value } from "typebox/value"
5
+
6
+ import { BODY_WEIGHT, STATEMENT_WEIGHT, WORD_PATTERN } from "./constants.ts"
7
+ import { SearchHitSchema, SearchOptionsSchema } from "./schemas.ts"
8
+ import type { SearchHit, SearchOptions, SearchResult } from "./types.ts"
9
+
10
+ export function readSearchHits(statement: StatementSync, query: string, options: SearchOptions): SearchResult {
11
+ if (!Value.Check(SearchOptionsSchema, options)) {
12
+ return { succeeded: false, reason: "invalid", problems: ["search options require a boolean includeArchived"] }
13
+ }
14
+
15
+ const terms = searchTermsOf(query)
16
+ if (terms.length === 0) return { succeeded: true, output: [] }
17
+
18
+ const rows = statement.all({
19
+ match: terms.map((term) => `"${term}"`).join(" OR "),
20
+ includeArchived: Number(options.includeArchived),
21
+ statementWeight: STATEMENT_WEIGHT,
22
+ bodyWeight: BODY_WEIGHT,
23
+ })
24
+ const hits: SearchHit[] = []
25
+ for (const row of rows) {
26
+ if (!Value.Check(SearchHitSchema, row) || !Number.isFinite(row.score)) {
27
+ return { succeeded: false, reason: "corrupted", problems: ["a search result does not match the index schema"] }
28
+ }
29
+ hits.push(row)
30
+ }
31
+ return { succeeded: true, output: hits }
32
+ }
33
+
34
+ export function searchTermsOf(query: string): string[] {
35
+ const words = query.toLowerCase().match(WORD_PATTERN)
36
+ if (!words) return []
37
+
38
+ return removeStopwords([...new Set(words)], eng)
39
+ }
@@ -0,0 +1,12 @@
1
+ export {
2
+ cosine,
3
+ type EmbeddingProvider,
4
+ type FusedPath,
5
+ fuseRankings,
6
+ MINIMUM_SIMILARITY,
7
+ type MinimumSimilarities,
8
+ planVectorRefresh,
9
+ type ScoredPath,
10
+ semanticRanking,
11
+ type VectorRefreshPlan,
12
+ } from "#src/domain"
@@ -0,0 +1,93 @@
1
+ import { Value } from "typebox/value"
2
+
3
+ import type { CatalogChanges, CatalogEntry } from "#src/domain"
4
+ import { catalogFolder } from "#src/domain"
5
+ import type { prepareCatalogStatements } from "./catalog-statements.ts"
6
+ import { corruptCatalog, validCatalogEntry } from "./inventory.ts"
7
+ import { CatalogChangesSchema, CatalogStateSchema } from "./schemas.ts"
8
+ import type { CatalogWriteRow, IndexWriteResult, SearchIndexRefusal } from "./types.ts"
9
+
10
+ export function writeCatalog(
11
+ statements: ReturnType<typeof prepareCatalogStatements>,
12
+ changes: CatalogChanges,
13
+ ): IndexWriteResult {
14
+ if (!validChanges(changes)) return invalidCatalog("the catalog changes are invalid or overlap")
15
+ const state = statements.state.get()
16
+ if (!Value.Check(CatalogStateSchema, state)) return corruptCatalog()
17
+ if (state.revision !== changes.expectedRevision) return staleCatalog()
18
+
19
+ for (const path of changes.deletes) statements.remove.run(path)
20
+ for (const entry of changes.upserts) writeCatalogEntry(statements, entry)
21
+ for (const update of changes.statUpdates) {
22
+ const result = statements.stat.run(update.stat.size, update.stat.mtimeMs, update.path)
23
+ if (result.changes !== 1) return invalidCatalog("stat updates require an existing path")
24
+ }
25
+ statements.prune.run()
26
+ statements.advance.run(changes.population)
27
+ return { succeeded: true }
28
+ }
29
+
30
+ function validChanges(changes: CatalogChanges): boolean {
31
+ const shape = {
32
+ expectedRevision: changes.expectedRevision,
33
+ upserts: changes.upserts,
34
+ deletes: changes.deletes,
35
+ statUpdates: changes.statUpdates,
36
+ population: changes.population,
37
+ }
38
+ if (!Value.Check(CatalogChangesSchema, shape)) return false
39
+ const paths = [
40
+ ...changes.deletes,
41
+ ...changes.upserts.map((entry) => entry.path),
42
+ ...changes.statUpdates.map((update) => update.path),
43
+ ]
44
+ return (
45
+ new Set(paths).size === paths.length &&
46
+ changes.upserts.every(validCatalogEntry) &&
47
+ changes.statUpdates.every((update) => Number.isFinite(update.stat.mtimeMs))
48
+ )
49
+ }
50
+
51
+ export function writeCatalogEntry(statements: ReturnType<typeof prepareCatalogStatements>, entry: CatalogEntry): void {
52
+ const row = emptyNoteRow(entry)
53
+ if (entry.note) {
54
+ row.id = entry.note.id
55
+ row.type = entry.note.type
56
+ row.statement = entry.note.statement
57
+ row.body = entry.note.body
58
+ row.dont_forget = 0
59
+ row.archived = 0
60
+ if (entry.note.dontForget) row.dont_forget = 1
61
+ if (entry.note.archived) row.archived = 1
62
+ }
63
+ statements.put.run({ ...row })
64
+ }
65
+
66
+ function emptyNoteRow(entry: CatalogEntry): CatalogWriteRow {
67
+ const row: CatalogWriteRow = {
68
+ path: entry.path,
69
+ folder: catalogFolder(entry.path),
70
+ id: null,
71
+ type: null,
72
+ statement: null,
73
+ body: null,
74
+ dont_forget: null,
75
+ archived: null,
76
+ size: entry.stat.size,
77
+ modified_ms: entry.stat.mtimeMs,
78
+ hash: entry.rawHash,
79
+ content_fingerprint: entry.contentFingerprint,
80
+ validation_fingerprint: entry.validationFingerprint,
81
+ needs_fixing: 0,
82
+ }
83
+ if (entry.needsFixing) row.needs_fixing = 1
84
+ return row
85
+ }
86
+
87
+ export function invalidCatalog(problem: string): IndexWriteResult {
88
+ return { succeeded: false, reason: "invalid", problems: [problem] }
89
+ }
90
+
91
+ export function staleCatalog(): SearchIndexRefusal {
92
+ return { succeeded: false, reason: "conflict", problems: ["the catalog changed since its inventory was read"] }
93
+ }
@@ -0,0 +1,56 @@
1
+ import { randomUUID } from "node:crypto"
2
+ import { renameSync, rmSync } from "node:fs"
3
+
4
+ import { openIndex } from "./open.ts"
5
+ import { indexFailure } from "./refusals.ts"
6
+ import type { IndexLocation, IndexReplacement, OpenedIndex, OpenIndexResult } from "./types.ts"
7
+
8
+ export function recoverIndex(location: IndexLocation): OpenIndexResult {
9
+ const opened = inspectExistingIndex(location)
10
+ if (opened.succeeded || opened.reason !== "corrupted") return opened
11
+
12
+ const temporaryPath = `${location.path}.rebuild-${randomUUID()}`
13
+ const replacement = installReplacement({ path: location.path, temporaryPath })
14
+ if (replacement.succeeded) return replacement
15
+
16
+ try {
17
+ rmSync(temporaryPath, { force: true })
18
+ } catch (error) {
19
+ if (!(error instanceof Error)) throw error
20
+ replacement.problems.push(`temporary index cleanup failed: ${error.message}`)
21
+ }
22
+ return replacement
23
+ }
24
+
25
+ function inspectExistingIndex(location: IndexLocation): OpenIndexResult {
26
+ const opened = openIndex(location.path)
27
+ if (!opened.succeeded) return opened
28
+ return validateOpenedIndex(opened)
29
+ }
30
+
31
+ function validateOpenedIndex(opened: OpenedIndex): OpenIndexResult {
32
+ const inventory = opened.output.inventory()
33
+ const vectors = opened.output.vectors()
34
+ if (inventory.succeeded && vectors.succeeded) return opened
35
+ const closed = opened.output.close()
36
+ if (!closed.succeeded) return closed
37
+ if (!inventory.succeeded) return inventory
38
+ if (!vectors.succeeded) return vectors
39
+ return opened
40
+ }
41
+
42
+ function installReplacement(request: IndexReplacement): OpenIndexResult {
43
+ try {
44
+ const temporary = openIndex(request.temporaryPath)
45
+ if (!temporary.succeeded) return temporary
46
+ const closed = temporary.output.close()
47
+ if (!closed.succeeded) return closed
48
+ renameSync(request.temporaryPath, request.path)
49
+ const opened = openIndex(request.path)
50
+ if (!opened.succeeded) return opened
51
+ return { ...opened, rebuilt: true }
52
+ } catch (error) {
53
+ if (!(error instanceof Error)) throw error
54
+ return indexFailure(error)
55
+ }
56
+ }
@@ -0,0 +1,21 @@
1
+ import { SQLITE_CORRUPT, SQLITE_ERROR, SQLITE_NOTADB, SQLITE_PRIMARY_CODE_MASK } from "./constants.ts"
2
+ import type { SearchIndexRefusal } from "./types.ts"
3
+
4
+ export function indexFailure(error: Error): SearchIndexRefusal {
5
+ if ("errcode" in error && typeof error.errcode === "number") {
6
+ const primaryCode = error.errcode & SQLITE_PRIMARY_CODE_MASK
7
+ if (primaryCode === SQLITE_ERROR || primaryCode === SQLITE_CORRUPT || primaryCode === SQLITE_NOTADB) {
8
+ return { succeeded: false, reason: "corrupted", problems: [error.message] }
9
+ }
10
+ }
11
+
12
+ return { succeeded: false, reason: "unavailable", problems: [error.message] }
13
+ }
14
+
15
+ export function closedIndex(): SearchIndexRefusal {
16
+ return {
17
+ succeeded: false,
18
+ reason: "closed",
19
+ problems: ["the search index is closed or unusable; open a new connection"],
20
+ }
21
+ }