pi-obsidian-memory 0.0.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. package/README.md +173 -7
  2. package/package.json +45 -7
  3. package/skills/obsidian-memory/SKILL.md +101 -0
  4. package/src/domain/capture/constants.ts +5 -0
  5. package/src/domain/capture/index.ts +6 -0
  6. package/src/domain/capture/input-problems.ts +9 -0
  7. package/src/domain/capture/schemas.ts +92 -0
  8. package/src/domain/capture/tally.ts +26 -0
  9. package/src/domain/capture/types.ts +49 -0
  10. package/src/domain/capture/validate.ts +75 -0
  11. package/src/domain/command-flags/constants.ts +141 -0
  12. package/src/domain/command-flags/index.ts +1 -0
  13. package/src/domain/config/change.ts +105 -0
  14. package/src/domain/config/constants.ts +25 -0
  15. package/src/domain/config/diagnostics.ts +35 -0
  16. package/src/domain/config/disclosures.ts +8 -0
  17. package/src/domain/config/fields.ts +7 -0
  18. package/src/domain/config/index.ts +11 -0
  19. package/src/domain/config/inspection.ts +43 -0
  20. package/src/domain/config/invariants.ts +68 -0
  21. package/src/domain/config/legacy-capture.ts +17 -0
  22. package/src/domain/config/observations.ts +109 -0
  23. package/src/domain/config/parse.ts +25 -0
  24. package/src/domain/config/paths.ts +61 -0
  25. package/src/domain/config/registration.ts +34 -0
  26. package/src/domain/config/repair.ts +36 -0
  27. package/src/domain/config/resources.ts +65 -0
  28. package/src/domain/config/rules.ts +49 -0
  29. package/src/domain/config/schemas.ts +155 -0
  30. package/src/domain/config/settings.ts +23 -0
  31. package/src/domain/config/types.ts +239 -0
  32. package/src/domain/decision-model/constants.ts +7 -0
  33. package/src/domain/decision-model/cutoffs.ts +8 -0
  34. package/src/domain/decision-model/endpoint.ts +11 -0
  35. package/src/domain/decision-model/failure-detail.ts +8 -0
  36. package/src/domain/decision-model/index.ts +6 -0
  37. package/src/domain/decision-model/rank.ts +36 -0
  38. package/src/domain/decision-model/types.ts +77 -0
  39. package/src/domain/embeddings/constants.ts +55 -0
  40. package/src/domain/embeddings/identity.ts +30 -0
  41. package/src/domain/embeddings/index.ts +5 -0
  42. package/src/domain/embeddings/schemas.ts +25 -0
  43. package/src/domain/embeddings/types.ts +52 -0
  44. package/src/domain/embeddings/vectors.ts +53 -0
  45. package/src/domain/folder-index/constants.ts +9 -0
  46. package/src/domain/folder-index/display.ts +22 -0
  47. package/src/domain/folder-index/index.ts +5 -0
  48. package/src/domain/folder-index/listing.ts +58 -0
  49. package/src/domain/folder-index/render.ts +114 -0
  50. package/src/domain/folder-index/types.ts +41 -0
  51. package/src/domain/index.ts +22 -0
  52. package/src/domain/lifecycle/index.ts +2 -0
  53. package/src/domain/lifecycle/lifecycle.ts +39 -0
  54. package/src/domain/lifecycle/types.ts +17 -0
  55. package/src/domain/loaded-memory/budget.ts +14 -0
  56. package/src/domain/loaded-memory/constants.ts +9 -0
  57. package/src/domain/loaded-memory/index.ts +4 -0
  58. package/src/domain/loaded-memory/render.ts +30 -0
  59. package/src/domain/loaded-memory/types.ts +19 -0
  60. package/src/domain/memory/draft.ts +12 -0
  61. package/src/domain/memory/index.ts +4 -0
  62. package/src/domain/memory/schemas.ts +15 -0
  63. package/src/domain/memory/target.ts +27 -0
  64. package/src/domain/memory/types.ts +20 -0
  65. package/src/domain/memory-agent/index.ts +5 -0
  66. package/src/domain/memory-agent/input-problems.ts +9 -0
  67. package/src/domain/memory-agent/refusal.ts +6 -0
  68. package/src/domain/memory-agent/schemas.ts +112 -0
  69. package/src/domain/memory-agent/types.ts +25 -0
  70. package/src/domain/memory-agent/validate.ts +67 -0
  71. package/src/domain/names/constants.ts +32 -0
  72. package/src/domain/names/index.ts +2 -0
  73. package/src/domain/names/names.ts +83 -0
  74. package/src/domain/note/check.ts +68 -0
  75. package/src/domain/note/constants.ts +15 -0
  76. package/src/domain/note/frontmatter-fields.ts +175 -0
  77. package/src/domain/note/frontmatter.ts +138 -0
  78. package/src/domain/note/index.ts +9 -0
  79. package/src/domain/note/parse.ts +41 -0
  80. package/src/domain/note/render.ts +27 -0
  81. package/src/domain/note/schema-errors.ts +41 -0
  82. package/src/domain/note/schemas.ts +38 -0
  83. package/src/domain/note/types.ts +53 -0
  84. package/src/domain/note/validate.ts +19 -0
  85. package/src/domain/path-platform/index.ts +2 -0
  86. package/src/domain/path-platform/path-module.ts +11 -0
  87. package/src/domain/path-platform/types.ts +1 -0
  88. package/src/domain/search-catalog/constants.ts +1 -0
  89. package/src/domain/search-catalog/coverage.ts +35 -0
  90. package/src/domain/search-catalog/dont-forget.ts +10 -0
  91. package/src/domain/search-catalog/fingerprint.ts +9 -0
  92. package/src/domain/search-catalog/index.ts +10 -0
  93. package/src/domain/search-catalog/inspection.ts +47 -0
  94. package/src/domain/search-catalog/plan.ts +68 -0
  95. package/src/domain/search-catalog/ranking.ts +27 -0
  96. package/src/domain/search-catalog/schemas.ts +49 -0
  97. package/src/domain/search-catalog/types.ts +103 -0
  98. package/src/domain/search-catalog/vector-refresh.ts +22 -0
  99. package/src/domain/shell-edit/command-segments.ts +28 -0
  100. package/src/domain/shell-edit/command-words.ts +22 -0
  101. package/src/domain/shell-edit/constants.ts +125 -0
  102. package/src/domain/shell-edit/executed-files.ts +154 -0
  103. package/src/domain/shell-edit/index.ts +6 -0
  104. package/src/domain/shell-edit/powershell-files.ts +38 -0
  105. package/src/domain/shell-edit/rules.ts +19 -0
  106. package/src/domain/shell-edit/types.ts +75 -0
  107. package/src/domain/tool-flags/constants.ts +178 -0
  108. package/src/domain/tool-flags/index.ts +2 -0
  109. package/src/domain/tool-flags/types.ts +7 -0
  110. package/src/domain/validation/constants.ts +1 -0
  111. package/src/domain/validation/describe.ts +137 -0
  112. package/src/domain/validation/index.ts +3 -0
  113. package/src/domain/validation/types.ts +3 -0
  114. package/src/domain/vault-access/absolute-candidate.ts +81 -0
  115. package/src/domain/vault-access/argument-tokens.ts +22 -0
  116. package/src/domain/vault-access/command-mentions-vault.ts +115 -0
  117. package/src/domain/vault-access/constants.ts +54 -0
  118. package/src/domain/vault-access/index.ts +7 -0
  119. package/src/domain/vault-access/types.ts +18 -0
  120. package/src/domain/vault-access/vault-access-refusal.ts +36 -0
  121. package/src/domain/vault-access/vault-location.ts +22 -0
  122. package/src/domain/vault-assets/index.ts +2 -0
  123. package/src/domain/vault-assets/render.ts +51 -0
  124. package/src/domain/vault-assets/types.ts +36 -0
  125. package/src/domain/vault-catalog/analyze.ts +37 -0
  126. package/src/domain/vault-catalog/classify.ts +37 -0
  127. package/src/domain/vault-catalog/dont-forget.ts +6 -0
  128. package/src/domain/vault-catalog/export-entries.ts +10 -0
  129. package/src/domain/vault-catalog/index.ts +5 -0
  130. package/src/domain/vault-catalog/types.ts +114 -0
  131. package/src/domain/vault-diagnosis/diagnose.ts +79 -0
  132. package/src/domain/vault-diagnosis/index.ts +2 -0
  133. package/src/domain/vault-diagnosis/types.ts +31 -0
  134. package/src/domain/vault-path/constants.ts +13 -0
  135. package/src/domain/vault-path/index.ts +2 -0
  136. package/src/domain/vault-path/vault-path.ts +65 -0
  137. package/src/pi/capture/cadence.ts +49 -0
  138. package/src/pi/capture/completion.ts +26 -0
  139. package/src/pi/capture/constants.ts +5 -0
  140. package/src/pi/capture/handlers.ts +30 -0
  141. package/src/pi/capture/index.ts +8 -0
  142. package/src/pi/capture/runtime.ts +83 -0
  143. package/src/pi/capture/schemas.ts +8 -0
  144. package/src/pi/capture/tool-calls.ts +6 -0
  145. package/src/pi/capture/transcript.ts +55 -0
  146. package/src/pi/capture/types.ts +46 -0
  147. package/src/pi/change-report/constants.ts +15 -0
  148. package/src/pi/change-report/index.ts +3 -0
  149. package/src/pi/change-report/report.ts +54 -0
  150. package/src/pi/change-report/types.ts +8 -0
  151. package/src/pi/context/constants.ts +5 -0
  152. package/src/pi/context/index.ts +3 -0
  153. package/src/pi/context/status.ts +15 -0
  154. package/src/pi/context/types.ts +98 -0
  155. package/src/pi/extension.ts +100 -0
  156. package/src/pi/index.ts +26 -0
  157. package/src/pi/memory-add/constants.ts +13 -0
  158. package/src/pi/memory-add/index.ts +5 -0
  159. package/src/pi/memory-add/memory-add.ts +31 -0
  160. package/src/pi/memory-add/respond.ts +55 -0
  161. package/src/pi/memory-add/schemas.ts +29 -0
  162. package/src/pi/memory-add/types.ts +15 -0
  163. package/src/pi/memory-archive/constants.ts +8 -0
  164. package/src/pi/memory-archive/index.ts +4 -0
  165. package/src/pi/memory-archive/memory-archive.ts +29 -0
  166. package/src/pi/memory-archive/schemas.ts +15 -0
  167. package/src/pi/memory-archive/types.ts +8 -0
  168. package/src/pi/memory-block/block.ts +75 -0
  169. package/src/pi/memory-block/constants.ts +24 -0
  170. package/src/pi/memory-block/index.ts +4 -0
  171. package/src/pi/memory-block/render.ts +54 -0
  172. package/src/pi/memory-block/types.ts +24 -0
  173. package/src/pi/memory-doctor/constants.ts +43 -0
  174. package/src/pi/memory-doctor/index.ts +4 -0
  175. package/src/pi/memory-doctor/memory-doctor.ts +135 -0
  176. package/src/pi/memory-doctor/report.ts +101 -0
  177. package/src/pi/memory-doctor/types.ts +13 -0
  178. package/src/pi/memory-export/constants.ts +15 -0
  179. package/src/pi/memory-export/index.ts +4 -0
  180. package/src/pi/memory-export/memory-export.ts +57 -0
  181. package/src/pi/memory-export/name.ts +9 -0
  182. package/src/pi/memory-export/types.ts +4 -0
  183. package/src/pi/memory-get/constants.ts +12 -0
  184. package/src/pi/memory-get/index.ts +5 -0
  185. package/src/pi/memory-get/memory-get.ts +23 -0
  186. package/src/pi/memory-get/respond.ts +38 -0
  187. package/src/pi/memory-get/schemas.ts +13 -0
  188. package/src/pi/memory-get/types.ts +10 -0
  189. package/src/pi/memory-init/constants.ts +17 -0
  190. package/src/pi/memory-init/index.ts +2 -0
  191. package/src/pi/memory-init/memory-init.ts +63 -0
  192. package/src/pi/memory-search/constants.ts +16 -0
  193. package/src/pi/memory-search/index.ts +5 -0
  194. package/src/pi/memory-search/memory-search.ts +22 -0
  195. package/src/pi/memory-search/respond.ts +62 -0
  196. package/src/pi/memory-search/schemas.ts +11 -0
  197. package/src/pi/memory-search/types.ts +10 -0
  198. package/src/pi/memory-session/constants.ts +7 -0
  199. package/src/pi/memory-session/index.ts +4 -0
  200. package/src/pi/memory-session/keeper.ts +101 -0
  201. package/src/pi/memory-session/respond.ts +6 -0
  202. package/src/pi/memory-session/types.ts +23 -0
  203. package/src/pi/memory-settings/constants.ts +69 -0
  204. package/src/pi/memory-settings/edits.ts +46 -0
  205. package/src/pi/memory-settings/index.ts +9 -0
  206. package/src/pi/memory-settings/lines.ts +119 -0
  207. package/src/pi/memory-settings/models.ts +81 -0
  208. package/src/pi/memory-settings/projects.ts +46 -0
  209. package/src/pi/memory-settings/providers.ts +77 -0
  210. package/src/pi/memory-settings/save.ts +16 -0
  211. package/src/pi/memory-settings/screen.ts +27 -0
  212. package/src/pi/memory-settings/types.ts +87 -0
  213. package/src/pi/memory-setup/constants.ts +33 -0
  214. package/src/pi/memory-setup/disclosure.ts +22 -0
  215. package/src/pi/memory-setup/index.ts +4 -0
  216. package/src/pi/memory-setup/memory-setup.ts +153 -0
  217. package/src/pi/memory-setup/types.ts +6 -0
  218. package/src/pi/memory-succeed/constants.ts +10 -0
  219. package/src/pi/memory-succeed/index.ts +4 -0
  220. package/src/pi/memory-succeed/memory-succeed.ts +34 -0
  221. package/src/pi/memory-succeed/schemas.ts +30 -0
  222. package/src/pi/memory-succeed/types.ts +8 -0
  223. package/src/pi/memory-update/constants.ts +8 -0
  224. package/src/pi/memory-update/index.ts +4 -0
  225. package/src/pi/memory-update/memory-update.ts +29 -0
  226. package/src/pi/memory-update/schemas.ts +24 -0
  227. package/src/pi/memory-update/types.ts +8 -0
  228. package/src/pi/paths/constants.ts +7 -0
  229. package/src/pi/paths/index.ts +2 -0
  230. package/src/pi/paths/paths.ts +15 -0
  231. package/src/pi/paths/platform.ts +7 -0
  232. package/src/pi/registrar.ts +25 -0
  233. package/src/pi/registration-report/constants.ts +13 -0
  234. package/src/pi/registration-report/index.ts +2 -0
  235. package/src/pi/registration-report/report.ts +26 -0
  236. package/src/pi/relevant-memory/constants.ts +3 -0
  237. package/src/pi/relevant-memory/index.ts +4 -0
  238. package/src/pi/relevant-memory/prompt.ts +23 -0
  239. package/src/pi/relevant-memory/runtime.ts +88 -0
  240. package/src/pi/relevant-memory/types.ts +14 -0
  241. package/src/pi/semantic/constants.ts +3 -0
  242. package/src/pi/semantic/index.ts +2 -0
  243. package/src/pi/semantic/runtime.ts +59 -0
  244. package/src/pi/session-start/constants.ts +7 -0
  245. package/src/pi/session-start/index.ts +3 -0
  246. package/src/pi/session-start/session-start.ts +48 -0
  247. package/src/pi/session-start/types.ts +5 -0
  248. package/src/pi/shell-edit-guard/guard.ts +41 -0
  249. package/src/pi/shell-edit-guard/index.ts +3 -0
  250. package/src/pi/shell-edit-guard/prompt.ts +30 -0
  251. package/src/pi/shell-edit-guard/types.ts +13 -0
  252. package/src/pi/types.ts +44 -0
  253. package/src/pi/vault-guard/constants.ts +1 -0
  254. package/src/pi/vault-guard/index.ts +4 -0
  255. package/src/pi/vault-guard/request.ts +39 -0
  256. package/src/pi/vault-guard/types.ts +5 -0
  257. package/src/pi/vault-guard/vault-guard.ts +21 -0
  258. package/src/services/capture-cadence/domain-rules.ts +8 -0
  259. package/src/services/capture-cadence/index.ts +1 -0
  260. package/src/services/clock/clock.ts +7 -0
  261. package/src/services/clock/index.ts +1 -0
  262. package/src/services/config/canonicalize.ts +163 -0
  263. package/src/services/config/constants.ts +1 -0
  264. package/src/services/config/fully-qualified-path.ts +14 -0
  265. package/src/services/config/index.ts +12 -0
  266. package/src/services/config/path-identity.ts +65 -0
  267. package/src/services/config/publication.ts +75 -0
  268. package/src/services/config/read.ts +47 -0
  269. package/src/services/config/registration.ts +26 -0
  270. package/src/services/config/resolve-input.ts +27 -0
  271. package/src/services/config/snapshot.ts +26 -0
  272. package/src/services/config/target.ts +2 -0
  273. package/src/services/config/types.ts +97 -0
  274. package/src/services/config/vault-access.ts +2 -0
  275. package/src/services/config/volume-namespace.ts +5 -0
  276. package/src/services/config/write.ts +63 -0
  277. package/src/services/decision-model/constants.ts +16 -0
  278. package/src/services/decision-model/decide.ts +42 -0
  279. package/src/services/decision-model/diagnostics.ts +6 -0
  280. package/src/services/decision-model/endpoint.ts +1 -0
  281. package/src/services/decision-model/failure-detail.ts +1 -0
  282. package/src/services/decision-model/index.ts +7 -0
  283. package/src/services/decision-model/interruption.ts +29 -0
  284. package/src/services/decision-model/jev.ts +61 -0
  285. package/src/services/decision-model/laya-batch.ts +64 -0
  286. package/src/services/decision-model/laya-http-failure.ts +41 -0
  287. package/src/services/decision-model/laya-response.ts +95 -0
  288. package/src/services/decision-model/laya.ts +35 -0
  289. package/src/services/decision-model/preflight.ts +24 -0
  290. package/src/services/decision-model/prompts.ts +36 -0
  291. package/src/services/decision-model/schemas.ts +43 -0
  292. package/src/services/decision-model/score-candidates.ts +41 -0
  293. package/src/services/decision-model/types.ts +182 -0
  294. package/src/services/embeddings/asset-download.ts +45 -0
  295. package/src/services/embeddings/asset-fetch.ts +39 -0
  296. package/src/services/embeddings/asset-inspection.ts +36 -0
  297. package/src/services/embeddings/batch.ts +32 -0
  298. package/src/services/embeddings/chunks.ts +80 -0
  299. package/src/services/embeddings/configuration.ts +8 -0
  300. package/src/services/embeddings/constants.ts +24 -0
  301. package/src/services/embeddings/errors.ts +11 -0
  302. package/src/services/embeddings/google.ts +90 -0
  303. package/src/services/embeddings/http.ts +64 -0
  304. package/src/services/embeddings/index.ts +17 -0
  305. package/src/services/embeddings/inference.ts +35 -0
  306. package/src/services/embeddings/local.ts +138 -0
  307. package/src/services/embeddings/model-asset.ts +68 -0
  308. package/src/services/embeddings/model-cache.ts +30 -0
  309. package/src/services/embeddings/openai.ts +64 -0
  310. package/src/services/embeddings/operation.ts +31 -0
  311. package/src/services/embeddings/responses.ts +41 -0
  312. package/src/services/embeddings/runtime.ts +13 -0
  313. package/src/services/embeddings/schemas.ts +53 -0
  314. package/src/services/embeddings/types.ts +116 -0
  315. package/src/services/id/id.ts +5 -0
  316. package/src/services/id/index.ts +1 -0
  317. package/src/services/index.ts +11 -0
  318. package/src/services/llm/capture.ts +19 -0
  319. package/src/services/llm/check-chat-models.ts +38 -0
  320. package/src/services/llm/complete.ts +57 -0
  321. package/src/services/llm/constants.ts +32 -0
  322. package/src/services/llm/domain-rules.ts +2 -0
  323. package/src/services/llm/index.ts +6 -0
  324. package/src/services/llm/lifetime.ts +16 -0
  325. package/src/services/llm/retrieve.ts +19 -0
  326. package/src/services/llm/schemas.ts +9 -0
  327. package/src/services/llm/types.ts +94 -0
  328. package/src/services/search-index/catalog-query.ts +34 -0
  329. package/src/services/search-index/catalog-statements.ts +33 -0
  330. package/src/services/search-index/catalog.ts +19 -0
  331. package/src/services/search-index/cleanup.ts +13 -0
  332. package/src/services/search-index/close.ts +5 -0
  333. package/src/services/search-index/constants.ts +102 -0
  334. package/src/services/search-index/dont-forget.ts +1 -0
  335. package/src/services/search-index/fingerprint.ts +17 -0
  336. package/src/services/search-index/folder-index-statements.ts +17 -0
  337. package/src/services/search-index/folder-index-storage.ts +54 -0
  338. package/src/services/search-index/folder-indexes.ts +13 -0
  339. package/src/services/search-index/index.ts +14 -0
  340. package/src/services/search-index/inspection.ts +1 -0
  341. package/src/services/search-index/inventory.ts +67 -0
  342. package/src/services/search-index/legacy.ts +64 -0
  343. package/src/services/search-index/location.ts +12 -0
  344. package/src/services/search-index/open.ts +46 -0
  345. package/src/services/search-index/query.ts +39 -0
  346. package/src/services/search-index/ranking.ts +12 -0
  347. package/src/services/search-index/reconcile.ts +93 -0
  348. package/src/services/search-index/recovery.ts +56 -0
  349. package/src/services/search-index/refusals.ts +21 -0
  350. package/src/services/search-index/schema.ts +42 -0
  351. package/src/services/search-index/schemas.ts +181 -0
  352. package/src/services/search-index/search.ts +5 -0
  353. package/src/services/search-index/statements.ts +18 -0
  354. package/src/services/search-index/storage.ts +207 -0
  355. package/src/services/search-index/types.ts +113 -0
  356. package/src/services/search-index/vector-statements.ts +18 -0
  357. package/src/services/search-index/vector-storage.ts +169 -0
  358. package/src/services/search-index/vectors.ts +18 -0
  359. package/src/services/search-index/write.ts +9 -0
  360. package/src/services/shell-edit/ask.ts +53 -0
  361. package/src/services/shell-edit/domain-rules.ts +2 -0
  362. package/src/services/shell-edit/index.ts +4 -0
  363. package/src/services/shell-edit/schemas.ts +23 -0
  364. package/src/services/shell-edit/types.ts +61 -0
  365. package/src/services/shell-scripts/constants.ts +1 -0
  366. package/src/services/shell-scripts/files.ts +16 -0
  367. package/src/services/shell-scripts/index.ts +5 -0
  368. package/src/services/shell-scripts/package-scripts.ts +74 -0
  369. package/src/services/shell-scripts/schemas.ts +3 -0
  370. package/src/services/shell-scripts/scripts.ts +27 -0
  371. package/src/services/shell-scripts/types.ts +11 -0
  372. package/src/services/vault/archive.ts +31 -0
  373. package/src/services/vault/bootstrap/ensure.ts +50 -0
  374. package/src/services/vault/bootstrap/index.ts +2 -0
  375. package/src/services/vault/bootstrap/paths.ts +57 -0
  376. package/src/services/vault/bootstrap/types.ts +17 -0
  377. package/src/services/vault/bootstrap/write.ts +47 -0
  378. package/src/services/vault/catalog/bytes.ts +51 -0
  379. package/src/services/vault/catalog/dont-forget.ts +1 -0
  380. package/src/services/vault/catalog/enumerate.ts +69 -0
  381. package/src/services/vault/catalog/export.ts +21 -0
  382. package/src/services/vault/catalog/failures.ts +16 -0
  383. package/src/services/vault/catalog/index.ts +10 -0
  384. package/src/services/vault/catalog/inspect.ts +41 -0
  385. package/src/services/vault/catalog/observe.ts +35 -0
  386. package/src/services/vault/catalog/resolve.ts +94 -0
  387. package/src/services/vault/catalog/stat.ts +23 -0
  388. package/src/services/vault/catalog/types.ts +69 -0
  389. package/src/services/vault/catalog/visit.ts +58 -0
  390. package/src/services/vault/complete-blank.ts +66 -0
  391. package/src/services/vault/constants.ts +3 -0
  392. package/src/services/vault/context/index.ts +1 -0
  393. package/src/services/vault/context/types.ts +10 -0
  394. package/src/services/vault/create.ts +19 -0
  395. package/src/services/vault/display.ts +6 -0
  396. package/src/services/vault/domain-rules.ts +10 -0
  397. package/src/services/vault/draft.ts +2 -0
  398. package/src/services/vault/filesystem/failures.ts +53 -0
  399. package/src/services/vault/filesystem/hash.ts +5 -0
  400. package/src/services/vault/filesystem/index.ts +5 -0
  401. package/src/services/vault/filesystem/read.ts +61 -0
  402. package/src/services/vault/filesystem/types.ts +36 -0
  403. package/src/services/vault/filesystem/write.ts +80 -0
  404. package/src/services/vault/find.ts +27 -0
  405. package/src/services/vault/folder-contents.ts +31 -0
  406. package/src/services/vault/folder-index/index.ts +2 -0
  407. package/src/services/vault/folder-index/read.ts +87 -0
  408. package/src/services/vault/folder-index/types.ts +19 -0
  409. package/src/services/vault/folder-listing.ts +1 -0
  410. package/src/services/vault/index.ts +21 -0
  411. package/src/services/vault/inspect-folder.ts +13 -0
  412. package/src/services/vault/list.ts +121 -0
  413. package/src/services/vault/memory-folder.ts +24 -0
  414. package/src/services/vault/paths.ts +11 -0
  415. package/src/services/vault/publish.ts +52 -0
  416. package/src/services/vault/read.ts +46 -0
  417. package/src/services/vault/refresh-folders.ts +197 -0
  418. package/src/services/vault/refresh-plan.ts +79 -0
  419. package/src/services/vault/refresh.ts +8 -0
  420. package/src/services/vault/refusals.ts +23 -0
  421. package/src/services/vault/relocate.ts +131 -0
  422. package/src/services/vault/relocation-checks.ts +89 -0
  423. package/src/services/vault/resolve-stored-file.ts +43 -0
  424. package/src/services/vault/resolve.ts +109 -0
  425. package/src/services/vault/succeed.ts +45 -0
  426. package/src/services/vault/types.ts +199 -0
  427. package/src/services/vault/update-file.ts +58 -0
  428. package/src/services/vault/update.ts +22 -0
  429. package/src/services/vault/write-new-file.ts +37 -0
  430. package/src/shared/index.ts +1 -0
  431. package/src/shared/result/index.ts +1 -0
  432. package/src/shared/result/types.ts +17 -0
  433. package/src/usecases/add-memory/add-memory.ts +83 -0
  434. package/src/usecases/add-memory/index.ts +4 -0
  435. package/src/usecases/add-memory/maintenance.ts +23 -0
  436. package/src/usecases/add-memory/schemas.ts +12 -0
  437. package/src/usecases/add-memory/types.ts +47 -0
  438. package/src/usecases/archive-memory/archive-memory.ts +27 -0
  439. package/src/usecases/archive-memory/index.ts +3 -0
  440. package/src/usecases/archive-memory/schemas.ts +11 -0
  441. package/src/usecases/archive-memory/types.ts +17 -0
  442. package/src/usecases/capture-memory/apply.ts +73 -0
  443. package/src/usecases/capture-memory/capture-memory.ts +117 -0
  444. package/src/usecases/capture-memory/constants.ts +15 -0
  445. package/src/usecases/capture-memory/index.ts +5 -0
  446. package/src/usecases/capture-memory/observe.ts +122 -0
  447. package/src/usecases/capture-memory/settings.ts +20 -0
  448. package/src/usecases/capture-memory/types.ts +103 -0
  449. package/src/usecases/check-shell-edit/check-shell-edit.ts +28 -0
  450. package/src/usecases/check-shell-edit/index.ts +2 -0
  451. package/src/usecases/check-shell-edit/types.ts +30 -0
  452. package/src/usecases/check-vault-access/check-vault-access.ts +23 -0
  453. package/src/usecases/check-vault-access/constants.ts +7 -0
  454. package/src/usecases/check-vault-access/index.ts +4 -0
  455. package/src/usecases/check-vault-access/raw-device.ts +10 -0
  456. package/src/usecases/check-vault-access/targets.ts +49 -0
  457. package/src/usecases/check-vault-access/types.ts +33 -0
  458. package/src/usecases/complete-blank-memory/complete-blank-memory.ts +48 -0
  459. package/src/usecases/complete-blank-memory/constants.ts +3 -0
  460. package/src/usecases/complete-blank-memory/index.ts +4 -0
  461. package/src/usecases/complete-blank-memory/schemas.ts +14 -0
  462. package/src/usecases/complete-blank-memory/types.ts +28 -0
  463. package/src/usecases/diagnose-memory/constants.ts +3 -0
  464. package/src/usecases/diagnose-memory/decision.ts +36 -0
  465. package/src/usecases/diagnose-memory/diagnose-memory.ts +52 -0
  466. package/src/usecases/diagnose-memory/embeddings.ts +39 -0
  467. package/src/usecases/diagnose-memory/index.ts +5 -0
  468. package/src/usecases/diagnose-memory/types.ts +86 -0
  469. package/src/usecases/diagnose-memory/vault.ts +33 -0
  470. package/src/usecases/export-memory/collect.ts +20 -0
  471. package/src/usecases/export-memory/constants.ts +3 -0
  472. package/src/usecases/export-memory/export-memory.ts +84 -0
  473. package/src/usecases/export-memory/index.ts +3 -0
  474. package/src/usecases/export-memory/types.ts +28 -0
  475. package/src/usecases/get-memory/get-memory.ts +97 -0
  476. package/src/usecases/get-memory/index.ts +2 -0
  477. package/src/usecases/get-memory/types.ts +25 -0
  478. package/src/usecases/index.ts +25 -0
  479. package/src/usecases/list-memory/index.ts +2 -0
  480. package/src/usecases/list-memory/leased/index.ts +2 -0
  481. package/src/usecases/list-memory/leased/read.ts +16 -0
  482. package/src/usecases/list-memory/leased/types.ts +21 -0
  483. package/src/usecases/list-memory/list-memory.ts +33 -0
  484. package/src/usecases/list-memory/types.ts +8 -0
  485. package/src/usecases/load-dont-forget/index.ts +2 -0
  486. package/src/usecases/load-dont-forget/load-dont-forget.ts +111 -0
  487. package/src/usecases/load-dont-forget/types.ts +26 -0
  488. package/src/usecases/memory-change/change.ts +42 -0
  489. package/src/usecases/memory-change/index.ts +5 -0
  490. package/src/usecases/memory-change/maintenance.ts +11 -0
  491. package/src/usecases/memory-change/partial.ts +18 -0
  492. package/src/usecases/memory-change/receipt.ts +40 -0
  493. package/src/usecases/memory-change/types.ts +44 -0
  494. package/src/usecases/operation-context/context.ts +37 -0
  495. package/src/usecases/operation-context/index.ts +2 -0
  496. package/src/usecases/operation-context/types.ts +19 -0
  497. package/src/usecases/registration/check.ts +6 -0
  498. package/src/usecases/registration/entry.ts +33 -0
  499. package/src/usecases/registration/index.ts +8 -0
  500. package/src/usecases/registration/init.ts +94 -0
  501. package/src/usecases/registration/prepare-init.ts +43 -0
  502. package/src/usecases/registration/prepare.ts +35 -0
  503. package/src/usecases/registration/propose.ts +34 -0
  504. package/src/usecases/registration/publication.ts +90 -0
  505. package/src/usecases/registration/setup.ts +41 -0
  506. package/src/usecases/registration/types.ts +107 -0
  507. package/src/usecases/relevant-memory/agent.ts +55 -0
  508. package/src/usecases/relevant-memory/constants.ts +28 -0
  509. package/src/usecases/relevant-memory/cutoffs.ts +29 -0
  510. package/src/usecases/relevant-memory/decision.ts +102 -0
  511. package/src/usecases/relevant-memory/index.ts +11 -0
  512. package/src/usecases/relevant-memory/loaded.ts +31 -0
  513. package/src/usecases/relevant-memory/refresh.ts +30 -0
  514. package/src/usecases/relevant-memory/retrieve-memory.ts +62 -0
  515. package/src/usecases/relevant-memory/schemas.ts +20 -0
  516. package/src/usecases/relevant-memory/session-memory.ts +53 -0
  517. package/src/usecases/relevant-memory/track-dont-forget.ts +13 -0
  518. package/src/usecases/relevant-memory/types.ts +106 -0
  519. package/src/usecases/resolve-memory/index.ts +2 -0
  520. package/src/usecases/resolve-memory/leased/index.ts +2 -0
  521. package/src/usecases/resolve-memory/leased/resolve.ts +109 -0
  522. package/src/usecases/resolve-memory/leased/types.ts +35 -0
  523. package/src/usecases/resolve-memory/resolve-memory.ts +23 -0
  524. package/src/usecases/resolve-memory/types.ts +7 -0
  525. package/src/usecases/search-memory/constants.ts +1 -0
  526. package/src/usecases/search-memory/index.ts +3 -0
  527. package/src/usecases/search-memory/search-memory.ts +132 -0
  528. package/src/usecases/search-memory/types.ts +39 -0
  529. package/src/usecases/semantic/constants.ts +7 -0
  530. package/src/usecases/semantic/index.ts +5 -0
  531. package/src/usecases/semantic/prepare.ts +30 -0
  532. package/src/usecases/semantic/rank.ts +83 -0
  533. package/src/usecases/semantic/refresh-vectors.ts +95 -0
  534. package/src/usecases/semantic/types.ts +17 -0
  535. package/src/usecases/semantic-port/index.ts +1 -0
  536. package/src/usecases/semantic-port/types.ts +20 -0
  537. package/src/usecases/semantic-provider/constants.ts +6 -0
  538. package/src/usecases/semantic-provider/index.ts +5 -0
  539. package/src/usecases/semantic-provider/local.ts +33 -0
  540. package/src/usecases/semantic-provider/remote.ts +10 -0
  541. package/src/usecases/semantic-provider/size.ts +10 -0
  542. package/src/usecases/semantic-provider/types.ts +19 -0
  543. package/src/usecases/session/index.ts +2 -0
  544. package/src/usecases/session/lease.ts +70 -0
  545. package/src/usecases/session/receipts.ts +46 -0
  546. package/src/usecases/session/state.ts +106 -0
  547. package/src/usecases/session/types.ts +45 -0
  548. package/src/usecases/settings/change.ts +142 -0
  549. package/src/usecases/settings/index.ts +3 -0
  550. package/src/usecases/settings/prepare.ts +24 -0
  551. package/src/usecases/settings/types.ts +32 -0
  552. package/src/usecases/succeed-memory/index.ts +3 -0
  553. package/src/usecases/succeed-memory/schemas.ts +13 -0
  554. package/src/usecases/succeed-memory/succeed-memory.ts +34 -0
  555. package/src/usecases/succeed-memory/types.ts +18 -0
  556. package/src/usecases/synchronize-memory/index.ts +2 -0
  557. package/src/usecases/synchronize-memory/leased/aliases.ts +55 -0
  558. package/src/usecases/synchronize-memory/leased/folder-states.ts +58 -0
  559. package/src/usecases/synchronize-memory/leased/index.ts +2 -0
  560. package/src/usecases/synchronize-memory/leased/inspection.ts +32 -0
  561. package/src/usecases/synchronize-memory/leased/maintenance.ts +41 -0
  562. package/src/usecases/synchronize-memory/leased/publication.ts +55 -0
  563. package/src/usecases/synchronize-memory/leased/scan.ts +37 -0
  564. package/src/usecases/synchronize-memory/leased/synchronize.ts +102 -0
  565. package/src/usecases/synchronize-memory/leased/types.ts +60 -0
  566. package/src/usecases/synchronize-memory/synchronize-memory.ts +26 -0
  567. package/src/usecases/synchronize-memory/types.ts +5 -0
  568. package/src/usecases/update-memory/index.ts +3 -0
  569. package/src/usecases/update-memory/schemas.ts +14 -0
  570. package/src/usecases/update-memory/types.ts +16 -0
  571. package/src/usecases/update-memory/update-memory.ts +31 -0
  572. package/CHANGELOG.md +0 -6
@@ -0,0 +1,47 @@
1
+ import type { InspectedVaultFile, VaultCatalogEntry, VaultCatalogFailure } from "#src/domain/vault-catalog"
2
+ import { semanticFingerprint } from "./fingerprint.ts"
3
+ import type { AliasFailureClassification, CatalogEntry } from "./types.ts"
4
+
5
+ export function inspectedCatalogEntry(file: InspectedVaultFile, validationFingerprint: string): CatalogEntry {
6
+ const entry: CatalogEntry = {
7
+ path: file.path,
8
+ stat: { size: file.stat.size, mtimeMs: file.stat.mtimeMs },
9
+ rawHash: file.rawHash,
10
+ contentFingerprint: null,
11
+ validationFingerprint,
12
+ note: null,
13
+ needsFixing: file.analysis.needsFixing,
14
+ }
15
+ const analysis = file.analysis
16
+ if (analysis.status !== "parsed" || !analysis.frontmatter) return entry
17
+ entry.note = {
18
+ id: analysis.frontmatter.id,
19
+ type: analysis.frontmatter.type,
20
+ statement: analysis.parsed.statement,
21
+ body: analysis.parsed.body,
22
+ dontForget: "dontForget" in analysis.frontmatter,
23
+ archived: !analysis.searchable,
24
+ }
25
+ entry.contentFingerprint = semanticFingerprint(entry.note)
26
+ return entry
27
+ }
28
+
29
+ export function reusableCatalogEntry(
30
+ file: VaultCatalogEntry,
31
+ cached: CatalogEntry,
32
+ validationFingerprint: string,
33
+ ): boolean {
34
+ return (
35
+ cached.validationFingerprint === validationFingerprint &&
36
+ cached.stat.size === file.stat.size &&
37
+ cached.stat.mtimeMs === file.stat.mtimeMs
38
+ )
39
+ }
40
+
41
+ export function classifyAliasFailure(failure: VaultCatalogFailure): AliasFailureClassification {
42
+ if (failure.reason === "excluded" || failure.reason === "cycle") {
43
+ if (failure.scope === "file") return { kind: "excluded-file", path: failure.path }
44
+ return { kind: "untraversed-directory", path: failure.path }
45
+ }
46
+ return { kind: "failed", path: failure.path, problems: failure.problems }
47
+ }
@@ -0,0 +1,68 @@
1
+ import { confirmedMissing, retiredAliasPath } from "./coverage.ts"
2
+ import type { CatalogEntry, CatalogPlan, CatalogScan, CatalogSnapshot, DuplicateCatalogId } from "./types.ts"
3
+
4
+ export function planCatalogChanges(snapshot: CatalogSnapshot, scan: CatalogScan): CatalogPlan {
5
+ const previous = new Map(snapshot.entries.map((entry) => [entry.path, entry]))
6
+ const plan: CatalogPlan = {
7
+ expectedRevision: snapshot.revision,
8
+ upserts: [],
9
+ deletes: [],
10
+ statUpdates: [],
11
+ duplicateIds: [],
12
+ reinspectPaths: [],
13
+ population: snapshot.population,
14
+ }
15
+
16
+ for (const entry of scan.entries) classifyEntry(entry, previous.get(entry.path), plan)
17
+ plan.deletes = snapshot.entries
18
+ .filter((entry) => confirmedMissing(entry.path, scan) || retiredAliasPath(entry.path, scan))
19
+ .map((entry) => entry.path)
20
+
21
+ const current = new Map(previous)
22
+ for (const path of plan.deletes) current.delete(path)
23
+ for (const entry of scan.entries) current.set(entry.path, entry)
24
+
25
+ plan.reinspectPaths = [...current.values()]
26
+ .filter((entry) => entry.validationFingerprint !== scan.validationFingerprint)
27
+ .map((entry) => entry.path)
28
+ if (scan.complete && scan.failedPaths.length === 0 && plan.reinspectPaths.length === 0) plan.population = "ready"
29
+
30
+ plan.duplicateIds = duplicateIds([...current.values()])
31
+ return plan
32
+ }
33
+
34
+ function classifyEntry(entry: CatalogEntry, previous: CatalogEntry | undefined, plan: CatalogPlan): void {
35
+ if (!previous || !sameContent(entry, previous)) {
36
+ plan.upserts.push(entry)
37
+ return
38
+ }
39
+
40
+ if (entry.stat.size !== previous.stat.size || entry.stat.mtimeMs !== previous.stat.mtimeMs) {
41
+ plan.statUpdates.push({ path: entry.path, stat: entry.stat })
42
+ }
43
+ }
44
+
45
+ function sameContent(left: CatalogEntry, right: CatalogEntry): boolean {
46
+ return (
47
+ left.rawHash === right.rawHash &&
48
+ left.validationFingerprint === right.validationFingerprint &&
49
+ left.contentFingerprint === right.contentFingerprint &&
50
+ left.needsFixing === right.needsFixing &&
51
+ JSON.stringify(left.note) === JSON.stringify(right.note)
52
+ )
53
+ }
54
+
55
+ function duplicateIds(entries: CatalogEntry[]): DuplicateCatalogId[] {
56
+ const paths = new Map<string, string[]>()
57
+ for (const entry of entries) {
58
+ if (!entry.note) continue
59
+ const group = paths.get(entry.note.id)
60
+ if (group) group.push(entry.path)
61
+ else paths.set(entry.note.id, [entry.path])
62
+ }
63
+
64
+ return [...paths]
65
+ .filter(([, group]) => group.length > 1)
66
+ .map(([id, group]) => ({ id, paths: group.sort() }))
67
+ .sort((left, right) => left.id.localeCompare(right.id))
68
+ }
@@ -0,0 +1,27 @@
1
+ import { standardRrfK } from "./constants.ts"
2
+ import type { FusedPath, ScoredPath } from "./types.ts"
3
+
4
+ export function fuseRankings(text: readonly string[], semantic: readonly string[]): FusedPath[] {
5
+ return [...new Set([...text, ...semantic])]
6
+ .map((path) => ({ path, score: reciprocalRank(text, path) + reciprocalRank(semantic, path) }))
7
+ .sort((left, right) => right.score - left.score || compareText(left.path, right.path))
8
+ }
9
+
10
+ function reciprocalRank(ranking: readonly string[], path: string): number {
11
+ const index = ranking.indexOf(path)
12
+ if (index < 0) return 0
13
+ return 1 / (standardRrfK + index + 1)
14
+ }
15
+
16
+ function compareText(left: string, right: string): number {
17
+ if (left < right) return -1
18
+ if (left > right) return 1
19
+ return 0
20
+ }
21
+
22
+ export function semanticRanking(scored: readonly ScoredPath[], minimumSimilarity: number | null): string[] {
23
+ return scored
24
+ .filter((item) => typeof minimumSimilarity !== "number" || item.similarity >= minimumSimilarity)
25
+ .sort((left, right) => right.similarity - left.similarity || compareText(left.path, right.path))
26
+ .map((item) => item.path)
27
+ }
@@ -0,0 +1,49 @@
1
+ import Type from "typebox"
2
+
3
+ import { NoteIdSchema, NoteTypeSchema } from "#src/domain/note"
4
+
5
+ export const CatalogPathSchema = Type.String({
6
+ minLength: 1,
7
+ pattern: "^(?!/)(?!.*//)(?!.*(?:^|/)\\.{1,2}(?:/|$))[^\\\\:]+(?<!/)$",
8
+ })
9
+
10
+ export const CatalogStatSchema = Type.Object(
11
+ {
12
+ size: Type.Integer({ minimum: 0, maximum: Number.MAX_SAFE_INTEGER }),
13
+ mtimeMs: Type.Number(),
14
+ },
15
+ { additionalProperties: false },
16
+ )
17
+
18
+ export const CatalogNoteSchema = Type.Object(
19
+ {
20
+ id: NoteIdSchema,
21
+ type: NoteTypeSchema,
22
+ statement: Type.String(),
23
+ body: Type.String(),
24
+ dontForget: Type.Boolean(),
25
+ archived: Type.Boolean(),
26
+ },
27
+ { additionalProperties: false },
28
+ )
29
+
30
+ export const CatalogEntrySchema = Type.Object(
31
+ {
32
+ path: CatalogPathSchema,
33
+ stat: CatalogStatSchema,
34
+ rawHash: Type.String({ minLength: 1 }),
35
+ contentFingerprint: Type.Union([Type.String({ minLength: 1 }), Type.Null()]),
36
+ validationFingerprint: Type.String({ minLength: 1 }),
37
+ note: Type.Union([CatalogNoteSchema, Type.Null()]),
38
+ needsFixing: Type.Boolean(),
39
+ },
40
+ { additionalProperties: false },
41
+ )
42
+
43
+ export const VectorGenerationSchema = Type.Object(
44
+ {
45
+ fingerprint: Type.String({ minLength: 1 }),
46
+ dimensions: Type.Integer({ minimum: 1, maximum: Number.MAX_SAFE_INTEGER }),
47
+ },
48
+ { additionalProperties: false },
49
+ )
@@ -0,0 +1,103 @@
1
+ import type { Static } from "typebox"
2
+
3
+ import type { CatalogEntrySchema, CatalogStatSchema, VectorGenerationSchema } from "./schemas.ts"
4
+
5
+ export type CatalogEntry = Static<typeof CatalogEntrySchema>
6
+ export type CatalogStat = Static<typeof CatalogStatSchema>
7
+ export type VectorGeneration = Static<typeof VectorGenerationSchema>
8
+ export type CatalogPopulation = "needs-population" | "ready"
9
+
10
+ export interface CatalogSnapshot {
11
+ entries: CatalogEntry[]
12
+ population: CatalogPopulation
13
+ revision: number
14
+ }
15
+
16
+ export interface CatalogScan {
17
+ entries: CatalogEntry[]
18
+ observedPaths: string[]
19
+ completeDirectories: string[]
20
+ failedPaths: string[]
21
+ untraversedAliasDirectories: string[]
22
+ excludedAliasFiles: string[]
23
+ validationFingerprint: string
24
+ complete: boolean
25
+ }
26
+
27
+ export interface CatalogStatUpdate {
28
+ path: string
29
+ stat: CatalogStat
30
+ }
31
+
32
+ export interface CatalogChanges {
33
+ expectedRevision: number
34
+ upserts: CatalogEntry[]
35
+ deletes: string[]
36
+ statUpdates: CatalogStatUpdate[]
37
+ population: CatalogPopulation
38
+ }
39
+
40
+ export interface DuplicateCatalogId {
41
+ id: string
42
+ paths: string[]
43
+ }
44
+
45
+ export interface CatalogPlan extends CatalogChanges {
46
+ duplicateIds: DuplicateCatalogId[]
47
+ reinspectPaths: string[]
48
+ }
49
+
50
+ export interface UntraversedAliasDirectory {
51
+ kind: "untraversed-directory"
52
+ path: string
53
+ }
54
+
55
+ export interface ExcludedAliasFile {
56
+ kind: "excluded-file"
57
+ path: string
58
+ }
59
+
60
+ export interface FailedAliasPath {
61
+ kind: "failed"
62
+ path: string
63
+ problems: string[]
64
+ }
65
+
66
+ export type AliasFailureClassification = UntraversedAliasDirectory | ExcludedAliasFile | FailedAliasPath
67
+
68
+ export interface SemanticContent {
69
+ statement: string
70
+ body: string
71
+ }
72
+
73
+ export interface VectorChunk {
74
+ contentFingerprint: string
75
+ chunk: number
76
+ vector: number[]
77
+ }
78
+
79
+ export interface VectorCache {
80
+ generation: VectorGeneration | null
81
+ chunks: VectorChunk[]
82
+ }
83
+
84
+ export interface VectorRefreshPlan {
85
+ embed: CatalogEntry[]
86
+ keep: VectorChunk[]
87
+ }
88
+
89
+ export interface ScoredPath {
90
+ path: string
91
+ similarity: number
92
+ }
93
+
94
+ export interface FusedPath {
95
+ path: string
96
+ score: number
97
+ }
98
+
99
+ export interface VectorReplacement {
100
+ expectedRevision: number
101
+ generation: VectorGeneration
102
+ chunks: VectorChunk[]
103
+ }
@@ -0,0 +1,22 @@
1
+ import type { CatalogEntry, VectorCache, VectorChunk, VectorRefreshPlan } from "./types.ts"
2
+
3
+ export function planVectorRefresh(
4
+ entries: readonly CatalogEntry[],
5
+ cache: VectorCache,
6
+ providerFingerprint: string,
7
+ ): VectorRefreshPlan {
8
+ const current = new Map<string, CatalogEntry>()
9
+ for (const entry of entries) {
10
+ if (!entry.note || entry.note.archived || !entry.contentFingerprint) continue
11
+ if (!current.has(entry.contentFingerprint)) current.set(entry.contentFingerprint, entry)
12
+ }
13
+ if (cache.generation?.fingerprint !== providerFingerprint) return { embed: [...current.values()], keep: [] }
14
+
15
+ const keep: VectorChunk[] = cache.chunks.filter((chunk) => current.has(chunk.contentFingerprint))
16
+ const cached = new Set(keep.map((chunk) => chunk.contentFingerprint))
17
+ const embed: CatalogEntry[] = []
18
+ for (const [fingerprint, entry] of current) {
19
+ if (!cached.has(fingerprint)) embed.push(entry)
20
+ }
21
+ return { embed, keep }
22
+ }
@@ -0,0 +1,28 @@
1
+ import { QUOTE_CHARACTERS } from "#src/domain/vault-access"
2
+
3
+ export function commandSegments(command: string): string[] {
4
+ const segments: string[] = []
5
+ let current = ""
6
+ let quote = ""
7
+ for (const character of command) {
8
+ if (quote) {
9
+ if (character === quote) quote = ""
10
+ current += character
11
+ } else if (QUOTE_CHARACTERS.includes(character)) {
12
+ quote = character
13
+ current += character
14
+ } else if (endsSegment(character, current)) {
15
+ segments.push(current)
16
+ current = ""
17
+ } else if (character !== "&" || current.trim() !== "") {
18
+ current += character
19
+ }
20
+ }
21
+ segments.push(current)
22
+ return segments.filter((segment) => segment.trim() !== "")
23
+ }
24
+
25
+ function endsSegment(character: string, current: string): boolean {
26
+ if (character === ";" || character === "|" || character === "\n") return true
27
+ return character === "&" && current.trim() !== ""
28
+ }
@@ -0,0 +1,22 @@
1
+ import { QUOTE_CHARACTERS } from "#src/domain/vault-access"
2
+
3
+ export function commandWords(segment: string): string[] {
4
+ const words: string[] = []
5
+ let current = ""
6
+ let quote = ""
7
+ for (const character of segment) {
8
+ if (quote) {
9
+ if (character === quote) quote = ""
10
+ else current += character
11
+ } else if (QUOTE_CHARACTERS.includes(character)) {
12
+ quote = character
13
+ } else if (/\s/.test(character)) {
14
+ if (current) words.push(current)
15
+ current = ""
16
+ } else {
17
+ current += character
18
+ }
19
+ }
20
+ if (current) words.push(current)
21
+ return words
22
+ }
@@ -0,0 +1,125 @@
1
+ import { NPM_VALUE_FLAGS } from "#src/domain/tool-flags"
2
+ import type { ShellEditQuestionName, ShellEditQuestions, ShellEditScores } from "./types.ts"
3
+
4
+ export const SCRIPT_EXTENSION = /\.(?:sh|ps1)$/i
5
+
6
+ export const LEADING_ENV_ASSIGNMENTS = /^\s*(?:[A-Za-z_][A-Za-z0-9_]*=(?:"[^"]*"|'[^']*'|[^\s"'])*\s+)+/
7
+
8
+ export const EXECUTABLE_SUFFIX = /\.exe$/
9
+
10
+ export const LAST_SEGMENT_START = /[^\\/]*$/
11
+
12
+ const EVAL_AND_PRINT_FLAGS = ["-e", "--eval", "-p", "--print"]
13
+
14
+ const PYTHON_INLINE_CODE_FLAGS = ["-c", "-m"]
15
+
16
+ const SHELL_INLINE_CODE_FLAGS = ["-c"]
17
+
18
+ export const INLINE_CODE_FLAGS = new Map([
19
+ ["node", [...EVAL_AND_PRINT_FLAGS, "-c", "--check"]],
20
+ ["tsx", EVAL_AND_PRINT_FLAGS],
21
+ ["ts-node", EVAL_AND_PRINT_FLAGS],
22
+ ["python", PYTHON_INLINE_CODE_FLAGS],
23
+ ["python3", PYTHON_INLINE_CODE_FLAGS],
24
+ ["py", PYTHON_INLINE_CODE_FLAGS],
25
+ ["bash", SHELL_INLINE_CODE_FLAGS],
26
+ ["sh", SHELL_INLINE_CODE_FLAGS],
27
+ ])
28
+
29
+ export const BUN_INLINE_CODE_FLAGS = EVAL_AND_PRINT_FLAGS
30
+
31
+ export const CONFIG_FILE_FLAGS = ["-c", "--config"]
32
+
33
+ export const RUN_SUBCOMMAND = "run"
34
+
35
+ export const NO_FLAGS: string[] = []
36
+
37
+ export const PACKAGE_MANAGERS = new Map([
38
+ ["npm", NPM_VALUE_FLAGS],
39
+ ["pnpm", NO_FLAGS],
40
+ ["yarn", NO_FLAGS],
41
+ ])
42
+
43
+ export const BUN_SOURCE_FILE = /[\\/]|\.(?:[cm]?[jt]sx?|sh|ps1)$/i
44
+
45
+ export const PRELOAD_FLAGS = ["-r", "--require", "--import", "--preload", "--loader", "--experimental-loader"]
46
+
47
+ export const PACKAGE_RUN_COMMANDS = ["run", "run-script"]
48
+
49
+ export const PACKAGE_DIRECT_SCRIPTS = ["test", "start"]
50
+
51
+ export const SHELL_EDIT_QUESTION_NAMES: readonly ShellEditQuestionName[] = [
52
+ "redirection",
53
+ "in_place",
54
+ "inline_code",
55
+ "script_writes",
56
+ "copy_download",
57
+ "hardlink",
58
+ ]
59
+
60
+ export const SHELL_EDIT_QUESTIONS: ShellEditQuestions = {
61
+ redirection: {
62
+ type: "bool",
63
+ instructions:
64
+ "Does `command` write output into a file through a redirection (`>` or `>>`) or a file-writing cmdlet (`tee`, `Out-File`, `Set-Content`, `Add-Content`)?",
65
+ criteria: { true: "`command` sends output into a file", false: "`command` writes no output into any file" },
66
+ },
67
+ in_place: {
68
+ type: "bool",
69
+ instructions:
70
+ "Does `command` change an existing file in place, for example with `sed -i`, `perl -pi`, or text read from a file, changed with `-replace` and written back to it, rather than through a linter, formatter, test runner, build, git or a package manager?",
71
+ criteria: {
72
+ true: "`command` rewrites an existing file in place",
73
+ false: "`command` leaves existing files' contents as they are",
74
+ },
75
+ },
76
+ inline_code: {
77
+ type: "bool",
78
+ instructions:
79
+ "Does `command` carry inline code (`node -e`, `python -c`, a PowerShell `-Command` block or similar) whose code creates or writes a file?",
80
+ criteria: {
81
+ true: "the inline code in `command` creates or writes a file",
82
+ false: "`command` has no inline code, or its inline code writes no file",
83
+ },
84
+ },
85
+ script_writes: {
86
+ type: "bool",
87
+ instructions:
88
+ "Does the code in any `scripts[*].text` create or write a file with its own code, rather than only launching a linter, formatter, test runner, build, git or a package manager?",
89
+ criteria: {
90
+ true: "a script's own code creates or writes a file",
91
+ false: "no script's own code creates or writes a file",
92
+ },
93
+ },
94
+ copy_download: {
95
+ type: "bool",
96
+ instructions:
97
+ "Does `command` create a file by copying or downloading content (`cp`, `Copy-Item`, `curl -o`, `Invoke-WebRequest -OutFile`), other than through git or a package manager?",
98
+ criteria: {
99
+ true: "`command` creates a file by copying or downloading",
100
+ false: "`command` copies and downloads no file",
101
+ },
102
+ },
103
+ hardlink: {
104
+ type: "bool",
105
+ instructions:
106
+ "Does `command` create a hardlink (`ln` without `-s`, `New-Item -ItemType HardLink`, `mklink /H`, `fsutil hardlink create`)?",
107
+ criteria: { true: "`command` creates a hardlink", false: "`command` creates no hardlink" },
108
+ },
109
+ }
110
+
111
+ export const SHELL_EDIT_CUTOFFS: ShellEditScores = {
112
+ redirection: 0.5,
113
+ in_place: 0.5,
114
+ inline_code: 0.5,
115
+ script_writes: 0.5,
116
+ copy_download: 0.5,
117
+ hardlink: 0.5,
118
+ }
119
+
120
+ export const SHELL_EDIT_REFUSED = "Refused by the shell-edit guard"
121
+
122
+ export const SHELL_EDIT_UNCHECKED = "Refused: the shell-edit guard could not check this command"
123
+
124
+ export const SHELL_EDIT_GUIDANCE =
125
+ "The shell never creates or changes files: use the edit or write tool. Deleting, moving and renaming files, linters, formatters, git, npm and test runners stay allowed."
@@ -0,0 +1,154 @@
1
+ import { BUN_FOLDER_FLAGS, BUN_VALUE_FLAGS, INTERPRETER_VALUE_FLAGS } from "#src/domain/command-flags"
2
+ import { NPM_PREFIX_FLAGS, NPM_WORKSPACE_FLAGS, POWERSHELL_PARAMETERS } from "#src/domain/tool-flags"
3
+ import { commandSegments } from "./command-segments.ts"
4
+ import { commandWords } from "./command-words.ts"
5
+ import {
6
+ BUN_INLINE_CODE_FLAGS,
7
+ BUN_SOURCE_FILE,
8
+ CONFIG_FILE_FLAGS,
9
+ EXECUTABLE_SUFFIX,
10
+ INLINE_CODE_FLAGS,
11
+ LAST_SEGMENT_START,
12
+ LEADING_ENV_ASSIGNMENTS,
13
+ NO_FLAGS,
14
+ PACKAGE_DIRECT_SCRIPTS,
15
+ PACKAGE_MANAGERS,
16
+ PACKAGE_RUN_COMMANDS,
17
+ PRELOAD_FLAGS,
18
+ RUN_SUBCOMMAND,
19
+ SCRIPT_EXTENSION,
20
+ } from "./constants.ts"
21
+ import { powershellFiles, scriptFile } from "./powershell-files.ts"
22
+ import type { ExecutedFile, FolderRead, InterpreterRules } from "./types.ts"
23
+
24
+ export function executedFiles(command: string): ExecutedFile[] {
25
+ const found = new Map<string, ExecutedFile>()
26
+ for (const segment of commandSegments(command)) {
27
+ for (const file of segmentFiles(segment)) found.set(JSON.stringify(file), file)
28
+ }
29
+ return [...found.values()]
30
+ }
31
+
32
+ function segmentFiles(segment: string): ExecutedFile[] {
33
+ const [first, ...args] = commandWords(segment.replace(LEADING_ENV_ASSIGNMENTS, ""))
34
+ if (typeof first !== "string") return []
35
+ const program = programName(first)
36
+ const inlineCode = INLINE_CODE_FLAGS.get(program)
37
+ const withValue = INTERPRETER_VALUE_FLAGS.get(program)
38
+ if (inlineCode && withValue) {
39
+ return interpreterFiles(args, { inlineCode, withValue, folderFlags: NO_FLAGS, mainFile: scriptFile })
40
+ }
41
+ if (program === "bun") return bunFiles(args)
42
+ if (program === "deno") return denoFiles(args)
43
+ const powershellParameters = POWERSHELL_PARAMETERS.get(program)
44
+ if (powershellParameters) return powershellFiles(args, powershellParameters)
45
+ const packageFlags = PACKAGE_MANAGERS.get(program)
46
+ if (packageFlags) return packageScripts(args, packageFlags)
47
+ if (SCRIPT_EXTENSION.test(first)) return [scriptFile(first)]
48
+ return []
49
+ }
50
+
51
+ function programName(token: string): string {
52
+ const name = token.slice(token.search(LAST_SEGMENT_START))
53
+ return name.toLowerCase().replace(EXECUTABLE_SUFFIX, "")
54
+ }
55
+
56
+ function packageScript(name: string, prefix: string): ExecutedFile {
57
+ return { kind: "package-script", name, prefix }
58
+ }
59
+
60
+ function bunRunTarget(name: string, folder: string): ExecutedFile {
61
+ if (BUN_SOURCE_FILE.test(name)) return scriptFile(name)
62
+ return packageScript(name, folder)
63
+ }
64
+
65
+ function bunFiles(args: string[]): ExecutedFile[] {
66
+ const rules = {
67
+ inlineCode: BUN_INLINE_CODE_FLAGS,
68
+ withValue: BUN_VALUE_FLAGS,
69
+ folderFlags: BUN_FOLDER_FLAGS,
70
+ mainFile: scriptFile,
71
+ }
72
+ if (args[0] === RUN_SUBCOMMAND) return interpreterFiles(args.slice(1), { ...rules, mainFile: bunRunTarget })
73
+ return interpreterFiles(args, rules)
74
+ }
75
+
76
+ function denoFiles(args: string[]): ExecutedFile[] {
77
+ if (args[0] !== RUN_SUBCOMMAND) return []
78
+ const rules = { inlineCode: NO_FLAGS, withValue: CONFIG_FILE_FLAGS, folderFlags: NO_FLAGS, mainFile: scriptFile }
79
+ return interpreterFiles(args.slice(1), rules)
80
+ }
81
+
82
+ function assignedValue(arg: string, flags: string[]): string {
83
+ const equals = arg.indexOf("=")
84
+ if (equals < 0 || !flags.includes(arg.slice(0, equals))) return ""
85
+ return arg.slice(equals + 1)
86
+ }
87
+
88
+ function isAssignment(arg: string, flags: string[]): boolean {
89
+ return assignedValue(arg, flags) !== ""
90
+ }
91
+
92
+ function folderRead(args: string[], index: number, flags: string[]): FolderRead {
93
+ const arg = args[index]
94
+ const next = args[index + 1]
95
+ if (typeof arg !== "string") return { folder: "", width: 0 }
96
+ if (flags.includes(arg) && typeof next === "string") return { folder: next, width: 2 }
97
+ if (isAssignment(arg, flags)) return { folder: assignedValue(arg, flags), width: 1 }
98
+ return { folder: "", width: 0 }
99
+ }
100
+
101
+ function interpreterFiles(args: string[], rules: InterpreterRules): ExecutedFile[] {
102
+ const files: ExecutedFile[] = []
103
+ let folder = ""
104
+ let index = 0
105
+ for (let arg = args[index]; typeof arg === "string"; arg = args[index]) {
106
+ const next = args[index + 1]
107
+ const read = folderRead(args, index, rules.folderFlags)
108
+ if (rules.inlineCode.includes(arg)) return files
109
+ if (read.width > 0) {
110
+ folder = read.folder
111
+ index += read.width
112
+ } else if (rules.withValue.includes(arg)) {
113
+ index += 2
114
+ } else if (PRELOAD_FLAGS.includes(arg)) {
115
+ if (typeof next === "string") files.push(scriptFile(next))
116
+ index += 2
117
+ } else if (arg.startsWith("-")) {
118
+ index += 1
119
+ } else {
120
+ return [...files, rules.mainFile(arg, folder)]
121
+ }
122
+ }
123
+ return files
124
+ }
125
+
126
+ function packageScriptOf(words: string[], prefix: string): ExecutedFile[] {
127
+ const [first, second] = words
128
+ if (typeof first !== "string") return []
129
+ if (PACKAGE_DIRECT_SCRIPTS.includes(first)) return [packageScript(first, prefix)]
130
+ if (PACKAGE_RUN_COMMANDS.includes(first) && typeof second === "string") return [packageScript(second, prefix)]
131
+ return []
132
+ }
133
+
134
+ function packageScripts(args: string[], valueFlags: string[]): ExecutedFile[] {
135
+ const prefixFlags = NPM_PREFIX_FLAGS.filter((flag) => valueFlags.includes(flag))
136
+ const workspaceFlags = NPM_WORKSPACE_FLAGS.filter((flag) => valueFlags.includes(flag))
137
+ const words: string[] = []
138
+ let prefix = ""
139
+ let index = 0
140
+ for (let arg = args[index]; typeof arg === "string" && arg !== "--"; arg = args[index]) {
141
+ const read = folderRead(args, index, prefixFlags)
142
+ if (workspaceFlags.includes(arg) || isAssignment(arg, workspaceFlags)) return []
143
+ if (read.width > 0) {
144
+ prefix = read.folder
145
+ index += read.width
146
+ } else if (valueFlags.includes(arg)) {
147
+ index += 2
148
+ } else {
149
+ if (!arg.startsWith("-")) words.push(arg)
150
+ index += 1
151
+ }
152
+ }
153
+ return packageScriptOf(words, prefix)
154
+ }
@@ -0,0 +1,6 @@
1
+ export * from "./command-segments.ts"
2
+ export * from "./command-words.ts"
3
+ export * from "./constants.ts"
4
+ export * from "./executed-files.ts"
5
+ export * from "./rules.ts"
6
+ export * from "./types.ts"