@soleri/core 2.10.0 → 2.11.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 (499) hide show
  1. package/dist/agency/agency-manager.d.ts +47 -0
  2. package/dist/agency/agency-manager.d.ts.map +1 -0
  3. package/dist/agency/agency-manager.js +281 -0
  4. package/dist/agency/agency-manager.js.map +1 -0
  5. package/dist/agency/index.d.ts +3 -0
  6. package/dist/agency/index.d.ts.map +1 -0
  7. package/dist/agency/index.js +2 -0
  8. package/dist/agency/index.js.map +1 -0
  9. package/dist/agency/types.d.ts +69 -0
  10. package/dist/agency/types.d.ts.map +1 -0
  11. package/dist/agency/types.js +5 -0
  12. package/dist/agency/types.js.map +1 -0
  13. package/dist/brain/brain.d.ts +0 -1
  14. package/dist/brain/brain.d.ts.map +1 -1
  15. package/dist/brain/brain.js +14 -0
  16. package/dist/brain/brain.js.map +1 -1
  17. package/dist/brain/intelligence.d.ts +5 -1
  18. package/dist/brain/intelligence.d.ts.map +1 -1
  19. package/dist/brain/intelligence.js +83 -0
  20. package/dist/brain/intelligence.js.map +1 -1
  21. package/dist/brain/types.d.ts +21 -0
  22. package/dist/brain/types.d.ts.map +1 -1
  23. package/dist/chat/agent-loop-types.d.ts +82 -0
  24. package/dist/chat/agent-loop-types.d.ts.map +1 -0
  25. package/dist/chat/agent-loop-types.js +8 -0
  26. package/dist/chat/agent-loop-types.js.map +1 -0
  27. package/dist/chat/agent-loop.d.ts +19 -0
  28. package/dist/chat/agent-loop.d.ts.map +1 -0
  29. package/dist/chat/agent-loop.js +261 -0
  30. package/dist/chat/agent-loop.js.map +1 -0
  31. package/dist/chat/auth-manager.d.ts +49 -0
  32. package/dist/chat/auth-manager.d.ts.map +1 -0
  33. package/dist/chat/auth-manager.js +152 -0
  34. package/dist/chat/auth-manager.js.map +1 -0
  35. package/dist/chat/browser-session.d.ts +86 -0
  36. package/dist/chat/browser-session.d.ts.map +1 -0
  37. package/dist/chat/browser-session.js +143 -0
  38. package/dist/chat/browser-session.js.map +1 -0
  39. package/dist/chat/cancellation.d.ts +54 -0
  40. package/dist/chat/cancellation.d.ts.map +1 -0
  41. package/dist/chat/cancellation.js +80 -0
  42. package/dist/chat/cancellation.js.map +1 -0
  43. package/dist/chat/chat-session.d.ts +86 -0
  44. package/dist/chat/chat-session.d.ts.map +1 -0
  45. package/dist/chat/chat-session.js +252 -0
  46. package/dist/chat/chat-session.js.map +1 -0
  47. package/dist/chat/file-handler.d.ts +63 -0
  48. package/dist/chat/file-handler.d.ts.map +1 -0
  49. package/dist/chat/file-handler.js +182 -0
  50. package/dist/chat/file-handler.js.map +1 -0
  51. package/dist/chat/fragment-buffer.d.ts +49 -0
  52. package/dist/chat/fragment-buffer.d.ts.map +1 -0
  53. package/dist/chat/fragment-buffer.js +130 -0
  54. package/dist/chat/fragment-buffer.js.map +1 -0
  55. package/dist/chat/index.d.ts +24 -0
  56. package/dist/chat/index.d.ts.map +1 -0
  57. package/dist/chat/index.js +15 -0
  58. package/dist/chat/index.js.map +1 -0
  59. package/dist/chat/mcp-bridge.d.ts +60 -0
  60. package/dist/chat/mcp-bridge.d.ts.map +1 -0
  61. package/dist/chat/mcp-bridge.js +111 -0
  62. package/dist/chat/mcp-bridge.js.map +1 -0
  63. package/dist/chat/notifications.d.ts +82 -0
  64. package/dist/chat/notifications.d.ts.map +1 -0
  65. package/dist/chat/notifications.js +119 -0
  66. package/dist/chat/notifications.js.map +1 -0
  67. package/dist/chat/output-compressor.d.ts +30 -0
  68. package/dist/chat/output-compressor.d.ts.map +1 -0
  69. package/dist/chat/output-compressor.js +95 -0
  70. package/dist/chat/output-compressor.js.map +1 -0
  71. package/dist/chat/queue.d.ts +91 -0
  72. package/dist/chat/queue.d.ts.map +1 -0
  73. package/dist/chat/queue.js +146 -0
  74. package/dist/chat/queue.js.map +1 -0
  75. package/dist/chat/response-chunker.d.ts +29 -0
  76. package/dist/chat/response-chunker.d.ts.map +1 -0
  77. package/dist/chat/response-chunker.js +163 -0
  78. package/dist/chat/response-chunker.js.map +1 -0
  79. package/dist/chat/self-update.d.ts +62 -0
  80. package/dist/chat/self-update.d.ts.map +1 -0
  81. package/dist/chat/self-update.js +90 -0
  82. package/dist/chat/self-update.js.map +1 -0
  83. package/dist/chat/types.d.ts +105 -0
  84. package/dist/chat/types.d.ts.map +1 -0
  85. package/dist/chat/types.js +8 -0
  86. package/dist/chat/types.js.map +1 -0
  87. package/dist/chat/voice.d.ts +39 -0
  88. package/dist/chat/voice.d.ts.map +1 -0
  89. package/dist/chat/voice.js +80 -0
  90. package/dist/chat/voice.js.map +1 -0
  91. package/dist/claudemd/compose.d.ts +31 -0
  92. package/dist/claudemd/compose.d.ts.map +1 -0
  93. package/dist/claudemd/compose.js +105 -0
  94. package/dist/claudemd/compose.js.map +1 -0
  95. package/dist/claudemd/index.d.ts +5 -0
  96. package/dist/claudemd/index.d.ts.map +1 -0
  97. package/dist/claudemd/index.js +3 -0
  98. package/dist/claudemd/index.js.map +1 -0
  99. package/dist/claudemd/inject.d.ts +31 -0
  100. package/dist/claudemd/inject.d.ts.map +1 -0
  101. package/dist/claudemd/inject.js +157 -0
  102. package/dist/claudemd/inject.js.map +1 -0
  103. package/dist/claudemd/types.d.ts +41 -0
  104. package/dist/claudemd/types.d.ts.map +1 -0
  105. package/dist/claudemd/types.js +5 -0
  106. package/dist/claudemd/types.js.map +1 -0
  107. package/dist/context/context-engine.d.ts +31 -0
  108. package/dist/context/context-engine.d.ts.map +1 -0
  109. package/dist/context/context-engine.js +245 -0
  110. package/dist/context/context-engine.js.map +1 -0
  111. package/dist/context/index.d.ts +3 -0
  112. package/dist/context/index.d.ts.map +1 -0
  113. package/dist/context/index.js +2 -0
  114. package/dist/context/index.js.map +1 -0
  115. package/dist/context/types.d.ts +54 -0
  116. package/dist/context/types.d.ts.map +1 -0
  117. package/dist/context/types.js +5 -0
  118. package/dist/context/types.js.map +1 -0
  119. package/dist/enforcement/adapters/claude-code.d.ts +18 -0
  120. package/dist/enforcement/adapters/claude-code.d.ts.map +1 -0
  121. package/dist/enforcement/adapters/claude-code.js +106 -0
  122. package/dist/enforcement/adapters/claude-code.js.map +1 -0
  123. package/dist/enforcement/adapters/index.d.ts +2 -0
  124. package/dist/enforcement/adapters/index.d.ts.map +1 -0
  125. package/dist/enforcement/adapters/index.js +2 -0
  126. package/dist/enforcement/adapters/index.js.map +1 -0
  127. package/dist/enforcement/index.d.ts +4 -0
  128. package/dist/enforcement/index.d.ts.map +1 -0
  129. package/dist/enforcement/index.js +3 -0
  130. package/dist/enforcement/index.js.map +1 -0
  131. package/dist/enforcement/registry.d.ts +23 -0
  132. package/dist/enforcement/registry.d.ts.map +1 -0
  133. package/dist/enforcement/registry.js +63 -0
  134. package/dist/enforcement/registry.js.map +1 -0
  135. package/dist/enforcement/types.d.ts +51 -0
  136. package/dist/enforcement/types.d.ts.map +1 -0
  137. package/dist/enforcement/types.js +8 -0
  138. package/dist/enforcement/types.js.map +1 -0
  139. package/dist/facades/facade-factory.d.ts +10 -3
  140. package/dist/facades/facade-factory.d.ts.map +1 -1
  141. package/dist/facades/facade-factory.js +94 -5
  142. package/dist/facades/facade-factory.js.map +1 -1
  143. package/dist/facades/types.d.ts +15 -1
  144. package/dist/facades/types.d.ts.map +1 -1
  145. package/dist/facades/types.js +6 -0
  146. package/dist/facades/types.js.map +1 -1
  147. package/dist/health/health-registry.d.ts +40 -0
  148. package/dist/health/health-registry.d.ts.map +1 -0
  149. package/dist/health/health-registry.js +134 -0
  150. package/dist/health/health-registry.js.map +1 -0
  151. package/dist/health/index.d.ts +5 -0
  152. package/dist/health/index.d.ts.map +1 -0
  153. package/dist/health/index.js +3 -0
  154. package/dist/health/index.js.map +1 -0
  155. package/dist/health/vault-integrity.d.ts +13 -0
  156. package/dist/health/vault-integrity.d.ts.map +1 -0
  157. package/dist/health/vault-integrity.js +49 -0
  158. package/dist/health/vault-integrity.js.map +1 -0
  159. package/dist/index.d.ts +67 -6
  160. package/dist/index.d.ts.map +1 -1
  161. package/dist/index.js +51 -3
  162. package/dist/index.js.map +1 -1
  163. package/dist/intake/intake-pipeline.d.ts +0 -7
  164. package/dist/intake/intake-pipeline.d.ts.map +1 -1
  165. package/dist/intake/intake-pipeline.js +1 -1
  166. package/dist/intake/intake-pipeline.js.map +1 -1
  167. package/dist/intelligence/types.d.ts +1 -0
  168. package/dist/intelligence/types.d.ts.map +1 -1
  169. package/dist/migrations/index.d.ts +6 -0
  170. package/dist/migrations/index.d.ts.map +1 -0
  171. package/dist/migrations/index.js +5 -0
  172. package/dist/migrations/index.js.map +1 -0
  173. package/dist/migrations/migration-runner.d.ts +51 -0
  174. package/dist/migrations/migration-runner.d.ts.map +1 -0
  175. package/dist/migrations/migration-runner.js +141 -0
  176. package/dist/migrations/migration-runner.js.map +1 -0
  177. package/dist/packs/index.d.ts +10 -0
  178. package/dist/packs/index.d.ts.map +1 -0
  179. package/dist/packs/index.js +8 -0
  180. package/dist/packs/index.js.map +1 -0
  181. package/dist/packs/lockfile.d.ts +97 -0
  182. package/dist/packs/lockfile.d.ts.map +1 -0
  183. package/dist/packs/lockfile.js +129 -0
  184. package/dist/packs/lockfile.js.map +1 -0
  185. package/dist/packs/pack-installer.d.ts +41 -0
  186. package/dist/packs/pack-installer.d.ts.map +1 -0
  187. package/dist/packs/pack-installer.js +253 -0
  188. package/dist/packs/pack-installer.js.map +1 -0
  189. package/dist/packs/resolver.d.ts +51 -0
  190. package/dist/packs/resolver.d.ts.map +1 -0
  191. package/dist/packs/resolver.js +195 -0
  192. package/dist/packs/resolver.js.map +1 -0
  193. package/dist/packs/types.d.ts +186 -0
  194. package/dist/packs/types.d.ts.map +1 -0
  195. package/dist/packs/types.js +69 -0
  196. package/dist/packs/types.js.map +1 -0
  197. package/dist/persistence/postgres-provider.d.ts +42 -7
  198. package/dist/persistence/postgres-provider.d.ts.map +1 -1
  199. package/dist/persistence/postgres-provider.js +187 -46
  200. package/dist/persistence/postgres-provider.js.map +1 -1
  201. package/dist/playbooks/index.d.ts +2 -0
  202. package/dist/playbooks/index.d.ts.map +1 -1
  203. package/dist/playbooks/index.js +2 -0
  204. package/dist/playbooks/index.js.map +1 -1
  205. package/dist/playbooks/playbook-executor.d.ts +100 -0
  206. package/dist/playbooks/playbook-executor.d.ts.map +1 -0
  207. package/dist/playbooks/playbook-executor.js +207 -0
  208. package/dist/playbooks/playbook-executor.js.map +1 -0
  209. package/dist/plugins/index.d.ts +7 -0
  210. package/dist/plugins/index.d.ts.map +1 -0
  211. package/dist/plugins/index.js +7 -0
  212. package/dist/plugins/index.js.map +1 -0
  213. package/dist/plugins/plugin-loader.d.ts +28 -0
  214. package/dist/plugins/plugin-loader.d.ts.map +1 -0
  215. package/dist/plugins/plugin-loader.js +150 -0
  216. package/dist/plugins/plugin-loader.js.map +1 -0
  217. package/dist/plugins/plugin-registry.d.ts +58 -0
  218. package/dist/plugins/plugin-registry.d.ts.map +1 -0
  219. package/dist/plugins/plugin-registry.js +157 -0
  220. package/dist/plugins/plugin-registry.js.map +1 -0
  221. package/dist/plugins/types.d.ts +180 -0
  222. package/dist/plugins/types.d.ts.map +1 -0
  223. package/dist/plugins/types.js +48 -0
  224. package/dist/plugins/types.js.map +1 -0
  225. package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
  226. package/dist/runtime/admin-extra-ops.js +181 -8
  227. package/dist/runtime/admin-extra-ops.js.map +1 -1
  228. package/dist/runtime/capture-ops.d.ts.map +1 -1
  229. package/dist/runtime/capture-ops.js +106 -7
  230. package/dist/runtime/capture-ops.js.map +1 -1
  231. package/dist/runtime/deprecation.d.ts +33 -0
  232. package/dist/runtime/deprecation.d.ts.map +1 -0
  233. package/dist/runtime/deprecation.js +41 -0
  234. package/dist/runtime/deprecation.js.map +1 -0
  235. package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
  236. package/dist/runtime/facades/admin-facade.js +12 -1
  237. package/dist/runtime/facades/admin-facade.js.map +1 -1
  238. package/dist/runtime/facades/agency-facade.d.ts +7 -0
  239. package/dist/runtime/facades/agency-facade.d.ts.map +1 -0
  240. package/dist/runtime/facades/agency-facade.js +103 -0
  241. package/dist/runtime/facades/agency-facade.js.map +1 -0
  242. package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
  243. package/dist/runtime/facades/brain-facade.js +58 -0
  244. package/dist/runtime/facades/brain-facade.js.map +1 -1
  245. package/dist/runtime/facades/chat-facade.d.ts +7 -0
  246. package/dist/runtime/facades/chat-facade.d.ts.map +1 -0
  247. package/dist/runtime/facades/chat-facade.js +808 -0
  248. package/dist/runtime/facades/chat-facade.js.map +1 -0
  249. package/dist/runtime/facades/context-facade.d.ts +7 -0
  250. package/dist/runtime/facades/context-facade.d.ts.map +1 -0
  251. package/dist/runtime/facades/context-facade.js +45 -0
  252. package/dist/runtime/facades/context-facade.js.map +1 -0
  253. package/dist/runtime/facades/index.d.ts.map +1 -1
  254. package/dist/runtime/facades/index.js +18 -0
  255. package/dist/runtime/facades/index.js.map +1 -1
  256. package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
  257. package/dist/runtime/facades/vault-facade.js +247 -1
  258. package/dist/runtime/facades/vault-facade.js.map +1 -1
  259. package/dist/runtime/feature-flags.d.ts +18 -0
  260. package/dist/runtime/feature-flags.d.ts.map +1 -0
  261. package/dist/runtime/feature-flags.js +90 -0
  262. package/dist/runtime/feature-flags.js.map +1 -0
  263. package/dist/runtime/pack-ops.d.ts +9 -0
  264. package/dist/runtime/pack-ops.d.ts.map +1 -0
  265. package/dist/runtime/pack-ops.js +76 -0
  266. package/dist/runtime/pack-ops.js.map +1 -0
  267. package/dist/runtime/playbook-ops.d.ts +3 -7
  268. package/dist/runtime/playbook-ops.d.ts.map +1 -1
  269. package/dist/runtime/playbook-ops.js +101 -10
  270. package/dist/runtime/playbook-ops.js.map +1 -1
  271. package/dist/runtime/plugin-ops.d.ts +9 -0
  272. package/dist/runtime/plugin-ops.d.ts.map +1 -0
  273. package/dist/runtime/plugin-ops.js +235 -0
  274. package/dist/runtime/plugin-ops.js.map +1 -0
  275. package/dist/runtime/runtime.d.ts.map +1 -1
  276. package/dist/runtime/runtime.js +72 -5
  277. package/dist/runtime/runtime.js.map +1 -1
  278. package/dist/runtime/telemetry-ops.d.ts +10 -0
  279. package/dist/runtime/telemetry-ops.d.ts.map +1 -0
  280. package/dist/runtime/telemetry-ops.js +53 -0
  281. package/dist/runtime/telemetry-ops.js.map +1 -0
  282. package/dist/runtime/types.d.ts +35 -0
  283. package/dist/runtime/types.d.ts.map +1 -1
  284. package/dist/runtime/vault-sharing-ops.d.ts +13 -0
  285. package/dist/runtime/vault-sharing-ops.d.ts.map +1 -0
  286. package/dist/runtime/vault-sharing-ops.js +345 -0
  287. package/dist/runtime/vault-sharing-ops.js.map +1 -0
  288. package/dist/streams/index.d.ts +1 -1
  289. package/dist/streams/index.d.ts.map +1 -1
  290. package/dist/streams/index.js +1 -1
  291. package/dist/streams/index.js.map +1 -1
  292. package/dist/streams/replayable-stream.d.ts +13 -1
  293. package/dist/streams/replayable-stream.d.ts.map +1 -1
  294. package/dist/streams/replayable-stream.js +27 -3
  295. package/dist/streams/replayable-stream.js.map +1 -1
  296. package/dist/text/similarity.d.ts +0 -1
  297. package/dist/text/similarity.d.ts.map +1 -1
  298. package/dist/text/similarity.js +1 -1
  299. package/dist/text/similarity.js.map +1 -1
  300. package/dist/transport/http-server.d.ts +56 -0
  301. package/dist/transport/http-server.d.ts.map +1 -0
  302. package/dist/transport/http-server.js +210 -0
  303. package/dist/transport/http-server.js.map +1 -0
  304. package/dist/transport/index.d.ts +11 -0
  305. package/dist/transport/index.d.ts.map +1 -0
  306. package/dist/transport/index.js +10 -0
  307. package/dist/transport/index.js.map +1 -0
  308. package/dist/transport/lsp-server.d.ts +140 -0
  309. package/dist/transport/lsp-server.d.ts.map +1 -0
  310. package/dist/transport/lsp-server.js +239 -0
  311. package/dist/transport/lsp-server.js.map +1 -0
  312. package/dist/transport/rate-limiter.d.ts +35 -0
  313. package/dist/transport/rate-limiter.d.ts.map +1 -0
  314. package/dist/transport/rate-limiter.js +72 -0
  315. package/dist/transport/rate-limiter.js.map +1 -0
  316. package/dist/transport/session-manager.d.ts +49 -0
  317. package/dist/transport/session-manager.d.ts.map +1 -0
  318. package/dist/transport/session-manager.js +83 -0
  319. package/dist/transport/session-manager.js.map +1 -0
  320. package/dist/transport/token-auth.d.ts +29 -0
  321. package/dist/transport/token-auth.d.ts.map +1 -0
  322. package/dist/transport/token-auth.js +84 -0
  323. package/dist/transport/token-auth.js.map +1 -0
  324. package/dist/transport/types.d.ts +61 -0
  325. package/dist/transport/types.d.ts.map +1 -0
  326. package/dist/transport/types.js +5 -0
  327. package/dist/transport/types.js.map +1 -0
  328. package/dist/transport/ws-server.d.ts +78 -0
  329. package/dist/transport/ws-server.d.ts.map +1 -0
  330. package/dist/transport/ws-server.js +342 -0
  331. package/dist/transport/ws-server.js.map +1 -0
  332. package/dist/vault/git-vault-sync.d.ts +107 -0
  333. package/dist/vault/git-vault-sync.d.ts.map +1 -0
  334. package/dist/vault/git-vault-sync.js +251 -0
  335. package/dist/vault/git-vault-sync.js.map +1 -0
  336. package/dist/vault/knowledge-review.d.ts +67 -0
  337. package/dist/vault/knowledge-review.d.ts.map +1 -0
  338. package/dist/vault/knowledge-review.js +133 -0
  339. package/dist/vault/knowledge-review.js.map +1 -0
  340. package/dist/vault/obsidian-sync.d.ts +94 -0
  341. package/dist/vault/obsidian-sync.d.ts.map +1 -0
  342. package/dist/vault/obsidian-sync.js +247 -0
  343. package/dist/vault/obsidian-sync.js.map +1 -0
  344. package/dist/vault/scope-detector.d.ts +31 -0
  345. package/dist/vault/scope-detector.d.ts.map +1 -0
  346. package/dist/vault/scope-detector.js +182 -0
  347. package/dist/vault/scope-detector.js.map +1 -0
  348. package/dist/vault/vault-branching.d.ts +71 -0
  349. package/dist/vault/vault-branching.d.ts.map +1 -0
  350. package/dist/vault/vault-branching.js +180 -0
  351. package/dist/vault/vault-branching.js.map +1 -0
  352. package/dist/vault/vault-manager.d.ts +89 -0
  353. package/dist/vault/vault-manager.d.ts.map +1 -0
  354. package/dist/vault/vault-manager.js +199 -0
  355. package/dist/vault/vault-manager.js.map +1 -0
  356. package/dist/vault/vault-types.d.ts +30 -0
  357. package/dist/vault/vault-types.d.ts.map +1 -0
  358. package/dist/vault/vault-types.js +10 -0
  359. package/dist/vault/vault-types.js.map +1 -0
  360. package/dist/vault/vault.d.ts +10 -0
  361. package/dist/vault/vault.d.ts.map +1 -1
  362. package/dist/vault/vault.js +36 -3
  363. package/dist/vault/vault.js.map +1 -1
  364. package/package.json +1 -1
  365. package/src/__tests__/admin-extra-ops.test.ts +31 -11
  366. package/src/__tests__/agency-manager.test.ts +374 -0
  367. package/src/__tests__/agent-loop.test.ts +256 -0
  368. package/src/__tests__/capture-ops.test.ts +275 -0
  369. package/src/__tests__/chat-differentiators.test.ts +251 -0
  370. package/src/__tests__/chat-enhanced.test.ts +390 -0
  371. package/src/__tests__/chat-transport.test.ts +665 -0
  372. package/src/__tests__/claudemd.test.ts +282 -0
  373. package/src/__tests__/context-engine.test.ts +256 -0
  374. package/src/__tests__/core-ops.test.ts +97 -5
  375. package/src/__tests__/deprecation.test.ts +78 -0
  376. package/src/__tests__/enforcement.test.ts +153 -0
  377. package/src/__tests__/facade-factory.test.ts +271 -0
  378. package/src/__tests__/feature-flags.test.ts +138 -0
  379. package/src/__tests__/git-vault-sync.test.ts +230 -0
  380. package/src/__tests__/health-registry.test.ts +173 -0
  381. package/src/__tests__/knowledge-review.test.ts +104 -0
  382. package/src/__tests__/lsp-transport.test.ts +442 -0
  383. package/src/__tests__/migration-runner.test.ts +170 -0
  384. package/src/__tests__/normalize.test.ts +10 -0
  385. package/src/__tests__/obsidian-sync.test.ts +354 -0
  386. package/src/__tests__/pack-lockfile.test.ts +261 -0
  387. package/src/__tests__/pack-ops.test.ts +146 -0
  388. package/src/__tests__/pack-system.test.ts +423 -0
  389. package/src/__tests__/playbook-executor.test.ts +249 -0
  390. package/src/__tests__/playbook-ops-execution.test.ts +189 -0
  391. package/src/__tests__/plugin-ops.test.ts +411 -0
  392. package/src/__tests__/plugin-system.test.ts +509 -0
  393. package/src/__tests__/postgres-provider.test.ts +64 -6
  394. package/src/__tests__/replayable-stream.test.ts +112 -1
  395. package/src/__tests__/scope-detector.test.ts +121 -0
  396. package/src/__tests__/session-lifecycle.test.ts +259 -0
  397. package/src/__tests__/transport.test.ts +758 -0
  398. package/src/__tests__/vault-branching.test.ts +274 -0
  399. package/src/__tests__/vault-connect.test.ts +179 -0
  400. package/src/__tests__/vault-integrity.test.ts +71 -0
  401. package/src/__tests__/vault-manager.test.ts +238 -0
  402. package/src/__tests__/vault-scaling.test.ts +281 -0
  403. package/src/__tests__/vault-sharing.test.ts +270 -0
  404. package/src/__tests__/ws-transport.test.ts +479 -0
  405. package/src/agency/agency-manager.ts +326 -0
  406. package/src/agency/index.ts +13 -0
  407. package/src/agency/types.ts +88 -0
  408. package/src/brain/brain.ts +15 -11
  409. package/src/brain/intelligence.ts +103 -0
  410. package/src/brain/types.ts +26 -0
  411. package/src/chat/agent-loop-types.ts +99 -0
  412. package/src/chat/agent-loop.ts +357 -0
  413. package/src/chat/auth-manager.ts +171 -0
  414. package/src/chat/browser-session.ts +188 -0
  415. package/src/chat/cancellation.ts +99 -0
  416. package/src/chat/chat-session.ts +283 -0
  417. package/src/chat/file-handler.ts +230 -0
  418. package/src/chat/fragment-buffer.ts +160 -0
  419. package/src/chat/index.ts +72 -0
  420. package/src/chat/mcp-bridge.ts +135 -0
  421. package/src/chat/notifications.ts +164 -0
  422. package/src/chat/output-compressor.ts +116 -0
  423. package/src/chat/queue.ts +208 -0
  424. package/src/chat/response-chunker.ts +200 -0
  425. package/src/chat/self-update.ts +117 -0
  426. package/src/chat/types.ts +126 -0
  427. package/src/chat/voice.ts +134 -0
  428. package/src/claudemd/compose.ts +142 -0
  429. package/src/claudemd/index.ts +17 -0
  430. package/src/claudemd/inject.ts +170 -0
  431. package/src/claudemd/types.ts +45 -0
  432. package/src/context/context-engine.ts +302 -0
  433. package/src/context/index.ts +11 -0
  434. package/src/context/types.ts +69 -0
  435. package/src/enforcement/adapters/claude-code.ts +135 -0
  436. package/src/enforcement/adapters/index.ts +1 -0
  437. package/src/enforcement/index.ts +10 -0
  438. package/src/enforcement/registry.ts +82 -0
  439. package/src/enforcement/types.ts +56 -0
  440. package/src/facades/facade-factory.ts +138 -5
  441. package/src/facades/types.ts +21 -0
  442. package/src/health/health-registry.ts +165 -0
  443. package/src/health/index.ts +11 -0
  444. package/src/health/vault-integrity.ts +66 -0
  445. package/src/index.ts +294 -2
  446. package/src/intake/intake-pipeline.ts +1 -1
  447. package/src/intelligence/types.ts +1 -0
  448. package/src/migrations/index.ts +6 -0
  449. package/src/migrations/migration-runner.ts +185 -0
  450. package/src/packs/index.ts +20 -0
  451. package/src/packs/lockfile.ts +180 -0
  452. package/src/packs/pack-installer.ts +289 -0
  453. package/src/packs/resolver.ts +237 -0
  454. package/src/packs/types.ts +125 -0
  455. package/src/persistence/postgres-provider.ts +211 -58
  456. package/src/playbooks/index.ts +11 -0
  457. package/src/playbooks/playbook-executor.ts +301 -0
  458. package/src/plugins/index.ts +19 -0
  459. package/src/plugins/plugin-loader.ts +183 -0
  460. package/src/plugins/plugin-registry.ts +187 -0
  461. package/src/plugins/types.ts +119 -0
  462. package/src/runtime/admin-extra-ops.ts +193 -8
  463. package/src/runtime/capture-ops.ts +113 -8
  464. package/src/runtime/deprecation.ts +58 -0
  465. package/src/runtime/facades/admin-facade.ts +16 -1
  466. package/src/runtime/facades/agency-facade.ts +111 -0
  467. package/src/runtime/facades/brain-facade.ts +60 -0
  468. package/src/runtime/facades/chat-facade.ts +918 -0
  469. package/src/runtime/facades/context-facade.ts +55 -0
  470. package/src/runtime/facades/index.ts +22 -1
  471. package/src/runtime/facades/vault-facade.ts +261 -1
  472. package/src/runtime/feature-flags.ts +101 -0
  473. package/src/runtime/pack-ops.ts +85 -0
  474. package/src/runtime/playbook-ops.ts +113 -9
  475. package/src/runtime/plugin-ops.ts +258 -0
  476. package/src/runtime/runtime.ts +84 -5
  477. package/src/runtime/telemetry-ops.ts +57 -0
  478. package/src/runtime/types.ts +35 -0
  479. package/src/runtime/vault-sharing-ops.ts +372 -0
  480. package/src/streams/index.ts +1 -1
  481. package/src/streams/replayable-stream.ts +34 -3
  482. package/src/text/similarity.ts +1 -1
  483. package/src/transport/http-server.ts +269 -0
  484. package/src/transport/index.ts +48 -0
  485. package/src/transport/lsp-server.ts +401 -0
  486. package/src/transport/rate-limiter.ts +97 -0
  487. package/src/transport/session-manager.ts +120 -0
  488. package/src/transport/token-auth.ts +96 -0
  489. package/src/transport/types.ts +66 -0
  490. package/src/transport/ws-server.ts +415 -0
  491. package/src/vault/git-vault-sync.ts +318 -0
  492. package/src/vault/knowledge-review.ts +221 -0
  493. package/src/vault/obsidian-sync.ts +346 -0
  494. package/src/vault/scope-detector.ts +219 -0
  495. package/src/vault/vault-branching.ts +264 -0
  496. package/src/vault/vault-manager.ts +237 -0
  497. package/src/vault/vault-types.ts +50 -0
  498. package/src/vault/vault.ts +41 -3
  499. package/src/governance/index.ts +0 -18
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Git Vault Sync — auto-commit vault changes to a local git repo.
3
+ *
4
+ * SQLite remains the primary store. This is an optional sync layer that
5
+ * serializes vault entries as JSON files in a git-tracked directory,
6
+ * committing each write with a descriptive message.
7
+ *
8
+ * Directory layout:
9
+ * <repoDir>/
10
+ * <domain>/
11
+ * <id>.json
12
+ *
13
+ * Usage:
14
+ * const sync = new GitVaultSync('/path/to/vault-git');
15
+ * await sync.init();
16
+ * await sync.onAdd(entry);
17
+ * await sync.onUpdate(entry);
18
+ * await sync.onRemove(entry.id, entry.type, entry.domain);
19
+ */
20
+
21
+ import { execFile } from 'node:child_process';
22
+ import {
23
+ existsSync,
24
+ mkdirSync,
25
+ writeFileSync,
26
+ unlinkSync,
27
+ readdirSync,
28
+ readFileSync,
29
+ } from 'node:fs';
30
+ import { join } from 'node:path';
31
+ import type { IntelligenceEntry } from '../intelligence/types.js';
32
+
33
+ export interface GitVaultSyncConfig {
34
+ /** Path to the git-tracked directory for vault entries. */
35
+ repoDir: string;
36
+ /** Git author name for commits. Default: 'soleri'. */
37
+ authorName?: string;
38
+ /** Git author email for commits. Default: 'soleri@localhost'. */
39
+ authorEmail?: string;
40
+ /** Whether to auto-commit. Default: true. If false, only writes files. */
41
+ autoCommit?: boolean;
42
+ }
43
+
44
+ export class GitVaultSync {
45
+ private repoDir: string;
46
+ private authorName: string;
47
+ private authorEmail: string;
48
+ private autoCommit: boolean;
49
+ private initialized = false;
50
+
51
+ constructor(config: GitVaultSyncConfig) {
52
+ this.repoDir = config.repoDir;
53
+ this.authorName = config.authorName ?? 'soleri';
54
+ this.authorEmail = config.authorEmail ?? 'soleri@localhost';
55
+ this.autoCommit = config.autoCommit ?? true;
56
+ }
57
+
58
+ /**
59
+ * Initialize the git repo if it doesn't exist.
60
+ * Creates the directory and runs `git init` if needed.
61
+ */
62
+ async init(): Promise<void> {
63
+ if (!existsSync(this.repoDir)) {
64
+ mkdirSync(this.repoDir, { recursive: true });
65
+ }
66
+ if (!existsSync(join(this.repoDir, '.git'))) {
67
+ await this.git('init');
68
+ // Set local author config
69
+ await this.git('config', 'user.name', this.authorName);
70
+ await this.git('config', 'user.email', this.authorEmail);
71
+ }
72
+ this.initialized = true;
73
+ }
74
+
75
+ /**
76
+ * Called when an entry is added to the vault.
77
+ */
78
+ async onAdd(entry: IntelligenceEntry): Promise<void> {
79
+ this.ensureInitialized();
80
+ this.writeEntry(entry);
81
+ if (this.autoCommit) {
82
+ const filePath = this.entryPath(entry);
83
+ await this.git('add', filePath);
84
+ await this.git(
85
+ 'commit',
86
+ '-m',
87
+ `vault: add ${entry.type} [${entry.domain}] ${entry.id}\n\n${entry.title}`,
88
+ '--allow-empty',
89
+ );
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Called when an entry is updated in the vault.
95
+ */
96
+ async onUpdate(entry: IntelligenceEntry): Promise<void> {
97
+ this.ensureInitialized();
98
+ this.writeEntry(entry);
99
+ if (this.autoCommit) {
100
+ const filePath = this.entryPath(entry);
101
+ await this.git('add', filePath);
102
+ await this.git(
103
+ 'commit',
104
+ '-m',
105
+ `vault: update ${entry.type} [${entry.domain}] ${entry.id}\n\n${entry.title}`,
106
+ '--allow-empty',
107
+ );
108
+ }
109
+ }
110
+
111
+ /**
112
+ * Called when an entry is removed from the vault.
113
+ */
114
+ async onRemove(id: string, type: string, domain: string): Promise<void> {
115
+ this.ensureInitialized();
116
+ const filePath = join(domain, `${id}.json`);
117
+ const fullPath = join(this.repoDir, filePath);
118
+ if (existsSync(fullPath)) {
119
+ unlinkSync(fullPath);
120
+ }
121
+ if (this.autoCommit) {
122
+ try {
123
+ await this.git('add', filePath);
124
+ await this.git('commit', '-m', `vault: remove ${type} [${domain}] ${id}`, '--allow-empty');
125
+ } catch {
126
+ // File may not be tracked yet — git add will fail, that's ok
127
+ }
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Bulk sync: write all entries and commit once.
133
+ */
134
+ async syncAll(entries: IntelligenceEntry[]): Promise<{ synced: number }> {
135
+ this.ensureInitialized();
136
+ for (const entry of entries) {
137
+ this.writeEntry(entry);
138
+ }
139
+ if (this.autoCommit && entries.length > 0) {
140
+ await this.git('add', '.');
141
+ await this.git('commit', '-m', `vault: bulk sync ${entries.length} entries`, '--allow-empty');
142
+ }
143
+ return { synced: entries.length };
144
+ }
145
+
146
+ /**
147
+ * Get the git log for the vault repo.
148
+ */
149
+ async log(limit = 20): Promise<string[]> {
150
+ this.ensureInitialized();
151
+ try {
152
+ const output = await this.git('log', '--oneline', `-${limit}`);
153
+ return output
154
+ .trim()
155
+ .split('\n')
156
+ .filter((l) => l.length > 0);
157
+ } catch {
158
+ return [];
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Pull entries from git directory into the vault.
164
+ * Reads all JSON files and returns them as IntelligenceEntry[].
165
+ * Conflict resolution: if onConflict is 'git', git version wins; 'vault' keeps existing.
166
+ */
167
+ async pull(
168
+ vault: {
169
+ get: (id: string) => IntelligenceEntry | null;
170
+ seed: (entries: IntelligenceEntry[]) => number;
171
+ },
172
+ options?: { onConflict?: 'git' | 'vault' },
173
+ ): Promise<{ imported: number; skipped: number; conflicts: number }> {
174
+ this.ensureInitialized();
175
+ const onConflict = options?.onConflict ?? 'git';
176
+ let imported = 0;
177
+ let skipped = 0;
178
+ let conflicts = 0;
179
+
180
+ const entries = this.readAllEntries();
181
+ for (const entry of entries) {
182
+ const existing = vault.get(entry.id);
183
+ if (existing) {
184
+ if (onConflict === 'vault') {
185
+ skipped++;
186
+ conflicts++;
187
+ continue;
188
+ }
189
+ conflicts++;
190
+ }
191
+ vault.seed([entry]);
192
+ imported++;
193
+ }
194
+
195
+ return { imported, skipped, conflicts };
196
+ }
197
+
198
+ /**
199
+ * Bidirectional sync: push vault entries to git AND pull git-only entries to vault.
200
+ */
201
+ async sync(
202
+ vault: {
203
+ get: (id: string) => IntelligenceEntry | null;
204
+ seed: (entries: IntelligenceEntry[]) => number;
205
+ exportAll: () => { entries: IntelligenceEntry[] };
206
+ },
207
+ options?: { onConflict?: 'git' | 'vault' },
208
+ ): Promise<{ pushed: number; pulled: number; conflicts: number }> {
209
+ this.ensureInitialized();
210
+ const onConflict = options?.onConflict ?? 'git';
211
+
212
+ // Push: vault → git
213
+ const { entries: vaultEntries } = vault.exportAll();
214
+ for (const entry of vaultEntries) {
215
+ this.writeEntry(entry);
216
+ }
217
+
218
+ // Pull: git → vault (only entries not in vault)
219
+ const gitEntries = this.readAllEntries();
220
+ const vaultIds = new Set(vaultEntries.map((e) => e.id));
221
+ let pulled = 0;
222
+ let conflicts = 0;
223
+
224
+ for (const entry of gitEntries) {
225
+ if (vaultIds.has(entry.id)) continue; // Already synced via push
226
+ const existing = vault.get(entry.id);
227
+ if (existing) {
228
+ if (onConflict === 'vault') {
229
+ conflicts++;
230
+ continue;
231
+ }
232
+ conflicts++;
233
+ }
234
+ vault.seed([entry]);
235
+ pulled++;
236
+ }
237
+
238
+ // Commit all changes
239
+ if (this.autoCommit && (vaultEntries.length > 0 || pulled > 0)) {
240
+ await this.git('add', '.');
241
+ await this.git(
242
+ 'commit',
243
+ '-m',
244
+ `vault: sync ${vaultEntries.length} pushed, ${pulled} pulled`,
245
+ '--allow-empty',
246
+ );
247
+ }
248
+
249
+ return { pushed: vaultEntries.length, pulled, conflicts };
250
+ }
251
+
252
+ /** Get the repo directory path. */
253
+ getRepoDir(): string {
254
+ return this.repoDir;
255
+ }
256
+
257
+ // ─── Internal ─────────────────────────────────────────────
258
+
259
+ /**
260
+ * Read all JSON entry files from the git directory.
261
+ */
262
+ private readAllEntries(): IntelligenceEntry[] {
263
+ const entries: IntelligenceEntry[] = [];
264
+ if (!existsSync(this.repoDir)) return entries;
265
+
266
+ const domains = readdirSync(this.repoDir, { withFileTypes: true })
267
+ .filter((d) => d.isDirectory() && d.name !== '.git')
268
+ .map((d) => d.name);
269
+
270
+ for (const domain of domains) {
271
+ const domainDir = join(this.repoDir, domain);
272
+ const files = readdirSync(domainDir).filter((f) => f.endsWith('.json'));
273
+ for (const file of files) {
274
+ try {
275
+ const content = readFileSync(join(domainDir, file), 'utf-8');
276
+ const entry = JSON.parse(content) as IntelligenceEntry;
277
+ if (entry.id && entry.type && entry.domain) {
278
+ entries.push(entry);
279
+ }
280
+ } catch {
281
+ // Skip malformed files
282
+ }
283
+ }
284
+ }
285
+ return entries;
286
+ }
287
+
288
+ private writeEntry(entry: IntelligenceEntry): void {
289
+ const domainDir = join(this.repoDir, entry.domain);
290
+ if (!existsSync(domainDir)) {
291
+ mkdirSync(domainDir, { recursive: true });
292
+ }
293
+ const filePath = join(domainDir, `${entry.id}.json`);
294
+ writeFileSync(filePath, JSON.stringify(entry, null, 2) + '\n', 'utf-8');
295
+ }
296
+
297
+ private entryPath(entry: IntelligenceEntry): string {
298
+ return join(entry.domain, `${entry.id}.json`);
299
+ }
300
+
301
+ private ensureInitialized(): void {
302
+ if (!this.initialized) {
303
+ throw new Error('GitVaultSync not initialized. Call init() first.');
304
+ }
305
+ }
306
+
307
+ private git(...args: string[]): Promise<string> {
308
+ return new Promise((resolve, reject) => {
309
+ execFile('git', args, { cwd: this.repoDir, timeout: 10_000 }, (error, stdout, stderr) => {
310
+ if (error) {
311
+ reject(new Error(`git ${args[0]} failed: ${stderr || error.message}`));
312
+ } else {
313
+ resolve(stdout);
314
+ }
315
+ });
316
+ });
317
+ }
318
+ }
@@ -0,0 +1,221 @@
1
+ /**
2
+ * Knowledge Review — team review workflows for vault entries.
3
+ *
4
+ * Lifecycle: draft → pending_review → approved | rejected
5
+ *
6
+ * Improved over Salvador: uses PersistenceProvider abstraction,
7
+ * decoupled from governance engine, and tracks review metadata.
8
+ */
9
+
10
+ import type { PersistenceProvider } from '../persistence/types.js';
11
+
12
+ // =============================================================================
13
+ // TYPES
14
+ // =============================================================================
15
+
16
+ export type ReviewStatus = 'draft' | 'pending_review' | 'approved' | 'rejected';
17
+
18
+ export interface ReviewEntry {
19
+ entryId: string;
20
+ status: ReviewStatus;
21
+ submittedBy: string | null;
22
+ reviewedBy: string | null;
23
+ reviewComment: string | null;
24
+ submittedAt: number | null;
25
+ reviewedAt: number | null;
26
+ }
27
+
28
+ export interface ReviewSubmission {
29
+ entryId: string;
30
+ submittedBy?: string;
31
+ }
32
+
33
+ export interface ReviewDecision {
34
+ entryId: string;
35
+ reviewedBy?: string;
36
+ comment?: string;
37
+ }
38
+
39
+ // =============================================================================
40
+ // KNOWLEDGE REVIEW
41
+ // =============================================================================
42
+
43
+ export class KnowledgeReview {
44
+ private provider: PersistenceProvider;
45
+
46
+ constructor(provider: PersistenceProvider) {
47
+ this.provider = provider;
48
+ this.initialize();
49
+ }
50
+
51
+ private initialize(): void {
52
+ this.provider.execSql(`
53
+ CREATE TABLE IF NOT EXISTS entry_reviews (
54
+ entry_id TEXT PRIMARY KEY,
55
+ status TEXT NOT NULL DEFAULT 'draft' CHECK(status IN ('draft', 'pending_review', 'approved', 'rejected')),
56
+ submitted_by TEXT,
57
+ reviewed_by TEXT,
58
+ review_comment TEXT,
59
+ submitted_at INTEGER,
60
+ reviewed_at INTEGER
61
+ );
62
+ CREATE INDEX IF NOT EXISTS idx_reviews_status ON entry_reviews(status);
63
+ `);
64
+ }
65
+
66
+ /**
67
+ * Submit an entry for review. Transitions from draft → pending_review.
68
+ */
69
+ submit(submission: ReviewSubmission): ReviewEntry {
70
+ const { entryId, submittedBy } = submission;
71
+ const existing = this.get(entryId);
72
+
73
+ if (existing && existing.status !== 'draft' && existing.status !== 'rejected') {
74
+ throw new Error(
75
+ `Entry '${entryId}' cannot be submitted — current status: ${existing.status}`,
76
+ );
77
+ }
78
+
79
+ const now = Math.floor(Date.now() / 1000);
80
+ this.provider.run(
81
+ `INSERT INTO entry_reviews (entry_id, status, submitted_by, submitted_at, reviewed_by, review_comment, reviewed_at)
82
+ VALUES (@entryId, 'pending_review', @submittedBy, @now, NULL, NULL, NULL)
83
+ ON CONFLICT(entry_id) DO UPDATE SET
84
+ status = 'pending_review',
85
+ submitted_by = @submittedBy,
86
+ submitted_at = @now,
87
+ reviewed_by = NULL,
88
+ review_comment = NULL,
89
+ reviewed_at = NULL`,
90
+ { entryId, submittedBy: submittedBy ?? null, now },
91
+ );
92
+ return this.get(entryId)!;
93
+ }
94
+
95
+ /**
96
+ * Approve a pending entry. Transitions from pending_review → approved.
97
+ */
98
+ approve(decision: ReviewDecision): ReviewEntry {
99
+ return this.decide(decision, 'approved');
100
+ }
101
+
102
+ /**
103
+ * Reject a pending entry. Transitions from pending_review → rejected.
104
+ */
105
+ reject(decision: ReviewDecision): ReviewEntry {
106
+ return this.decide(decision, 'rejected');
107
+ }
108
+
109
+ /**
110
+ * Get the review status for an entry.
111
+ */
112
+ get(entryId: string): ReviewEntry | null {
113
+ const row = this.provider.get<{
114
+ entry_id: string;
115
+ status: string;
116
+ submitted_by: string | null;
117
+ reviewed_by: string | null;
118
+ review_comment: string | null;
119
+ submitted_at: number | null;
120
+ reviewed_at: number | null;
121
+ }>('SELECT * FROM entry_reviews WHERE entry_id = @entryId', { entryId });
122
+
123
+ if (!row) return null;
124
+ return rowToReview(row);
125
+ }
126
+
127
+ /**
128
+ * List entries by review status.
129
+ */
130
+ listPending(limit = 50): ReviewEntry[] {
131
+ return this.listByStatus('pending_review', limit);
132
+ }
133
+
134
+ listByStatus(status: ReviewStatus, limit = 50): ReviewEntry[] {
135
+ const rows = this.provider.all<{
136
+ entry_id: string;
137
+ status: string;
138
+ submitted_by: string | null;
139
+ reviewed_by: string | null;
140
+ review_comment: string | null;
141
+ submitted_at: number | null;
142
+ reviewed_at: number | null;
143
+ }>(
144
+ 'SELECT * FROM entry_reviews WHERE status = @status ORDER BY submitted_at DESC LIMIT @limit',
145
+ {
146
+ status,
147
+ limit,
148
+ },
149
+ );
150
+ return rows.map(rowToReview);
151
+ }
152
+
153
+ /**
154
+ * Get review statistics.
155
+ */
156
+ stats(): { total: number; byStatus: Record<string, number> } {
157
+ const total =
158
+ this.provider.get<{ c: number }>('SELECT COUNT(*) as c FROM entry_reviews')?.c ?? 0;
159
+ const rows = this.provider.all<{ status: string; count: number }>(
160
+ 'SELECT status, COUNT(*) as count FROM entry_reviews GROUP BY status',
161
+ );
162
+ return {
163
+ total,
164
+ byStatus: Object.fromEntries(rows.map((r) => [r.status, r.count])),
165
+ };
166
+ }
167
+
168
+ /**
169
+ * Remove review record (e.g., when entry is deleted).
170
+ */
171
+ remove(entryId: string): boolean {
172
+ return (
173
+ this.provider.run('DELETE FROM entry_reviews WHERE entry_id = @entryId', { entryId })
174
+ .changes > 0
175
+ );
176
+ }
177
+
178
+ // ─── Internal ───────────────────────────────────────────────
179
+
180
+ private decide(decision: ReviewDecision, newStatus: 'approved' | 'rejected'): ReviewEntry {
181
+ const existing = this.get(decision.entryId);
182
+ if (!existing || existing.status !== 'pending_review') {
183
+ throw new Error(
184
+ `Entry '${decision.entryId}' is not pending review — current status: ${existing?.status ?? 'none'}`,
185
+ );
186
+ }
187
+
188
+ const now = Math.floor(Date.now() / 1000);
189
+ this.provider.run(
190
+ `UPDATE entry_reviews SET status = @status, reviewed_by = @reviewedBy, review_comment = @comment, reviewed_at = @now WHERE entry_id = @entryId`,
191
+ {
192
+ status: newStatus,
193
+ reviewedBy: decision.reviewedBy ?? null,
194
+ comment: decision.comment ?? null,
195
+ now,
196
+ entryId: decision.entryId,
197
+ },
198
+ );
199
+ return this.get(decision.entryId)!;
200
+ }
201
+ }
202
+
203
+ function rowToReview(row: {
204
+ entry_id: string;
205
+ status: string;
206
+ submitted_by: string | null;
207
+ reviewed_by: string | null;
208
+ review_comment: string | null;
209
+ submitted_at: number | null;
210
+ reviewed_at: number | null;
211
+ }): ReviewEntry {
212
+ return {
213
+ entryId: row.entry_id,
214
+ status: row.status as ReviewStatus,
215
+ submittedBy: row.submitted_by,
216
+ reviewedBy: row.reviewed_by,
217
+ reviewComment: row.review_comment,
218
+ submittedAt: row.submitted_at,
219
+ reviewedAt: row.reviewed_at,
220
+ };
221
+ }