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,16 @@
1
+ import { readFile } from "node:fs/promises"
2
+
3
+ import type { ScriptTextResult } from "./types.ts"
4
+
5
+ export function isAbsentError(error: Error): boolean {
6
+ return "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")
7
+ }
8
+
9
+ export async function readScriptText(path: string): Promise<ScriptTextResult> {
10
+ try {
11
+ return { succeeded: true, output: await readFile(path, "utf8") }
12
+ } catch (error) {
13
+ if (error instanceof Error && isAbsentError(error)) return { succeeded: false }
14
+ return { succeeded: false, problems: [`${path} cannot be read: ${String(error)}`] }
15
+ }
16
+ }
@@ -0,0 +1,5 @@
1
+ export * from "./constants.ts"
2
+ export * from "./files.ts"
3
+ export * from "./package-scripts.ts"
4
+ export * from "./scripts.ts"
5
+ export * from "./types.ts"
@@ -0,0 +1,74 @@
1
+ import { stat } from "node:fs/promises"
2
+ import { dirname, join, resolve } from "node:path"
3
+
4
+ import { Value } from "typebox/value"
5
+
6
+ import { PACKAGE_SCRIPT_PREFIX } from "./constants.ts"
7
+ import { isAbsentError, readScriptText } from "./files.ts"
8
+ import { PackageScriptsSchema } from "./schemas.ts"
9
+ import type { ExecutedScriptsResult, ScriptLinesResult } from "./types.ts"
10
+
11
+ async function nearestPackageJson(cwd: string): Promise<string> {
12
+ for (let folder = resolve(cwd); ; folder = dirname(folder)) {
13
+ const candidate = join(folder, "package.json")
14
+ try {
15
+ await stat(candidate)
16
+ return candidate
17
+ } catch (error) {
18
+ if (!(error instanceof Error && isAbsentError(error))) throw error
19
+ }
20
+ if (dirname(folder) === folder) return ""
21
+ }
22
+ }
23
+
24
+ async function packageJsonFor(cwd: string, prefix: string): Promise<string> {
25
+ if (prefix === "") return nearestPackageJson(cwd)
26
+ return join(resolve(cwd, prefix), "package.json")
27
+ }
28
+
29
+ function scriptLabel(prefix: string, name: string): string {
30
+ if (prefix === "") return PACKAGE_SCRIPT_PREFIX + name
31
+ return `${prefix}/${PACKAGE_SCRIPT_PREFIX}${name}`
32
+ }
33
+
34
+ function scriptLines(path: string, text: string): ScriptLinesResult {
35
+ try {
36
+ const parsed = JSON.parse(text)
37
+ if (!Value.Check(PackageScriptsSchema, parsed)) {
38
+ return { succeeded: false, problems: [`${path}: "scripts" must map names to text`] }
39
+ }
40
+ if (!parsed.scripts) return { succeeded: true, output: new Map() }
41
+ return { succeeded: true, output: new Map(Object.entries(parsed.scripts)) }
42
+ } catch (error) {
43
+ return { succeeded: false, problems: [`${path} is not valid JSON: ${String(error)}`] }
44
+ }
45
+ }
46
+
47
+ export async function readPackageScripts(cwd: string, prefix: string, names: string[]): Promise<ExecutedScriptsResult> {
48
+ const label = (name: string) => scriptLabel(prefix, name)
49
+ const labels = names.map(label)
50
+ if (names.length === 0) return { succeeded: true, output: { scripts: [], missing: [] } }
51
+ try {
52
+ const path = await packageJsonFor(cwd, prefix)
53
+ if (path === "") return { succeeded: true, output: { scripts: [], missing: labels } }
54
+ const read = await readScriptText(path)
55
+ if (!read.succeeded) {
56
+ if ("problems" in read) return read
57
+ return { succeeded: true, output: { scripts: [], missing: labels } }
58
+ }
59
+ const lines = scriptLines(path, read.output)
60
+ if (!lines.succeeded) return lines
61
+ const scripts = names.flatMap((name) => {
62
+ const text = lines.output.get(name)
63
+ if (typeof text === "string") return [{ path: label(name), text }]
64
+ return []
65
+ })
66
+ const missing = names.filter((name) => !lines.output.has(name)).map(label)
67
+ return { succeeded: true, output: { scripts, missing } }
68
+ } catch (error) {
69
+ return {
70
+ succeeded: false,
71
+ problems: [`package.json above ${resolve(cwd)} cannot be found or read: ${String(error)}`],
72
+ }
73
+ }
74
+ }
@@ -0,0 +1,3 @@
1
+ import Type from "typebox"
2
+
3
+ export const PackageScriptsSchema = Type.Object({ scripts: Type.Optional(Type.Record(Type.String(), Type.String())) })
@@ -0,0 +1,27 @@
1
+ import { resolve } from "node:path"
2
+
3
+ import type { ExecutedFile, ShellEditScript } from "#src/domain"
4
+ import { readScriptText } from "./files.ts"
5
+ import { readPackageScripts } from "./package-scripts.ts"
6
+ import type { ExecutedScriptsResult } from "./types.ts"
7
+
8
+ export async function readExecutedScripts(cwd: string, files: ExecutedFile[]): Promise<ExecutedScriptsResult> {
9
+ const scripts: ShellEditScript[] = []
10
+ const missing: string[] = []
11
+ for (const file of files) {
12
+ if (file.kind !== "script") continue
13
+ const read = await readScriptText(resolve(cwd, file.path))
14
+ if (read.succeeded) scripts.push({ path: file.path, text: read.output })
15
+ else if ("problems" in read) return read
16
+ else missing.push(file.path)
17
+ }
18
+ const packages = files.filter((file) => file.kind === "package-script")
19
+ for (const prefix of new Set(packages.map((file) => file.prefix))) {
20
+ const names = packages.filter((file) => file.prefix === prefix).map((file) => file.name)
21
+ const packaged = await readPackageScripts(cwd, prefix, names)
22
+ if (!packaged.succeeded) return packaged
23
+ scripts.push(...packaged.output.scripts)
24
+ missing.push(...packaged.output.missing)
25
+ }
26
+ return { succeeded: true, output: { scripts, missing } }
27
+ }
@@ -0,0 +1,11 @@
1
+ import type { ShellEditScript } from "#src/domain"
2
+ import type { Absent, Failed, Succeeded } from "#src/shared"
3
+
4
+ export interface ExecutedScripts {
5
+ scripts: ShellEditScript[]
6
+ missing: string[]
7
+ }
8
+
9
+ export type ScriptTextResult = Succeeded<string> | Absent | Failed
10
+ export type ExecutedScriptsResult = Succeeded<ExecutedScripts> | Failed
11
+ export type ScriptLinesResult = Succeeded<Map<string, string>> | Failed
@@ -0,0 +1,31 @@
1
+ import { archiveNote } from "#src/domain"
2
+ import type { NamedVaultContext } from "#src/services/vault/context"
3
+ import { relocateNote } from "./relocate.ts"
4
+ import type { ArchiveRequest, ExactArchiveRequest, PlacedResult } from "./types.ts"
5
+
6
+ export async function archiveStoredNote(vault: NamedVaultContext, request: ArchiveRequest): Promise<PlacedResult> {
7
+ return archiveOriginal(vault, request, null)
8
+ }
9
+
10
+ export async function archiveStoredFile(vault: NamedVaultContext, request: ExactArchiveRequest): Promise<PlacedResult> {
11
+ return archiveOriginal(vault, request, request.path)
12
+ }
13
+
14
+ async function archiveOriginal(
15
+ vault: NamedVaultContext,
16
+ request: ArchiveRequest,
17
+ originalPath: string | null,
18
+ ): Promise<PlacedResult> {
19
+ const archived = archiveNote(request.note, request.today)
20
+ const relocated = await relocateNote(vault, {
21
+ original: request.note,
22
+ originalPath,
23
+ hashWhenRead: request.hashWhenRead,
24
+ written: [archived],
25
+ })
26
+ if (!relocated.succeeded) {
27
+ return relocated
28
+ }
29
+
30
+ return { ...relocated, output: archived }
31
+ }
@@ -0,0 +1,50 @@
1
+ import { mkdir } from "node:fs/promises"
2
+
3
+ import {
4
+ renderVaultAssets,
5
+ type VaultBootstrapProgress,
6
+ type VaultBootstrapResult,
7
+ type VaultCatalogFailure,
8
+ } from "#src/domain"
9
+ import { catalogIoFailure, resolveCatalogRoot } from "#src/services/vault/catalog"
10
+ import type { NamedVaultContext } from "#src/services/vault/context"
11
+ import { ensureTemplateFolder } from "./paths.ts"
12
+ import { createAssetExclusively } from "./write.ts"
13
+
14
+ export async function ensureVaultAssets(vault: NamedVaultContext): Promise<VaultBootstrapResult> {
15
+ const progress: VaultBootstrapProgress = { createdRoot: false, created: [], preserved: [], maintenanceProblems: [] }
16
+ try {
17
+ const created = await mkdir(vault.path, { recursive: true })
18
+ progress.createdRoot = typeof created === "string"
19
+ } catch (error) {
20
+ if (!(error instanceof Error)) throw error
21
+ return bootstrapFailure(progress, catalogIoFailure(error, { path: "", scope: "directory" }))
22
+ }
23
+ const root = await resolveCatalogRoot(vault)
24
+ if (!root.succeeded) return bootstrapFailure(progress, root)
25
+ const templates = await ensureTemplateFolder(root.output)
26
+ if (!templates.succeeded) return bootstrapFailure(progress, templates)
27
+ return installAssets(root.output, templates.output, progress)
28
+ }
29
+
30
+ async function installAssets(
31
+ root: string,
32
+ templates: string,
33
+ progress: VaultBootstrapProgress,
34
+ ): Promise<VaultBootstrapResult> {
35
+ for (const asset of renderVaultAssets()) {
36
+ let folder = ""
37
+ let name = asset.path
38
+ if (asset.path.startsWith("_templates/")) {
39
+ folder = templates
40
+ name = asset.path.slice("_templates/".length)
41
+ }
42
+ const written = await createAssetExclusively({ root, folder, name, content: asset.content, progress })
43
+ if (!written.succeeded) return bootstrapFailure(progress, written)
44
+ }
45
+ return { succeeded: true, output: progress }
46
+ }
47
+
48
+ function bootstrapFailure(progress: VaultBootstrapProgress, failure: VaultCatalogFailure): VaultBootstrapResult {
49
+ return { succeeded: false, ...progress, failure, problems: failure.problems }
50
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./ensure.ts"
2
+ export * from "./types.ts"
@@ -0,0 +1,57 @@
1
+ import { mkdir, readdir } from "node:fs/promises"
2
+ import { join } from "node:path"
3
+
4
+ import { catalogFailure, catalogIoFailure, resolveCatalogEntry } from "#src/services/vault/catalog"
5
+ import type { AssetLocation, AssetPathResult } from "./types.ts"
6
+
7
+ export async function existingAsset(location: AssetLocation): Promise<AssetPathResult> {
8
+ const folder = await resolveCatalogEntry({ root: location.root, path: location.folder })
9
+ if (!folder.succeeded) return folder
10
+ try {
11
+ const names = await readdir(folder.output.absolutePath)
12
+ const matches = names.filter((name) => name.toLowerCase() === location.name.toLowerCase())
13
+ if (matches.length > 1) {
14
+ return catalogFailure({
15
+ path: location.folder,
16
+ scope: "entry",
17
+ reason: "invalid-path",
18
+ problem: `Ambiguous asset name: ${location.name}`,
19
+ })
20
+ }
21
+ const name = matches[0]
22
+ if (!name) return { succeeded: true, output: "" }
23
+ return { succeeded: true, output: [location.folder, name].filter((part) => part !== "").join("/") }
24
+ } catch (error) {
25
+ if (error instanceof Error) return catalogIoFailure(error, { path: location.folder, scope: "directory" })
26
+ throw error
27
+ }
28
+ }
29
+
30
+ export async function ensureTemplateFolder(root: string): Promise<AssetPathResult> {
31
+ const existing = await existingAsset({ root, folder: "", name: "_templates" })
32
+ if (!existing.succeeded) return existing
33
+ if (existing.output !== "") return checkedDirectory(root, existing.output)
34
+ try {
35
+ await mkdir(join(root, "_templates"))
36
+ } catch (error) {
37
+ if (!(error instanceof Error)) throw error
38
+ if (!("code" in error) || error.code !== "EEXIST") {
39
+ return catalogIoFailure(error, { path: "_templates", scope: "directory" })
40
+ }
41
+ }
42
+ return checkedDirectory(root, "_templates")
43
+ }
44
+
45
+ async function checkedDirectory(root: string, path: string): Promise<AssetPathResult> {
46
+ const resolved = await resolveCatalogEntry({ root, path })
47
+ if (!resolved.succeeded) return resolved
48
+ if (resolved.output.kind !== "directory") {
49
+ return catalogFailure({
50
+ path,
51
+ scope: "directory",
52
+ reason: "not-directory",
53
+ problem: "Templates must be a directory",
54
+ })
55
+ }
56
+ return { succeeded: true, output: path }
57
+ }
@@ -0,0 +1,17 @@
1
+ import type { VaultBootstrapProgress, VaultCatalogFailure } from "#src/domain"
2
+ import type { Succeeded } from "#src/shared"
3
+
4
+ export type { VaultBootstrapFailure, VaultBootstrapProgress, VaultBootstrapResult } from "#src/domain"
5
+
6
+ export interface AssetLocation {
7
+ root: string
8
+ folder: string
9
+ name: string
10
+ }
11
+
12
+ export interface AssetWriteRequest extends AssetLocation {
13
+ content: string
14
+ progress: VaultBootstrapProgress
15
+ }
16
+
17
+ export type AssetPathResult = Succeeded<string> | VaultCatalogFailure
@@ -0,0 +1,47 @@
1
+ import { join } from "node:path"
2
+
3
+ import type { VaultCatalogFailure } from "#src/domain"
4
+ import { catalogFailure, catalogIoFailure, resolveCatalogEntry } from "#src/services/vault/catalog"
5
+ import { publishExclusively } from "#src/services/vault/filesystem"
6
+ import type { Done } from "#src/shared"
7
+ import { existingAsset } from "./paths.ts"
8
+ import type { AssetWriteRequest } from "./types.ts"
9
+
10
+ export async function createAssetExclusively(request: AssetWriteRequest): Promise<Done | VaultCatalogFailure> {
11
+ const existing = await existingAsset(request)
12
+ if (!existing.succeeded) return existing
13
+ if (existing.output !== "") return preserveAsset(request, existing.output)
14
+ const parent = await resolveCatalogEntry({ root: request.root, path: request.folder })
15
+ if (!parent.succeeded) return parent
16
+ return publishAsset(request, parent.output.absolutePath)
17
+ }
18
+
19
+ async function publishAsset(request: AssetWriteRequest, parent: string): Promise<Done | VaultCatalogFailure> {
20
+ const path = [request.folder, request.name].filter((part) => part !== "").join("/")
21
+ try {
22
+ const written = await publishExclusively(join(parent, request.name), request.content)
23
+ if (!written.succeeded) {
24
+ if (written.reason !== "exists") {
25
+ return { succeeded: false, path, scope: "file", reason: "not-writable", problems: written.problems }
26
+ }
27
+ request.progress.maintenanceProblems.push(...written.problems)
28
+ return preserveAsset(request, path)
29
+ }
30
+ if (written.maintenanceProblems) request.progress.maintenanceProblems.push(...written.maintenanceProblems)
31
+ request.progress.created.push(path)
32
+ return { succeeded: true }
33
+ } catch (error) {
34
+ if (error instanceof Error) return catalogIoFailure(error, { path, scope: "file" })
35
+ throw error
36
+ }
37
+ }
38
+
39
+ async function preserveAsset(request: AssetWriteRequest, path: string): Promise<Done | VaultCatalogFailure> {
40
+ const resolved = await resolveCatalogEntry({ root: request.root, path })
41
+ if (!resolved.succeeded) return resolved
42
+ if (resolved.output.kind !== "file") {
43
+ return catalogFailure({ path, scope: "file", reason: "not-file", problem: "The asset path is not a regular file" })
44
+ }
45
+ request.progress.preserved.push(path)
46
+ return { succeeded: true }
47
+ }
@@ -0,0 +1,51 @@
1
+ import { open, stat } from "node:fs/promises"
2
+
3
+ import type { VaultCatalogFailure } from "#src/domain"
4
+ import type { VaultContext } from "#src/services/vault/context"
5
+ import { hashOf } from "#src/services/vault/filesystem"
6
+ import { catalogFailure, catalogIoFailure } from "./failures.ts"
7
+ import { resolveCatalogEntry, resolveCatalogRoot } from "./resolve.ts"
8
+ import { catalogStat, sameCatalogStat } from "./stat.ts"
9
+ import type { CatalogBytesResult, CatalogReadRequest, ResolvedCatalogEntry } from "./types.ts"
10
+
11
+ export async function readCatalogBytes(vault: VaultContext, request: CatalogReadRequest): Promise<CatalogBytesResult> {
12
+ const root = await resolveCatalogRoot(vault)
13
+ if (!root.succeeded) return root
14
+ const resolved = await resolveCatalogEntry({ root: root.output, path: request.path })
15
+ if (!resolved.succeeded) return resolved
16
+ if (resolved.output.kind !== "file") {
17
+ return catalogFailure({ path: request.path, scope: "file", reason: "not-file", problem: "Expected a regular file" })
18
+ }
19
+ try {
20
+ return await readStableBytes(resolved.output, request)
21
+ } catch (error) {
22
+ if (error instanceof Error) return catalogIoFailure(error, { path: request.path, scope: "file" })
23
+ throw error
24
+ }
25
+ }
26
+
27
+ async function readStableBytes(entry: ResolvedCatalogEntry, request: CatalogReadRequest): Promise<CatalogBytesResult> {
28
+ const before = entry.stat
29
+ if (request.expectedStat && !sameCatalogStat(before, request.expectedStat)) return changed(request.path)
30
+ const file = await open(entry.absolutePath, "r")
31
+ try {
32
+ const opened = catalogStat(await file.stat())
33
+ if (!sameCatalogStat(before, opened)) return changed(request.path)
34
+ const bytes = await file.readFile()
35
+ const after = catalogStat(await file.stat())
36
+ if (!sameCatalogStat(before, after)) return changed(request.path)
37
+ if (!sameCatalogStat(after, catalogStat(await stat(entry.absolutePath)))) return changed(request.path)
38
+ return { succeeded: true, output: { path: request.path, bytes, rawHash: hashOf(bytes), stat: after } }
39
+ } finally {
40
+ await file.close()
41
+ }
42
+ }
43
+
44
+ function changed(path: string): VaultCatalogFailure {
45
+ return catalogFailure({
46
+ path,
47
+ scope: "file",
48
+ reason: "changed",
49
+ problem: "The file changed while collecting its snapshot",
50
+ })
51
+ }
@@ -0,0 +1 @@
1
+ export { isLoadedDontForget } from "#src/domain"
@@ -0,0 +1,69 @@
1
+ import type { Dirent } from "node:fs"
2
+ import { readdir } from "node:fs/promises"
3
+
4
+ import { catalogFileKind, isCatalogHidden, isCatalogNotePath, type VaultEnumerationResult } from "#src/domain"
5
+ import type { VaultContext } from "#src/services/vault/context"
6
+ import { catalogIoFailure } from "./failures.ts"
7
+ import { resolveCatalogEntry, resolveCatalogRoot, resolveListedEntry } from "./resolve.ts"
8
+ import type { CatalogResolveResult, CatalogWalk, CatalogWalkRequest } from "./types.ts"
9
+ import { visitCatalogEntry } from "./visit.ts"
10
+
11
+ export async function enumerateVault(vault: VaultContext): Promise<VaultEnumerationResult> {
12
+ return walkVault({ vault, mode: "memory" })
13
+ }
14
+
15
+ export async function walkVault(request: CatalogWalkRequest): Promise<VaultEnumerationResult> {
16
+ const root = await resolveCatalogRoot(request.vault)
17
+ if (!root.succeeded) return root
18
+ const walk: CatalogWalk = {
19
+ ...request,
20
+ root: root.output,
21
+ pending: [""],
22
+ inventory: { entries: [], observedPaths: [], completeDirectories: [], failures: [], aliases: [] },
23
+ }
24
+ while (walk.pending.length > 0) {
25
+ const folder = walk.pending.pop()
26
+ if (typeof folder === "string") await enumerateDirectory(walk, folder)
27
+ }
28
+ walk.inventory.entries.sort((a, b) => a.path.localeCompare(b.path))
29
+ return { succeeded: true, output: walk.inventory }
30
+ }
31
+
32
+ async function enumerateDirectory(walk: CatalogWalk, folder: string): Promise<void> {
33
+ const resolved = await resolveCatalogEntry({ root: walk.root, path: folder })
34
+ if (!resolved.succeeded) {
35
+ walk.inventory.failures.push({ ...resolved, scope: "directory" })
36
+ return
37
+ }
38
+ try {
39
+ const canonicalFolder = resolved.output.canonicalPath === folder
40
+ const entries = await readdir(resolved.output.absolutePath, { withFileTypes: true })
41
+ walk.inventory.completeDirectories.push(folder)
42
+ for (const entry of entries) {
43
+ const path = [folder, entry.name].filter((part) => part !== "").join("/")
44
+ if (skipEntry(walk, path, entry.isDirectory())) continue
45
+ walk.inventory.observedPaths.push(path)
46
+ visitCatalogEntry(walk, path, await resolveListing(walk, path, entry, canonicalFolder))
47
+ }
48
+ } catch (error) {
49
+ if (!(error instanceof Error)) throw error
50
+ walk.inventory.failures.push(catalogIoFailure(error, { path: folder, scope: "directory" }))
51
+ }
52
+ }
53
+
54
+ async function resolveListing(
55
+ walk: CatalogWalk,
56
+ path: string,
57
+ entry: Dirent,
58
+ canonicalFolder: boolean,
59
+ ): Promise<CatalogResolveResult> {
60
+ const location = { root: walk.root, path }
61
+ if (canonicalFolder) return resolveListedEntry(location, entry)
62
+ return resolveCatalogEntry(location)
63
+ }
64
+
65
+ function skipEntry(walk: CatalogWalk, path: string, directory: boolean): boolean {
66
+ if (walk.mode === "export") return isCatalogHidden(path) || catalogFileKind(path) === "temporary"
67
+ if (directory) return isCatalogHidden(path)
68
+ return isCatalogHidden(path) && !isCatalogNotePath(path) && catalogFileKind(path) !== "temporary"
69
+ }
@@ -0,0 +1,21 @@
1
+ import type { VaultCatalogFailure, VaultExportFile, VaultExportResult } from "#src/domain"
2
+ import type { VaultContext } from "#src/services/vault/context"
3
+ import { readCatalogBytes } from "./bytes.ts"
4
+ import { walkVault } from "./enumerate.ts"
5
+
6
+ export async function collectExportFiles(vault: VaultContext): Promise<VaultExportResult> {
7
+ const scan = await walkVault({ vault, mode: "export" })
8
+ if (!scan.succeeded) return { succeeded: false, failures: [scan], problems: scan.problems }
9
+ const failures: VaultCatalogFailure[] = [...scan.output.failures]
10
+ const files: VaultExportFile[] = []
11
+ for (const entry of scan.output.entries) {
12
+ if (entry.kind === "folder" || entry.kind === "temporary") continue
13
+ const read = await readCatalogBytes(vault, { path: entry.path, expectedStat: entry.stat })
14
+ if (read.succeeded) files.push(read.output)
15
+ else failures.push(read)
16
+ }
17
+ if (failures.length > 0) {
18
+ return { succeeded: false, failures, problems: failures.flatMap((failure) => failure.problems) }
19
+ }
20
+ return { succeeded: true, output: files }
21
+ }
@@ -0,0 +1,16 @@
1
+ import type { VaultCatalogFailure } from "#src/domain"
2
+ import type { CatalogFailureDetail, CatalogOperation } from "./types.ts"
3
+
4
+ export function catalogFailure(detail: CatalogFailureDetail): VaultCatalogFailure {
5
+ return { succeeded: false, path: detail.path, scope: detail.scope, reason: detail.reason, problems: [detail.problem] }
6
+ }
7
+
8
+ export function catalogIoFailure(error: Error, operation: CatalogOperation): VaultCatalogFailure {
9
+ let reason: VaultCatalogFailure["reason"] = "io-error"
10
+ if ("code" in error) {
11
+ if (error.code === "ENOENT") reason = "not-found"
12
+ if (error.code === "ENOTDIR") reason = "not-directory"
13
+ if (error.code === "EACCES" || error.code === "EPERM" || error.code === "EBUSY") reason = "unreadable"
14
+ }
15
+ return catalogFailure({ ...operation, reason, problem: error.message })
16
+ }
@@ -0,0 +1,10 @@
1
+ export * from "./bytes.ts"
2
+ export * from "./dont-forget.ts"
3
+ export * from "./enumerate.ts"
4
+ export * from "./export.ts"
5
+ export * from "./failures.ts"
6
+ export * from "./inspect.ts"
7
+ export * from "./observe.ts"
8
+ export * from "./resolve.ts"
9
+ export * from "./stat.ts"
10
+ export * from "./types.ts"
@@ -0,0 +1,41 @@
1
+ import {
2
+ analyzeVaultNote,
3
+ type InspectedVaultFile,
4
+ isCatalogNotePath,
5
+ isRootArchive,
6
+ type VaultExportFile,
7
+ type VaultFileRequest,
8
+ type VaultInspectionResult,
9
+ } from "#src/domain"
10
+ import type { VaultContext } from "#src/services/vault/context"
11
+ import { readCatalogBytes } from "./bytes.ts"
12
+ import { catalogFailure } from "./failures.ts"
13
+ import { resolveCatalogEntry, resolveCatalogRoot } from "./resolve.ts"
14
+
15
+ export async function inspectVaultFile(vault: VaultContext, request: VaultFileRequest): Promise<VaultInspectionResult> {
16
+ const root = await resolveCatalogRoot(vault)
17
+ if (!root.succeeded) return root
18
+ const resolved = await resolveCatalogEntry({ root: root.output, path: request.path })
19
+ if (!resolved.succeeded) return resolved
20
+ const canonicalPath = resolved.output.canonicalPath
21
+ if (resolved.output.kind !== "file" || ![request.path, canonicalPath].every(isCatalogNotePath)) {
22
+ return catalogFailure({
23
+ path: request.path,
24
+ scope: "file",
25
+ reason: "excluded",
26
+ problem: "This path is not a memory note",
27
+ })
28
+ }
29
+
30
+ const raw = await readCatalogBytes(vault, { ...request, expectedStat: resolved.output.stat })
31
+ if (!raw.succeeded) return raw
32
+ return { succeeded: true, output: inspectContent(vault, raw.output, canonicalPath) }
33
+ }
34
+
35
+ function inspectContent(vault: VaultContext, raw: VaultExportFile, canonicalPath: string): InspectedVaultFile {
36
+ const text = Buffer.from(raw.bytes).toString("utf8")
37
+ const archived = isRootArchive(raw.path) || isRootArchive(canonicalPath)
38
+ const statement = canonicalPath.slice(canonicalPath.lastIndexOf("/") + 1, -3)
39
+ const analysis = analyzeVaultNote({ statement, text, archived, limits: vault.limits })
40
+ return { path: raw.path, canonicalPath, text, rawHash: raw.rawHash, stat: raw.stat, archived, analysis }
41
+ }
@@ -0,0 +1,35 @@
1
+ import { isCatalogHidden, isRootTemplate, type VaultFileRequest } from "#src/domain"
2
+ import type { VaultContext } from "#src/services/vault/context"
3
+ import { catalogFailure } from "./failures.ts"
4
+ import { resolveCatalogEntry, resolveCatalogRoot } from "./resolve.ts"
5
+ import type { CatalogResolveResult } from "./types.ts"
6
+
7
+ export async function observeVaultPath(vault: VaultContext, request: VaultFileRequest): Promise<CatalogResolveResult> {
8
+ let path = request.path
9
+ if (path.length > 1 && path.endsWith("/")) path = path.slice(0, -1)
10
+ const root = await resolveCatalogRoot(vault)
11
+ if (!root.succeeded) return root
12
+ const entry = await resolveCatalogEntry({ root: root.output, path })
13
+ if (!entry.succeeded) return entry
14
+ if (request.path.endsWith("/") && entry.output.kind !== "directory") {
15
+ return catalogFailure({
16
+ path: request.path,
17
+ scope: "directory",
18
+ reason: "not-directory",
19
+ problem: "Expected a folder",
20
+ })
21
+ }
22
+ if (entry.output.kind === "directory" && ![path, entry.output.canonicalPath].every(isReadableFolder)) {
23
+ return catalogFailure({
24
+ path: request.path,
25
+ scope: "directory",
26
+ reason: "excluded",
27
+ problem: "This folder is not readable memory",
28
+ })
29
+ }
30
+ return entry
31
+ }
32
+
33
+ function isReadableFolder(path: string): boolean {
34
+ return !isCatalogHidden(path) && !isRootTemplate(path)
35
+ }