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,109 @@
1
+ import { isAbsolute, join, relative, sep } from "node:path"
2
+
3
+ import { checkFileName, checkVaultPath, joinVaultPath, VAULT_PATH_SEPARATOR } from "#src/domain"
4
+ import { linkStatOf, realPathOf } from "#src/services/vault/filesystem"
5
+ import type { ResolveResult } from "./types.ts"
6
+
7
+ export async function resolveFolder(vault: string, folder: string): Promise<ResolveResult> {
8
+ return resolveParts(vault, checkVaultPath(folder), partsOf(folder), "directory")
9
+ }
10
+
11
+ export async function resolveFile(vault: string, folder: string, fileName: string): Promise<ResolveResult> {
12
+ const problems = [...checkVaultPath(folder), ...checkFileName(fileName)]
13
+ return resolveParts(vault, problems, [...partsOf(folder), fileName], "file")
14
+ }
15
+
16
+ async function resolveParts(
17
+ vault: string,
18
+ problems: string[],
19
+ parts: string[],
20
+ kind: "directory" | "file",
21
+ ): Promise<ResolveResult> {
22
+ if (problems.length > 0) {
23
+ return { succeeded: false, reason: "invalid", problems }
24
+ }
25
+
26
+ const root = await resolveRoot(vault)
27
+ if (!root.succeeded) {
28
+ return root
29
+ }
30
+
31
+ let current = root.output
32
+ for (const [depth, part] of parts.entries()) {
33
+ const path = join(current, part)
34
+ const target = await resolveEntry(root.output, path, joinVaultPath(...parts.slice(0, depth + 1)))
35
+ if (!target.succeeded) {
36
+ return target
37
+ }
38
+
39
+ const stat = await linkStatOf(target.output)
40
+ if (!stat.succeeded) {
41
+ if (stat.reason === "not-found") {
42
+ return { succeeded: true, output: join(target.output, ...parts.slice(depth + 1)) }
43
+ }
44
+ return stat
45
+ }
46
+ if ((depth < parts.length - 1 || kind === "directory") && !stat.output.isDirectory()) {
47
+ return { succeeded: false, reason: "not-directory", problems: [`${path} is not a directory`] }
48
+ }
49
+
50
+ current = target.output
51
+ }
52
+ return { succeeded: true, output: current }
53
+ }
54
+
55
+ async function resolveRoot(vault: string): Promise<ResolveResult> {
56
+ const root = await realPathOf(vault)
57
+ if (!root.succeeded) {
58
+ if (root.reason === "not-found") {
59
+ return { succeeded: false, reason: "vault-missing", problems: [`the vault folder ${vault} does not exist`] }
60
+ }
61
+ return root
62
+ }
63
+
64
+ const stat = await linkStatOf(root.output)
65
+ if (!stat.succeeded) {
66
+ if (stat.reason === "not-found") {
67
+ return { succeeded: false, reason: "vault-missing", problems: stat.problems }
68
+ }
69
+ return stat
70
+ }
71
+ if (!stat.output.isDirectory()) {
72
+ return { succeeded: false, reason: "not-directory", problems: [`the vault ${vault} is not a directory`] }
73
+ }
74
+ return root
75
+ }
76
+
77
+ async function resolveEntry(root: string, path: string, displayPath: string): Promise<ResolveResult> {
78
+ const stat = await linkStatOf(path)
79
+ if (!stat.succeeded) {
80
+ if (stat.reason === "not-found") {
81
+ return { succeeded: true, output: path }
82
+ }
83
+ return stat
84
+ }
85
+ if (!stat.output.isSymbolicLink()) {
86
+ return { succeeded: true, output: path }
87
+ }
88
+
89
+ const target = await realPathOf(path)
90
+ if (!target.succeeded) {
91
+ if (target.reason === "not-found" || target.code === "ELOOP") {
92
+ return { succeeded: false, reason: "outside-vault", problems: [`${displayPath} is a link that does not resolve`] }
93
+ }
94
+ return target
95
+ }
96
+ if (!isInside(root, target.output)) {
97
+ return { succeeded: false, reason: "outside-vault", problems: [`${displayPath} leads outside the vault`] }
98
+ }
99
+ return target
100
+ }
101
+
102
+ function isInside(root: string, path: string): boolean {
103
+ const fromRoot = relative(root, path)
104
+ return !isAbsolute(fromRoot) && fromRoot !== ".." && !fromRoot.startsWith(`..${sep}`)
105
+ }
106
+
107
+ function partsOf(folder: string): string[] {
108
+ return folder.split(VAULT_PATH_SEPARATOR).filter((part) => part.length > 0)
109
+ }
@@ -0,0 +1,45 @@
1
+ import { checkMemoryFolder, succeedNote } from "#src/domain"
2
+ import type { NamedVaultContext } from "#src/services/vault/context"
3
+ import { resolveMemoryFolder } from "./memory-folder.ts"
4
+ import { relocateNote } from "./relocate.ts"
5
+ import type { ExactSucceedRequest, SucceedRequest, SuccessionResult } from "./types.ts"
6
+
7
+ export async function succeedStoredNote(vault: NamedVaultContext, request: SucceedRequest): Promise<SuccessionResult> {
8
+ return succeedOriginal(vault, request, null)
9
+ }
10
+
11
+ export async function succeedStoredFile(
12
+ vault: NamedVaultContext,
13
+ request: ExactSucceedRequest,
14
+ ): Promise<SuccessionResult> {
15
+ return succeedOriginal(vault, request, request.path)
16
+ }
17
+
18
+ async function succeedOriginal(
19
+ vault: NamedVaultContext,
20
+ request: SucceedRequest,
21
+ originalPath: string | null,
22
+ ): Promise<SuccessionResult> {
23
+ const problems = checkMemoryFolder(request.successor.folder)
24
+ if (problems.length > 0) {
25
+ return { succeeded: false, reason: "invalid", problems }
26
+ }
27
+
28
+ const destination = await resolveMemoryFolder(vault.path, request.successor.folder)
29
+ if (!destination.succeeded) {
30
+ return destination
31
+ }
32
+
33
+ const succession = succeedNote(request.previous, request.successor, request.today)
34
+ const relocated = await relocateNote(vault, {
35
+ original: request.previous,
36
+ originalPath,
37
+ hashWhenRead: request.hashWhenRead,
38
+ written: [succession.archived, succession.successor],
39
+ })
40
+ if (!relocated.succeeded) {
41
+ return relocated
42
+ }
43
+
44
+ return { ...relocated, output: succession }
45
+ }
@@ -0,0 +1,199 @@
1
+ import type {
2
+ InvalidNote,
3
+ Note,
4
+ ParsedNote,
5
+ PlacedNote,
6
+ ProblemFolder,
7
+ Succession,
8
+ VaultCatalogFailure,
9
+ VaultFileStat,
10
+ } from "#src/domain"
11
+ import type { Done, Failed, Succeeded } from "#src/shared"
12
+
13
+ export interface ExactUpdateRequest {
14
+ path: string
15
+ note: Note
16
+ expectedHash: string
17
+ }
18
+
19
+ export interface StoredFilePath {
20
+ folder: string
21
+ fileName: string
22
+ }
23
+
24
+ export interface UpdateFileRequest {
25
+ folder: string
26
+ fileName: string
27
+ note: Note
28
+ expectedHash: string
29
+ }
30
+
31
+ export interface CompleteBlankRequest {
32
+ path: string
33
+ expectedHash: string
34
+ note: Note
35
+ confirmed: true
36
+ }
37
+
38
+ export interface BlankCompletionRefusal extends Failed {
39
+ reason: "not-blank" | "path-mismatch"
40
+ }
41
+
42
+ export type CompleteBlankResult = UpdateResult | BlankCompletionRefusal | VaultCatalogFailure
43
+
44
+ export interface StoredNote {
45
+ note: Note
46
+ hash: string
47
+ }
48
+
49
+ export interface MaintenanceWarnings {
50
+ maintenanceProblems?: string[]
51
+ }
52
+
53
+ export interface FolderListing {
54
+ subjects: string[]
55
+ notes: Note[]
56
+ invalid: InvalidNote[]
57
+ problemFolders?: ProblemFolder[]
58
+ }
59
+
60
+ export interface ArchiveRequest {
61
+ note: PlacedNote
62
+ hashWhenRead: string
63
+ today: string
64
+ }
65
+
66
+ export interface ExactArchiveRequest extends ArchiveRequest {
67
+ path: string
68
+ }
69
+
70
+ export interface SucceedRequest {
71
+ previous: PlacedNote
72
+ hashWhenRead: string
73
+ successor: PlacedNote
74
+ today: string
75
+ }
76
+
77
+ export interface ExactSucceedRequest extends SucceedRequest {
78
+ path: string
79
+ }
80
+
81
+ export interface FileRelocationRequest extends RelocationRequest {
82
+ originalPath: string | null
83
+ }
84
+
85
+ export interface RelocationRequest {
86
+ original: PlacedNote
87
+ hashWhenRead: string
88
+ written: [PlacedNote, ...PlacedNote[]]
89
+ }
90
+
91
+ export interface ResolveRefusal extends Failed {
92
+ reason: "invalid" | "outside-vault" | "vault-missing" | "not-directory" | "not-readable"
93
+ }
94
+
95
+ export interface ReadRefusal extends Failed {
96
+ reason: ResolveRefusal["reason"] | "not-found"
97
+ }
98
+
99
+ export interface CreateRefusal extends Failed {
100
+ reason: ResolveRefusal["reason"] | "not-writable" | "not-found"
101
+ }
102
+
103
+ export interface ExistingNoteRefusal extends Failed {
104
+ reason: "exists"
105
+ existingStatement: string
106
+ }
107
+
108
+ export interface UpdateRefusal extends Failed {
109
+ reason: CreateRefusal["reason"] | "conflict"
110
+ }
111
+
112
+ export interface IoRefusal extends Failed {
113
+ reason: "io-error"
114
+ }
115
+
116
+ export interface RefreshRefusal extends Failed {
117
+ reason: CreateRefusal["reason"] | "io-error" | "interrupted"
118
+ }
119
+
120
+ export interface RefreshPlan {
121
+ folders: Set<string>
122
+ refusals: RefreshRefusal[]
123
+ }
124
+
125
+ export type RefreshContinuation = () => boolean
126
+ export type RefreshScope = "with-ancestors" | "exact"
127
+
128
+ export type IndexStat = VaultFileStat
129
+
130
+ export interface RefreshedFolder {
131
+ folder: string
132
+ index: IndexStat
133
+ settled: boolean
134
+ }
135
+
136
+ export interface RefreshedFolders {
137
+ refreshed: RefreshedFolder[]
138
+ }
139
+
140
+ export interface FolderRefreshed extends MaintenanceWarnings {
141
+ index: IndexStat
142
+ settled: boolean
143
+ }
144
+
145
+ export interface ListingDraft extends FolderListing {
146
+ settled: boolean
147
+ }
148
+
149
+ export interface SettledListing {
150
+ listing: FolderListing
151
+ settled: boolean
152
+ }
153
+
154
+ export type LifecycleRefusal = UpdateRefusal | ExistingNoteRefusal
155
+ export type VaultRefusal = LifecycleRefusal | IoRefusal
156
+ export type VaultFailureReason = VaultRefusal["reason"]
157
+
158
+ export interface PartialRelocation extends Failed {
159
+ reason: "partial"
160
+ cause: LifecycleRefusal | IoRefusal
161
+ written: PlacedNote[]
162
+ originalState: "present" | "missing" | "unknown"
163
+ }
164
+
165
+ export interface RelocationProgress {
166
+ written: PlacedNote[]
167
+ maintenanceProblems: string[]
168
+ }
169
+
170
+ export interface NeedsFixingNote extends Failed {
171
+ reason: "needs-fixing"
172
+ parsed: ParsedNote
173
+ hash: string
174
+ }
175
+
176
+ export type CreateResult = (Succeeded<StoredNote> & MaintenanceWarnings) | CreateRefusal | ExistingNoteRefusal
177
+ export type UpdateResult = (Succeeded<StoredNote> & MaintenanceWarnings) | UpdateRefusal
178
+ export type VaultResult = CreateResult | UpdateResult
179
+ export type ReadNoteResult = Succeeded<StoredNote> | ReadRefusal | NeedsFixingNote
180
+ export type CheckResult = Done | LifecycleRefusal
181
+ export type RemovalResult = Succeeded<string> | LifecycleRefusal
182
+ export type RelocationWriteResult = RemovalResult | PartialRelocation
183
+ export type RelocationResult = (Done & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
184
+ export type PlacedResult = (Succeeded<PlacedNote> & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
185
+ export type SuccessionResult = (Succeeded<Succession> & MaintenanceWarnings) | LifecycleRefusal | PartialRelocation
186
+ export type RefreshResult = (Done & MaintenanceWarnings) | RefreshRefusal
187
+ export type FolderRefreshResult = RefreshResult & RefreshedFolders
188
+ export type FolderRefreshOutcome = Succeeded<FolderRefreshed> | RefreshRefusal
189
+ export type ResolveResult = Succeeded<string> | ResolveRefusal
190
+ export type ListResult = Succeeded<FolderListing> | ReadRefusal
191
+ export type SettledListResult = Succeeded<SettledListing> | ReadRefusal
192
+ export type VaultFolderState = "missing" | "empty" | "populated" | "not-directory"
193
+ export type VaultFolderResult = Succeeded<VaultFolderState> | IoRefusal
194
+
195
+ export interface NewFileRefusal extends Failed {
196
+ reason: "exists" | "not-found" | "io-error"
197
+ }
198
+
199
+ export type WriteNewFileResult = Done | NewFileRefusal
@@ -0,0 +1,58 @@
1
+ import { checkFileName, checkNote, renderNote } from "#src/domain"
2
+ import type { VaultContext } from "#src/services/vault/context"
3
+ import { hashOf, readRawFile, writeAtomically } from "#src/services/vault/filesystem"
4
+ import { displayNotePath } from "./display.ts"
5
+ import { refuseWrite } from "./refusals.ts"
6
+ import { resolveFile } from "./resolve.ts"
7
+ import { resolveStoredFile } from "./resolve-stored-file.ts"
8
+ import type { ResolveResult, UpdateFileRequest, UpdateResult } from "./types.ts"
9
+
10
+ export async function updateNoteFile(
11
+ vault: VaultContext,
12
+ request: UpdateFileRequest,
13
+ exactPath?: string,
14
+ ): Promise<UpdateResult> {
15
+ const { folder, fileName, note, expectedHash } = request
16
+ const problems = [...checkNote(note, vault.limits), ...checkFileName(fileName)]
17
+ if (fileName.slice(-3).toLowerCase() !== ".md" || fileName.slice(0, -3) !== note.statement) {
18
+ problems.push("The destination filename must match the note statement and have a Markdown extension")
19
+ }
20
+ if (problems.length > 0) {
21
+ return { succeeded: false, reason: "invalid", problems }
22
+ }
23
+
24
+ const path = await resolveUpdatePath(vault.path, request, exactPath)
25
+ if (!path.succeeded) {
26
+ return path
27
+ }
28
+
29
+ const current = await readRawFile(path.output)
30
+ if (!current.succeeded && current.reason !== "not-found") {
31
+ return current
32
+ }
33
+ if (!current.succeeded || hashOf(current.output) !== expectedHash) {
34
+ const problem = `${displayNotePath(folder, note.statement)} changed on disk since it was read`
35
+ return { succeeded: false, reason: "conflict", problems: [problem] }
36
+ }
37
+
38
+ const text = renderNote(note)
39
+ const written = await writeAtomically(path.output, text)
40
+ if (!written.succeeded) {
41
+ return refuseWrite(folder, note.statement, written)
42
+ }
43
+
44
+ const result: UpdateResult = { succeeded: true, output: { note, hash: hashOf(text) } }
45
+ if (written.maintenanceProblems) {
46
+ result.maintenanceProblems = written.maintenanceProblems
47
+ }
48
+ return result
49
+ }
50
+
51
+ async function resolveUpdatePath(
52
+ vault: string,
53
+ request: UpdateFileRequest,
54
+ exactPath: string | undefined,
55
+ ): Promise<ResolveResult> {
56
+ if (typeof exactPath === "string") return resolveStoredFile(vault, exactPath, request.note.statement)
57
+ return resolveFile(vault, request.folder, request.fileName)
58
+ }
@@ -0,0 +1,22 @@
1
+ import type { Note } from "#src/domain"
2
+ import type { VaultContext } from "#src/services/vault/context"
3
+ import { noteFileName, storedFilePath } from "./paths.ts"
4
+ import type { ExactUpdateRequest, UpdateResult } from "./types.ts"
5
+ import { updateNoteFile } from "./update-file.ts"
6
+
7
+ export async function updateStoredFile(vault: VaultContext, request: ExactUpdateRequest): Promise<UpdateResult> {
8
+ return updateNoteFile(
9
+ vault,
10
+ { ...storedFilePath(request.path), note: request.note, expectedHash: request.expectedHash },
11
+ request.path,
12
+ )
13
+ }
14
+
15
+ export async function updateNote(
16
+ vault: VaultContext,
17
+ folder: string,
18
+ note: Note,
19
+ hashWhenRead: string,
20
+ ): Promise<UpdateResult> {
21
+ return updateNoteFile(vault, { folder, fileName: noteFileName(note.statement), note, expectedHash: hashWhenRead })
22
+ }
@@ -0,0 +1,37 @@
1
+ import { open } from "node:fs/promises"
2
+
3
+ import { errorCode, removeFile } from "#src/services/vault/filesystem"
4
+ import type { NewFileRefusal, WriteNewFileResult } from "./types.ts"
5
+
6
+ export async function writeNewFile(path: string, bytes: Uint8Array): Promise<WriteNewFileResult> {
7
+ let created = false
8
+ try {
9
+ const handle = await open(path, "wx")
10
+ created = true
11
+ try {
12
+ await handle.writeFile(bytes)
13
+ } finally {
14
+ await handle.close()
15
+ }
16
+ return { succeeded: true }
17
+ } catch (error) {
18
+ if (!(error instanceof Error)) throw error
19
+ const refusal = refusalOf(error, path)
20
+ if (!created) return refusal
21
+ const removed = await removeFile(path)
22
+ if (removed.succeeded) return refusal
23
+ return { ...refusal, problems: [...refusal.problems, ...removed.problems.map(partialFileProblem)] }
24
+ }
25
+ }
26
+
27
+ function partialFileProblem(problem: string): string {
28
+ return `The partly written file was left behind: ${problem}`
29
+ }
30
+
31
+ function refusalOf(error: Error, path: string): NewFileRefusal {
32
+ const code = errorCode(error)
33
+ const problems = [`${path} cannot be created (${code})`]
34
+ if (code === "EEXIST") return { succeeded: false, reason: "exists", problems }
35
+ if (code === "ENOENT" || code === "ENOTDIR") return { succeeded: false, reason: "not-found", problems }
36
+ return { succeeded: false, reason: "io-error", problems }
37
+ }
@@ -0,0 +1 @@
1
+ export * from "./result/index.ts"
@@ -0,0 +1 @@
1
+ export * from "./types.ts"
@@ -0,0 +1,17 @@
1
+ export interface Succeeded<Output> {
2
+ succeeded: true
3
+ output: Output
4
+ }
5
+
6
+ export interface Done {
7
+ succeeded: true
8
+ }
9
+
10
+ export interface Failed {
11
+ succeeded: false
12
+ problems: string[]
13
+ }
14
+
15
+ export interface Absent {
16
+ succeeded: false
17
+ }
@@ -0,0 +1,83 @@
1
+ import {
2
+ createMemoryNote,
3
+ displayNotePath,
4
+ type ExistingNoteRefusal,
5
+ newNote,
6
+ newNoteId,
7
+ type ReadNoteResult,
8
+ readConfig,
9
+ readNote,
10
+ targetVault,
11
+ today,
12
+ } from "#src/services"
13
+ import {
14
+ captureMemoryOperationContext,
15
+ type MemoryOperationContext,
16
+ memoryAdmissionRefusal,
17
+ memoryOperationInterruption,
18
+ } from "#src/usecases/operation-context"
19
+ import { maintainAddedMemory } from "./maintenance.ts"
20
+ import type { AddMemoryRequest, AddMemoryResult } from "./types.ts"
21
+
22
+ export async function addMemory(
23
+ request: AddMemoryRequest,
24
+ callerContext: MemoryOperationContext,
25
+ ): Promise<AddMemoryResult> {
26
+ const context = captureMemoryOperationContext(callerContext)
27
+ const lease = await context.session.acquire(context.stamp, context.signal)
28
+ if (!lease) return memoryAdmissionRefusal(context)
29
+ try {
30
+ const interrupted = memoryOperationInterruption(context)
31
+ if (interrupted) return interrupted
32
+ return await addLeasedMemory(request, context)
33
+ } finally {
34
+ lease.release()
35
+ }
36
+ }
37
+
38
+ async function addLeasedMemory(request: AddMemoryRequest, context: MemoryOperationContext): Promise<AddMemoryResult> {
39
+ const config = await readConfig(context.configPath, context.platform)
40
+ if (!config.succeeded) {
41
+ return config
42
+ }
43
+
44
+ const target = targetVault(config.output, request.scope, context.workingFolder, context.platform)
45
+ if (!target.succeeded) {
46
+ return { ...target, configPath: context.configPath }
47
+ }
48
+
49
+ const { path, name } = target.output
50
+ const { limits } = config.output
51
+ const vault = { path, name, limits }
52
+ const created = await createMemoryNote(vault, request.folder, newNote(request.draft, newNoteId(), today()))
53
+ if (!created.succeeded && created.reason === "exists") {
54
+ const existing = await readNote(vault, request.folder, created.existingStatement)
55
+ return refuseExisting(created, existing)
56
+ }
57
+
58
+ if (!created.succeeded) {
59
+ return created
60
+ }
61
+
62
+ const maintenanceProblems = await maintainAddedMemory(vault, request.folder, created)
63
+ const notePath = displayNotePath(request.folder, created.output.note.statement)
64
+ return {
65
+ succeeded: true,
66
+ output: {
67
+ scope: request.scope,
68
+ vaultName: name,
69
+ folder: request.folder,
70
+ notePath,
71
+ stored: created.output,
72
+ maintenanceProblems,
73
+ },
74
+ }
75
+ }
76
+
77
+ function refuseExisting(refusal: ExistingNoteRefusal, existing: ReadNoteResult): AddMemoryResult {
78
+ if (!existing.succeeded) {
79
+ return refusal
80
+ }
81
+
82
+ return { succeeded: false, reason: "exists", problems: refusal.problems, existing: existing.output }
83
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./add-memory.ts"
2
+ export * from "./maintenance.ts"
3
+ export * from "./schemas.ts"
4
+ export * from "./types.ts"
@@ -0,0 +1,23 @@
1
+ import { type CreateResult, type NamedVaultContext, type RefreshResult, refreshIndexes } from "#src/services"
2
+ import type { Done } from "#src/shared"
3
+
4
+ export async function maintainAddedMemory(
5
+ vault: NamedVaultContext,
6
+ folder: string,
7
+ created: Extract<CreateResult, Done>,
8
+ ): Promise<string[]> {
9
+ const refreshed = await refreshIndexes(vault, folder)
10
+ return [...maintenanceProblemsOf(created), ...maintenanceProblemsOf(refreshed)]
11
+ }
12
+
13
+ export function maintenanceProblemsOf(result: CreateResult | RefreshResult): string[] {
14
+ if (!result.succeeded) {
15
+ return result.problems.map((problem) => `${result.reason}: ${problem}`)
16
+ }
17
+
18
+ if (result.maintenanceProblems) {
19
+ return result.maintenanceProblems
20
+ }
21
+
22
+ return []
23
+ }
@@ -0,0 +1,12 @@
1
+ import Type from "typebox"
2
+
3
+ import { MemoryDraftSchema, MemoryScopeSchema } from "#src/services"
4
+
5
+ export const AddMemoryRequestSchema = Type.Object(
6
+ {
7
+ scope: MemoryScopeSchema,
8
+ folder: Type.String(),
9
+ draft: MemoryDraftSchema,
10
+ },
11
+ { additionalProperties: false },
12
+ )
@@ -0,0 +1,47 @@
1
+ import type { Static } from "typebox"
2
+
3
+ import type {
4
+ ConfigRefusal,
5
+ CreateResult,
6
+ MemoryScope,
7
+ NoProjectRefusal,
8
+ PathPlatform,
9
+ StoredNote,
10
+ } from "#src/services"
11
+ import type { Failed, Succeeded } from "#src/shared"
12
+ import type { MemoryOperationRefusal } from "#src/usecases/operation-context"
13
+ import type { AddMemoryRequestSchema } from "./schemas.ts"
14
+
15
+ export type AddMemoryRequest = Static<typeof AddMemoryRequestSchema>
16
+
17
+ export interface MemoryContext {
18
+ configPath: string
19
+ workingFolder: string
20
+ platform: PathPlatform
21
+ }
22
+
23
+ export interface AddedMemory {
24
+ scope: MemoryScope
25
+ vaultName: string
26
+ folder: string
27
+ notePath: string
28
+ stored: StoredNote
29
+ maintenanceProblems: string[]
30
+ }
31
+
32
+ export interface UnregisteredProjectRefusal extends NoProjectRefusal {
33
+ configPath: string
34
+ }
35
+
36
+ export interface ExistingMemoryRefusal extends Failed {
37
+ reason: "exists"
38
+ existing: StoredNote
39
+ }
40
+
41
+ export type AddMemoryResult =
42
+ | Succeeded<AddedMemory>
43
+ | ConfigRefusal
44
+ | UnregisteredProjectRefusal
45
+ | Extract<CreateResult, Failed>
46
+ | ExistingMemoryRefusal
47
+ | MemoryOperationRefusal