pi-obsidian-memory 0.0.1 → 0.1.1

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 +237 -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,54 @@
1
+ import type { DontForgetVault, LoadDontForgetResult, LoadedDontForgetNote } from "#src/usecases"
2
+ import {
3
+ BLOCK_FIELD_SEPARATOR,
4
+ BLOCK_INTRO,
5
+ BLOCK_NEEDS_FIXING_HEADING,
6
+ BLOCK_SEPARATOR,
7
+ DONT_FORGET_HEADING,
8
+ LOAD_ERROR_PREFIX,
9
+ LOAD_FAILURE_PREFIX,
10
+ LOAD_FAILURE_SUFFIX,
11
+ NO_DONT_FORGET,
12
+ NOTE_HEADING_PREFIX,
13
+ } from "./constants.ts"
14
+
15
+ export function renderMemoryBlock(result: LoadDontForgetResult): string | null {
16
+ if (!result.succeeded) {
17
+ if (result.reason === "not-configured") return null
18
+ return renderLoadFailure(result.problems.join("; "))
19
+ }
20
+ const notes = result.output.vaults.flatMap((vault) => vault.notes)
21
+ const parts = [BLOCK_INTRO]
22
+ if (notes.length === 0) parts.push(NO_DONT_FORGET)
23
+ else parts.push(DONT_FORGET_HEADING, ...notes.map(renderNote))
24
+ for (const vault of result.output.vaults) parts.push(...renderFailure(vault))
25
+ return parts.join(BLOCK_SEPARATOR)
26
+ }
27
+
28
+ function renderNote(note: LoadedDontForgetNote): string {
29
+ const heading = `${NOTE_HEADING_PREFIX}${[note.vault, note.path, note.type].join(BLOCK_FIELD_SEPARATOR)}`
30
+ const lines = [heading, note.body]
31
+ if (note.problems.length > 0)
32
+ lines.push(BLOCK_NEEDS_FIXING_HEADING, ...note.problems.map((problem) => `- ${problem}`))
33
+ return lines.join("\n")
34
+ }
35
+
36
+ function renderFailure(vault: DontForgetVault): string[] {
37
+ return vault.problems.map((problem) => `${LOAD_FAILURE_PREFIX} ${vault.vault} ${LOAD_FAILURE_SUFFIX} ${problem}`)
38
+ }
39
+
40
+ export function loadNotices(result: LoadDontForgetResult): string[] {
41
+ if (!result.succeeded) {
42
+ if (result.reason === "not-configured") return []
43
+ return [renderLoadNotice(result.problems.join("; "))]
44
+ }
45
+ return result.output.vaults.flatMap(renderFailure)
46
+ }
47
+
48
+ export function renderLoadNotice(message: string): string {
49
+ return `${LOAD_ERROR_PREFIX} ${message}`
50
+ }
51
+
52
+ export function renderLoadFailure(message: string): string {
53
+ return [BLOCK_INTRO, renderLoadNotice(message)].join(BLOCK_SEPARATOR)
54
+ }
@@ -0,0 +1,24 @@
1
+ import type { BeforeAgentStartEvent, BeforeAgentStartEventResult } from "@earendil-works/pi-coding-agent"
2
+
3
+ import type { MemoryPiContext } from "#src/pi/context"
4
+ import type { LoadDontForgetResult, LoadedMemory, MemoryOperationContext } from "#src/usecases"
5
+
6
+ export type BeforeAgentStartHandler = (
7
+ event: BeforeAgentStartEvent,
8
+ ctx: MemoryPiContext,
9
+ ) => Promise<BeforeAgentStartEventResult | undefined>
10
+
11
+ export type RelevantLoader = () => Promise<string | null>
12
+
13
+ export type BlockNotifier = (messages: string[]) => void
14
+
15
+ export interface BlockStart {
16
+ ctx: MemoryPiContext
17
+ context: MemoryOperationContext
18
+ configured: boolean
19
+ loaded: LoadedMemory
20
+ relevant: RelevantLoader
21
+ notify: BlockNotifier
22
+ }
23
+
24
+ export type DontForgetLoader = (context: MemoryOperationContext) => Promise<LoadDontForgetResult>
@@ -0,0 +1,43 @@
1
+ export const MEMORY_DOCTOR_COMMAND = "memory-doctor"
2
+
3
+ export const MEMORY_DOCTOR_DESCRIPTION = "Check the memory for problems and offer to complete blank notes"
4
+
5
+ export const DOCTOR_TITLE = "Memory doctor"
6
+
7
+ export const DOCTOR_SETUP_HINT = "Run /memory-setup to create or repair the config."
8
+
9
+ export const NO_PROBLEMS = "no problems found."
10
+
11
+ export const COULD_NOT_CHECK = "could not be checked."
12
+
13
+ export const DOCTOR_NO_PROJECT_VAULT = "No project vault is registered for this folder."
14
+
15
+ export const DOCTOR_INVALID_HEADING = "Invalid notes:"
16
+
17
+ export const DUPLICATES_HEADING = "Copied ids:"
18
+
19
+ export const BLANK_HEADING = "Blank notes (no frontmatter):"
20
+
21
+ export const TEMPORARIES_HEADING = "Leftover temporary files:"
22
+
23
+ export const UNREADABLE_HEADING = "Files that could not be read:"
24
+
25
+ export const CUTOFF_SOURCES = new Map<string, string>([
26
+ ["config", "config"],
27
+ ["typesafe", "TypeSafe starting value"],
28
+ ["missing", "missing"],
29
+ ])
30
+
31
+ export const CUTOFFS_HINT = "set both cutoffs in /memory-setup, see docs/decision-thresholds.md"
32
+
33
+ export const MODELS_HEADING = "Models:"
34
+
35
+ export const COMPLETE_TYPE_TITLE = "Complete this blank note: which type is it?"
36
+
37
+ export const COMPLETE_BODY_TITLE = "Body of the new note (written in English)"
38
+
39
+ export const COMPLETE_CONFIRM_MESSAGE = "A new id and dates are added and the file is rewritten as a note."
40
+
41
+ export const COMPLETED = "Completed"
42
+
43
+ export const COMPLETE_SKIPPED = "Left unchanged:"
@@ -0,0 +1,4 @@
1
+ export * from "./constants.ts"
2
+ export * from "./memory-doctor.ts"
3
+ export * from "./report.ts"
4
+ export * from "./types.ts"
@@ -0,0 +1,135 @@
1
+ import type { MemoryCommand, MemoryPaths, MemoryPiContext } from "#src/pi/context"
2
+ import type { MemorySessionKeeper } from "#src/pi/memory-session"
3
+ import {
4
+ BLANK_NOTE_TYPES,
5
+ type BlankFile,
6
+ completeBlankMemory,
7
+ type DecisionProbe,
8
+ type DiagnosedMemory,
9
+ diagnoseMemory,
10
+ type EmbeddingProbe,
11
+ type MemoryOperationContext,
12
+ type VaultReport,
13
+ } from "#src/usecases"
14
+ import {
15
+ COMPLETE_BODY_TITLE,
16
+ COMPLETE_CONFIRM_MESSAGE,
17
+ COMPLETE_SKIPPED,
18
+ COMPLETE_TYPE_TITLE,
19
+ COMPLETED,
20
+ DOCTOR_SETUP_HINT,
21
+ MEMORY_DOCTOR_DESCRIPTION,
22
+ } from "./constants.ts"
23
+ import { renderDoctorReport } from "./report.ts"
24
+ import type { BlankTarget, DoctorModelPort } from "./types.ts"
25
+
26
+ export function memoryDoctorCommand(
27
+ paths: MemoryPaths,
28
+ sessions: MemorySessionKeeper,
29
+ modelCachePath: string,
30
+ ): MemoryCommand {
31
+ return {
32
+ description: MEMORY_DOCTOR_DESCRIPTION,
33
+ async handler(_args, ctx) {
34
+ if (!ctx.hasUI) return
35
+ const { registration } = sessions.registrationFlow(ctx, paths)
36
+ await runMemoryDoctor(ctx, registration, modelCachePath)
37
+ },
38
+ }
39
+ }
40
+
41
+ async function runMemoryDoctor(
42
+ ctx: MemoryPiContext,
43
+ context: MemoryOperationContext,
44
+ modelCachePath: string,
45
+ ): Promise<void> {
46
+ const port: DoctorModelPort = {
47
+ find: (provider, id) => ctx.modelRegistry.find(provider, id),
48
+ configured: (model) => ctx.modelRegistry.hasConfiguredAuth(model),
49
+ auth: (model) => ctx.modelRegistry.getApiKeyAndHeaders(model),
50
+ }
51
+ const diagnosed = await diagnoseMemory(
52
+ { port, embeddings: embeddingProbeOf(ctx, modelCachePath), decision: decisionProbeOf(ctx) },
53
+ context,
54
+ )
55
+ if (!diagnosed.succeeded) {
56
+ return ctx.ui.notify([...diagnosed.problems, DOCTOR_SETUP_HINT].join("\n"), "error")
57
+ }
58
+ ctx.ui.notify(renderDoctorReport(diagnosed.output), levelOf(diagnosed.output))
59
+ for (const target of blankTargets(diagnosed.output)) await offerCompletion(ctx, context, target)
60
+ }
61
+
62
+ function levelOf(diagnosed: DiagnosedMemory): "info" | "warning" {
63
+ for (const report of diagnosed.vaults) {
64
+ if ("problems" in report) return "warning"
65
+ const { diagnosis } = report
66
+ const found = [
67
+ diagnosis.invalid,
68
+ diagnosis.duplicateIds,
69
+ diagnosis.blank,
70
+ diagnosis.temporaries,
71
+ diagnosis.crowdedFolders,
72
+ ]
73
+ if (found.some((items) => items.length > 0) || report.unreadable.length > 0) return "warning"
74
+ }
75
+ if (diagnosed.models.some((report) => report.check.status !== "ok")) return "warning"
76
+ if (diagnosed.embeddings.status !== "ready") return "warning"
77
+ if ("problem" in diagnosed.decision) return "warning"
78
+ if (diagnosed.cutoffs.gate.source === "missing" || diagnosed.cutoffs.relevance.source === "missing") return "warning"
79
+ return "info"
80
+ }
81
+
82
+ function blankTargets(diagnosed: DiagnosedMemory): BlankTarget[] {
83
+ const reports = diagnosed.vaults.filter((report): report is VaultReport => "blanks" in report)
84
+ return reports.flatMap((report) => report.blanks.map((blank: BlankFile) => ({ vault: report.vault, blank })))
85
+ }
86
+
87
+ async function offerCompletion(
88
+ ctx: MemoryPiContext,
89
+ context: MemoryOperationContext,
90
+ target: BlankTarget,
91
+ ): Promise<void> {
92
+ const { vault, blank } = target
93
+ const label = `${vault}/${blank.path}`
94
+ const type = await ctx.ui.select(`${COMPLETE_TYPE_TITLE} (${label})`, [...BLANK_NOTE_TYPES])
95
+ if (!isNoteType(type)) return ctx.ui.notify(`${COMPLETE_SKIPPED} ${label}`, "info")
96
+ let body = ""
97
+ if (blank.empty) {
98
+ const typed = await ctx.ui.input(`${COMPLETE_BODY_TITLE} (${label})`)
99
+ if (typeof typed !== "string" || typed.trim() === "") return ctx.ui.notify(`${COMPLETE_SKIPPED} ${label}`, "info")
100
+ body = typed
101
+ }
102
+ const confirmed = await ctx.ui.confirm(`Complete ${label} as a ${type} note?`, COMPLETE_CONFIRM_MESSAGE)
103
+ if (!confirmed) return ctx.ui.notify(`${COMPLETE_SKIPPED} ${label}`, "info")
104
+ const result = await completeBlankMemory(
105
+ { vault, path: blank.path, expectedHash: blank.rawHash, type, body },
106
+ context,
107
+ )
108
+ if (!result.succeeded) return ctx.ui.notify(result.problems.join("\n"), "error")
109
+ const warnings = result.output.maintenanceProblems.map((problem) => `\nMaintenance warning: ${problem}`)
110
+ ctx.ui.notify(`${COMPLETED} ${label} as a ${type} note.${warnings.join("")}`, "info")
111
+ }
112
+
113
+ function isNoteType(value: string | undefined): value is (typeof BLANK_NOTE_TYPES)[number] {
114
+ return typeof value === "string" && BLANK_NOTE_TYPES.some((type) => type === value)
115
+ }
116
+
117
+ function embeddingProbeOf(ctx: MemoryPiContext, modelCachePath: string): EmbeddingProbe {
118
+ return {
119
+ modelCachePath,
120
+ async hasCredentials(provider) {
121
+ const key = await ctx.modelRegistry.getApiKeyForProvider(provider)
122
+ return typeof key === "string" && key !== ""
123
+ },
124
+ }
125
+ }
126
+
127
+ function decisionProbeOf(ctx: MemoryPiContext): DecisionProbe {
128
+ return {
129
+ hasClassifier: (provider, model) => typeof ctx.modelRegistry.findOfType("classifier", provider, model) === "object",
130
+ async hasCredentials(provider) {
131
+ const key = await ctx.modelRegistry.getApiKeyForProvider(provider)
132
+ return typeof key === "string" && key !== ""
133
+ },
134
+ }
135
+ }
@@ -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"