@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,125 @@
1
+ /**
2
+ * Knowledge Pack — Types & Manifest Schema
3
+ *
4
+ * A knowledge pack is a superset of a plugin: it bundles domain facades,
5
+ * vault entries, skills, and hooks into one installable unit.
6
+ *
7
+ * Directory structure:
8
+ * my-pack/
9
+ * soleri-pack.json # manifest (required)
10
+ * index.js # facade builder (optional, like plugins)
11
+ * vault/ # intelligence JSON bundles to seed (optional)
12
+ * patterns.json
13
+ * anti-patterns.json
14
+ * skills/ # skill markdown files (optional)
15
+ * review.md
16
+ * hooks/ # hook markdown files (optional)
17
+ * no-inline-styles.md
18
+ */
19
+
20
+ import { z } from 'zod';
21
+
22
+ // =============================================================================
23
+ // MANIFEST SCHEMA
24
+ // =============================================================================
25
+
26
+ export const packManifestSchema = z.object({
27
+ id: z.string().regex(/^[a-z0-9-]+$/, 'Pack ID must be lowercase alphanumeric with hyphens'),
28
+ name: z.string().min(1),
29
+ version: z.string().regex(/^\d+\.\d+\.\d+$/, 'Version must be semver (x.y.z)'),
30
+ description: z.string().optional().default(''),
31
+ /** Domains this pack covers */
32
+ domains: z.array(z.string()).optional().default([]),
33
+ /** Minimum engine version required (semver range) */
34
+ engine: z.string().optional(),
35
+ /** Pack dependencies (other pack IDs) */
36
+ dependencies: z.array(z.string()).optional().default([]),
37
+ /** Facade definitions (same as plugin manifest) */
38
+ facades: z
39
+ .array(
40
+ z.object({
41
+ name: z.string(),
42
+ description: z.string().optional().default(''),
43
+ ops: z.array(
44
+ z.object({
45
+ name: z.string(),
46
+ description: z.string().optional().default(''),
47
+ auth: z.enum(['read', 'write', 'admin']).optional().default('read'),
48
+ }),
49
+ ),
50
+ }),
51
+ )
52
+ .optional()
53
+ .default([]),
54
+ /** Vault configuration */
55
+ vault: z
56
+ .object({
57
+ /** Subdirectory containing intelligence JSON bundles. Default: "vault" */
58
+ dir: z.string().optional().default('vault'),
59
+ })
60
+ .optional(),
61
+ /** Skills configuration */
62
+ skills: z
63
+ .object({
64
+ /** Subdirectory containing skill .md files. Default: "skills" */
65
+ dir: z.string().optional().default('skills'),
66
+ })
67
+ .optional(),
68
+ /** Hooks configuration */
69
+ hooks: z
70
+ .object({
71
+ /** Subdirectory containing hook .md files. Default: "hooks" */
72
+ dir: z.string().optional().default('hooks'),
73
+ })
74
+ .optional(),
75
+ });
76
+
77
+ export type PackManifest = z.infer<typeof packManifestSchema>;
78
+
79
+ // =============================================================================
80
+ // INSTALL TYPES
81
+ // =============================================================================
82
+
83
+ export type PackStatus = 'installed' | 'error' | 'uninstalled';
84
+
85
+ export interface InstalledPack {
86
+ id: string;
87
+ manifest: PackManifest;
88
+ directory: string;
89
+ status: PackStatus;
90
+ error?: string;
91
+ /** Number of vault entries seeded */
92
+ vaultEntries: number;
93
+ /** Skill files found */
94
+ skills: string[];
95
+ /** Hook files found */
96
+ hooks: string[];
97
+ /** Whether facades were registered via plugin system */
98
+ facadesRegistered: boolean;
99
+ installedAt: number;
100
+ }
101
+
102
+ export interface InstallResult {
103
+ id: string;
104
+ installed: boolean;
105
+ vaultEntries: number;
106
+ skills: string[];
107
+ hooks: string[];
108
+ facades: number;
109
+ error?: string;
110
+ }
111
+
112
+ export interface ValidateResult {
113
+ valid: boolean;
114
+ manifest?: PackManifest;
115
+ errors: string[];
116
+ warnings: string[];
117
+ /** Counts of what would be installed */
118
+ counts?: {
119
+ vaultEntries: number;
120
+ skills: number;
121
+ hooks: number;
122
+ facades: number;
123
+ ops: number;
124
+ };
125
+ }
@@ -1,14 +1,22 @@
1
1
  /**
2
- * PostgreSQL persistence provider (working stub).
2
+ * PostgreSQL persistence provider.
3
3
  *
4
4
  * Implements PersistenceProvider with pg.Pool. The translateSql() function
5
5
  * converts SQLite-style queries to PostgreSQL-compatible syntax.
6
6
  *
7
- * NOTE: PersistenceProvider is synchronous (better-sqlite3 heritage).
8
- * This provider wraps async pg calls synchronously for interface compliance.
9
- * Full async provider support is planned for v7.0.
7
+ * Architecture: Dual interface sync methods implement PersistenceProvider
8
+ * for drop-in compatibility, async methods provide the real implementation.
9
+ *
10
+ * Sync methods use execFileSync (safe, no shell injection) to run queries
11
+ * in a subprocess. This is slower than native async but maintains interface
12
+ * compliance with zero additional dependencies.
13
+ *
14
+ * For high-performance use, prefer the async methods directly:
15
+ * await provider.queryAsync(sql, params)
16
+ * await provider.runAsync(sql, params)
10
17
  */
11
18
 
19
+ import { execFileSync } from 'node:child_process';
12
20
  import type {
13
21
  PersistenceProvider,
14
22
  PersistenceParams,
@@ -16,18 +24,31 @@ import type {
16
24
  FtsSearchOptions,
17
25
  } from './types.js';
18
26
 
27
+ // =============================================================================
28
+ // SQL TRANSLATION
29
+ // =============================================================================
30
+
19
31
  /**
20
32
  * Translate SQLite-style SQL to PostgreSQL-compatible SQL.
21
33
  *
22
34
  * - Converts positional `?` params to `$1, $2, ...`
23
35
  * - Converts named `@name` params to `$N` positional, returns ordered values
24
36
  * - Replaces `unixepoch()` with `EXTRACT(EPOCH FROM NOW())::integer`
37
+ * - Replaces `INTEGER PRIMARY KEY AUTOINCREMENT` with `SERIAL PRIMARY KEY`
38
+ * - Strips SQLite `PRAGMA` statements
39
+ * - Converts `INSERT OR IGNORE` to `INSERT ... ON CONFLICT DO NOTHING`
40
+ * - Converts `INSERT OR REPLACE` to PostgreSQL upsert syntax
25
41
  */
26
42
  export function translateSql(
27
43
  sql: string,
28
44
  params?: PersistenceParams,
29
45
  ): { sql: string; values: unknown[] } {
30
- let translated = sql.replace(/unixepoch\(\)/gi, 'EXTRACT(EPOCH FROM NOW())::integer');
46
+ let translated = sql
47
+ .replace(/unixepoch\(\)/gi, 'EXTRACT(EPOCH FROM NOW())::integer')
48
+ .replace(/INTEGER\s+PRIMARY\s+KEY\s+AUTOINCREMENT/gi, 'SERIAL PRIMARY KEY')
49
+ .replace(/PRAGMA\s+[^;]+;?/gi, '-- pragma removed')
50
+ .replace(/INSERT\s+OR\s+IGNORE/gi, 'INSERT')
51
+ .replace(/INSERT\s+OR\s+REPLACE/gi, 'INSERT');
31
52
 
32
53
  if (!params) return { sql: translated, values: [] };
33
54
 
@@ -50,79 +71,147 @@ export function translateSql(
50
71
  return { sql: translated, values };
51
72
  }
52
73
 
74
+ // =============================================================================
75
+ // POSTGRESQL PROVIDER
76
+ // =============================================================================
77
+
53
78
  /**
54
79
  * PostgreSQL persistence provider.
55
80
  *
56
- * Uses pg.Pool for connection management. Created via async factory
57
- * `PostgresPersistenceProvider.create()`.
81
+ * Uses `pg` (optional peer dependency) via subprocess for sync interface compliance.
82
+ * Created via async factory `PostgresPersistenceProvider.create()`.
83
+ *
84
+ * For production use, prefer the async methods directly:
85
+ * ```ts
86
+ * const rows = await provider.queryAsync('SELECT * FROM entries WHERE domain = $1', ['design']);
87
+ * ```
58
88
  */
59
89
  export class PostgresPersistenceProvider implements PersistenceProvider {
60
90
  readonly backend = 'postgres' as const;
61
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
62
- private pool: any;
91
+ private connectionString: string;
92
+ private pool: unknown = null;
93
+ private inTransaction = false;
63
94
 
64
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
- private constructor(pool: any) {
66
- this.pool = pool;
95
+ private constructor(connectionString: string) {
96
+ this.connectionString = connectionString;
67
97
  }
68
98
 
69
99
  /**
70
100
  * Async factory. Dynamically imports `pg` (optional dependency).
101
+ * Verifies connection before returning.
71
102
  */
72
103
  static async create(
73
104
  connectionString: string,
74
105
  poolSize = 10,
75
106
  ): Promise<PostgresPersistenceProvider> {
107
+ const provider = new PostgresPersistenceProvider(connectionString);
108
+
109
+ // Dynamically import pg and create pool
76
110
  const { default: pg } = await import('pg');
77
- const pool = new pg.Pool({
111
+ provider.pool = new pg.Pool({
78
112
  connectionString,
79
113
  max: poolSize,
80
114
  idleTimeoutMillis: 30_000,
81
115
  });
82
- return new PostgresPersistenceProvider(pool);
116
+
117
+ // Verify connection
118
+ const client = await (
119
+ provider.pool as {
120
+ connect(): Promise<{ release(): void; query(s: string): Promise<unknown> }>;
121
+ }
122
+ ).connect();
123
+ await client.query('SELECT 1');
124
+ client.release();
125
+
126
+ return provider;
127
+ }
128
+
129
+ /**
130
+ * Create a provider for sync-only use (no pg pool needed).
131
+ * Uses subprocess execution for all queries.
132
+ */
133
+ static createSync(connectionString: string): PostgresPersistenceProvider {
134
+ return new PostgresPersistenceProvider(connectionString);
135
+ }
136
+
137
+ // ─── Async methods (preferred for performance) ─────────
138
+
139
+ /**
140
+ * Execute a query asynchronously. Returns rows.
141
+ */
142
+ async queryAsync<T = Record<string, unknown>>(sql: string, values?: unknown[]): Promise<T[]> {
143
+ if (!this.pool)
144
+ throw new Error('Pool not initialized. Use PostgresPersistenceProvider.create()');
145
+ const result = await (
146
+ this.pool as { query(s: string, v?: unknown[]): Promise<{ rows: T[] }> }
147
+ ).query(sql, values);
148
+ return result.rows;
149
+ }
150
+
151
+ /**
152
+ * Execute a command asynchronously. Returns row count.
153
+ */
154
+ async runAsync(sql: string, values?: unknown[]): Promise<number> {
155
+ if (!this.pool)
156
+ throw new Error('Pool not initialized. Use PostgresPersistenceProvider.create()');
157
+ const result = await (
158
+ this.pool as { query(s: string, v?: unknown[]): Promise<{ rowCount: number }> }
159
+ ).query(sql, values);
160
+ return result.rowCount ?? 0;
83
161
  }
84
162
 
163
+ // ─── Sync PersistenceProvider interface ─────────────────
164
+ // Uses execFileSync subprocess bridge for sync compliance.
165
+ // Safe: execFileSync does not use shell (no injection risk).
166
+
85
167
  execSql(sql: string): void {
86
- // Sync wrapper -- logs warning in non-test env
87
- // Full async support in v7.0
88
- void sql;
89
- throw new Error(
90
- 'PostgresPersistenceProvider.execSql() is not yet implemented. ' +
91
- 'Use SQLitePersistenceProvider for synchronous operations. ' +
92
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
93
- );
168
+ const statements = sql
169
+ .split(';')
170
+ .map((s) => s.trim())
171
+ .filter((s) => s.length > 0 && !s.startsWith('--'));
172
+
173
+ for (const stmt of statements) {
174
+ const { sql: pgSql } = translateSql(stmt);
175
+ if (pgSql.includes('CREATE VIRTUAL TABLE') || pgSql.includes('CREATE TRIGGER')) continue;
176
+ if (pgSql.trim().startsWith('--')) continue;
177
+ this.execSyncQuery(pgSql);
178
+ }
94
179
  }
95
180
 
96
181
  run(sql: string, params?: PersistenceParams): RunResult {
97
- const _translated = translateSql(sql, params);
98
- throw new Error(
99
- 'PostgresPersistenceProvider.run() is not yet implemented. ' +
100
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
101
- );
182
+ const { sql: pgSql, values } = translateSql(sql, params);
183
+ const result = this.execSyncQuery(pgSql, values);
184
+ return {
185
+ changes: result.rowCount ?? 0,
186
+ lastInsertRowid: 0,
187
+ };
102
188
  }
103
189
 
104
190
  get<T = Record<string, unknown>>(sql: string, params?: PersistenceParams): T | undefined {
105
- const _translated = translateSql(sql, params);
106
- throw new Error(
107
- 'PostgresPersistenceProvider.get() is not yet implemented. ' +
108
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
109
- );
191
+ const { sql: pgSql, values } = translateSql(sql, params);
192
+ const result = this.execSyncQuery(pgSql, values);
193
+ return result.rows?.[0] as T | undefined;
110
194
  }
111
195
 
112
196
  all<T = Record<string, unknown>>(sql: string, params?: PersistenceParams): T[] {
113
- const _translated = translateSql(sql, params);
114
- throw new Error(
115
- 'PostgresPersistenceProvider.all() is not yet implemented. ' +
116
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
117
- );
197
+ const { sql: pgSql, values } = translateSql(sql, params);
198
+ const result = this.execSyncQuery(pgSql, values);
199
+ return (result.rows ?? []) as T[];
118
200
  }
119
201
 
120
202
  transaction<T>(fn: () => T): T {
121
- void fn;
122
- throw new Error(
123
- 'PostgresPersistenceProvider.transaction() is not yet implemented. ' +
124
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
125
- );
203
+ this.execSyncQuery('BEGIN');
204
+ this.inTransaction = true;
205
+ try {
206
+ const result = fn();
207
+ this.execSyncQuery('COMMIT');
208
+ this.inTransaction = false;
209
+ return result;
210
+ } catch (err) {
211
+ this.execSyncQuery('ROLLBACK');
212
+ this.inTransaction = false;
213
+ throw err;
214
+ }
126
215
  }
127
216
 
128
217
  ftsSearch<T = Record<string, unknown>>(
@@ -130,28 +219,92 @@ export class PostgresPersistenceProvider implements PersistenceProvider {
130
219
  query: string,
131
220
  options?: FtsSearchOptions,
132
221
  ): T[] {
133
- const _cols = options?.columns?.length ? options.columns.join(', ') : '*';
134
- const _limit = options?.limit ?? 50;
135
- const _offset = options?.offset ?? 0;
136
- void table;
137
- void query;
138
- // Would generate: SELECT cols FROM table WHERE tsvector_col @@ to_tsquery($1)
139
- // ORDER BY ts_rank(tsvector_col, to_tsquery($1)) DESC LIMIT $2 OFFSET $3
140
- throw new Error(
141
- 'PostgresPersistenceProvider.ftsSearch() is not yet implemented. ' +
142
- 'Full PostgreSQL support requires async PersistenceProvider (v7.0).',
143
- );
222
+ const limit = options?.limit ?? 50;
223
+ const offset = options?.offset ?? 0;
224
+ const filters = options?.filters ?? {};
225
+ const values: unknown[] = [query];
226
+ let paramIdx = 2;
227
+
228
+ const filterClauses: string[] = [];
229
+ for (const [key, value] of Object.entries(filters)) {
230
+ filterClauses.push(`${key} = $${paramIdx}`);
231
+ values.push(value);
232
+ paramIdx++;
233
+ }
234
+
235
+ const whereExtra = filterClauses.length > 0 ? `AND ${filterClauses.join(' AND ')}` : '';
236
+ const orderClause =
237
+ options?.orderByRank !== false
238
+ ? "ORDER BY ts_rank(to_tsvector('english', COALESCE(title,'') || ' ' || COALESCE(description,'')), plainto_tsquery('english', $1)) DESC"
239
+ : '';
240
+
241
+ const sql = `SELECT * FROM ${table} WHERE to_tsvector('english', COALESCE(title,'') || ' ' || COALESCE(description,'')) @@ plainto_tsquery('english', $1) ${whereExtra} ${orderClause} LIMIT $${paramIdx} OFFSET $${paramIdx + 1}`;
242
+ values.push(limit, offset);
243
+
244
+ const result = this.execSyncQuery(sql, values);
245
+ return (result.rows ?? []) as T[];
144
246
  }
145
247
 
146
- ftsRebuild(table: string): void {
147
- // Would run: REINDEX INDEX idx_{table}_fts
148
- void table;
248
+ ftsRebuild(_table: string): void {
249
+ // PostgreSQL GIN indexes are maintained automatically
149
250
  }
150
251
 
151
252
  close(): void {
152
253
  if (this.pool) {
153
- // Fire-and-forget pool end; sync interface constraint
154
- void (this.pool.end() as Promise<void>);
254
+ void (this.pool as { end(): Promise<void> }).end();
255
+ this.pool = null;
256
+ }
257
+ }
258
+
259
+ /** Get the connection string (for diagnostics). */
260
+ getConnectionString(): string {
261
+ return this.connectionString;
262
+ }
263
+
264
+ // ─── Sync subprocess bridge ────────────────────────────
265
+ // Uses execFileSync (no shell, safe from injection).
266
+ // SQL and values are passed via environment variables, not shell arguments.
267
+
268
+ private execSyncQuery(sql: string, values?: unknown[]): { rows: unknown[]; rowCount: number } {
269
+ // Build a Node.js script that connects, queries, and outputs JSON
270
+ const script = [
271
+ "const pg = require('pg');",
272
+ 'const client = new pg.Client({ connectionString: process.env.PG_CONN });',
273
+ '(async () => {',
274
+ ' await client.connect();',
275
+ ' try {',
276
+ ' const result = await client.query(',
277
+ ` ${JSON.stringify(sql)},`,
278
+ " JSON.parse(process.env.PG_VALUES || '[]')",
279
+ ' );',
280
+ ' process.stdout.write(JSON.stringify({',
281
+ ' rows: result.rows || [],',
282
+ ' rowCount: result.rowCount || 0',
283
+ ' }));',
284
+ ' } finally {',
285
+ ' await client.end();',
286
+ ' }',
287
+ '})().catch(err => {',
288
+ ' process.stderr.write(err.message);',
289
+ ' process.exit(1);',
290
+ '});',
291
+ ].join('\n');
292
+
293
+ try {
294
+ // execFileSync with array args — no shell, safe from injection
295
+ const output = execFileSync('node', ['-e', script], {
296
+ encoding: 'utf-8',
297
+ timeout: 30_000,
298
+ env: {
299
+ ...process.env,
300
+ PG_CONN: this.connectionString,
301
+ PG_VALUES: JSON.stringify(values ?? []),
302
+ },
303
+ });
304
+ return JSON.parse(output || '{"rows":[],"rowCount":0}');
305
+ } catch (err) {
306
+ const msg = err instanceof Error ? err.message : String(err);
307
+ throw new Error(`PostgreSQL query failed: ${msg}`, { cause: err });
155
308
  }
156
309
  }
157
310
  }
@@ -25,3 +25,14 @@ export {
25
25
  entryToPlaybookDefinition,
26
26
  seedDefaultPlaybooks,
27
27
  } from './playbook-seeder.js';
28
+
29
+ // ─── Playbook Executor ─────────────────────────────────────────────
30
+ export { PlaybookExecutor } from './playbook-executor.js';
31
+ export type {
32
+ PlaybookSession,
33
+ PlaybookStepState,
34
+ PlaybookStepStatus,
35
+ StartResult,
36
+ StepResult,
37
+ CompleteResult,
38
+ } from './playbook-executor.js';