@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,188 @@
1
+ /**
2
+ * Browser Session Manager — per-chat Playwright isolation.
3
+ *
4
+ * Manages a pool of Playwright MCP client sessions, one per chat.
5
+ * Lazy initialization on first use, idle timeout eviction, FIFO
6
+ * eviction when max sessions reached.
7
+ *
8
+ * The actual Playwright MCP server is spawned as a child process
9
+ * via stdio transport. This module manages the lifecycle.
10
+ */
11
+
12
+ import { spawn, type ChildProcess } from 'node:child_process';
13
+
14
+ // ─── Types ────────────────────────────────────────────────────────────
15
+
16
+ export interface BrowserSessionConfig {
17
+ /** Idle timeout before closing a session (ms). Default: 5 minutes. */
18
+ idleTimeoutMs?: number;
19
+ /** Max concurrent browser sessions. Default: 3. */
20
+ maxSessions?: number;
21
+ /** Command to spawn Playwright MCP. Default: 'npx'. */
22
+ command?: string;
23
+ /** Args for the command. Default: ['@playwright/mcp', '--headless']. */
24
+ args?: string[];
25
+ }
26
+
27
+ export interface BrowserSession {
28
+ chatId: string;
29
+ process: ChildProcess;
30
+ lastUsed: number;
31
+ idleTimer: ReturnType<typeof setTimeout> | null;
32
+ }
33
+
34
+ export interface BrowserTool {
35
+ name: string;
36
+ description: string;
37
+ inputSchema: Record<string, unknown>;
38
+ }
39
+
40
+ export interface BrowserToolResult {
41
+ content: Array<{ type: string; text?: string; data?: string; mimeType?: string }>;
42
+ isError?: boolean;
43
+ }
44
+
45
+ // ─── Session Manager ─────────────────────────────────────────────────
46
+
47
+ const DEFAULT_IDLE_TIMEOUT = 5 * 60 * 1000; // 5 minutes
48
+ const DEFAULT_MAX_SESSIONS = 3;
49
+
50
+ export class BrowserSessionManager {
51
+ private sessions = new Map<string, BrowserSession>();
52
+ private readonly idleTimeoutMs: number;
53
+ private readonly maxSessions: number;
54
+ private readonly command: string;
55
+ private readonly args: string[];
56
+
57
+ constructor(config: BrowserSessionConfig = {}) {
58
+ this.idleTimeoutMs = config.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT;
59
+ this.maxSessions = config.maxSessions ?? DEFAULT_MAX_SESSIONS;
60
+ this.command = config.command ?? 'npx';
61
+ this.args = config.args ?? ['@playwright/mcp', '--headless'];
62
+ }
63
+
64
+ /**
65
+ * Get or create a browser session for a chat.
66
+ * Returns the session, spawning a new process if needed.
67
+ */
68
+ acquire(chatId: string): BrowserSession {
69
+ const existing = this.sessions.get(chatId);
70
+ if (existing) {
71
+ // Reset idle timer
72
+ if (existing.idleTimer) clearTimeout(existing.idleTimer);
73
+ existing.lastUsed = Date.now();
74
+ existing.idleTimer = setTimeout(() => this.release(chatId), this.idleTimeoutMs);
75
+ return existing;
76
+ }
77
+
78
+ // Evict if at capacity
79
+ if (this.sessions.size >= this.maxSessions) {
80
+ this.evictOldest();
81
+ }
82
+
83
+ // Spawn new Playwright MCP process
84
+ const proc = spawn(this.command, this.args, {
85
+ stdio: ['pipe', 'pipe', 'pipe'],
86
+ env: { ...process.env },
87
+ });
88
+
89
+ const session: BrowserSession = {
90
+ chatId,
91
+ process: proc,
92
+ lastUsed: Date.now(),
93
+ idleTimer: setTimeout(() => this.release(chatId), this.idleTimeoutMs),
94
+ };
95
+
96
+ proc.on('exit', () => {
97
+ // Clean up if process dies unexpectedly
98
+ const s = this.sessions.get(chatId);
99
+ if (s && s.process === proc) {
100
+ if (s.idleTimer) clearTimeout(s.idleTimer);
101
+ this.sessions.delete(chatId);
102
+ }
103
+ });
104
+
105
+ this.sessions.set(chatId, session);
106
+ return session;
107
+ }
108
+
109
+ /**
110
+ * Release a browser session (close process, remove from pool).
111
+ */
112
+ release(chatId: string): boolean {
113
+ const session = this.sessions.get(chatId);
114
+ if (!session) return false;
115
+
116
+ if (session.idleTimer) clearTimeout(session.idleTimer);
117
+
118
+ try {
119
+ session.process.kill();
120
+ } catch {
121
+ // Process may already be dead
122
+ }
123
+
124
+ this.sessions.delete(chatId);
125
+ return true;
126
+ }
127
+
128
+ /**
129
+ * Check if a chat has an active browser session.
130
+ */
131
+ has(chatId: string): boolean {
132
+ return this.sessions.has(chatId);
133
+ }
134
+
135
+ /**
136
+ * Close all browser sessions.
137
+ */
138
+ closeAll(): number {
139
+ let count = 0;
140
+ for (const chatId of this.sessions.keys()) {
141
+ if (this.release(chatId)) count++;
142
+ }
143
+ return count;
144
+ }
145
+
146
+ /**
147
+ * Get number of active sessions.
148
+ */
149
+ get size(): number {
150
+ return this.sessions.size;
151
+ }
152
+
153
+ /**
154
+ * List active session chat IDs.
155
+ */
156
+ listSessions(): string[] {
157
+ return [...this.sessions.keys()];
158
+ }
159
+
160
+ /**
161
+ * Get session info.
162
+ */
163
+ getInfo(chatId: string): { lastUsed: number; pid: number | null } | null {
164
+ const session = this.sessions.get(chatId);
165
+ if (!session) return null;
166
+ return {
167
+ lastUsed: session.lastUsed,
168
+ pid: session.process.pid ?? null,
169
+ };
170
+ }
171
+
172
+ /**
173
+ * Evict the oldest (least recently used) session.
174
+ */
175
+ private evictOldest(): void {
176
+ let oldest: string | null = null;
177
+ let oldestTime = Infinity;
178
+
179
+ for (const [chatId, session] of this.sessions) {
180
+ if (session.lastUsed < oldestTime) {
181
+ oldestTime = session.lastUsed;
182
+ oldest = chatId;
183
+ }
184
+ }
185
+
186
+ if (oldest) this.release(oldest);
187
+ }
188
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Task Cancellation Manager — per-chat AbortController management.
3
+ *
4
+ * Maps chat/session IDs to AbortControllers so running tasks can be
5
+ * cancelled from commands (e.g. /stop) or inline buttons.
6
+ *
7
+ * The agent loop already accepts AbortSignal — this provides the
8
+ * lifecycle management layer on top.
9
+ */
10
+
11
+ export interface CancellationInfo {
12
+ /** The AbortController for this task. */
13
+ controller: AbortController;
14
+ /** Unix timestamp ms when the task started. */
15
+ startedAt: number;
16
+ /** Optional description of what's running. */
17
+ description?: string;
18
+ }
19
+
20
+ export class TaskCancellationManager {
21
+ private active = new Map<string, CancellationInfo>();
22
+
23
+ /**
24
+ * Create a new AbortController for a chat/session.
25
+ * If one already exists, it is cancelled first.
26
+ */
27
+ create(chatId: string, description?: string): AbortSignal {
28
+ // Cancel existing task if any
29
+ this.cancel(chatId);
30
+
31
+ const controller = new AbortController();
32
+ this.active.set(chatId, {
33
+ controller,
34
+ startedAt: Date.now(),
35
+ description,
36
+ });
37
+
38
+ return controller.signal;
39
+ }
40
+
41
+ /**
42
+ * Cancel the running task for a chat. Returns info about what was cancelled.
43
+ */
44
+ cancel(chatId: string): CancellationInfo | null {
45
+ const info = this.active.get(chatId);
46
+ if (!info) return null;
47
+
48
+ info.controller.abort();
49
+ this.active.delete(chatId);
50
+ return info;
51
+ }
52
+
53
+ /**
54
+ * Mark a task as complete (remove without aborting).
55
+ */
56
+ complete(chatId: string): void {
57
+ this.active.delete(chatId);
58
+ }
59
+
60
+ /**
61
+ * Check if a chat has a running task.
62
+ */
63
+ isRunning(chatId: string): boolean {
64
+ return this.active.has(chatId);
65
+ }
66
+
67
+ /**
68
+ * Get info about a running task.
69
+ */
70
+ getInfo(chatId: string): CancellationInfo | null {
71
+ return this.active.get(chatId) ?? null;
72
+ }
73
+
74
+ /**
75
+ * Get all running task IDs.
76
+ */
77
+ listRunning(): string[] {
78
+ return [...this.active.keys()];
79
+ }
80
+
81
+ /**
82
+ * Number of active tasks.
83
+ */
84
+ get size(): number {
85
+ return this.active.size;
86
+ }
87
+
88
+ /**
89
+ * Cancel all running tasks.
90
+ */
91
+ cancelAll(): number {
92
+ let count = 0;
93
+ for (const [chatId] of this.active) {
94
+ this.cancel(chatId);
95
+ count++;
96
+ }
97
+ return count;
98
+ }
99
+ }
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Chat Session Manager — per-conversation history with disk persistence.
3
+ *
4
+ * Ported from Salvador's session-manager.ts with improvements:
5
+ * - Transport-agnostic (no Telegram coupling)
6
+ * - Synchronous persistence (matches Soleri's better-sqlite3 heritage)
7
+ * - Simpler compaction (no personality tracking)
8
+ * - TTL-based reaping with unref'd timer
9
+ */
10
+
11
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync, readdirSync } from 'node:fs';
12
+ import { join } from 'node:path';
13
+ import type { ChatSession, ChatSessionConfig, ChatMessage } from './types.js';
14
+
15
+ const DEFAULT_TTL_MS = 7_200_000; // 2 hours
16
+ const DEFAULT_COMPACTION_THRESHOLD = 100;
17
+ const DEFAULT_COMPACTION_KEEP = 40;
18
+ const REAPER_INTERVAL_MS = 60_000; // 1 minute
19
+
20
+ export class ChatSessionManager {
21
+ private sessions = new Map<string, ChatSession>();
22
+ private config: Required<ChatSessionConfig>;
23
+ private reaperTimer: ReturnType<typeof setInterval> | null = null;
24
+
25
+ constructor(config: ChatSessionConfig) {
26
+ this.config = {
27
+ storageDir: config.storageDir,
28
+ ttlMs: config.ttlMs ?? DEFAULT_TTL_MS,
29
+ compactionThreshold: config.compactionThreshold ?? DEFAULT_COMPACTION_THRESHOLD,
30
+ compactionKeep: config.compactionKeep ?? DEFAULT_COMPACTION_KEEP,
31
+ };
32
+
33
+ mkdirSync(this.config.storageDir, { recursive: true });
34
+ }
35
+
36
+ // ─── Lifecycle ──────────────────────────────────────────────────
37
+
38
+ /**
39
+ * Get or create a session. Loads from disk if not in memory.
40
+ */
41
+ getOrCreate(sessionId: string): ChatSession {
42
+ let session = this.sessions.get(sessionId);
43
+ if (session) {
44
+ session.lastActiveAt = Date.now();
45
+ return session;
46
+ }
47
+
48
+ // Try loading from disk
49
+ session = this.loadFromDisk(sessionId);
50
+ if (session) {
51
+ session.lastActiveAt = Date.now();
52
+ this.sessions.set(sessionId, session);
53
+ return session;
54
+ }
55
+
56
+ // Create new
57
+ const now = Date.now();
58
+ session = {
59
+ id: sessionId,
60
+ messages: [],
61
+ createdAt: now,
62
+ lastActiveAt: now,
63
+ };
64
+ this.sessions.set(sessionId, session);
65
+ this.persistToDisk(session);
66
+ return session;
67
+ }
68
+
69
+ /**
70
+ * Get a session without creating one.
71
+ */
72
+ get(sessionId: string): ChatSession | undefined {
73
+ return this.sessions.get(sessionId) ?? this.loadFromDisk(sessionId);
74
+ }
75
+
76
+ /**
77
+ * Check if a session exists (memory or disk).
78
+ */
79
+ has(sessionId: string): boolean {
80
+ if (this.sessions.has(sessionId)) return true;
81
+ return existsSync(this.sessionPath(sessionId));
82
+ }
83
+
84
+ // ─── Message Management ─────────────────────────────────────────
85
+
86
+ /**
87
+ * Append a message and persist.
88
+ */
89
+ appendMessage(sessionId: string, message: ChatMessage): void {
90
+ const session = this.getOrCreate(sessionId);
91
+ session.messages.push(message);
92
+ session.lastActiveAt = Date.now();
93
+
94
+ // Auto-compact if threshold exceeded
95
+ if (session.messages.length > this.config.compactionThreshold) {
96
+ this.compact(session);
97
+ }
98
+
99
+ this.persistToDisk(session);
100
+ }
101
+
102
+ /**
103
+ * Append multiple messages (e.g. assistant response + tool blocks).
104
+ */
105
+ appendMessages(sessionId: string, messages: ChatMessage[]): void {
106
+ const session = this.getOrCreate(sessionId);
107
+ session.messages.push(...messages);
108
+ session.lastActiveAt = Date.now();
109
+
110
+ if (session.messages.length > this.config.compactionThreshold) {
111
+ this.compact(session);
112
+ }
113
+
114
+ this.persistToDisk(session);
115
+ }
116
+
117
+ /**
118
+ * Get message count for a session.
119
+ */
120
+ messageCount(sessionId: string): number {
121
+ const session = this.sessions.get(sessionId);
122
+ return session?.messages.length ?? 0;
123
+ }
124
+
125
+ // ─── Session Operations ─────────────────────────────────────────
126
+
127
+ /**
128
+ * Clear session history (keep session alive, wipe messages).
129
+ */
130
+ clear(sessionId: string): void {
131
+ const session = this.sessions.get(sessionId);
132
+ if (session) {
133
+ session.messages = [];
134
+ session.lastActiveAt = Date.now();
135
+ this.persistToDisk(session);
136
+ } else {
137
+ // Remove from disk
138
+ this.removeFromDisk(sessionId);
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Delete a session entirely (memory + disk).
144
+ */
145
+ delete(sessionId: string): void {
146
+ this.sessions.delete(sessionId);
147
+ this.removeFromDisk(sessionId);
148
+ }
149
+
150
+ /**
151
+ * List all active session IDs (memory only — disk sessions not loaded).
152
+ */
153
+ listActive(): string[] {
154
+ return [...this.sessions.keys()];
155
+ }
156
+
157
+ /**
158
+ * List all session IDs (memory + disk).
159
+ */
160
+ listAll(): string[] {
161
+ const memoryIds = new Set(this.sessions.keys());
162
+ try {
163
+ const files = readdirSync(this.config.storageDir);
164
+ for (const f of files) {
165
+ if (f.endsWith('.json')) {
166
+ memoryIds.add(f.replace('.json', ''));
167
+ }
168
+ }
169
+ } catch {
170
+ // Directory may not exist yet
171
+ }
172
+ return [...memoryIds];
173
+ }
174
+
175
+ /**
176
+ * Number of active (in-memory) sessions.
177
+ */
178
+ get size(): number {
179
+ return this.sessions.size;
180
+ }
181
+
182
+ /**
183
+ * Update session metadata.
184
+ */
185
+ setMeta(sessionId: string, meta: Record<string, unknown>): void {
186
+ const session = this.getOrCreate(sessionId);
187
+ session.meta = { ...session.meta, ...meta };
188
+ this.persistToDisk(session);
189
+ }
190
+
191
+ // ─── Reaping (TTL cleanup) ─────────────────────────────────────
192
+
193
+ /**
194
+ * Start periodic TTL-based session cleanup.
195
+ */
196
+ startReaper(): void {
197
+ if (this.reaperTimer) return;
198
+ this.reaperTimer = setInterval(() => this.reap(), REAPER_INTERVAL_MS);
199
+ this.reaperTimer.unref();
200
+ }
201
+
202
+ /**
203
+ * Stop the reaper.
204
+ */
205
+ stopReaper(): void {
206
+ if (this.reaperTimer) {
207
+ clearInterval(this.reaperTimer);
208
+ this.reaperTimer = null;
209
+ }
210
+ }
211
+
212
+ /**
213
+ * Reap expired sessions. Returns number of sessions reaped.
214
+ */
215
+ reap(): number {
216
+ if (this.config.ttlMs <= 0) return 0;
217
+
218
+ const now = Date.now();
219
+ const cutoff = now - this.config.ttlMs;
220
+ let reaped = 0;
221
+
222
+ for (const [id, session] of this.sessions) {
223
+ if (session.lastActiveAt < cutoff) {
224
+ this.sessions.delete(id);
225
+ this.removeFromDisk(id);
226
+ reaped++;
227
+ }
228
+ }
229
+
230
+ return reaped;
231
+ }
232
+
233
+ /**
234
+ * Close all sessions and stop reaper.
235
+ */
236
+ close(): void {
237
+ this.stopReaper();
238
+ this.sessions.clear();
239
+ }
240
+
241
+ // ─── Private ───────────────────────────────────────────────────
242
+
243
+ private compact(session: ChatSession): void {
244
+ const keep = this.config.compactionKeep;
245
+ if (session.messages.length <= keep) return;
246
+ session.messages = session.messages.slice(-keep);
247
+ }
248
+
249
+ private sessionPath(sessionId: string): string {
250
+ // Sanitize ID for filesystem safety
251
+ const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, '_');
252
+ return join(this.config.storageDir, `${safe}.json`);
253
+ }
254
+
255
+ private persistToDisk(session: ChatSession): void {
256
+ try {
257
+ writeFileSync(this.sessionPath(session.id), JSON.stringify(session), 'utf-8');
258
+ } catch {
259
+ // Disk write failure is non-critical — session lives in memory
260
+ }
261
+ }
262
+
263
+ private loadFromDisk(sessionId: string): ChatSession | undefined {
264
+ const path = this.sessionPath(sessionId);
265
+ if (!existsSync(path)) return undefined;
266
+
267
+ try {
268
+ const data = readFileSync(path, 'utf-8');
269
+ return JSON.parse(data) as ChatSession;
270
+ } catch {
271
+ return undefined;
272
+ }
273
+ }
274
+
275
+ private removeFromDisk(sessionId: string): void {
276
+ const path = this.sessionPath(sessionId);
277
+ try {
278
+ rmSync(path, { force: true });
279
+ } catch {
280
+ // Removal failure is non-critical
281
+ }
282
+ }
283
+ }