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,163 @@
1
+ import { lstat, realpath, stat } from "node:fs/promises"
2
+ import { join, parse, resolve, sep } from "node:path"
3
+
4
+ import {
5
+ configLocationProblems,
6
+ infrastructureProblems,
7
+ type MemoryConfig,
8
+ type ProjectEntry,
9
+ parseConfig,
10
+ registrationProblems,
11
+ } from "#src/domain"
12
+ import { isFullyQualifiedPath } from "./fully-qualified-path.ts"
13
+ import type {
14
+ CanonicalConfigResult,
15
+ CanonicalPathResult,
16
+ ConfigRegistrationLocation,
17
+ ConfigRegistrationLocationResult,
18
+ RegistrationPaths,
19
+ RegistrationPathsResult,
20
+ } from "./types.ts"
21
+ import { isNamespaceVolumeRoot } from "./volume-namespace.ts"
22
+
23
+ export async function canonicalizeRegistration(request: RegistrationPaths): Promise<RegistrationPathsResult> {
24
+ const location = await canonicalizeConfigLocation(request)
25
+ const index = await canonicalField(request.indexPath, "indexPath", "directory")
26
+ const problems: string[] = []
27
+ if (!location.succeeded) problems.push(...location.problems)
28
+ if (!index.succeeded) problems.push(...index.problems)
29
+ if (!location.succeeded || !index.succeeded) {
30
+ return { succeeded: false, problems }
31
+ }
32
+
33
+ const canonical = { ...location.output, indexPath: index.output }
34
+ problems.push(
35
+ ...infrastructureProblems(request, request.platform),
36
+ ...infrastructureProblems(canonical, request.platform),
37
+ )
38
+ if (problems.length > 0) {
39
+ return { succeeded: false, problems: [...new Set(problems)] }
40
+ }
41
+
42
+ return { succeeded: true, output: canonical }
43
+ }
44
+
45
+ export async function canonicalizeConfigLocation(
46
+ request: ConfigRegistrationLocation,
47
+ ): Promise<ConfigRegistrationLocationResult> {
48
+ const parsed = parseConfig(JSON.stringify(request.config), request.platform)
49
+ if (!parsed.succeeded) {
50
+ return parsed
51
+ }
52
+
53
+ const config = await canonicalConfig(parsed.output)
54
+ const path = await canonicalField(request.configPath, "configPath", "file")
55
+ const problems: string[] = []
56
+ if (!config.succeeded) problems.push(...config.problems)
57
+ if (!path.succeeded) problems.push(...path.problems)
58
+ if (!config.succeeded || !path.succeeded) {
59
+ return { succeeded: false, problems }
60
+ }
61
+
62
+ const canonical = { config: config.output, configPath: path.output, platform: request.platform }
63
+ problems.push(
64
+ ...registrationProblems(canonical.config, request.platform),
65
+ ...configLocationProblems(request, request.platform),
66
+ ...configLocationProblems(canonical, request.platform),
67
+ )
68
+ if (problems.length > 0) {
69
+ return { succeeded: false, problems: [...new Set(problems)] }
70
+ }
71
+
72
+ return { succeeded: true, output: canonical }
73
+ }
74
+
75
+ async function canonicalConfig(config: MemoryConfig): Promise<CanonicalConfigResult> {
76
+ const problems: string[] = []
77
+ const global = await canonicalField(config.global.vault, "global.vault", "directory")
78
+ if (!global.succeeded) problems.push(...global.problems)
79
+
80
+ const projects: ProjectEntry[] = []
81
+ for (const [index, project] of config.projects.entries()) {
82
+ const folder = await canonicalField(project.folder, `projects.${index}.folder`, "directory")
83
+ const vault = await canonicalField(project.vault, `projects.${index}.vault`, "directory")
84
+ if (!folder.succeeded) problems.push(...folder.problems)
85
+ if (!vault.succeeded) problems.push(...vault.problems)
86
+ if (folder.succeeded && vault.succeeded) {
87
+ projects.push({ ...project, folder: folder.output, vault: vault.output })
88
+ }
89
+ }
90
+ if (!global.succeeded || problems.length > 0) {
91
+ return { succeeded: false, problems }
92
+ }
93
+
94
+ return { succeeded: true, output: { ...config, global: { vault: global.output }, projects } }
95
+ }
96
+
97
+ export function canonicalizeWorkingFolder(path: string): Promise<CanonicalPathResult> {
98
+ return canonicalField(path, "workingFolder", "directory")
99
+ }
100
+
101
+ export function canonicalizeAccessPath(absolute: string): Promise<CanonicalPathResult> {
102
+ return canonicalField(absolute, "accessPath", "file")
103
+ }
104
+
105
+ async function canonicalField(path: string, field: string, kind: "file" | "directory"): Promise<CanonicalPathResult> {
106
+ try {
107
+ if (kind === "directory") {
108
+ return { succeeded: true, output: await canonicalDirectory(path) }
109
+ }
110
+
111
+ return { succeeded: true, output: await canonicalPath(path) }
112
+ } catch (error) {
113
+ return { succeeded: false, problems: [`${field}: ${String(error)}`] }
114
+ }
115
+ }
116
+
117
+ async function canonicalDirectory(path: string): Promise<string> {
118
+ const canonical = await canonicalPath(path)
119
+
120
+ try {
121
+ if (!(await stat(canonical)).isDirectory()) {
122
+ throw new Error(`${path}: expected a directory`)
123
+ }
124
+ } catch (error) {
125
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT")) {
126
+ throw error
127
+ }
128
+ }
129
+
130
+ return canonical
131
+ }
132
+
133
+ async function canonicalPath(path: string): Promise<string> {
134
+ if (!isFullyQualifiedPath(path)) {
135
+ throw new Error(`${path}: expected a fully qualified absolute path on this platform`)
136
+ }
137
+
138
+ const absolute = resolve(path)
139
+ const root = parse(absolute).root
140
+ if (isNamespaceVolumeRoot(root)) {
141
+ throw new Error(`${path}: volume GUID paths are not supported`)
142
+ }
143
+ const parts = absolute.slice(root.length).split(sep).filter(Boolean)
144
+ let current = await realpath(root)
145
+
146
+ for (const [index, part] of parts.entries()) {
147
+ if (!(await stat(current)).isDirectory()) {
148
+ throw new Error(`${current}: expected an existing ancestor directory`)
149
+ }
150
+ const candidate = join(current, part)
151
+ try {
152
+ await lstat(candidate)
153
+ } catch (error) {
154
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
155
+ return join(current, ...parts.slice(index))
156
+ }
157
+ throw error
158
+ }
159
+ current = await realpath(candidate)
160
+ }
161
+
162
+ return current
163
+ }
@@ -0,0 +1 @@
1
+ export const NAMESPACE_VOLUME_ROOT = /^\\\\[?.]\\Volume\{[^}]+\}\\?$/i
@@ -0,0 +1,14 @@
1
+ import { isAbsolute, parse, sep } from "node:path"
2
+
3
+ export function isFullyQualifiedPath(path: string): boolean {
4
+ if (!isAbsolute(path)) {
5
+ return false
6
+ }
7
+
8
+ const root = parse(path).root.replaceAll("\\", "/")
9
+ if (sep === "\\" && !root.includes(":") && !root.startsWith("//")) {
10
+ return false
11
+ }
12
+
13
+ return true
14
+ }
@@ -0,0 +1,12 @@
1
+ export * from "./canonicalize.ts"
2
+ export * from "./fully-qualified-path.ts"
3
+ export * from "./path-identity.ts"
4
+ export * from "./read.ts"
5
+ export * from "./registration.ts"
6
+ export * from "./resolve-input.ts"
7
+ export * from "./snapshot.ts"
8
+ export * from "./target.ts"
9
+ export * from "./types.ts"
10
+ export * from "./vault-access.ts"
11
+ export * from "./volume-namespace.ts"
12
+ export * from "./write.ts"
@@ -0,0 +1,65 @@
1
+ import { stat } from "node:fs/promises"
2
+ import { dirname, resolve } from "node:path"
3
+
4
+ import { isFullyQualifiedPath } from "./fully-qualified-path.ts"
5
+ import type { FileIdentityResult, PathIdentitiesResult, PathIdentity } from "./types.ts"
6
+ import { isNamespaceVolumeRoot } from "./volume-namespace.ts"
7
+
8
+ export async function fileIdentity(path: string): Promise<FileIdentityResult> {
9
+ if (!isFullyQualifiedPath(path)) {
10
+ return { succeeded: false, problems: [`${path}: expected a fully qualified absolute path on this platform`] }
11
+ }
12
+
13
+ try {
14
+ return { succeeded: true, output: await identityOf(path) }
15
+ } catch (error) {
16
+ return { succeeded: false, problems: [`${path}: ${String(error)}`] }
17
+ }
18
+ }
19
+
20
+ export async function pathIdentities(absolute: string): Promise<PathIdentitiesResult> {
21
+ if (!isFullyQualifiedPath(absolute)) {
22
+ return { succeeded: false, problems: [`${absolute}: expected a fully qualified absolute path on this platform`] }
23
+ }
24
+
25
+ const identities: PathIdentity[] = []
26
+ try {
27
+ for (const path of chain(resolve(absolute))) {
28
+ if (await exists(path)) {
29
+ identities.push(await identityOf(path))
30
+ }
31
+ }
32
+ } catch (error) {
33
+ return { succeeded: false, problems: [`${absolute}: ${String(error)}`] }
34
+ }
35
+
36
+ if (identities.length === 0) {
37
+ return { succeeded: false, problems: [`${absolute}: no existing ancestor`] }
38
+ }
39
+ return { succeeded: true, output: identities }
40
+ }
41
+
42
+ function chain(path: string): string[] {
43
+ const paths = [path]
44
+ for (let parent = dirname(path); parent !== paths.at(-1); parent = dirname(parent)) {
45
+ paths.push(parent)
46
+ }
47
+ return paths.filter((path) => !isNamespaceVolumeRoot(path))
48
+ }
49
+
50
+ async function exists(path: string): Promise<boolean> {
51
+ try {
52
+ await stat(path)
53
+ return true
54
+ } catch (error) {
55
+ if (error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")) {
56
+ return false
57
+ }
58
+ throw error
59
+ }
60
+ }
61
+
62
+ async function identityOf(path: string): Promise<PathIdentity> {
63
+ const stats = await stat(path, { bigint: true })
64
+ return { device: String(stats.dev), inode: String(stats.ino) }
65
+ }
@@ -0,0 +1,75 @@
1
+ import { createHash } from "node:crypto"
2
+ import { link, open, rename, unlink } from "node:fs/promises"
3
+
4
+ import { readConfigSnapshot } from "./snapshot.ts"
5
+ import type {
6
+ CheckConfigSnapshotResult,
7
+ ConfigPublicationRequest,
8
+ WriteConfigRequest,
9
+ WriteConfigResult,
10
+ } from "./types.ts"
11
+
12
+ export async function checkConfigSnapshot(request: WriteConfigRequest): Promise<CheckConfigSnapshotResult> {
13
+ const snapshot = await readConfigSnapshot(request)
14
+ if (!snapshot.succeeded) {
15
+ return { ...snapshot, reason: "unavailable", warnings: [] }
16
+ }
17
+ if (snapshot.output.hash !== request.expectedHash) {
18
+ return { succeeded: false, reason: "conflict", problems: ["config changed since it was read"], warnings: [] }
19
+ }
20
+ if (
21
+ snapshot.output.state === "present" &&
22
+ snapshot.output.repair.replacementRequired &&
23
+ !request.replacementConfirmed
24
+ ) {
25
+ return {
26
+ succeeded: false,
27
+ reason: "replacement-required",
28
+ problems: ["invalid JSON requires explicit replacement confirmation"],
29
+ warnings: [],
30
+ }
31
+ }
32
+ return snapshot
33
+ }
34
+
35
+ export async function publishConfig(context: ConfigPublicationRequest): Promise<WriteConfigResult> {
36
+ const { request, temporaryPath, warnings } = context
37
+ const text = `${JSON.stringify(request.config, null, 2)}\n`
38
+ const handle = await open(temporaryPath, "wx")
39
+ try {
40
+ try {
41
+ await handle.writeFile(text, "utf8")
42
+ await handle.sync()
43
+ } finally {
44
+ await handle.close()
45
+ }
46
+ return await installConfig(context, text)
47
+ } finally {
48
+ await removeConfigArtifact(temporaryPath, warnings)
49
+ }
50
+ }
51
+
52
+ async function installConfig(context: ConfigPublicationRequest, text: string): Promise<WriteConfigResult> {
53
+ const { request, temporaryPath, warnings } = context
54
+ const snapshot = await checkConfigSnapshot(request)
55
+ if (!snapshot.succeeded) {
56
+ return { ...snapshot, warnings }
57
+ }
58
+ if (snapshot.output.state === "missing") {
59
+ await link(temporaryPath, request.path)
60
+ } else {
61
+ await rename(temporaryPath, request.path)
62
+ }
63
+ return { succeeded: true, output: { hash: createHash("sha256").update(text).digest("hex") }, warnings }
64
+ }
65
+
66
+ export async function removeConfigArtifact(path: string, warnings: string[]): Promise<void> {
67
+ try {
68
+ await unlink(path)
69
+ } catch (error) {
70
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
71
+ return
72
+ }
73
+ warnings.push(`${path}: could not remove registration artifact (${String(error)})`)
74
+ }
75
+ }
@@ -0,0 +1,47 @@
1
+ import { readFile } from "node:fs/promises"
2
+
3
+ import type { PathPlatform } from "#src/domain"
4
+ import { parseConfig } from "#src/domain"
5
+ import { canonicalizeConfigLocation } from "./canonicalize.ts"
6
+ import type { ReadConfigResult } from "./types.ts"
7
+
8
+ export async function readConfig(path: string, platform: PathPlatform): Promise<ReadConfigResult> {
9
+ let text: string
10
+ try {
11
+ text = await readFile(path, "utf8")
12
+ } catch (error) {
13
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
14
+ return {
15
+ succeeded: false,
16
+ reason: "not-configured",
17
+ configPath: path,
18
+ problems: ["memory is not configured"],
19
+ }
20
+ }
21
+
22
+ let code = "UNKNOWN"
23
+ if (error instanceof Error && "code" in error && typeof error.code === "string") {
24
+ code = error.code
25
+ }
26
+
27
+ return {
28
+ succeeded: false,
29
+ reason: "unreadable",
30
+ configPath: path,
31
+ code,
32
+ problems: [`${path}: cannot read config (${code})`],
33
+ }
34
+ }
35
+
36
+ const parsed = parseConfig(text, platform)
37
+ if (!parsed.succeeded) {
38
+ return { succeeded: false, reason: "invalid-config", configPath: path, problems: parsed.problems }
39
+ }
40
+
41
+ const canonical = await canonicalizeConfigLocation({ config: parsed.output, configPath: path, platform })
42
+ if (!canonical.succeeded) {
43
+ return { succeeded: false, reason: "invalid-config", configPath: path, problems: canonical.problems }
44
+ }
45
+
46
+ return parsed
47
+ }
@@ -0,0 +1,26 @@
1
+ export type {
2
+ ChatModelReference,
3
+ ConfigFields,
4
+ ConfigRepairDraft,
5
+ InitProposal,
6
+ MemoryConfig,
7
+ ParseConfigResult,
8
+ ProjectEntry,
9
+ ResolveProjectResult,
10
+ SettingChange,
11
+ SettingNumberKind,
12
+ SettingNumberResult,
13
+ SetupDisclosure,
14
+ SetupProposal,
15
+ } from "#src/domain"
16
+ export {
17
+ changeSetting,
18
+ inspectConfigForRepair,
19
+ parseSettingNumber,
20
+ prepareSetupDefaults,
21
+ proposeInit,
22
+ proposeSetup,
23
+ resolveProject,
24
+ setupDisclosures,
25
+ } from "#src/domain"
26
+ export { checkConfigSnapshot } from "./publication.ts"
@@ -0,0 +1,27 @@
1
+ import { isAbsolute, parse, resolve, sep } from "node:path"
2
+
3
+ import type { CanonicalPathResult, RegistrationVaultInput } from "./types.ts"
4
+
5
+ export function resolveRegistrationVault(request: RegistrationVaultInput): CanonicalPathResult {
6
+ if (!fullyQualified(request.workingFolder)) {
7
+ return { succeeded: false, problems: ["workingFolder must be a fully qualified absolute path"] }
8
+ }
9
+ if (request.vault.trim() === "" || ambiguousWindowsPath(request.vault)) {
10
+ return { succeeded: false, problems: ["vault must be a nonblank unambiguous path"] }
11
+ }
12
+ if (isAbsolute(request.vault) && !fullyQualified(request.vault)) {
13
+ return { succeeded: false, problems: ["vault must include its absolute root"] }
14
+ }
15
+ return { succeeded: true, output: resolve(request.workingFolder, request.vault) }
16
+ }
17
+
18
+ function fullyQualified(path: string): boolean {
19
+ if (!isAbsolute(path) || ambiguousWindowsPath(path)) return false
20
+ const root = parse(path).root.replaceAll("\\", "/")
21
+ if (sep === "\\" && !root.includes(":") && !root.startsWith("//")) return false
22
+ return true
23
+ }
24
+
25
+ function ambiguousWindowsPath(path: string): boolean {
26
+ return /^[A-Za-z]:(?![/\\])/.test(path) || /^\\(?!\\)/.test(path)
27
+ }
@@ -0,0 +1,26 @@
1
+ import { createHash } from "node:crypto"
2
+ import { readFile } from "node:fs/promises"
3
+
4
+ import { assessConfig } from "#src/domain"
5
+ import type { ConfigLocation, ReadConfigSnapshotResult } from "./types.ts"
6
+
7
+ export async function readConfigSnapshot(request: ConfigLocation): Promise<ReadConfigSnapshotResult> {
8
+ try {
9
+ const bytes = await readFile(request.path)
10
+ const text = bytes.toString("utf8")
11
+ return {
12
+ succeeded: true,
13
+ output: {
14
+ state: "present",
15
+ hash: createHash("sha256").update(bytes).digest("hex"),
16
+ text,
17
+ ...assessConfig(text, request.platform),
18
+ },
19
+ }
20
+ } catch (error) {
21
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
22
+ return { succeeded: true, output: { state: "missing", hash: null } }
23
+ }
24
+ return { succeeded: false, problems: [`${request.path}: ${String(error)}`] }
25
+ }
26
+ }
@@ -0,0 +1,2 @@
1
+ export type { MemoryScope, NoProjectRefusal, TargetVaultResult, VaultTarget } from "#src/domain"
2
+ export { MemoryScopeSchema, targetVault } from "#src/domain"
@@ -0,0 +1,97 @@
1
+ import type { ConfigRepairDraft, MemoryConfig, ParseConfigResult, PathPlatform } from "#src/domain"
2
+ import type { Failed, Succeeded } from "#src/shared"
3
+
4
+ export type ConfigFailureReason = "not-configured" | "invalid-config" | "unreadable"
5
+
6
+ export interface ConfigRefusal extends Failed {
7
+ reason: ConfigFailureReason
8
+ configPath: string
9
+ }
10
+
11
+ export interface ConfigUnreadable extends ConfigRefusal {
12
+ reason: "unreadable"
13
+ code: string
14
+ }
15
+
16
+ export type ReadConfigResult = Succeeded<MemoryConfig> | ConfigRefusal | ConfigUnreadable
17
+
18
+ export interface ConfigLocation {
19
+ path: string
20
+ platform: PathPlatform
21
+ }
22
+
23
+ export interface RegistrationVaultInput {
24
+ vault: string
25
+ workingFolder: string
26
+ }
27
+
28
+ export interface MissingConfigSnapshot {
29
+ state: "missing"
30
+ hash: null
31
+ }
32
+
33
+ export interface PresentConfigSnapshot {
34
+ state: "present"
35
+ hash: string
36
+ text: string
37
+ lexicalParse: ParseConfigResult
38
+ repair: ConfigRepairDraft
39
+ }
40
+
41
+ export type ConfigSnapshot = MissingConfigSnapshot | PresentConfigSnapshot
42
+ export type ReadConfigSnapshotResult = Succeeded<ConfigSnapshot> | Failed
43
+
44
+ export interface ConfigRegistrationLocation {
45
+ config: MemoryConfig
46
+ configPath: string
47
+ platform: PathPlatform
48
+ }
49
+
50
+ export type ConfigRegistrationLocationResult = Succeeded<ConfigRegistrationLocation> | Failed
51
+
52
+ export interface RegistrationPaths extends ConfigRegistrationLocation {
53
+ indexPath: string
54
+ }
55
+
56
+ export type RegistrationPathsResult = Succeeded<RegistrationPaths> | Failed
57
+ export type CanonicalPathResult = Succeeded<string> | Failed
58
+ export type CanonicalConfigResult = Succeeded<MemoryConfig> | Failed
59
+
60
+ export interface WriteConfigRequest extends ConfigLocation {
61
+ indexPath: string
62
+ config: MemoryConfig
63
+ expectedHash: string | null
64
+ replacementConfirmed?: true
65
+ }
66
+
67
+ export interface ConfigPublication {
68
+ hash: string
69
+ }
70
+
71
+ export interface ConfigWritten extends Succeeded<ConfigPublication> {
72
+ warnings: string[]
73
+ }
74
+
75
+ export type ConfigWriteFailureReason = "conflict" | "invalid-config" | "replacement-required" | "unavailable"
76
+
77
+ export interface ConfigWriteRefusal extends Failed {
78
+ reason: ConfigWriteFailureReason
79
+ warnings: string[]
80
+ }
81
+
82
+ export type WriteConfigResult = ConfigWritten | ConfigWriteRefusal
83
+ export type CheckConfigSnapshotResult = Succeeded<ConfigSnapshot> | ConfigWriteRefusal
84
+
85
+ export interface ConfigPublicationRequest {
86
+ request: WriteConfigRequest
87
+ temporaryPath: string
88
+ warnings: string[]
89
+ }
90
+
91
+ export interface PathIdentity {
92
+ device: string
93
+ inode: string
94
+ }
95
+
96
+ export type FileIdentityResult = Succeeded<PathIdentity> | Failed
97
+ export type PathIdentitiesResult = Succeeded<PathIdentity[]> | Failed
@@ -0,0 +1,2 @@
1
+ export type { PathPlatform, VaultAccessRequest } from "#src/domain"
2
+ export { absoluteCandidate, VAULT_ACCESS_REFUSAL, vaultAccessRefusal } from "#src/domain"
@@ -0,0 +1,5 @@
1
+ import { NAMESPACE_VOLUME_ROOT } from "./constants.ts"
2
+
3
+ export function isNamespaceVolumeRoot(path: string): boolean {
4
+ return NAMESPACE_VOLUME_ROOT.test(path)
5
+ }
@@ -0,0 +1,63 @@
1
+ import { randomUUID } from "node:crypto"
2
+ import { mkdir, open } from "node:fs/promises"
3
+ import { basename, dirname, join } from "node:path"
4
+
5
+ import { canonicalizeRegistration } from "./canonicalize.ts"
6
+ import { checkConfigSnapshot, publishConfig, removeConfigArtifact } from "./publication.ts"
7
+ import type { WriteConfigRequest, WriteConfigResult } from "./types.ts"
8
+
9
+ export async function writeConfig(request: WriteConfigRequest): Promise<WriteConfigResult> {
10
+ const canonical = await canonicalizeRegistration({
11
+ config: request.config,
12
+ configPath: request.path,
13
+ indexPath: request.indexPath,
14
+ platform: request.platform,
15
+ })
16
+ if (!canonical.succeeded) {
17
+ return { ...canonical, reason: "invalid-config", warnings: [] }
18
+ }
19
+ const resolved = { ...request, path: canonical.output.configPath }
20
+ try {
21
+ await mkdir(dirname(resolved.path), { recursive: true })
22
+ return await writeWithLock(resolved)
23
+ } catch (error) {
24
+ return { succeeded: false, reason: "unavailable", problems: [String(error)], warnings: [] }
25
+ }
26
+ }
27
+
28
+ async function writeWithLock(request: WriteConfigRequest): Promise<WriteConfigResult> {
29
+ const lockPath = join(dirname(request.path), `.${basename(request.path)}.lock`)
30
+ const lock = await open(lockPath, "wx")
31
+ const warnings: string[] = []
32
+ try {
33
+ return await writeCheckedConfig(request, warnings)
34
+ } finally {
35
+ try {
36
+ await lock.close()
37
+ } catch (error) {
38
+ warnings.push(`${lockPath}: could not close lock (${String(error)})`)
39
+ }
40
+ await removeConfigArtifact(lockPath, warnings)
41
+ }
42
+ }
43
+
44
+ async function writeCheckedConfig(request: WriteConfigRequest, warnings: string[]): Promise<WriteConfigResult> {
45
+ const temporaryPath = join(dirname(request.path), `.${basename(request.path)}.tmp-${randomUUID()}`)
46
+ try {
47
+ const snapshot = await checkConfigSnapshot(request)
48
+ if (!snapshot.succeeded) {
49
+ return { ...snapshot, warnings }
50
+ }
51
+ return await publishConfig({ request, temporaryPath, warnings })
52
+ } catch (error) {
53
+ if (error instanceof Error && "code" in error && error.code === "EEXIST") {
54
+ return {
55
+ succeeded: false,
56
+ reason: "conflict",
57
+ problems: ["config publication destination already exists"],
58
+ warnings,
59
+ }
60
+ }
61
+ return { succeeded: false, reason: "unavailable", problems: [String(error)], warnings }
62
+ }
63
+ }
@@ -0,0 +1,16 @@
1
+ export const defaultLayaSettings = {
2
+ provider: "laya",
3
+ endpoint: "http://127.0.0.1:8000/v1/systemone",
4
+ model: "multilingual",
5
+ maxTokens: 8192,
6
+ headMaxTokens: 192,
7
+ } as const
8
+
9
+ export const defaultJevModel = "jev-latest"
10
+ export const maxDecisionResponseBytes = 65_536
11
+
12
+ export const modelVersionPattern = /^\d+(?:\.\d+)*$/
13
+
14
+ export const layaNoulLabels = { true: "A", false: "B" } as const
15
+ export const layaServeMaxBatchStates = 64
16
+ export const maxLayaBatchResponseBytes = layaServeMaxBatchStates * maxDecisionResponseBytes