pi-obsidian-memory 0.0.0 → 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 +45 -7
  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 -6
@@ -0,0 +1,101 @@
1
+ import type {
2
+ CutoffReport,
3
+ CutoffValue,
4
+ DecisionReport,
5
+ DiagnosedMemory,
6
+ EmbeddingReport,
7
+ ModelReport,
8
+ VaultReport,
9
+ VaultReportFailure,
10
+ } from "#src/usecases"
11
+ import {
12
+ BLANK_HEADING,
13
+ COULD_NOT_CHECK,
14
+ CUTOFF_SOURCES,
15
+ CUTOFFS_HINT,
16
+ DOCTOR_INVALID_HEADING,
17
+ DOCTOR_NO_PROJECT_VAULT,
18
+ DOCTOR_TITLE,
19
+ DUPLICATES_HEADING,
20
+ MODELS_HEADING,
21
+ NO_PROBLEMS,
22
+ TEMPORARIES_HEADING,
23
+ UNREADABLE_HEADING,
24
+ } from "./constants.ts"
25
+
26
+ export function renderDoctorReport(diagnosed: DiagnosedMemory): string {
27
+ const sections = diagnosed.vaults.map((report) => renderVault(report, diagnosed.maxNotesPerFolder))
28
+ const lines = [DOCTOR_TITLE, "", ...sections.flatMap((section) => [...section, ""])]
29
+ if (diagnosed.projectMissing) lines.push(DOCTOR_NO_PROJECT_VAULT, "")
30
+ lines.push(MODELS_HEADING, ...diagnosed.models.map(renderModel), renderEmbeddings(diagnosed.embeddings))
31
+ lines.push(renderDecision(diagnosed.decision), renderCutoffs(diagnosed.cutoffs))
32
+ return lines.join("\n")
33
+ }
34
+
35
+ function renderVault(report: VaultReport | VaultReportFailure, limit: number): string[] {
36
+ const title = vaultTitle(report.vault)
37
+ if ("problems" in report) return [`${title}: ${COULD_NOT_CHECK}`, ...report.problems.map((problem) => `- ${problem}`)]
38
+ const { diagnosis } = report
39
+ const groups: string[][] = []
40
+ addGroup(
41
+ groups,
42
+ DOCTOR_INVALID_HEADING,
43
+ diagnosis.invalid.map((note) => `${note.path}: ${note.problems.join("; ")}`),
44
+ )
45
+ addGroup(
46
+ groups,
47
+ DUPLICATES_HEADING,
48
+ diagnosis.duplicateIds.map((copy) => `${copy.id}: ${copy.paths.join(", ")}`),
49
+ )
50
+ addGroup(groups, BLANK_HEADING, diagnosis.blank)
51
+ addGroup(groups, TEMPORARIES_HEADING, diagnosis.temporaries)
52
+ addGroup(
53
+ groups,
54
+ `Folders above ${limit} notes (consider splitting them):`,
55
+ diagnosis.crowdedFolders.map((folder) => `${folder.folder}: ${folder.count} notes`),
56
+ )
57
+ addGroup(groups, UNREADABLE_HEADING, report.unreadable)
58
+ if (groups.length === 0) return [`${title}: ${NO_PROBLEMS}`]
59
+ return [`${title}:`, ...groups.flat()]
60
+ }
61
+
62
+ function addGroup(groups: string[][], heading: string, items: string[]): void {
63
+ if (items.length === 0) return
64
+ groups.push([heading, ...items.map((item) => `- ${item}`)])
65
+ }
66
+
67
+ function vaultTitle(scope: string): string {
68
+ if (scope === "global") return "Global vault"
69
+ return "Project vault"
70
+ }
71
+
72
+ function renderEmbeddings(report: EmbeddingReport): string {
73
+ const name = `embeddings ${report.provider}/${report.model}`
74
+ if (report.status === "ready") return `- ${name}: ready`
75
+ return `- ${name}: ${report.problem}`
76
+ }
77
+
78
+ function renderDecision(report: DecisionReport): string {
79
+ const name = `decision model ${report.provider}/${report.model}`
80
+ if ("problem" in report) return `- ${name}: ${report.problem}`
81
+ return `- ${name}: ready (${report.detail})`
82
+ }
83
+
84
+ function cutoffText(name: string, value: CutoffValue): string {
85
+ const source = CUTOFF_SOURCES.get(value.source)
86
+ if (typeof value.value !== "number") return `${name} ${source}`
87
+ return `${name} ${value.value} (${source})`
88
+ }
89
+
90
+ function renderCutoffs(cutoffs: CutoffReport): string {
91
+ const line = `- decision cutoffs: ${cutoffText("gate", cutoffs.gate)}, ${cutoffText("relevance", cutoffs.relevance)}`
92
+ if (cutoffs.gate.source === "missing" || cutoffs.relevance.source === "missing") return `${line}; ${CUTOFFS_HINT}`
93
+ return line
94
+ }
95
+
96
+ function renderModel(report: ModelReport): string {
97
+ const { check } = report
98
+ const name = `${report.role} ${check.model.provider}/${check.model.id}`
99
+ if (check.status === "ok") return `- ${name}: ok`
100
+ return `- ${name}: ${check.problem}`
101
+ }
@@ -0,0 +1,13 @@
1
+ import type { ChatModelSource, ModelAuthResult } from "#src/pi/context"
2
+ import type { BlankFile, VaultReport } from "#src/usecases"
3
+
4
+ export interface BlankTarget {
5
+ vault: VaultReport["vault"]
6
+ blank: BlankFile
7
+ }
8
+
9
+ export interface DoctorModelPort {
10
+ find(provider: string, id: string): ChatModelSource | undefined
11
+ configured(model: ChatModelSource): boolean
12
+ auth(model: ChatModelSource): Promise<ModelAuthResult>
13
+ }
@@ -0,0 +1,15 @@
1
+ export const MEMORY_EXPORT_COMMAND = "memory-export"
2
+
3
+ export const MEMORY_EXPORT_DESCRIPTION = "Export the global and project memory as one .zip file"
4
+
5
+ export const EXPORT_FOLDER_TITLE = "Save the export in which folder? (empty: the working folder)"
6
+
7
+ export const EXPORT_NAME_TITLE = "File name (empty: the suggested one)"
8
+
9
+ export const EXPORT_CANCELLED = "Export cancelled: nothing was written."
10
+
11
+ export const EXPORT_DONE = "Exported"
12
+
13
+ export const EXPORT_SETUP_HINT = "Run /memory-setup first."
14
+
15
+ export const EXPORT_NAME_TAKEN = "already exists and was kept; choose another name."
@@ -0,0 +1,4 @@
1
+ export * from "./constants.ts"
2
+ export * from "./memory-export.ts"
3
+ export * from "./name.ts"
4
+ export * from "./types.ts"
@@ -0,0 +1,57 @@
1
+ import type { MemoryCommand, MemoryPaths, MemoryPiContext } from "#src/pi/context"
2
+ import type { MemorySessionKeeper } from "#src/pi/memory-session"
3
+ import { hostPathPlatform } from "#src/pi/paths"
4
+ import { type ExportedMemory, exportMemory, type MemoryOperationContext } from "#src/usecases"
5
+ import {
6
+ EXPORT_CANCELLED,
7
+ EXPORT_DONE,
8
+ EXPORT_FOLDER_TITLE,
9
+ EXPORT_NAME_TAKEN,
10
+ EXPORT_NAME_TITLE,
11
+ EXPORT_SETUP_HINT,
12
+ MEMORY_EXPORT_DESCRIPTION,
13
+ } from "./constants.ts"
14
+ import { defaultExportName } from "./name.ts"
15
+ import type { ExportFailure } from "./types.ts"
16
+
17
+ export function memoryExportCommand(paths: MemoryPaths, sessions: MemorySessionKeeper): MemoryCommand {
18
+ return {
19
+ description: MEMORY_EXPORT_DESCRIPTION,
20
+ async handler(_args, ctx) {
21
+ if (!ctx.hasUI) return
22
+ const { registration } = sessions.registrationFlow(ctx, paths)
23
+ await runMemoryExport(ctx, registration)
24
+ },
25
+ }
26
+ }
27
+
28
+ async function runMemoryExport(ctx: MemoryPiContext, context: MemoryOperationContext): Promise<void> {
29
+ const folder = await askOrDefault(ctx, EXPORT_FOLDER_TITLE, ctx.cwd)
30
+ if (typeof folder !== "string") return ctx.ui.notify(EXPORT_CANCELLED, "info")
31
+ const suggested = defaultExportName(new Date())
32
+ for (;;) {
33
+ const fileName = await askOrDefault(ctx, EXPORT_NAME_TITLE, suggested)
34
+ if (typeof fileName !== "string") return ctx.ui.notify(EXPORT_CANCELLED, "info")
35
+ const result = await exportMemory({ folder, fileName, platform: hostPathPlatform(process.platform) }, context)
36
+ if (result.succeeded) return ctx.ui.notify(describeExported(result.output), "info")
37
+ if (result.reason !== "exists") return ctx.ui.notify(describeRefusal(result), "error")
38
+ ctx.ui.notify(`${fileName} ${EXPORT_NAME_TAKEN}`, "error")
39
+ }
40
+ }
41
+
42
+ async function askOrDefault(ctx: MemoryPiContext, title: string, fallback: string): Promise<string | null> {
43
+ const answer = await ctx.ui.input(title, fallback)
44
+ if (typeof answer !== "string") return null
45
+ if (answer.trim() === "") return fallback
46
+ return answer.trim()
47
+ }
48
+
49
+ function describeRefusal(result: ExportFailure): string {
50
+ const lines = [...result.problems]
51
+ if (result.reason === "not-configured" || result.reason === "invalid-config") lines.push(EXPORT_SETUP_HINT)
52
+ return lines.join("\n")
53
+ }
54
+
55
+ function describeExported(output: ExportedMemory): string {
56
+ return `${EXPORT_DONE} ${output.files} files from ${output.vaults.join(" and ")} to ${output.path}`
57
+ }
@@ -0,0 +1,9 @@
1
+ export function defaultExportName(now: Date): string {
2
+ const date = [now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate())].join("-")
3
+ const time = [pad(now.getHours()), pad(now.getMinutes()), pad(now.getSeconds())].join("")
4
+ return `memory-export-${date}-${time}.zip`
5
+ }
6
+
7
+ function pad(value: number): string {
8
+ return String(value).padStart(2, "0")
9
+ }
@@ -0,0 +1,4 @@
1
+ import type { Done } from "#src/shared"
2
+ import type { ExportMemoryResult } from "#src/usecases"
3
+
4
+ export type ExportFailure = Exclude<ExportMemoryResult, Done>
@@ -0,0 +1,12 @@
1
+ export const MEMORY_GET_TOOL_NAME = "memory_get"
2
+
3
+ export const MEMORY_GET_TOOL_LABEL = "Memory get"
4
+
5
+ export const MEMORY_GET_TOOL_DESCRIPTION =
6
+ 'Read a note in full, or a folder\'s index (path "" = root); archive/ paths can be read.'
7
+
8
+ export const GET_FIELD_SEPARATOR = " · "
9
+
10
+ export const GET_NEEDS_FIXING_HEADING = "Needs fixing:"
11
+
12
+ export const UNCLOSED_NOTICE = "This file cannot be read as a note: it has no closed frontmatter block."
@@ -0,0 +1,5 @@
1
+ export * from "./constants.ts"
2
+ export * from "./memory-get.ts"
3
+ export * from "./respond.ts"
4
+ export * from "./schemas.ts"
5
+ export * from "./types.ts"
@@ -0,0 +1,23 @@
1
+ import type { MemoryPaths } from "#src/pi/context"
2
+ import { type MemorySessionKeeper, noSessionResponse } from "#src/pi/memory-session"
3
+ import { getMemory } from "#src/usecases"
4
+ import { MEMORY_GET_TOOL_DESCRIPTION, MEMORY_GET_TOOL_LABEL, MEMORY_GET_TOOL_NAME } from "./constants.ts"
5
+ import { respondToGet } from "./respond.ts"
6
+ import { MemoryGetParamsSchema } from "./schemas.ts"
7
+ import type { MemoryGetTool } from "./types.ts"
8
+
9
+ export function memoryGetTool(paths: MemoryPaths, sessions: MemorySessionKeeper): MemoryGetTool {
10
+ return {
11
+ name: MEMORY_GET_TOOL_NAME,
12
+ label: MEMORY_GET_TOOL_LABEL,
13
+ description: MEMORY_GET_TOOL_DESCRIPTION,
14
+ parameters: MemoryGetParamsSchema,
15
+ async execute(toolCallId, params, signal, _onUpdate, ctx) {
16
+ const request = { vault: params.vault, path: params.path }
17
+ const read = { ...request, sourceCallId: toolCallId }
18
+ const result = await sessions.readFresh(ctx.cwd, paths, signal, (context) => getMemory(read, context))
19
+ if (!result) return noSessionResponse()
20
+ return respondToGet(request, result)
21
+ },
22
+ }
23
+ }
@@ -0,0 +1,38 @@
1
+ import { SETUP_GUIDANCE } from "#src/pi/memory-add"
2
+ import type { GetMemoryRequest, GetMemoryResult } from "#src/usecases"
3
+ import { GET_FIELD_SEPARATOR, GET_NEEDS_FIXING_HEADING, UNCLOSED_NOTICE } from "./constants.ts"
4
+ import type { MemoryGetResponse } from "./types.ts"
5
+
6
+ export function respondToGet(
7
+ request: Pick<GetMemoryRequest, "vault" | "path">,
8
+ result: GetMemoryResult,
9
+ ): MemoryGetResponse {
10
+ if (result.succeeded) {
11
+ if (result.output.kind === "folder") return reply([result.output.text], false)
12
+ const { file } = result.output
13
+ const problems = [
14
+ ...file.analysis.frontmatterProblems,
15
+ ...file.analysis.nameProblems,
16
+ ...file.analysis.bodyProblems,
17
+ ]
18
+ const lines = [[request.vault, request.path].join(GET_FIELD_SEPARATOR), file.text]
19
+ if (problems.length > 0) lines.push(GET_NEEDS_FIXING_HEADING, ...problems.map((problem) => `- ${problem}`))
20
+ return reply(lines, false)
21
+ }
22
+ switch (result.reason) {
23
+ case "unclosed-frontmatter":
24
+ return reply(
25
+ [UNCLOSED_NOTICE, GET_NEEDS_FIXING_HEADING, ...result.problems.map((problem) => `- ${problem}`)],
26
+ true,
27
+ )
28
+ case "not-configured":
29
+ case "invalid-config":
30
+ return reply([...result.problems, SETUP_GUIDANCE], true)
31
+ default:
32
+ return reply(result.problems, true)
33
+ }
34
+ }
35
+
36
+ function reply(lines: string[], isError: boolean): MemoryGetResponse {
37
+ return { content: [{ type: "text", text: lines.join("\n") }], details: undefined, isError }
38
+ }
@@ -0,0 +1,13 @@
1
+ import Type from "typebox"
2
+
3
+ export const MemoryGetParamsSchema = Type.Object(
4
+ {
5
+ vault: Type.Union([Type.Literal("global"), Type.Literal("project")], {
6
+ description: "global: about the user. project: about this project.",
7
+ }),
8
+ path: Type.String({
9
+ description: 'Path inside the vault, as memory_search shows it: a note, a folder, or "" for the vault root.',
10
+ }),
11
+ },
12
+ { additionalProperties: false },
13
+ )
@@ -0,0 +1,10 @@
1
+ import type { AgentToolResult, ToolDefinition } from "@earendil-works/pi-coding-agent"
2
+ import type { Static } from "typebox"
3
+
4
+ import type { MemoryGetParamsSchema } from "./schemas.ts"
5
+
6
+ export type MemoryGetParams = Static<typeof MemoryGetParamsSchema>
7
+
8
+ export type MemoryGetTool = ToolDefinition<typeof MemoryGetParamsSchema, undefined>
9
+
10
+ export type MemoryGetResponse = AgentToolResult<undefined>
@@ -0,0 +1,17 @@
1
+ export const MEMORY_INIT_COMMAND = "memory-init"
2
+
3
+ export const MEMORY_INIT_DESCRIPTION = "Register this folder as a project with its own memory vault"
4
+
5
+ export const INIT_NAME_TITLE = "Project name (empty keeps the suggested one)"
6
+
7
+ export const INIT_VAULT_TITLE = "Project vault folder (absolute path; created if missing)"
8
+
9
+ export const INIT_REPOINT_VAULT_TITLE = "New vault folder for this project (absolute path; created if missing)"
10
+
11
+ export const INIT_VAULT_PLACEHOLDER = "Absolute folder path"
12
+
13
+ export const INIT_SETUP_HINT = "Run /memory-setup first."
14
+
15
+ export const INIT_CANCELLED = "Init cancelled: nothing changed."
16
+
17
+ export const INIT_DONE = "Project registered:"
@@ -0,0 +1,2 @@
1
+ export * from "./constants.ts"
2
+ export * from "./memory-init.ts"
@@ -0,0 +1,63 @@
1
+ import type { MemoryCommand, MemoryPaths, MemoryPiContext } from "#src/pi/context"
2
+ import type { MemorySessionKeeper } from "#src/pi/memory-session"
3
+ import { describeRegistered, describeRegistrationFailure } from "#src/pi/registration-report"
4
+ import {
5
+ checkProjectName,
6
+ type InitPreparation,
7
+ initProjectMemory,
8
+ prepareProjectInit,
9
+ type RegistrationContext,
10
+ } from "#src/usecases"
11
+ import {
12
+ INIT_CANCELLED,
13
+ INIT_DONE,
14
+ INIT_NAME_TITLE,
15
+ INIT_REPOINT_VAULT_TITLE,
16
+ INIT_SETUP_HINT,
17
+ INIT_VAULT_PLACEHOLDER,
18
+ INIT_VAULT_TITLE,
19
+ MEMORY_INIT_DESCRIPTION,
20
+ } from "./constants.ts"
21
+
22
+ export function memoryInitCommand(paths: MemoryPaths, sessions: MemorySessionKeeper): MemoryCommand {
23
+ return {
24
+ description: MEMORY_INIT_DESCRIPTION,
25
+ async handler(_args, ctx) {
26
+ if (!ctx.hasUI) return
27
+ const { registration } = sessions.registrationFlow(ctx, paths)
28
+ await runMemoryInit(ctx, registration)
29
+ },
30
+ }
31
+ }
32
+
33
+ async function runMemoryInit(ctx: MemoryPiContext, registration: RegistrationContext): Promise<void> {
34
+ const preparation = await prepareProjectInit(registration)
35
+ if (!preparation.succeeded) {
36
+ const lines = [...preparation.problems]
37
+ if (preparation.reason !== "unreadable") lines.push(INIT_SETUP_HINT)
38
+ return ctx.ui.notify(lines.join("\n"), "error")
39
+ }
40
+ const name = await askName(ctx, preparation.output)
41
+ if (typeof name !== "string") return ctx.ui.notify(INIT_CANCELLED, "info")
42
+ const vault = await askVault(ctx, preparation.output)
43
+ if (typeof vault !== "string") return ctx.ui.notify(INIT_CANCELLED, "info")
44
+ const result = await initProjectMemory({ name, vault, expectedHash: preparation.output.expectedHash }, registration)
45
+ if (!result.succeeded) return ctx.ui.notify(describeRegistrationFailure(result), "error")
46
+ ctx.ui.notify(describeRegistered(`${INIT_DONE} ${name}`, result.output), "info")
47
+ }
48
+
49
+ async function askName(ctx: MemoryPiContext, preparation: InitPreparation): Promise<string | null> {
50
+ if (preparation.existing) return preparation.existing.name
51
+ for (;;) {
52
+ const answer = await ctx.ui.input(INIT_NAME_TITLE, preparation.defaultName)
53
+ if (typeof answer !== "string") return null
54
+ const checked = checkProjectName(preparation, answer)
55
+ if (checked.succeeded) return checked.output
56
+ ctx.ui.notify(checked.problems.join("\n"), "error")
57
+ }
58
+ }
59
+
60
+ function askVault(ctx: MemoryPiContext, preparation: InitPreparation): Promise<string | undefined> {
61
+ if (preparation.existing) return ctx.ui.input(INIT_REPOINT_VAULT_TITLE, INIT_VAULT_PLACEHOLDER)
62
+ return ctx.ui.input(INIT_VAULT_TITLE, INIT_VAULT_PLACEHOLDER)
63
+ }
@@ -0,0 +1,16 @@
1
+ export const MEMORY_SEARCH_TOOL_NAME = "memory_search"
2
+
3
+ export const MEMORY_SEARCH_TOOL_LABEL = "Memory search"
4
+
5
+ export const MEMORY_SEARCH_TOOL_DESCRIPTION =
6
+ "Search long-term memory by words. Archived notes and notes without valid frontmatter are not searched."
7
+
8
+ export const NO_PROJECT_VAULT = "No project vault is registered for this folder."
9
+
10
+ export const READ_HINT = 'Try other words or walk folders with memory_get (path "" is the vault root).'
11
+
12
+ export const SEARCH_FIELD_SEPARATOR = " · "
13
+
14
+ export const DONT_FORGET_MARK = "don't forget"
15
+
16
+ export const NEEDS_FIXING_MARK = "needs fixing"
@@ -0,0 +1,5 @@
1
+ export * from "./constants.ts"
2
+ export * from "./memory-search.ts"
3
+ export * from "./respond.ts"
4
+ export * from "./schemas.ts"
5
+ export * from "./types.ts"
@@ -0,0 +1,22 @@
1
+ import type { MemoryPaths } from "#src/pi/context"
2
+ import { type MemorySessionKeeper, noSessionResponse } from "#src/pi/memory-session"
3
+ import { searchMemory } from "#src/usecases"
4
+ import { MEMORY_SEARCH_TOOL_DESCRIPTION, MEMORY_SEARCH_TOOL_LABEL, MEMORY_SEARCH_TOOL_NAME } from "./constants.ts"
5
+ import { respondToSearch } from "./respond.ts"
6
+ import { MemorySearchParamsSchema } from "./schemas.ts"
7
+ import type { MemorySearchTool } from "./types.ts"
8
+
9
+ export function memorySearchTool(paths: MemoryPaths, sessions: MemorySessionKeeper): MemorySearchTool {
10
+ return {
11
+ name: MEMORY_SEARCH_TOOL_NAME,
12
+ label: MEMORY_SEARCH_TOOL_LABEL,
13
+ description: MEMORY_SEARCH_TOOL_DESCRIPTION,
14
+ parameters: MemorySearchParamsSchema,
15
+ async execute(_toolCallId, params, signal, _onUpdate, ctx) {
16
+ const request = { query: params.query, vault: params.vault }
17
+ const result = await sessions.readFresh(ctx.cwd, paths, signal, (context) => searchMemory(request, context))
18
+ if (!result) return noSessionResponse()
19
+ return respondToSearch(result)
20
+ },
21
+ }
22
+ }
@@ -0,0 +1,62 @@
1
+ import { SETUP_GUIDANCE } from "#src/pi/memory-add"
2
+ import type { SearchedMemory, SearchMemoryResult, VaultSearchFailure, VaultSearchHits } from "#src/usecases"
3
+ import {
4
+ DONT_FORGET_MARK,
5
+ NEEDS_FIXING_MARK,
6
+ NO_PROJECT_VAULT,
7
+ READ_HINT,
8
+ SEARCH_FIELD_SEPARATOR,
9
+ } from "./constants.ts"
10
+ import type { MemorySearchResponse } from "./types.ts"
11
+
12
+ export function respondToSearch(result: SearchMemoryResult): MemorySearchResponse {
13
+ if (result.succeeded) return describeSearched(result.output)
14
+ switch (result.reason) {
15
+ case "not-configured":
16
+ case "invalid-config":
17
+ return reply([...result.problems, SETUP_GUIDANCE], true)
18
+ default:
19
+ return reply(result.problems, true)
20
+ }
21
+ }
22
+
23
+ function describeSearched(searched: SearchedMemory): MemorySearchResponse {
24
+ const lines: string[] = []
25
+ const failures = searched.vaults.filter(isFailure)
26
+ const answered = searched.vaults.filter(isHits)
27
+ for (const entry of answered) {
28
+ for (const hit of entry.hits) lines.push(describeHit(entry.vault, hit))
29
+ }
30
+ if (answered.length > 0 && lines.length === 0) {
31
+ const names = answered.map((entry) => entry.vault).join(", ")
32
+ lines.push(`No notes found in ${names}. ${READ_HINT}`)
33
+ }
34
+ for (const entry of failures) {
35
+ for (const problem of entry.problems) lines.push(`Could not search ${entry.vault}: ${problem}`)
36
+ }
37
+ for (const entry of answered) {
38
+ for (const warning of entry.warnings) lines.push(`Warning: ${warning}`)
39
+ }
40
+ lines.push(...searched.semantic.problems)
41
+ if (searched.projectMissing) lines.push(NO_PROJECT_VAULT)
42
+ return reply(lines, answered.length === 0)
43
+ }
44
+
45
+ function describeHit(vault: string, hit: VaultSearchHits["hits"][number]): string {
46
+ const fields = [vault, hit.path, hit.type]
47
+ if (hit.dontForget) fields.push(DONT_FORGET_MARK)
48
+ if (hit.needsFixing) fields.push(NEEDS_FIXING_MARK)
49
+ return fields.join(SEARCH_FIELD_SEPARATOR)
50
+ }
51
+
52
+ function isFailure(entry: VaultSearchHits | VaultSearchFailure): entry is VaultSearchFailure {
53
+ return "problems" in entry
54
+ }
55
+
56
+ function isHits(entry: VaultSearchHits | VaultSearchFailure): entry is VaultSearchHits {
57
+ return "hits" in entry
58
+ }
59
+
60
+ function reply(lines: string[], isError: boolean): MemorySearchResponse {
61
+ return { content: [{ type: "text", text: lines.join("\n") }], details: undefined, isError }
62
+ }
@@ -0,0 +1,11 @@
1
+ import Type from "typebox"
2
+
3
+ export const MemorySearchParamsSchema = Type.Object(
4
+ {
5
+ query: Type.String({ minLength: 1, description: "Words to look for, in English." }),
6
+ vault: Type.Union([Type.Literal("global"), Type.Literal("project"), Type.Literal("both")], {
7
+ description: "global: about the user. project: about this project. both: search the two, each on its own.",
8
+ }),
9
+ },
10
+ { additionalProperties: false },
11
+ )
@@ -0,0 +1,10 @@
1
+ import type { AgentToolResult, ToolDefinition } from "@earendil-works/pi-coding-agent"
2
+ import type { Static } from "typebox"
3
+
4
+ import type { MemorySearchParamsSchema } from "./schemas.ts"
5
+
6
+ export type MemorySearchParams = Static<typeof MemorySearchParamsSchema>
7
+
8
+ export type MemorySearchTool = ToolDefinition<typeof MemorySearchParamsSchema, undefined>
9
+
10
+ export type MemorySearchResponse = AgentToolResult<undefined>
@@ -0,0 +1,7 @@
1
+ export const NO_SESSION_NOTICE = "Memory is not ready in this session; try again after the session has started."
2
+
3
+ export const STALE_SESSION_REASON = "stale-session"
4
+
5
+ export const CAPTURE_BRANCH = "capture"
6
+
7
+ export const RETRIEVAL_BRANCH = "retrieval"
@@ -0,0 +1,4 @@
1
+ export * from "./constants.ts"
2
+ export * from "./keeper.ts"
3
+ export * from "./respond.ts"
4
+ export * from "./types.ts"
@@ -0,0 +1,101 @@
1
+ import type { MemoryPaths, MemoryPiContext } from "#src/pi/context"
2
+ import { hostPathPlatform } from "#src/pi/paths"
3
+ import type { SemanticRuntime } from "#src/pi/semantic"
4
+ import { createMemorySession, LoadedMemory, type MemoryOperationContext, type MemorySession } from "#src/usecases"
5
+ import { CAPTURE_BRANCH, RETRIEVAL_BRANCH, STALE_SESSION_REASON } from "./constants.ts"
6
+ import type { ReadOutcome, ReadRun, RegistrationFlow } from "./types.ts"
7
+
8
+ export class MemorySessionKeeper {
9
+ #session: MemorySession | null = null
10
+ #semantic: SemanticRuntime | null = null
11
+ #loaded = new LoadedMemory()
12
+
13
+ constructor(semantic?: SemanticRuntime) {
14
+ if (semantic) this.#semantic = semantic
15
+ }
16
+
17
+ start(ctx: MemoryPiContext): MemorySession {
18
+ if (this.#session) this.#session.abortPending()
19
+ const session = createMemorySession({ sessionId: ctx.sessionManager.getSessionId(), branchId: null })
20
+ if (this.#semantic) this.#semantic.attach(ctx)
21
+ this.#session = session
22
+ this.#loaded = new LoadedMemory()
23
+ return session
24
+ }
25
+
26
+ shutdown(): void {
27
+ if (this.#session) this.#session.abortPending()
28
+ this.#session = null
29
+ }
30
+
31
+ operationContext(
32
+ session: MemorySession,
33
+ workingFolder: string,
34
+ paths: MemoryPaths,
35
+ callerSignal: AbortSignal | undefined,
36
+ ): MemoryOperationContext {
37
+ const stamp = session.stamp()
38
+ let signal = session.signal(stamp)
39
+ if (callerSignal) signal = AbortSignal.any([signal, callerSignal])
40
+ const context: MemoryOperationContext = {
41
+ configPath: paths.configPath,
42
+ indexPath: paths.indexPath,
43
+ workingFolder,
44
+ platform: hostPathPlatform(process.platform),
45
+ session,
46
+ stamp,
47
+ signal,
48
+ }
49
+ if (this.#semantic) context.semantic = this.#semantic.source
50
+ return context
51
+ }
52
+
53
+ currentOperation(
54
+ workingFolder: string,
55
+ paths: MemoryPaths,
56
+ callerSignal: AbortSignal | undefined,
57
+ ): MemoryOperationContext | null {
58
+ if (!this.#session) return null
59
+ return this.operationContext(this.#session, workingFolder, paths, callerSignal)
60
+ }
61
+
62
+ loaded(): LoadedMemory {
63
+ return this.#loaded
64
+ }
65
+
66
+ captureOperation(workingFolder: string, paths: MemoryPaths): MemoryOperationContext | null {
67
+ return this.#siblingOperation(CAPTURE_BRANCH, workingFolder, paths)
68
+ }
69
+
70
+ retrievalOperation(workingFolder: string, paths: MemoryPaths): MemoryOperationContext | null {
71
+ return this.#siblingOperation(RETRIEVAL_BRANCH, workingFolder, paths)
72
+ }
73
+
74
+ #siblingOperation(branchId: string, workingFolder: string, paths: MemoryPaths): MemoryOperationContext | null {
75
+ const main = this.#session
76
+ if (!main) return null
77
+ const sibling = main.sibling({ sessionId: main.stamp().sessionId, branchId })
78
+ return this.operationContext(sibling, workingFolder, paths, main.signal(main.stamp()))
79
+ }
80
+
81
+ async readFresh<Outcome extends ReadOutcome>(
82
+ workingFolder: string,
83
+ paths: MemoryPaths,
84
+ callerSignal: AbortSignal | undefined,
85
+ run: ReadRun<Outcome>,
86
+ ): Promise<Outcome | null> {
87
+ const first = this.currentOperation(workingFolder, paths, callerSignal)
88
+ if (!first) return null
89
+ const result = await run(first)
90
+ if (result.succeeded || result.reason !== STALE_SESSION_REASON) return result
91
+ const second = this.currentOperation(workingFolder, paths, callerSignal)
92
+ if (!second) return result
93
+ return run(second)
94
+ }
95
+
96
+ registrationFlow(ctx: MemoryPiContext, paths: MemoryPaths): RegistrationFlow {
97
+ let session = this.#session
98
+ if (!session) session = this.start(ctx)
99
+ return { session, registration: this.operationContext(session, ctx.cwd, paths, undefined) }
100
+ }
101
+ }