@tekmidian/pai 0.54.0 → 0.55.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 (251) hide show
  1. package/dist/{aibroker-client-CNfIBrl5.mjs → aibroker-client-B8Wtasez.mjs} +1 -1
  2. package/dist/{aibroker-client-DzkTpVjx.mjs → aibroker-client-BK1h--W_.mjs} +3 -3
  3. package/dist/{aibroker-client-DzkTpVjx.mjs.map → aibroker-client-BK1h--W_.mjs.map} +1 -1
  4. package/dist/{indexer-backend-CdvCJCkD.mjs → async-CLvuY7b-.mjs} +7 -7
  5. package/dist/async-CLvuY7b-.mjs.map +1 -0
  6. package/dist/auto-route-CF8WNaoy.mjs +100 -0
  7. package/dist/auto-route-CF8WNaoy.mjs.map +1 -0
  8. package/dist/{chain-BcBDJ1Id.mjs → chain-DogidBji.mjs} +4 -4
  9. package/dist/{chain-BcBDJ1Id.mjs.map → chain-DogidBji.mjs.map} +1 -1
  10. package/dist/cli/index.mjs +22 -23
  11. package/dist/cli/index.mjs.map +1 -1
  12. package/dist/cli/program.d.mts.map +1 -1
  13. package/dist/cli/program.mjs +22 -23
  14. package/dist/{clusters-Cw_P6lO-.mjs → clusters-Ci1mseh2.mjs} +4 -36
  15. package/dist/clusters-Ci1mseh2.mjs.map +1 -0
  16. package/dist/{config-B3EPzRjf.mjs → config-B93YS8tP.mjs} +3 -3
  17. package/dist/{config-B3EPzRjf.mjs.map → config-B93YS8tP.mjs.map} +1 -1
  18. package/dist/{config-Bn9jpblO.mjs → config-D1omG_UU.mjs} +3 -3
  19. package/dist/{config-Bn9jpblO.mjs.map → config-D1omG_UU.mjs.map} +1 -1
  20. package/dist/{config-RjeVGJ7K.mjs → config-DCYWFaEi.mjs} +1 -1
  21. package/dist/{context-handover-cache-CXyH6QsC.mjs → context-handover-cache-k2kWbE6G.mjs} +82 -99
  22. package/dist/context-handover-cache-k2kWbE6G.mjs.map +1 -0
  23. package/dist/daemon/index.mjs +18 -24
  24. package/dist/daemon/index.mjs.map +1 -1
  25. package/dist/daemon-B7Y8GQnt.mjs +19 -0
  26. package/dist/{daemon-BkJNFWr9.mjs → daemon-Cgrdvdo6.mjs} +97 -466
  27. package/dist/daemon-Cgrdvdo6.mjs.map +1 -0
  28. package/dist/daemon-mcp/index.mjs +10 -10
  29. package/dist/daemon-mcp/index.mjs.map +1 -1
  30. package/dist/{detector-DWXkeTlk.mjs → detector-3g7XuU1r.mjs} +5 -12
  31. package/dist/detector-3g7XuU1r.mjs.map +1 -0
  32. package/dist/detector-DgDn56j-.mjs +3 -0
  33. package/dist/{embeddings-ClqKtLZ8.mjs → embeddings-BNv3TQC5.mjs} +1 -1
  34. package/dist/{embeddings-DvRKcQyt.mjs → embeddings-DfrYNIng.mjs} +1 -1
  35. package/dist/{embeddings-DvRKcQyt.mjs.map → embeddings-DfrYNIng.mjs.map} +1 -1
  36. package/dist/factory-C9wGUe30.mjs +3 -0
  37. package/dist/factory-DiuntvwG.mjs +250 -0
  38. package/dist/factory-DiuntvwG.mjs.map +1 -0
  39. package/dist/{fallback-CPfyTSTx.mjs → fallback-DS6AEJsU.mjs} +190 -132
  40. package/dist/fallback-DS6AEJsU.mjs.map +1 -0
  41. package/dist/federation-db-CJDw_Pwq.mjs +3 -0
  42. package/dist/{db-DJ8rk0VM.mjs → federation-db-w8e-sKjp.mjs} +5 -5
  43. package/dist/federation-db-w8e-sKjp.mjs.map +1 -0
  44. package/dist/{helpers-crDEr6S2.mjs → helpers-D9WkIf9R.mjs} +1 -1
  45. package/dist/{helpers-crDEr6S2.mjs.map → helpers-D9WkIf9R.mjs.map} +1 -1
  46. package/dist/hooks/capture-all-events.mjs.map +1 -1
  47. package/dist/hooks/capture-session-summary.mjs.map +1 -1
  48. package/dist/hooks/capture-tool-output.mjs.map +1 -1
  49. package/dist/hooks/context-compression-hook.mjs.map +1 -1
  50. package/dist/hooks/load-core-context.mjs +5 -0
  51. package/dist/hooks/load-core-context.mjs.map +2 -2
  52. package/dist/hooks/load-project-context.mjs.map +1 -1
  53. package/dist/hooks/post-compact-inject.mjs.map +1 -1
  54. package/dist/hooks/route-agents-to-worker.mjs.map +1 -1
  55. package/dist/hooks/route-edits-to-worker.mjs +1 -1
  56. package/dist/hooks/route-edits-to-worker.mjs.map +2 -2
  57. package/dist/hooks/security-validator.mjs +8367 -19
  58. package/dist/hooks/security-validator.mjs.map +4 -4
  59. package/dist/hooks/stop-hook.mjs.map +2 -2
  60. package/dist/hooks/whisper-rules.mjs.map +2 -2
  61. package/dist/hooks/worker-proxy.mjs.map +1 -1
  62. package/dist/hooks/worker-status-line.mjs.map +2 -2
  63. package/dist/hooks/worker-supervision.mjs.map +1 -1
  64. package/dist/index.d.mts +327 -100
  65. package/dist/index.d.mts.map +1 -1
  66. package/dist/index.mjs +7 -11
  67. package/dist/indexer-backend-Cc-_NK3q.mjs +1 -0
  68. package/dist/indexer-backend-DcDtin1O.mjs +5 -0
  69. package/dist/{ipc-client-C6NryMMb.mjs → ipc-client-Dasm515c.mjs} +2 -2
  70. package/dist/{ipc-client-C6NryMMb.mjs.map → ipc-client-Dasm515c.mjs.map} +1 -1
  71. package/dist/kg-entity-Cj8Q6YmU.mjs +29 -0
  72. package/dist/kg-entity-Cj8Q6YmU.mjs.map +1 -0
  73. package/dist/{latent-ideas-BfL4nCQ3.mjs → latent-ideas-BRy6HNwg.mjs} +4 -4
  74. package/dist/{latent-ideas-BfL4nCQ3.mjs.map → latent-ideas-BRy6HNwg.mjs.map} +1 -1
  75. package/dist/{link-boost-C5PaNdzm.mjs → link-boost-BptbAPuv.mjs} +1 -1
  76. package/dist/{link-boost-C5PaNdzm.mjs.map → link-boost-BptbAPuv.mjs.map} +1 -1
  77. package/dist/{main-resolver-Bt1f6jJc.mjs → main-resolver-Dx-pxic1.mjs} +56 -31
  78. package/dist/main-resolver-Dx-pxic1.mjs.map +1 -0
  79. package/dist/main-resolver-uDtK9p6e.mjs +7 -0
  80. package/dist/merge-BncjJTfb.mjs +3 -0
  81. package/dist/merge-xoyfZQ4W.mjs +6 -0
  82. package/dist/merge-xoyfZQ4W.mjs.map +1 -0
  83. package/dist/{migrate-CfERwXhY.mjs → migrate-BD7D8EEh.mjs} +21 -54
  84. package/dist/migrate-BD7D8EEh.mjs.map +1 -0
  85. package/dist/{neighborhood-CETR_P4y.mjs → neighborhood-D8uscnGy.mjs} +4 -25
  86. package/dist/neighborhood-D8uscnGy.mjs.map +1 -0
  87. package/dist/{note-context-DCcRWBoN.mjs → note-context-CgffaUMh.mjs} +3 -23
  88. package/dist/note-context-CgffaUMh.mjs.map +1 -0
  89. package/dist/{pai-home-ChAOupZc.mjs → pai-home-CeOIYltV.mjs} +2 -2
  90. package/dist/pai-home-CeOIYltV.mjs.map +1 -0
  91. package/dist/{pai-marker-B20KqhA8.mjs → pai-marker-D1MMswkz.mjs} +1 -1
  92. package/dist/{pai-marker-B20KqhA8.mjs.map → pai-marker-D1MMswkz.mjs.map} +1 -1
  93. package/dist/{planner-BLbCtBUa.mjs → planner-C2wWnZrZ.mjs} +7 -7
  94. package/dist/{planner-BLbCtBUa.mjs.map → planner-C2wWnZrZ.mjs.map} +1 -1
  95. package/dist/{postgres-CUSXWgTG.mjs → postgres-nvU5pShF.mjs} +863 -4
  96. package/dist/postgres-nvU5pShF.mjs.map +1 -0
  97. package/dist/{program-DYux0CW2.mjs → program-Cb-9J5Ie.mjs} +2260 -1399
  98. package/dist/program-Cb-9J5Ie.mjs.map +1 -0
  99. package/dist/query-feedback-COYCnvHQ.mjs +3 -0
  100. package/dist/{query-feedback-CTs_jx6i.mjs → query-feedback-xz5axTj3.mjs} +3 -3
  101. package/dist/query-feedback-xz5axTj3.mjs.map +1 -0
  102. package/dist/{db-Ddns80yf.mjs → registry-db-Bkpbp7Gf.mjs} +5 -5
  103. package/dist/registry-db-Bkpbp7Gf.mjs.map +1 -0
  104. package/dist/registry-db-DwXpf7yF.mjs +3 -0
  105. package/dist/registry-postgres-B07-hmn8.mjs +795 -0
  106. package/dist/registry-postgres-B07-hmn8.mjs.map +1 -0
  107. package/dist/registry-sqlite-CkGND_tm.mjs +593 -0
  108. package/dist/registry-sqlite-CkGND_tm.mjs.map +1 -0
  109. package/dist/{reranker-B5qUTamW.mjs → reranker-BS5gqGeF.mjs} +1 -1
  110. package/dist/{reranker-HHmhZk6v.mjs → reranker-CRVawoEh.mjs} +1 -1
  111. package/dist/{reranker-HHmhZk6v.mjs.map → reranker-CRVawoEh.mjs.map} +1 -1
  112. package/dist/router-BXOf_e9e.mjs +3 -0
  113. package/dist/{router-DBAZfE7X.mjs → router-BdxdsAvs.mjs} +2 -2
  114. package/dist/{router-DBAZfE7X.mjs.map → router-BdxdsAvs.mjs.map} +1 -1
  115. package/dist/{run-C7EDdVAB.mjs → run-DkTrZejF.mjs} +268 -53
  116. package/dist/run-DkTrZejF.mjs.map +1 -0
  117. package/dist/{runtime-paths-B0P1TvUr.mjs → runtime-paths-BRwDeBEg.mjs} +1 -1
  118. package/dist/{runtime-paths-B0P1TvUr.mjs.map → runtime-paths-BRwDeBEg.mjs.map} +1 -1
  119. package/dist/search-BQHL5wDr.mjs +3 -0
  120. package/dist/search-BaTbyWjK.mjs +107 -0
  121. package/dist/search-BaTbyWjK.mjs.map +1 -0
  122. package/dist/{server-CGiHdaUp.mjs → server-CGuZFOeR.mjs} +4 -4
  123. package/dist/{server-CGiHdaUp.mjs.map → server-CGuZFOeR.mjs.map} +1 -1
  124. package/dist/{session-keepalive-DC2JGggK.mjs → session-keepalive-C5_69Av6.mjs} +7 -7
  125. package/dist/{session-keepalive-DC2JGggK.mjs.map → session-keepalive-C5_69Av6.mjs.map} +1 -1
  126. package/dist/skills/Plan/SKILL.md +1 -1
  127. package/dist/{sources-KBGEA_E6.mjs → sources-BBe3AZ-W.mjs} +8 -27
  128. package/dist/sources-BBe3AZ-W.mjs.map +1 -0
  129. package/dist/sqlite-D9p5a4qe.mjs +935 -0
  130. package/dist/sqlite-D9p5a4qe.mjs.map +1 -0
  131. package/dist/state-CwlGAKgF.mjs +3 -0
  132. package/dist/{state-DwrsOoMi.mjs → state-n13uPK5B.mjs} +6 -5
  133. package/dist/state-n13uPK5B.mjs.map +1 -0
  134. package/dist/{stop-words-BaMEGVeY.mjs → stop-words-ClCwO8mZ.mjs} +1 -1
  135. package/dist/{stop-words-BaMEGVeY.mjs.map → stop-words-ClCwO8mZ.mjs.map} +1 -1
  136. package/dist/{themes-BVoAnLZj.mjs → themes-B2v7RNnA.mjs} +3 -3
  137. package/dist/{themes-BVoAnLZj.mjs.map → themes-B2v7RNnA.mjs.map} +1 -1
  138. package/dist/{tools-BEqiJt_j.mjs → tools-Diro2s8J.mjs} +157 -398
  139. package/dist/tools-Diro2s8J.mjs.map +1 -0
  140. package/dist/{tools-BwsOTmjh.mjs → tools-KgL1rkPD.mjs} +4 -4
  141. package/dist/{trace-Cy8quQTm.mjs → trace-BRflVyBi.mjs} +1 -1
  142. package/dist/{trace-Cy8quQTm.mjs.map → trace-BRflVyBi.mjs.map} +1 -1
  143. package/dist/{utils-BD8g8oSf.mjs → utils-BrX9FLeK.mjs} +1 -1
  144. package/dist/{utils-CJymHkYm.mjs → utils-C9HsYDpO.mjs} +1 -1
  145. package/dist/{utils-CJymHkYm.mjs.map → utils-C9HsYDpO.mjs.map} +1 -1
  146. package/dist/{vault-indexer-C5i-OAyr.mjs → vault-indexer-DHYBpRZ5.mjs} +2 -2
  147. package/dist/{vault-indexer-C5i-OAyr.mjs.map → vault-indexer-DHYBpRZ5.mjs.map} +1 -1
  148. package/dist/{wakeup-Yk5lQ0jb.mjs → wakeup-D0uvqLsE.mjs} +95 -4
  149. package/dist/wakeup-D0uvqLsE.mjs.map +1 -0
  150. package/dist/work-queue-worker-DEbWsrDQ.mjs +11 -0
  151. package/dist/{work-queue-worker-utPp4hUv.mjs → work-queue-worker-DufMOtrL.mjs} +9 -9
  152. package/dist/work-queue-worker-DufMOtrL.mjs.map +1 -0
  153. package/dist/{zettelkasten-DezbXghl.mjs → zettelkasten-BPxSOalU.mjs} +4 -4
  154. package/dist/{zettelkasten-DezbXghl.mjs.map → zettelkasten-BPxSOalU.mjs.map} +1 -1
  155. package/docker/init.sql +5 -1
  156. package/docs/commands/README.md +5 -0
  157. package/docs/commands/audit.md +1 -1
  158. package/docs/commands/backup.md +1 -1
  159. package/docs/commands/clear-names.md +1 -1
  160. package/docs/commands/config.md +4 -4
  161. package/docs/commands/daemon.md +1 -1
  162. package/docs/commands/db.md +15 -1
  163. package/docs/commands/end.md +1 -1
  164. package/docs/commands/help.md +1 -1
  165. package/docs/commands/hooks-db.md +47 -0
  166. package/docs/commands/identity.md +1 -1
  167. package/docs/commands/kg.md +1 -1
  168. package/docs/commands/launch.md +1 -1
  169. package/docs/commands/mcp.md +1 -1
  170. package/docs/commands/memory.md +1 -1
  171. package/docs/commands/notify.md +1 -1
  172. package/docs/commands/observation.md +1 -1
  173. package/docs/commands/obsidian.md +1 -1
  174. package/docs/commands/pause.md +1 -1
  175. package/docs/commands/project.md +1 -1
  176. package/docs/commands/projects.md +1 -1
  177. package/docs/commands/registry.md +1 -1
  178. package/docs/commands/restore.md +1 -1
  179. package/docs/commands/session.md +2 -2
  180. package/docs/commands/sessions.md +1 -1
  181. package/docs/commands/setup.md +1 -1
  182. package/docs/commands/shell-init.md +1 -1
  183. package/docs/commands/skill.md +1 -1
  184. package/docs/commands/task.md +1 -1
  185. package/docs/commands/topic.md +1 -1
  186. package/docs/commands/update.md +1 -1
  187. package/docs/commands/worker.md +1 -1
  188. package/docs/commands/zettel.md +1 -1
  189. package/docs/design/postgres-only.md +438 -0
  190. package/docs/design/registry-method-map.md +174 -0
  191. package/package.json +1 -1
  192. package/src/hooks/pre-compact.sh +2 -40
  193. package/src/hooks/session-hooks-db.test.ts +93 -0
  194. package/src/hooks/session-stop.sh +2 -26
  195. package/src/hooks/ts/lib/edit-gate.test.ts +9 -0
  196. package/src/hooks/ts/lib/edit-gate.ts +5 -2
  197. package/src/hooks/ts/lib/plutil-guard.test.ts +54 -0
  198. package/src/hooks/ts/lib/plutil-guard.ts +43 -0
  199. package/src/hooks/ts/lib/worker-git-guard.test.ts +134 -0
  200. package/src/hooks/ts/lib/worker-git-guard.ts +103 -0
  201. package/src/hooks/ts/pre-tool-use/security-validator.test.ts +68 -0
  202. package/src/hooks/ts/pre-tool-use/security-validator.ts +69 -21
  203. package/src/hooks/ts/session-start/load-core-context.ts +13 -0
  204. package/src/hooks/ts/session-start/session-start-worker-guard.test.ts +13 -0
  205. package/dist/auto-route-CcD0OWWB.mjs +0 -86
  206. package/dist/auto-route-CcD0OWWB.mjs.map +0 -1
  207. package/dist/clusters-Cw_P6lO-.mjs.map +0 -1
  208. package/dist/context-handover-cache-CXyH6QsC.mjs.map +0 -1
  209. package/dist/daemon-BkJNFWr9.mjs.map +0 -1
  210. package/dist/daemon-CiythMfR.mjs +0 -25
  211. package/dist/db-BOBfewFH.mjs +0 -3
  212. package/dist/db-DJ8rk0VM.mjs.map +0 -1
  213. package/dist/db-DbY2O8QO.mjs +0 -3
  214. package/dist/db-Ddns80yf.mjs.map +0 -1
  215. package/dist/detect-Bf2z-oKB.mjs +0 -86
  216. package/dist/detect-Bf2z-oKB.mjs.map +0 -1
  217. package/dist/detector-CkwkXuGh.mjs +0 -5
  218. package/dist/detector-DWXkeTlk.mjs.map +0 -1
  219. package/dist/factory-Ba8j9K7q.mjs +0 -3
  220. package/dist/factory-Bt7TWQje.mjs +0 -150
  221. package/dist/factory-Bt7TWQje.mjs.map +0 -1
  222. package/dist/fallback-CPfyTSTx.mjs.map +0 -1
  223. package/dist/indexer-backend-CdvCJCkD.mjs.map +0 -1
  224. package/dist/kg-entity-BSW7ra8i.mjs +0 -176
  225. package/dist/kg-entity-BSW7ra8i.mjs.map +0 -1
  226. package/dist/main-resolver-Bt1f6jJc.mjs.map +0 -1
  227. package/dist/main-resolver-DYHhw5Ig.mjs +0 -7
  228. package/dist/migrate-CfERwXhY.mjs.map +0 -1
  229. package/dist/neighborhood-CETR_P4y.mjs.map +0 -1
  230. package/dist/note-context-DCcRWBoN.mjs.map +0 -1
  231. package/dist/pai-home-ChAOupZc.mjs.map +0 -1
  232. package/dist/postgres-CUSXWgTG.mjs.map +0 -1
  233. package/dist/program-DYux0CW2.mjs.map +0 -1
  234. package/dist/query-feedback-Bm6XvCmg.mjs +0 -3
  235. package/dist/query-feedback-CTs_jx6i.mjs.map +0 -1
  236. package/dist/router-CremHKTI.mjs +0 -3
  237. package/dist/run-C7EDdVAB.mjs.map +0 -1
  238. package/dist/search-B69cQwDB.mjs +0 -303
  239. package/dist/search-B69cQwDB.mjs.map +0 -1
  240. package/dist/search-fb-5ovj4.mjs +0 -4
  241. package/dist/sources-KBGEA_E6.mjs.map +0 -1
  242. package/dist/sqlite-By6r2YhZ.mjs +0 -271
  243. package/dist/sqlite-By6r2YhZ.mjs.map +0 -1
  244. package/dist/state-Ca0ltLgI.mjs +0 -3
  245. package/dist/state-DwrsOoMi.mjs.map +0 -1
  246. package/dist/sync-Btcb6xA4.mjs +0 -310
  247. package/dist/sync-Btcb6xA4.mjs.map +0 -1
  248. package/dist/tools-BEqiJt_j.mjs.map +0 -1
  249. package/dist/wakeup-Yk5lQ0jb.mjs.map +0 -1
  250. package/dist/work-queue-worker-DsdJx-jn.mjs +0 -14
  251. package/dist/work-queue-worker-utPp4hUv.mjs.map +0 -1
@@ -1,12 +1,11 @@
1
- import { a as paiHomePath, o as resolvePaiFile, r as migratePaiFile } from "./pai-home-ChAOupZc.mjs";
2
- import { _ as warn, c as ok, i as err, n as dim, r as encodeDir, s as now, t as bold } from "./utils-CJymHkYm.mjs";
3
- import { a as slugify, i as parseSessionFilename, n as decodeEncodedDir, t as buildEncodedDirMap } from "./migrate-CfERwXhY.mjs";
4
- import { n as ensurePaiMarker, t as discoverPaiMarkers } from "./pai-marker-B20KqhA8.mjs";
5
- import { r as openFederation } from "./db-DJ8rk0VM.mjs";
6
- import { C as readWorkersSection, T as resolveModelCapability, m as defaultWorkersConfig } from "./config-B3EPzRjf.mjs";
7
- import { i as kgAdd, o as kgInvalidate, r as upsertKgEntity, s as kgQuery } from "./kg-entity-BSW7ra8i.mjs";
8
- import { b as workersLogDir, h as ensureNoMcpConfig, i as buildRunEnv, n as ensureProxyRunning, p as resolveTarget, t as DEFAULT_PROXY_PORT } from "./server-CGiHdaUp.mjs";
9
- import { d as registryDb, k as storageBackend, n as daemonConfig } from "./state-DwrsOoMi.mjs";
1
+ import { _ as warn, c as ok, i as err, n as dim, r as encodeDir, s as now, t as bold } from "./utils-C9HsYDpO.mjs";
2
+ import { a as slugify, i as parseSessionFilename, n as decodeEncodedDir, t as buildEncodedDirMap } from "./migrate-BD7D8EEh.mjs";
3
+ import { n as ensurePaiMarker, t as discoverPaiMarkers } from "./pai-marker-D1MMswkz.mjs";
4
+ import { i as getRegistryBackend } from "./factory-DiuntvwG.mjs";
5
+ import { a as paiHomePath, o as resolvePaiFile, r as migratePaiFile } from "./pai-home-CeOIYltV.mjs";
6
+ import { C as readWorkersSection, T as resolveModelCapability, m as defaultWorkersConfig } from "./config-B93YS8tP.mjs";
7
+ import { b as workersLogDir, h as ensureNoMcpConfig, i as buildRunEnv, n as ensureProxyRunning, p as resolveTarget, t as DEFAULT_PROXY_PORT } from "./server-CGuZFOeR.mjs";
8
+ import { k as storageBackend, n as daemonConfig } from "./state-n13uPK5B.mjs";
10
9
  import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
11
10
  import { homedir, tmpdir } from "node:os";
12
11
  import { basename, dirname, join, resolve } from "node:path";
@@ -199,9 +198,9 @@ function findMovedProjects(rows, byCwd, resolvesNow) {
199
198
  * Permits the write when the new value resolves to transcripts, or when the
200
199
  * existing one resolves to nothing — i.e. whenever it cannot make things worse.
201
200
  */
202
- function worthWriting(db, projectId, encodedDir) {
201
+ async function worthWriting(backend, projectId, encodedDir) {
203
202
  if (transcriptFiles(join(claudeProjectsDir(), encodedDir)).length > 0) return true;
204
- const current = db.prepare("SELECT encoded_dir FROM projects WHERE id = ?").get(projectId)?.encoded_dir;
203
+ const current = (await backend.getProjectById(projectId))?.encoded_dir;
205
204
  if (!current) return true;
206
205
  return transcriptFiles(join(claudeProjectsDir(), current)).length === 0;
207
206
  }
@@ -216,58 +215,51 @@ function worthWriting(db, projectId, encodedDir) {
216
215
  * display_name is set to basename(rootPath) on INSERT so that the unified
217
216
  * listing always shows a human-readable name rather than the kebab-case slug.
218
217
  */
219
- function upsertProject(db, slug, rootPath, encodedDir) {
218
+ async function upsertProject(backend, slug, rootPath, encodedDir) {
220
219
  const ts = now();
221
- const byPath = db.prepare("SELECT id FROM projects WHERE root_path = ?").get(rootPath);
220
+ const byPath = await backend.getProjectByRootPath(rootPath);
222
221
  if (byPath) {
223
- const encodedOwner = db.prepare("SELECT id FROM projects WHERE encoded_dir = ?").get(encodedDir);
224
- if ((!encodedOwner || encodedOwner.id === byPath.id) && worthWriting(db, byPath.id, encodedDir)) db.prepare("UPDATE projects SET encoded_dir = ?, updated_at = ? WHERE id = ?").run(encodedDir, ts, byPath.id);
222
+ const encodedOwner = await backend.getProjectByEncodedDir(encodedDir);
223
+ if ((!encodedOwner || encodedOwner.id === byPath.id) && await worthWriting(backend, byPath.id, encodedDir)) await backend.updateProjectPath(byPath.id, { encodedDir }, ts);
225
224
  return {
226
225
  id: byPath.id,
227
226
  isNew: false
228
227
  };
229
228
  }
230
- const byEncoded = db.prepare("SELECT id FROM projects WHERE encoded_dir = ?").get(encodedDir);
229
+ const byEncoded = await backend.getProjectByEncodedDir(encodedDir);
231
230
  if (byEncoded) {
232
- const pathOwner = db.prepare("SELECT id FROM projects WHERE root_path = ?").get(rootPath);
233
- if (!pathOwner || pathOwner.id === byEncoded.id) db.prepare("UPDATE projects SET root_path = ?, updated_at = ? WHERE id = ?").run(rootPath, ts, byEncoded.id);
231
+ const pathOwner = await backend.getProjectByRootPath(rootPath);
232
+ if (!pathOwner || pathOwner.id === byEncoded.id) await backend.updateProjectPath(byEncoded.id, { rootPath }, ts);
234
233
  return {
235
234
  id: byEncoded.id,
236
235
  isNew: false
237
236
  };
238
237
  }
239
- let finalSlug = slug;
240
- let attempt = 0;
241
- while (true) {
242
- if (!db.prepare("SELECT id FROM projects WHERE slug = ?").get(finalSlug)) break;
243
- attempt++;
244
- finalSlug = `${slug}-${attempt}`;
245
- }
246
- const displayName = basename(rootPath) || finalSlug;
247
- const result = db.prepare(`INSERT OR IGNORE INTO projects
248
- (slug, display_name, root_path, encoded_dir, type, status, created_at, updated_at)
249
- VALUES (?, ?, ?, ?, 'local', 'active', ?, ?)`).run(finalSlug, displayName, rootPath, encodedDir, ts, ts);
250
- if (result.changes === 0) {
251
- const fallback = db.prepare("SELECT id FROM projects WHERE encoded_dir = ?").get(encodedDir) ?? db.prepare("SELECT id FROM projects WHERE root_path = ?").get(rootPath);
252
- if (fallback) return {
253
- id: fallback.id,
254
- isNew: false
255
- };
256
- throw new Error(`upsertProject: INSERT OR IGNORE was suppressed but no matching row found for root_path=${rootPath} encoded_dir=${encodedDir}`);
257
- }
238
+ const displayName = basename(rootPath) || slug;
239
+ const result = await backend.createProjectWithSlugRetry({
240
+ baseSlug: slug,
241
+ displayName,
242
+ rootPath,
243
+ encodedDir,
244
+ createdAt: ts,
245
+ updatedAt: ts
246
+ });
258
247
  return {
259
- id: result.lastInsertRowid,
260
- isNew: true
248
+ id: result.id,
249
+ isNew: result.created
261
250
  };
262
251
  }
263
252
  /** Upsert a session note. Returns true if newly inserted. */
264
- function upsertSession(db, projectId, number, date, slug, title, filename) {
265
- if (db.prepare("SELECT id FROM sessions WHERE project_id = ? AND number = ?").get(projectId, number)) return false;
266
- const ts = now();
267
- db.prepare(`INSERT INTO sessions
268
- (project_id, number, date, slug, title, filename, status, created_at)
269
- VALUES (?, ?, ?, ?, ?, ?, 'completed', ?)`).run(projectId, number, date, slug, title, filename, ts);
270
- return true;
253
+ async function upsertSession(backend, projectId, number, date, slug, title, filename) {
254
+ return backend.upsertSessionIfAbsent({
255
+ projectId,
256
+ number,
257
+ date,
258
+ slug,
259
+ title,
260
+ filename,
261
+ createdAt: now()
262
+ });
271
263
  }
272
264
 
273
265
  //#endregion
@@ -367,7 +359,8 @@ function findNoteFiles(dir) {
367
359
  }
368
360
  return results;
369
361
  }
370
- function performScan(db) {
362
+ async function performScan() {
363
+ const backend = await getRegistryBackend();
371
364
  const result = {
372
365
  projectsScanned: 0,
373
366
  projectsNew: 0,
@@ -395,7 +388,7 @@ function performScan(db) {
395
388
  }
396
389
  rootPath = canonicalPath(rootPath);
397
390
  const slug = slugify(basename(rootPath) || encodedDir);
398
- const { id, isNew } = upsertProject(db, slug, rootPath, encodedDir);
391
+ const { id, isNew } = await upsertProject(backend, slug, rootPath, encodedDir);
399
392
  result.projectsScanned++;
400
393
  if (isNew) result.projectsNew++;
401
394
  else result.projectsUpdated++;
@@ -404,7 +397,7 @@ function performScan(db) {
404
397
  } catch {}
405
398
  const claudeNotesDir = join(CLAUDE_PROJECTS_DIR$1, encodedDir, "Notes");
406
399
  if (existsSync(claudeNotesDir)) {
407
- if (claudeNotesDir !== join(rootPath, "Notes")) db.prepare("UPDATE projects SET claude_notes_dir = ?, updated_at = ? WHERE id = ?").run(claudeNotesDir, Date.now(), id);
400
+ if (claudeNotesDir !== join(rootPath, "Notes")) await backend.updateProjectClaudeNotesDir(id, claudeNotesDir, Date.now());
408
401
  }
409
402
  if (!existsSync(claudeNotesDir)) continue;
410
403
  const noteFiles = findNoteFiles(claudeNotesDir);
@@ -412,11 +405,11 @@ function performScan(db) {
412
405
  const parsed = parseSessionFilename(filename);
413
406
  if (!parsed) continue;
414
407
  result.sessionsScanned++;
415
- if (upsertSession(db, id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
408
+ if (await upsertSession(backend, id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
416
409
  }
417
410
  }
418
411
  {
419
- const activeProjects = db.prepare("SELECT id, slug, root_path FROM projects WHERE status = 'active'").all();
412
+ const activeProjects = await backend.listProjects({ status: "active" });
420
413
  for (const project of activeProjects) {
421
414
  const notesDir = join(project.root_path, "Notes");
422
415
  if (!existsSync(notesDir)) continue;
@@ -430,7 +423,7 @@ function performScan(db) {
430
423
  const parsed = parseSessionFilename(filename);
431
424
  if (!parsed) continue;
432
425
  result.sessionsScanned++;
433
- if (upsertSession(db, project.id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
426
+ if (await upsertSession(backend, project.id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
434
427
  }
435
428
  }
436
429
  }
@@ -454,7 +447,7 @@ function performScan(db) {
454
447
  const childPath = canonicalPath(join(scanDir, child));
455
448
  const childSlug = slugify(child);
456
449
  const childEncoded = encodeDir(childPath);
457
- const existing = db.prepare("SELECT id FROM projects WHERE root_path = ?").get(childPath);
450
+ const existing = await backend.getProjectByRootPath(childPath);
458
451
  if (existing) {
459
452
  result.projectsScanned++;
460
453
  result.projectsUpdated++;
@@ -468,12 +461,12 @@ function performScan(db) {
468
461
  const parsed = parseSessionFilename(filename);
469
462
  if (!parsed) continue;
470
463
  result.sessionsScanned++;
471
- if (upsertSession(db, existing.id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
464
+ if (await upsertSession(backend, existing.id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
472
465
  }
473
466
  }
474
467
  continue;
475
468
  }
476
- const { id, isNew } = upsertProject(db, childSlug, childPath, childEncoded);
469
+ const { id, isNew } = await upsertProject(backend, childSlug, childPath, childEncoded);
477
470
  result.projectsScanned++;
478
471
  if (isNew) result.projectsNew++;
479
472
  else result.projectsUpdated++;
@@ -487,7 +480,7 @@ function performScan(db) {
487
480
  const parsed = parseSessionFilename(filename);
488
481
  if (!parsed) continue;
489
482
  result.sessionsScanned++;
490
- if (upsertSession(db, id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
483
+ if (await upsertSession(backend, id, parsed.number, parsed.date, parsed.slug, parsed.title, parsed.filename)) result.sessionsNew++;
491
484
  }
492
485
  }
493
486
  }
@@ -495,28 +488,31 @@ function performScan(db) {
495
488
  if (config.scan_dirs.length) {
496
489
  const markers = discoverPaiMarkers(config.scan_dirs.map(resolveHome).filter(existsSync));
497
490
  for (const marker of markers) {
498
- const registeredRow = db.prepare("SELECT id, root_path, slug, encoded_dir FROM projects WHERE slug = ?").get(marker.slug);
491
+ const registeredRow = await backend.getProjectBySlug(marker.slug);
499
492
  if (!registeredRow) continue;
500
493
  const markerRoot = canonicalPath(marker.projectRoot);
501
494
  if (registeredRow.root_path !== markerRoot) {
502
495
  const newEncoded = encodeDir(markerRoot);
503
496
  const now4 = Date.now();
504
- const encodedOwner = db.prepare("SELECT id FROM projects WHERE encoded_dir = ?").get(newEncoded);
505
- const pathOwner = db.prepare("SELECT id FROM projects WHERE root_path = ?").get(markerRoot);
497
+ const encodedOwner = await backend.getProjectByEncodedDir(newEncoded);
498
+ const pathOwner = await backend.getProjectByRootPath(markerRoot);
506
499
  const encodedSafe = !encodedOwner || encodedOwner.id === registeredRow.id;
507
500
  const pathSafe = !pathOwner || pathOwner.id === registeredRow.id;
508
501
  const derivedResolves = transcriptFiles(join(claudeProjectsDir(), newEncoded)).length > 0;
509
502
  const currentResolves = Boolean(registeredRow.encoded_dir) && transcriptFiles(join(claudeProjectsDir(), registeredRow.encoded_dir)).length > 0;
510
- if (encodedSafe && pathSafe && (derivedResolves || !currentResolves)) db.prepare("UPDATE projects SET root_path = ?, encoded_dir = ?, updated_at = ? WHERE id = ?").run(markerRoot, newEncoded, now4, registeredRow.id);
511
- else if (pathSafe) db.prepare("UPDATE projects SET root_path = ?, updated_at = ? WHERE id = ?").run(markerRoot, now4, registeredRow.id);
503
+ if (encodedSafe && pathSafe && (derivedResolves || !currentResolves)) await backend.updateProjectPath(registeredRow.id, {
504
+ rootPath: markerRoot,
505
+ encodedDir: newEncoded
506
+ }, now4);
507
+ else if (pathSafe) await backend.updateProjectPath(registeredRow.id, { rootPath: markerRoot }, now4);
512
508
  }
513
509
  }
514
510
  }
515
511
  {
516
- const stale = db.prepare("SELECT id, slug, root_path FROM projects WHERE display_name = slug AND root_path IS NOT NULL AND root_path != ''").all();
512
+ const stale = (await backend.listProjects()).filter((p) => p.display_name === p.slug && p.root_path);
517
513
  for (const row of stale) {
518
514
  const name = basename(row.root_path);
519
- if (name && name !== row.slug) db.prepare("UPDATE projects SET display_name = ?, updated_at = ? WHERE id = ?").run(name, Date.now(), row.id);
515
+ if (name && name !== row.slug) await backend.updateProjectDisplayName(row.id, name, Date.now());
520
516
  }
521
517
  }
522
518
  return result;
@@ -529,7 +525,7 @@ function performScan(db) {
529
525
  * this flag exists for hook/daemon-triggered invocations that
530
526
  * want minimal log output.
531
527
  */
532
- function cmdScan(db, opts = {}) {
528
+ async function cmdScan(opts = {}) {
533
529
  const config = loadScanConfig();
534
530
  if (!opts.quick) {
535
531
  console.log(dim("Scanning ~/.claude/projects/ ..."));
@@ -538,7 +534,7 @@ function cmdScan(db, opts = {}) {
538
534
  }
539
535
  let result;
540
536
  try {
541
- result = performScan(db);
537
+ result = await performScan();
542
538
  } catch (e) {
543
539
  console.error(err(String(e)));
544
540
  process.exitCode = 1;
@@ -2166,7 +2162,7 @@ function extractJsonSpan(text) {
2166
2162
  * Best-effort: per-triple errors are caught and logged but never thrown.
2167
2163
  * Returns a small stats object so callers can report progress.
2168
2164
  */
2169
- async function extractAndStoreTriples$1(pool, params) {
2165
+ async function extractAndStoreTriples$1(backend, params) {
2170
2166
  const stats = {
2171
2167
  extracted: 0,
2172
2168
  added: 0,
@@ -2186,12 +2182,12 @@ async function extractAndStoreTriples$1(pool, params) {
2186
2182
  if (Array.isArray(parsed)) triples = parsed;
2187
2183
  else if (parsed && typeof parsed === "object" && Array.isArray(parsed.relations)) {
2188
2184
  const newFmt = parsed;
2189
- if (params.federationDb && Array.isArray(newFmt.entities)) {
2185
+ if (Array.isArray(newFmt.entities)) {
2190
2186
  const tenantId = params.tenantId ?? "default";
2191
2187
  for (const entity of newFmt.entities) {
2192
2188
  if (!entity.name) continue;
2193
2189
  try {
2194
- upsertKgEntity(params.federationDb, {
2190
+ await backend.upsertKgEntity({
2195
2191
  name: entity.name,
2196
2192
  type: entity.type ?? "unknown",
2197
2193
  description: entity.description,
@@ -2223,7 +2219,7 @@ async function extractAndStoreTriples$1(pool, params) {
2223
2219
  for (const t of triples) {
2224
2220
  if (!t.subject || !t.predicate || !t.object) continue;
2225
2221
  try {
2226
- const existing = await kgQuery(pool, {
2222
+ const existing = await backend.queryKgTriples({
2227
2223
  subject: t.subject,
2228
2224
  predicate: t.predicate,
2229
2225
  project_id: params.projectId ?? void 0
@@ -2231,10 +2227,10 @@ async function extractAndStoreTriples$1(pool, params) {
2231
2227
  if (existing.find((e) => e.object === t.object && !e.valid_to)) continue;
2232
2228
  const supersedes = existing.find((e) => e.object !== t.object && !e.valid_to);
2233
2229
  if (supersedes) {
2234
- await kgInvalidate(pool, supersedes.id);
2230
+ await backend.invalidateKgTriple(supersedes.id);
2235
2231
  stats.superseded++;
2236
2232
  }
2237
- await kgAdd(pool, {
2233
+ await backend.addKgTriple({
2238
2234
  subject: t.subject,
2239
2235
  predicate: t.predicate,
2240
2236
  object: t.object,
@@ -2861,13 +2857,12 @@ ${aiBody}
2861
2857
  }
2862
2858
  }
2863
2859
  /**
2864
- * Look up the integer project_id from the registry DB for a given slug.
2865
- * Returns null if not found or registryDb is not yet initialized.
2860
+ * Look up the integer project_id from the registry backend for a given slug.
2861
+ * Returns null if not found.
2866
2862
  */
2867
- function lookupProjectId(slug) {
2863
+ async function lookupProjectId(slug) {
2868
2864
  try {
2869
- if (!registryDb) return null;
2870
- return registryDb.prepare("SELECT id FROM projects WHERE slug = ? LIMIT 1").get(slug)?.id ?? null;
2865
+ return (await (await getRegistryBackend()).getProjectBySlug(slug))?.id ?? null;
2871
2866
  } catch {
2872
2867
  return null;
2873
2868
  }
@@ -2880,32 +2875,20 @@ function lookupProjectId(slug) {
2880
2875
  */
2881
2876
  async function extractAndStoreTriples(params) {
2882
2877
  try {
2883
- if (!storageBackend || storageBackend.backendType !== "postgres") return;
2884
- const pool = storageBackend.getPool?.();
2885
- if (!pool) {
2886
- process.stderr.write("[session-summary] Triple extraction: no pool available.\n");
2887
- return;
2888
- }
2878
+ if (!storageBackend?.supportsPostgresFeatures) return;
2889
2879
  const cfg = daemonConfig;
2890
2880
  if (cfg && cfg.kg_extraction_enabled === false) {
2891
2881
  process.stderr.write("[session-summary] Triple extraction disabled via kg_extraction_enabled=false.\n");
2892
2882
  return;
2893
2883
  }
2894
- const federationDb = openFederation();
2895
- let result;
2896
- try {
2897
- result = await extractAndStoreTriples$1(pool, {
2898
- summaryText: params.summaryText,
2899
- projectSlug: params.projectSlug,
2900
- projectId: params.projectId,
2901
- sessionId: params.sessionId,
2902
- gitLog: params.gitLog,
2903
- model: "sonnet",
2904
- federationDb
2905
- });
2906
- } finally {
2907
- federationDb.close();
2908
- }
2884
+ const result = await extractAndStoreTriples$1(storageBackend, {
2885
+ summaryText: params.summaryText,
2886
+ projectSlug: params.projectSlug,
2887
+ projectId: params.projectId,
2888
+ sessionId: params.sessionId,
2889
+ gitLog: params.gitLog,
2890
+ model: "sonnet"
2891
+ });
2909
2892
  process.stderr.write(`[session-summary] Triple extraction complete: ${result.extracted} extracted, ${result.added} added, ${result.superseded} superseded.\n`);
2910
2893
  } catch (err) {
2911
2894
  process.stderr.write(`[session-summary] Triple extraction failed: ${err}\n`);
@@ -2975,7 +2958,7 @@ async function handleSessionSummary(payload) {
2975
2958
  await extractAndStoreTriples({
2976
2959
  summaryText,
2977
2960
  projectSlug: projectSlug ?? basename(cwd),
2978
- projectId: projectSlug ? lookupProjectId(projectSlug) : null,
2961
+ projectId: projectSlug ? await lookupProjectId(projectSlug) : null,
2979
2962
  sessionId: sessionId ?? cwd,
2980
2963
  gitLog,
2981
2964
  model: selectedModel
@@ -3239,4 +3222,4 @@ function writeContextHandoverCache(cache) {
3239
3222
 
3240
3223
  //#endregion
3241
3224
  export { archiveSessionFilesToSessionsDir as A, claudeProjectsDir as B, findLatestNote as C, appendCheckpoint as D, addWorkToSessionNote as E, performScan as F, scanTranscriptFolders as H, resolveHome as I, saveScanConfig as L, cmdScan as M, loadScanConfig as N, finalizeSessionNote as O, migrateScanConfig as P, upsertProject as R, applyContinue as S, readBodyFile as T, transcriptFiles as U, findMovedProjects as V, spawnSummarizer as _, enqueue as a, updateTodoContinue as b, loadQueue as c, migrateWorkQueue as d, contentToText as f, migrateSummaryCooldowns as g, handleSessionSummary as h, dequeue as i, findNotesDir$1 as j, getCurrentNotePath as k, markCompleted as l, getGitContext as m, writeContextHandoverCache as n, getStats as o, findLatestJsonl as p, cleanup as r, hasPendingOrProcessingOfType as s, readContextHandoverCache as t, markFailed as u, extractAndStoreTriples$1 as v, findNotesDir as w, appendCheckpointToNote as x, sessionIdFromTranscript as y, upsertSession as z };
3242
- //# sourceMappingURL=context-handover-cache-CXyH6QsC.mjs.map
3225
+ //# sourceMappingURL=context-handover-cache-k2kWbE6G.mjs.map