@openacp/cli 0.6.10 → 2026.326.2

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 (256) hide show
  1. package/dist/{action-detect-P7ZE4NEM.js → action-detect-QPA775HB.js} +2 -2
  2. package/dist/adapter-6ANPBSVU.js +16 -0
  3. package/dist/{discord-OMC52Y54.js → adapter-77ZCVABT.js} +520 -365
  4. package/dist/adapter-77ZCVABT.js.map +1 -0
  5. package/dist/{adapter-ZOANORGM.js → adapter-PQGHVG4K.js} +300 -93
  6. package/dist/adapter-PQGHVG4K.js.map +1 -0
  7. package/dist/{admin-6SYB6XCZ.js → admin-GBPZFFAU.js} +3 -3
  8. package/dist/agent-catalog-YHBFERYO.js +11 -0
  9. package/dist/{agent-dependencies-4OWBMZWZ.js → agent-dependencies-WS7Z2DFW.js} +2 -2
  10. package/dist/agent-registry-5LZT7CUB.js +9 -0
  11. package/dist/agent-store-VSHNY5GT.js +9 -0
  12. package/dist/{agents-QO7DKARJ.js → agents-BWU4MRRD.js} +3 -3
  13. package/dist/{api-client-CFQT5U7D.js → api-client-AQPNKXI2.js} +2 -2
  14. package/dist/api-server-3PYLRBCN.js +8 -0
  15. package/dist/api-server-CHVSUDBX.js +11 -0
  16. package/dist/{autostart-X33OGMX6.js → autostart-6JS565RY.js} +3 -3
  17. package/dist/chunk-2CX4IEEC.js +124 -0
  18. package/dist/chunk-2CX4IEEC.js.map +1 -0
  19. package/dist/{chunk-O7CPGUAI.js → chunk-4KGLKKQK.js} +4 -4
  20. package/dist/chunk-4KGLKKQK.js.map +1 -0
  21. package/dist/{chunk-W3EYKZNQ.js → chunk-4WXALZA3.js} +2 -2
  22. package/dist/chunk-4WXALZA3.js.map +1 -0
  23. package/dist/chunk-5OCGO27U.js +125 -0
  24. package/dist/chunk-5OCGO27U.js.map +1 -0
  25. package/dist/{chunk-OWP7RZ62.js → chunk-5ZOFBTOR.js} +118 -262
  26. package/dist/chunk-5ZOFBTOR.js.map +1 -0
  27. package/dist/chunk-6RXVEXF3.js +23 -0
  28. package/dist/chunk-6RXVEXF3.js.map +1 -0
  29. package/dist/{chunk-34M4OS5P.js → chunk-A6Y4GZM3.js} +3 -3
  30. package/dist/chunk-A6Y4GZM3.js.map +1 -0
  31. package/dist/chunk-AD3X6DGK.js +166 -0
  32. package/dist/chunk-AD3X6DGK.js.map +1 -0
  33. package/dist/{chunk-7QJS2XBD.js → chunk-AFKX424Q.js} +2 -2
  34. package/dist/chunk-AFKX424Q.js.map +1 -0
  35. package/dist/chunk-APS6UEFU.js +259 -0
  36. package/dist/chunk-APS6UEFU.js.map +1 -0
  37. package/dist/chunk-BLQUXO7S.js +113 -0
  38. package/dist/chunk-BLQUXO7S.js.map +1 -0
  39. package/dist/{chunk-WTZDAYZX.js → chunk-BQ6FR32N.js} +3 -3
  40. package/dist/chunk-BQ6FR32N.js.map +1 -0
  41. package/dist/chunk-FNRSWA2K.js +1 -0
  42. package/dist/chunk-FQEBWOZR.js +3557 -0
  43. package/dist/chunk-FQEBWOZR.js.map +1 -0
  44. package/dist/{chunk-4CTX774K.js → chunk-GJOY37U7.js} +4 -4
  45. package/dist/chunk-GJOY37U7.js.map +1 -0
  46. package/dist/{chunk-I7WC6E5S.js → chunk-HVBNCPAY.js} +2 -2
  47. package/dist/chunk-HVBNCPAY.js.map +1 -0
  48. package/dist/{chunk-2HMQOC7N.js → chunk-I3CGU5W7.js} +4 -4
  49. package/dist/chunk-I3CGU5W7.js.map +1 -0
  50. package/dist/{chunk-NVPG6JCL.js → chunk-L7YNNBI5.js} +3 -3
  51. package/dist/chunk-L7YNNBI5.js.map +1 -0
  52. package/dist/chunk-LGFWH3AE.js +26 -0
  53. package/dist/chunk-LGFWH3AE.js.map +1 -0
  54. package/dist/chunk-MLF4W5R6.js +101 -0
  55. package/dist/chunk-MLF4W5R6.js.map +1 -0
  56. package/dist/{chunk-KIRH7TUJ.js → chunk-MTSDOSXS.js} +3 -3
  57. package/dist/chunk-MTSDOSXS.js.map +1 -0
  58. package/dist/{chunk-J4SJTKIK.js → chunk-NAM4ERUW.js} +3 -3
  59. package/dist/chunk-NAM4ERUW.js.map +1 -0
  60. package/dist/{chunk-MKHUZLII.js → chunk-NBFIBGAT.js} +39 -25
  61. package/dist/chunk-NBFIBGAT.js.map +1 -0
  62. package/dist/{chunk-BNLGTZ34.js → chunk-O5RG4YZY.js} +3 -3
  63. package/dist/chunk-O5RG4YZY.js.map +1 -0
  64. package/dist/{chunk-JHYXKVV2.js → chunk-ODUM3D6X.js} +2 -2
  65. package/dist/chunk-ODUM3D6X.js.map +1 -0
  66. package/dist/chunk-OYSAN7UX.js +15 -0
  67. package/dist/chunk-OYSAN7UX.js.map +1 -0
  68. package/dist/chunk-P4SNGQNI.js +158 -0
  69. package/dist/chunk-P4SNGQNI.js.map +1 -0
  70. package/dist/{chunk-2CJ46J3C.js → chunk-PPSMUECX.js} +3 -3
  71. package/dist/chunk-PPSMUECX.js.map +1 -0
  72. package/dist/chunk-Q6ZXJTZB.js +56 -0
  73. package/dist/chunk-Q6ZXJTZB.js.map +1 -0
  74. package/dist/{chunk-XANPHG7W.js → chunk-QSDZDHNS.js} +7 -7
  75. package/dist/chunk-QSDZDHNS.js.map +1 -0
  76. package/dist/{chunk-33RP6K2O.js → chunk-QVMEF6FB.js} +6 -6
  77. package/dist/chunk-QVMEF6FB.js.map +1 -0
  78. package/dist/chunk-QWP76EBW.js +536 -0
  79. package/dist/chunk-QWP76EBW.js.map +1 -0
  80. package/dist/{chunk-V5GZQEIY.js → chunk-RBYBSSGO.js} +4 -4
  81. package/dist/chunk-RBYBSSGO.js.map +1 -0
  82. package/dist/{chunk-CS3KCJ5D.js → chunk-RKB2ZK6S.js} +555 -383
  83. package/dist/chunk-RKB2ZK6S.js.map +1 -0
  84. package/dist/{chunk-UKT3G5IA.js → chunk-SHTGQGAU.js} +7 -7
  85. package/dist/chunk-SHTGQGAU.js.map +1 -0
  86. package/dist/chunk-SNPYTMPR.js +51 -0
  87. package/dist/chunk-SNPYTMPR.js.map +1 -0
  88. package/dist/chunk-UB2QB6DE.js +124 -0
  89. package/dist/chunk-UB2QB6DE.js.map +1 -0
  90. package/dist/chunk-UNJUWWQO.js +1108 -0
  91. package/dist/chunk-UNJUWWQO.js.map +1 -0
  92. package/dist/chunk-V2M243KZ.js +445 -0
  93. package/dist/chunk-V2M243KZ.js.map +1 -0
  94. package/dist/chunk-V5JT5TPD.js +97 -0
  95. package/dist/chunk-V5JT5TPD.js.map +1 -0
  96. package/dist/chunk-W26AUH5B.js +61 -0
  97. package/dist/chunk-W26AUH5B.js.map +1 -0
  98. package/dist/chunk-WAAD23KY.js +222 -0
  99. package/dist/chunk-WAAD23KY.js.map +1 -0
  100. package/dist/chunk-WIIZNPCR.js +150 -0
  101. package/dist/chunk-WIIZNPCR.js.map +1 -0
  102. package/dist/chunk-WQCJTU2C.js +84 -0
  103. package/dist/chunk-WQCJTU2C.js.map +1 -0
  104. package/dist/chunk-WVLDNYOJ.js +150 -0
  105. package/dist/chunk-WVLDNYOJ.js.map +1 -0
  106. package/dist/chunk-WXVT3AOY.js +22 -0
  107. package/dist/chunk-WXVT3AOY.js.map +1 -0
  108. package/dist/{chunk-GAK6PIBW.js → chunk-XMMAGAT4.js} +2 -2
  109. package/dist/chunk-XMMAGAT4.js.map +1 -0
  110. package/dist/chunk-Y64XWMJ4.js +212 -0
  111. package/dist/chunk-Y64XWMJ4.js.map +1 -0
  112. package/dist/chunk-YEULD3SG.js +62 -0
  113. package/dist/chunk-YEULD3SG.js.map +1 -0
  114. package/dist/chunk-ZHGPZBS4.js +49 -0
  115. package/dist/chunk-ZHGPZBS4.js.map +1 -0
  116. package/dist/{chunk-JKBFUAJK.js → chunk-ZSLHHQPQ.js} +2 -2
  117. package/dist/chunk-ZSLHHQPQ.js.map +1 -0
  118. package/dist/cli.js +496 -150
  119. package/dist/cli.js.map +1 -1
  120. package/dist/{config-6S355X75.js → config-I4FMCJGZ.js} +3 -3
  121. package/dist/config-editor-HNEKXRLQ.js +11 -0
  122. package/dist/{config-registry-AHYI4MYL.js → config-registry-CUMNXFGK.js} +2 -2
  123. package/dist/context-XM6E22LM.js +10 -0
  124. package/dist/core-plugins-VEUNFTMB.js +27 -0
  125. package/dist/{daemon-4CS6HMB5.js → daemon-PXO5QPCR.js} +4 -4
  126. package/dist/dev-loader-RDC5E2CW.js +50 -0
  127. package/dist/dev-loader-RDC5E2CW.js.map +1 -0
  128. package/dist/discord-NOJQ5PZO.js +8 -0
  129. package/dist/doctor-H72BZOPA.js +10 -0
  130. package/dist/{doctor-OLYBO3V3.js → doctor-RF6BHMCC.js} +5 -5
  131. package/dist/file-service-EUODJAIT.js +9 -0
  132. package/dist/file-service-EUODJAIT.js.map +1 -0
  133. package/dist/index.d.ts +1293 -188
  134. package/dist/index.js +387 -48
  135. package/dist/index.js.map +1 -1
  136. package/dist/{install-cloudflared-Z7VCGOVG.js → install-cloudflared-AN24L4DP.js} +5 -5
  137. package/dist/install-cloudflared-AN24L4DP.js.map +1 -0
  138. package/dist/install-context-XPWTFT3J.js +78 -0
  139. package/dist/install-context-XPWTFT3J.js.map +1 -0
  140. package/dist/{install-jq-HUYSQWKR.js → install-jq-CRVDJGF3.js} +5 -5
  141. package/dist/install-jq-CRVDJGF3.js.map +1 -0
  142. package/dist/{integrate-PNEHRY2I.js → integrate-5C6KSU6D.js} +2 -2
  143. package/dist/integrate-5C6KSU6D.js.map +1 -0
  144. package/dist/{log-NXABYJTT.js → log-LZ7FTRKG.js} +2 -2
  145. package/dist/log-LZ7FTRKG.js.map +1 -0
  146. package/dist/main-T5WVCCFN.js +715 -0
  147. package/dist/main-T5WVCCFN.js.map +1 -0
  148. package/dist/{menu-YY5MKHEK.js → menu-YDQ2LWAR.js} +2 -2
  149. package/dist/menu-YDQ2LWAR.js.map +1 -0
  150. package/dist/{new-session-FEO4J4VU.js → new-session-AVQCNXRG.js} +5 -5
  151. package/dist/new-session-AVQCNXRG.js.map +1 -0
  152. package/dist/notifications-D5BRDNSU.js +9 -0
  153. package/dist/notifications-D5BRDNSU.js.map +1 -0
  154. package/dist/plugin-create-JVCVUG6V.js +331 -0
  155. package/dist/plugin-create-JVCVUG6V.js.map +1 -0
  156. package/dist/plugin-registry-WB3DR67H.js +8 -0
  157. package/dist/plugin-registry-WB3DR67H.js.map +1 -0
  158. package/dist/{post-upgrade-CJG5I7M2.js → post-upgrade-XLHZ6ZB7.js} +8 -8
  159. package/dist/post-upgrade-XLHZ6ZB7.js.map +1 -0
  160. package/dist/read-text-file-IRZM3QLM.js +8 -0
  161. package/dist/read-text-file-IRZM3QLM.js.map +1 -0
  162. package/dist/security-YNRBW6S7.js +9 -0
  163. package/dist/security-YNRBW6S7.js.map +1 -0
  164. package/dist/{session-IUSI7P5S.js → session-KZFA6Z26.js} +4 -4
  165. package/dist/session-KZFA6Z26.js.map +1 -0
  166. package/dist/{settings-RQPAM4KC.js → settings-MFYM7CZO.js} +4 -4
  167. package/dist/settings-MFYM7CZO.js.map +1 -0
  168. package/dist/settings-manager-MD2U4ZV2.js +8 -0
  169. package/dist/settings-manager-MD2U4ZV2.js.map +1 -0
  170. package/dist/{chunk-LCRLAV4G.js → setup-BAI2F24H.js} +154 -492
  171. package/dist/setup-BAI2F24H.js.map +1 -0
  172. package/dist/slack-KH7E3VBS.js +8 -0
  173. package/dist/slack-KH7E3VBS.js.map +1 -0
  174. package/dist/speech-2GHQNRIO.js +9 -0
  175. package/dist/speech-2GHQNRIO.js.map +1 -0
  176. package/dist/telegram-ZDC3JQF2.js +8 -0
  177. package/dist/telegram-ZDC3JQF2.js.map +1 -0
  178. package/dist/tunnel-M47I7H4B.js +8 -0
  179. package/dist/tunnel-M47I7H4B.js.map +1 -0
  180. package/dist/{tunnel-service-CJLUH6SZ.js → tunnel-service-WADYHREX.js} +17 -17
  181. package/dist/tunnel-service-WADYHREX.js.map +1 -0
  182. package/dist/usage-WYNK6ZC5.js +10 -0
  183. package/dist/usage-WYNK6ZC5.js.map +1 -0
  184. package/dist/validators-6CLEZUBD.js +8 -0
  185. package/dist/validators-6CLEZUBD.js.map +1 -0
  186. package/dist/validators-WSTBNKRW.js +12 -0
  187. package/dist/validators-WSTBNKRW.js.map +1 -0
  188. package/package.json +1 -1
  189. package/dist/adapter-ZOANORGM.js.map +0 -1
  190. package/dist/agent-catalog-FC3HGDEQ.js +0 -11
  191. package/dist/agent-registry-WT4NXPYG.js +0 -9
  192. package/dist/agent-store-VZLFPTZU.js +0 -9
  193. package/dist/chunk-2CJ46J3C.js.map +0 -1
  194. package/dist/chunk-2HMQOC7N.js.map +0 -1
  195. package/dist/chunk-33RP6K2O.js.map +0 -1
  196. package/dist/chunk-34M4OS5P.js.map +0 -1
  197. package/dist/chunk-4CTX774K.js.map +0 -1
  198. package/dist/chunk-7QJS2XBD.js.map +0 -1
  199. package/dist/chunk-BNLGTZ34.js.map +0 -1
  200. package/dist/chunk-CS3KCJ5D.js.map +0 -1
  201. package/dist/chunk-GAK6PIBW.js.map +0 -1
  202. package/dist/chunk-I7WC6E5S.js.map +0 -1
  203. package/dist/chunk-J4SJTKIK.js.map +0 -1
  204. package/dist/chunk-JHYXKVV2.js.map +0 -1
  205. package/dist/chunk-JKBFUAJK.js.map +0 -1
  206. package/dist/chunk-KIRH7TUJ.js.map +0 -1
  207. package/dist/chunk-LBIKITQT.js +0 -22
  208. package/dist/chunk-LBIKITQT.js.map +0 -1
  209. package/dist/chunk-LCRLAV4G.js.map +0 -1
  210. package/dist/chunk-LGP2YGRL.js +0 -4880
  211. package/dist/chunk-LGP2YGRL.js.map +0 -1
  212. package/dist/chunk-MKHUZLII.js.map +0 -1
  213. package/dist/chunk-NAMYZIS5.js +0 -1
  214. package/dist/chunk-NVPG6JCL.js.map +0 -1
  215. package/dist/chunk-O7CPGUAI.js.map +0 -1
  216. package/dist/chunk-OWP7RZ62.js.map +0 -1
  217. package/dist/chunk-UKT3G5IA.js.map +0 -1
  218. package/dist/chunk-V5GZQEIY.js.map +0 -1
  219. package/dist/chunk-VOIJ6OY4.js +0 -63
  220. package/dist/chunk-VOIJ6OY4.js.map +0 -1
  221. package/dist/chunk-W3EYKZNQ.js.map +0 -1
  222. package/dist/chunk-WTZDAYZX.js.map +0 -1
  223. package/dist/chunk-XANPHG7W.js.map +0 -1
  224. package/dist/config-editor-QQTZMWGD.js +0 -13
  225. package/dist/discord-OMC52Y54.js.map +0 -1
  226. package/dist/doctor-HZZ5BSHB.js +0 -10
  227. package/dist/install-cloudflared-Z7VCGOVG.js.map +0 -1
  228. package/dist/install-jq-HUYSQWKR.js.map +0 -1
  229. package/dist/integrate-PNEHRY2I.js.map +0 -1
  230. package/dist/main-XOZCLFUK.js +0 -238
  231. package/dist/main-XOZCLFUK.js.map +0 -1
  232. package/dist/post-upgrade-CJG5I7M2.js.map +0 -1
  233. package/dist/setup-XHS4OMPM.js +0 -37
  234. package/dist/tunnel-service-CJLUH6SZ.js.map +0 -1
  235. /package/dist/{action-detect-P7ZE4NEM.js.map → action-detect-QPA775HB.js.map} +0 -0
  236. /package/dist/{admin-6SYB6XCZ.js.map → adapter-6ANPBSVU.js.map} +0 -0
  237. /package/dist/{agent-catalog-FC3HGDEQ.js.map → admin-GBPZFFAU.js.map} +0 -0
  238. /package/dist/{agent-dependencies-4OWBMZWZ.js.map → agent-catalog-YHBFERYO.js.map} +0 -0
  239. /package/dist/{agent-registry-WT4NXPYG.js.map → agent-dependencies-WS7Z2DFW.js.map} +0 -0
  240. /package/dist/{agent-store-VZLFPTZU.js.map → agent-registry-5LZT7CUB.js.map} +0 -0
  241. /package/dist/{agents-QO7DKARJ.js.map → agent-store-VSHNY5GT.js.map} +0 -0
  242. /package/dist/{api-client-CFQT5U7D.js.map → agents-BWU4MRRD.js.map} +0 -0
  243. /package/dist/{autostart-X33OGMX6.js.map → api-client-AQPNKXI2.js.map} +0 -0
  244. /package/dist/{chunk-NAMYZIS5.js.map → api-server-3PYLRBCN.js.map} +0 -0
  245. /package/dist/{config-6S355X75.js.map → api-server-CHVSUDBX.js.map} +0 -0
  246. /package/dist/{config-editor-QQTZMWGD.js.map → autostart-6JS565RY.js.map} +0 -0
  247. /package/dist/{config-registry-AHYI4MYL.js.map → chunk-FNRSWA2K.js.map} +0 -0
  248. /package/dist/{daemon-4CS6HMB5.js.map → config-I4FMCJGZ.js.map} +0 -0
  249. /package/dist/{doctor-HZZ5BSHB.js.map → config-editor-HNEKXRLQ.js.map} +0 -0
  250. /package/dist/{doctor-OLYBO3V3.js.map → config-registry-CUMNXFGK.js.map} +0 -0
  251. /package/dist/{log-NXABYJTT.js.map → context-XM6E22LM.js.map} +0 -0
  252. /package/dist/{menu-YY5MKHEK.js.map → core-plugins-VEUNFTMB.js.map} +0 -0
  253. /package/dist/{new-session-FEO4J4VU.js.map → daemon-PXO5QPCR.js.map} +0 -0
  254. /package/dist/{session-IUSI7P5S.js.map → discord-NOJQ5PZO.js.map} +0 -0
  255. /package/dist/{settings-RQPAM4KC.js.map → doctor-H72BZOPA.js.map} +0 -0
  256. /package/dist/{setup-XHS4OMPM.js.map → doctor-RF6BHMCC.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../src/core/streams.ts","../../src/core/stderr-capture.ts","../../src/core/typed-emitter.ts","../../src/core/agent-instance.ts","../../src/core/agent-manager.ts","../../src/core/prompt-queue.ts","../../src/core/permission-gate.ts","../../src/core/session.ts","../../src/core/session-manager.ts","../../src/core/file-service.ts","../../src/core/session-bridge.ts","../../src/core/notification.ts","../../src/tunnel/extract-file-info.ts","../../src/core/message-transformer.ts","../../src/core/usage-store.ts","../../src/core/usage-budget.ts","../../src/core/security-guard.ts","../../src/core/session-factory.ts","../../src/core/event-bus.ts","../../src/core/speech/speech-service.ts","../../src/core/speech/providers/groq.ts","../../src/core/speech/providers/edge-tts.ts","../../src/core/context/context-manager.ts","../../src/core/context/context-cache.ts","../../src/core/context/context-provider.ts","../../src/core/context/entire/checkpoint-reader.ts","../../src/core/context/entire/message-cleaner.ts","../../src/core/context/entire/conversation-builder.ts","../../src/core/context/entire/entire-provider.ts","../../src/core/core.ts","../../src/core/session-store.ts","../../src/core/sse-manager.ts","../../src/core/static-server.ts","../../src/core/api/index.ts","../../src/core/api/router.ts","../../src/core/api/routes/health.ts","../../src/core/api/routes/sessions.ts","../../src/core/api/routes/config.ts","../../src/core/api/routes/topics.ts","../../src/core/api/routes/tunnel.ts","../../src/core/api/routes/agents.ts","../../src/core/api/routes/notify.ts","../../src/core/topic-manager.ts"],"sourcesContent":["import type { Writable, Readable } from 'node:stream'\n\nexport function nodeToWebWritable(nodeStream: Writable): WritableStream<Uint8Array> {\n return new WritableStream<Uint8Array>({\n write(chunk) {\n return new Promise<void>((resolve, reject) => {\n nodeStream.write(Buffer.from(chunk), (err) => {\n if (err) reject(err)\n else resolve()\n })\n })\n },\n })\n}\n\nexport function nodeToWebReadable(nodeStream: Readable): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n nodeStream.on('data', (chunk: Buffer) => {\n controller.enqueue(new Uint8Array(chunk))\n })\n nodeStream.on('end', () => controller.close())\n nodeStream.on('error', (err) => controller.error(err))\n },\n })\n}\n","export class StderrCapture {\n private lines: string[] = []\n\n constructor(private maxLines: number = 50) {}\n\n append(chunk: string): void {\n this.lines.push(...chunk.split('\\n').filter(Boolean))\n if (this.lines.length > this.maxLines) {\n this.lines = this.lines.slice(-this.maxLines)\n }\n }\n\n getLastLines(): string {\n return this.lines.join('\\n')\n }\n}\n","/**\n * A minimal, generic typed event emitter.\n *\n * Usage:\n * interface MyEvents {\n * data: (payload: string) => void\n * error: (err: Error) => void\n * }\n * const emitter = new TypedEmitter<MyEvents>()\n * emitter.on('data', (payload) => { ... })\n * emitter.emit('data', 'hello')\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class TypedEmitter<T extends Record<string & keyof T, (...args: any[]) => void>> {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private listeners = new Map<keyof T, Set<(...args: any[]) => void>>()\n private paused = false\n private buffer: Array<{ event: keyof T; args: unknown[] }> = []\n\n on<K extends keyof T>(event: K, listener: T[K]): this {\n let set = this.listeners.get(event)\n if (!set) {\n set = new Set()\n this.listeners.set(event, set)\n }\n set.add(listener)\n return this\n }\n\n off<K extends keyof T>(event: K, listener: T[K]): this {\n this.listeners.get(event)?.delete(listener)\n return this\n }\n\n emit<K extends keyof T>(event: K, ...args: Parameters<T[K]>): void {\n if (this.paused) {\n // Check passthrough filter — some events may bypass the pause\n if (this.passthroughFn?.(event, args)) {\n this.deliver(event, args)\n } else {\n this.buffer.push({ event, args })\n }\n return\n }\n this.deliver(event, args)\n }\n\n /**\n * Pause event delivery. Events emitted while paused are buffered.\n * Optionally pass a filter to allow specific events through even while paused.\n */\n pause(passthrough?: (event: keyof T, args: unknown[]) => boolean): void {\n this.paused = true\n this.passthroughFn = passthrough\n }\n private passthroughFn?: (event: keyof T, args: unknown[]) => boolean\n\n /** Resume event delivery and replay buffered events in order. */\n resume(): void {\n this.paused = false\n this.passthroughFn = undefined\n const buffered = this.buffer.splice(0)\n for (const { event, args } of buffered) {\n this.deliver(event, args)\n }\n }\n\n /** Discard all buffered events without delivering them. */\n clearBuffer(): void {\n this.buffer.length = 0\n }\n\n get isPaused(): boolean {\n return this.paused\n }\n\n get bufferSize(): number {\n return this.buffer.length\n }\n\n removeAllListeners(event?: keyof T): void {\n if (event) {\n this.listeners.delete(event)\n } else {\n this.listeners.clear()\n }\n }\n\n private deliver(event: keyof T, args: unknown[]): void {\n const set = this.listeners.get(event)\n if (!set) return\n for (const listener of set) {\n (listener as (...a: unknown[]) => void)(...args)\n }\n }\n}\n","import { spawn, execFileSync, type ChildProcess } from \"node:child_process\";\nimport { Transform } from \"node:stream\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { randomUUID } from \"node:crypto\";\nimport { ClientSideConnection, ndJsonStream } from \"@agentclientprotocol/sdk\";\nimport type {\n Agent,\n Client,\n PromptResponse,\n PermissionOption as SdkPermissionOption,\n} from \"@agentclientprotocol/sdk\";\nimport { nodeToWebWritable, nodeToWebReadable } from \"./streams.js\";\nimport { StderrCapture } from \"./stderr-capture.js\";\nimport { TypedEmitter } from \"./typed-emitter.js\";\nimport type {\n AgentDefinition,\n AgentEvent,\n Attachment,\n PermissionRequest,\n} from \"./types.js\";\nimport { createChildLogger } from \"./log.js\";\nconst log = createChildLogger({ module: \"agent-instance\" });\n\n/** Find the nearest ancestor directory containing package.json */\nfunction findPackageRoot(startDir: string): string {\n let dir = startDir;\n while (dir !== path.dirname(dir)) {\n if (fs.existsSync(path.join(dir, \"package.json\"))) {\n return dir;\n }\n dir = path.dirname(dir);\n }\n return startDir;\n}\n\n/** Resolve an agent command to a directly executable form (avoids shell wrappers) */\nfunction resolveAgentCommand(cmd: string): { command: string; args: string[] } {\n // Directories to search for node_modules: cwd AND the package's own directory\n const searchRoots = [process.cwd()];\n // Add the directory where this package is installed (for global installs)\n // Use findPackageRoot instead of hardcoded \"../..\" to handle both tsc (dist/core/)\n // and tsup bundle (dist/) directory structures correctly\n const ownDir = findPackageRoot(import.meta.dirname);\n if (ownDir !== process.cwd()) {\n searchRoots.push(ownDir);\n }\n\n // 1. Check node_modules for the package's actual JS entry point\n for (const root of searchRoots) {\n const packageDirs = [\n path.resolve(root, \"node_modules\", \"@zed-industries\", cmd, \"dist\", \"index.js\"),\n path.resolve(root, \"node_modules\", cmd, \"dist\", \"index.js\"),\n ];\n for (const jsPath of packageDirs) {\n if (fs.existsSync(jsPath)) {\n return { command: process.execPath, args: [jsPath] };\n }\n }\n }\n\n // 2. Check .bin — if it's a JS file with shebang, run with node directly\n for (const root of searchRoots) {\n const localBin = path.resolve(root, \"node_modules\", \".bin\", cmd);\n if (fs.existsSync(localBin)) {\n const content = fs.readFileSync(localBin, \"utf-8\");\n if (content.startsWith(\"#!/usr/bin/env node\")) {\n return { command: process.execPath, args: [localBin] };\n }\n // Shell wrapper — try to find the target JS file\n const match = content.match(/\"([^\"]+\\.js)\"/);\n if (match) {\n const target = path.resolve(path.dirname(localBin), match[1]);\n if (fs.existsSync(target)) {\n return { command: process.execPath, args: [target] };\n }\n }\n }\n }\n\n // 3. Try resolving from PATH using which\n try {\n const fullPath = execFileSync(\"which\", [cmd], { encoding: \"utf-8\" }).trim();\n if (fullPath) {\n const content = fs.readFileSync(fullPath, \"utf-8\");\n if (content.startsWith(\"#!/usr/bin/env node\")) {\n return { command: process.execPath, args: [fullPath] };\n }\n }\n } catch {\n // which failed\n }\n\n // 4. Fallback: use command as-is\n return { command: cmd, args: [] };\n}\n\ninterface TerminalState {\n process: ChildProcess;\n output: string;\n exitStatus: { exitCode: number | null; signal: string | null } | null;\n}\n\nexport interface AgentInstanceEvents {\n agent_event: (event: AgentEvent) => void;\n}\n\nexport class AgentInstance extends TypedEmitter<AgentInstanceEvents> {\n private connection!: ClientSideConnection;\n private child!: ChildProcess;\n private stderrCapture!: StderrCapture;\n private terminals: Map<string, TerminalState> = new Map();\n\n sessionId!: string;\n agentName: string;\n promptCapabilities?: { image?: boolean; audio?: boolean };\n\n // Callback — set by core when wiring events\n onPermissionRequest: (request: PermissionRequest) => Promise<string> =\n async () => \"\";\n\n private constructor(agentName: string) {\n super();\n this.agentName = agentName;\n }\n\n private static async spawnSubprocess(\n agentDef: AgentDefinition,\n workingDirectory: string,\n ): Promise<AgentInstance> {\n const instance = new AgentInstance(agentDef.name);\n const resolved = resolveAgentCommand(agentDef.command);\n log.debug(\n {\n agentName: agentDef.name,\n command: resolved.command,\n args: resolved.args,\n },\n \"Resolved agent command\",\n );\n\n instance.child = spawn(\n resolved.command,\n [...resolved.args, ...agentDef.args],\n {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n cwd: workingDirectory,\n env: { ...process.env, ...agentDef.env },\n },\n );\n\n await new Promise<void>((resolve, reject) => {\n instance.child.on(\"error\", (err) => {\n reject(\n new Error(\n `Failed to spawn agent \"${agentDef.name}\": ${err.message}. Is \"${agentDef.command}\" installed?`,\n ),\n );\n });\n instance.child.on(\"spawn\", () => resolve());\n });\n\n instance.stderrCapture = new StderrCapture(50);\n instance.child.stderr!.on(\"data\", (chunk: Buffer) => {\n instance.stderrCapture.append(chunk.toString());\n });\n\n const stdinLogger = new Transform({\n transform(chunk, _enc, cb) {\n log.debug(\n { direction: \"send\", raw: chunk.toString().trimEnd() },\n \"ACP raw\",\n );\n cb(null, chunk);\n },\n });\n stdinLogger.pipe(instance.child.stdin!);\n\n const stdoutLogger = new Transform({\n transform(chunk, _enc, cb) {\n log.debug(\n { direction: \"recv\", raw: chunk.toString().trimEnd() },\n \"ACP raw\",\n );\n cb(null, chunk);\n },\n });\n instance.child.stdout!.pipe(stdoutLogger);\n\n const toAgent = nodeToWebWritable(stdinLogger);\n const fromAgent = nodeToWebReadable(stdoutLogger);\n const stream = ndJsonStream(toAgent, fromAgent);\n\n instance.connection = new ClientSideConnection(\n (_agent: Agent): Client => instance.createClient(_agent),\n stream,\n );\n\n const initResponse = await instance.connection.initialize({\n protocolVersion: 1,\n clientCapabilities: {\n fs: { readTextFile: true, writeTextFile: true },\n terminal: true,\n },\n });\n instance.promptCapabilities =\n initResponse.agentCapabilities?.promptCapabilities;\n\n log.info(\n { promptCapabilities: instance.promptCapabilities ?? {} },\n \"Agent prompt capabilities\",\n );\n\n return instance;\n }\n\n private setupCrashDetection(): void {\n this.child.on(\"exit\", (code, signal) => {\n log.info(\n { sessionId: this.sessionId, exitCode: code, signal },\n \"Agent process exited\",\n );\n if (code !== 0 && code !== null) {\n const stderr = this.stderrCapture.getLastLines();\n this.emit('agent_event', {\n type: \"error\",\n message: `Agent crashed (exit code ${code})\\n${stderr}`,\n });\n }\n });\n\n this.connection.closed.then(() => {\n log.debug({ sessionId: this.sessionId }, \"ACP connection closed\");\n });\n }\n\n static async spawn(\n agentDef: AgentDefinition,\n workingDirectory: string,\n ): Promise<AgentInstance> {\n log.debug(\n { agentName: agentDef.name, command: agentDef.command },\n \"Spawning agent\",\n );\n const spawnStart = Date.now();\n\n const instance = await AgentInstance.spawnSubprocess(\n agentDef,\n workingDirectory,\n );\n\n const response = await instance.connection.newSession({\n cwd: workingDirectory,\n mcpServers: [],\n });\n instance.sessionId = response.sessionId;\n instance.setupCrashDetection();\n\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent spawn complete\",\n );\n return instance;\n }\n\n static async resume(\n agentDef: AgentDefinition,\n workingDirectory: string,\n agentSessionId: string,\n ): Promise<AgentInstance> {\n log.debug({ agentName: agentDef.name, agentSessionId }, \"Resuming agent\");\n const spawnStart = Date.now();\n\n const instance = await AgentInstance.spawnSubprocess(\n agentDef,\n workingDirectory,\n );\n\n try {\n const response = await instance.connection.unstable_resumeSession({\n sessionId: agentSessionId,\n cwd: workingDirectory,\n });\n instance.sessionId = response.sessionId;\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent resume complete\",\n );\n } catch (err) {\n log.warn(\n { err, agentSessionId },\n \"Resume failed, falling back to new session\",\n );\n const response = await instance.connection.newSession({\n cwd: workingDirectory,\n mcpServers: [],\n });\n instance.sessionId = response.sessionId;\n log.info(\n { sessionId: response.sessionId, durationMs: Date.now() - spawnStart },\n \"Agent fallback spawn complete\",\n );\n }\n\n instance.setupCrashDetection();\n return instance;\n }\n\n // createClient — implemented in Task 6b\n private createClient(_agent: Agent): Client {\n const self = this;\n const MAX_OUTPUT_BYTES = 1024 * 1024; // 1MB cap\n\n return {\n // ── Session updates ──────────────────────────────────────────────────\n async sessionUpdate(params) {\n const update = params.update;\n let event: AgentEvent | null = null;\n\n switch (update.sessionUpdate) {\n case \"agent_message_chunk\":\n if (update.content.type === \"text\") {\n event = { type: \"text\", content: update.content.text };\n } else if (update.content.type === \"image\") {\n // ACP SDK types don't expose data/mimeType fields for image content\n const c = update.content as unknown as { data: string; mimeType: string };\n event = { type: \"image_content\", data: c.data, mimeType: c.mimeType };\n } else if (update.content.type === \"audio\") {\n // ACP SDK types don't expose data/mimeType fields for audio content\n const c = update.content as unknown as { data: string; mimeType: string };\n event = { type: \"audio_content\", data: c.data, mimeType: c.mimeType };\n }\n break;\n case \"agent_thought_chunk\":\n if (update.content.type === \"text\") {\n event = { type: \"thought\", content: update.content.text };\n }\n break;\n case \"tool_call\":\n event = {\n type: \"tool_call\",\n id: update.toolCallId,\n name: update.title,\n kind: update.kind ?? undefined,\n status: update.status ?? \"pending\",\n content: update.content ?? undefined,\n rawInput: (update as any).rawInput ?? undefined,\n meta: (update as any)._meta ?? undefined,\n };\n break;\n case \"tool_call_update\":\n event = {\n type: \"tool_update\",\n id: update.toolCallId,\n name: update.title ?? undefined,\n kind: update.kind ?? undefined,\n status: update.status ?? \"pending\",\n content: update.content ?? undefined,\n rawInput: (update as any).rawInput ?? undefined,\n meta: (update as any)._meta ?? undefined,\n };\n break;\n case \"plan\":\n event = { type: \"plan\", entries: update.entries };\n break;\n case \"usage_update\":\n event = {\n type: \"usage\",\n tokensUsed: update.used,\n contextSize: update.size,\n cost: update.cost ?? undefined,\n };\n break;\n case \"available_commands_update\":\n event = {\n type: \"commands_update\",\n commands: update.availableCommands,\n };\n break;\n default:\n // Unknown update type — ignore\n return;\n }\n\n if (event !== null) {\n self.emit('agent_event', event);\n }\n },\n\n // ── Permission requests ──────────────────────────────────────────────\n async requestPermission(params) {\n const permissionRequest: PermissionRequest = {\n id: params.toolCall.toolCallId,\n description: params.toolCall.title ?? params.toolCall.toolCallId,\n options: params.options.map((opt: SdkPermissionOption) => ({\n id: opt.optionId,\n label: opt.name,\n isAllow: opt.kind === \"allow_once\" || opt.kind === \"allow_always\",\n })),\n };\n\n const selectedOptionId =\n await self.onPermissionRequest(permissionRequest);\n return {\n outcome: { outcome: \"selected\" as const, optionId: selectedOptionId },\n };\n },\n\n // ── File operations ──────────────────────────────────────────────────\n async readTextFile(params) {\n const content = await fs.promises.readFile(params.path, \"utf-8\");\n return { content };\n },\n\n async writeTextFile(params) {\n await fs.promises.mkdir(path.dirname(params.path), { recursive: true });\n await fs.promises.writeFile(params.path, params.content, \"utf-8\");\n return {};\n },\n\n // ── Terminal operations ──────────────────────────────────────────────\n async createTerminal(params) {\n const terminalId = randomUUID();\n const args = params.args ?? [];\n const env: Record<string, string> = {};\n for (const ev of params.env ?? []) {\n env[ev.name] = ev.value;\n }\n\n const childProcess = spawn(params.command, args, {\n cwd: params.cwd ?? undefined,\n env: { ...process.env, ...env },\n shell: false,\n });\n\n const state: TerminalState = {\n process: childProcess,\n output: \"\",\n exitStatus: null,\n };\n self.terminals.set(terminalId, state);\n\n const outputByteLimit = params.outputByteLimit ?? MAX_OUTPUT_BYTES;\n\n const appendOutput = (chunk: string) => {\n state.output += chunk;\n // Truncate from the beginning if over limit\n const bytes = Buffer.byteLength(state.output, \"utf-8\");\n if (bytes > outputByteLimit) {\n // Find truncation point at character boundary\n const excess = bytes - outputByteLimit;\n state.output = state.output.slice(excess);\n }\n };\n\n childProcess.stdout?.on(\"data\", (chunk: Buffer) =>\n appendOutput(chunk.toString()),\n );\n childProcess.stderr?.on(\"data\", (chunk: Buffer) =>\n appendOutput(chunk.toString()),\n );\n\n childProcess.on(\"exit\", (code, signal) => {\n state.exitStatus = { exitCode: code, signal };\n });\n\n return { terminalId };\n },\n\n async terminalOutput(params) {\n const state = self.terminals.get(params.terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`);\n }\n return {\n output: state.output,\n truncated: false,\n exitStatus: state.exitStatus\n ? {\n exitCode: state.exitStatus.exitCode,\n signal: state.exitStatus.signal,\n }\n : undefined,\n };\n },\n\n async waitForTerminalExit(params) {\n const state = self.terminals.get(params.terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`);\n }\n if (state.exitStatus !== null) {\n return {\n exitCode: state.exitStatus.exitCode,\n signal: state.exitStatus.signal,\n };\n }\n return new Promise((resolve) => {\n state.process.on(\"exit\", (code, signal) => {\n resolve({ exitCode: code, signal });\n });\n });\n },\n\n async killTerminal(params) {\n const state = self.terminals.get(params.terminalId);\n if (!state) {\n throw new Error(`Terminal not found: ${params.terminalId}`);\n }\n state.process.kill(\"SIGTERM\");\n return {};\n },\n\n async releaseTerminal(params) {\n const state = self.terminals.get(params.terminalId);\n if (!state) {\n return;\n }\n state.process.kill(\"SIGKILL\");\n self.terminals.delete(params.terminalId);\n },\n };\n }\n\n async prompt(text: string, attachments?: Attachment[]): Promise<PromptResponse> {\n const contentBlocks: Array<Record<string, unknown>> = [{ type: \"text\", text }];\n\n // MIME types supported by Claude API for base64 image content\n const SUPPORTED_IMAGE_MIMES = new Set([\"image/jpeg\", \"image/png\", \"image/gif\", \"image/webp\"]);\n\n for (const att of attachments ?? []) {\n const tooLarge = att.size > 10 * 1024 * 1024; // 10MB base64 guard\n\n if (att.type === \"image\" && this.promptCapabilities?.image && !tooLarge && SUPPORTED_IMAGE_MIMES.has(att.mimeType)) {\n const data = await fs.promises.readFile(att.filePath);\n contentBlocks.push({ type: \"image\", data: data.toString(\"base64\"), mimeType: att.mimeType });\n } else if (att.type === \"audio\" && this.promptCapabilities?.audio && !tooLarge) {\n const data = await fs.promises.readFile(att.filePath);\n contentBlocks.push({ type: \"audio\", data: data.toString(\"base64\"), mimeType: att.mimeType });\n } else {\n // Fallback: append file path to text so agent can read from disk\n if ((att.type === \"image\" || att.type === \"audio\") && !tooLarge) {\n log.debug(\n { type: att.type, capabilities: this.promptCapabilities ?? {} },\n \"Agent does not support %s content, falling back to file path\",\n att.type,\n );\n }\n (contentBlocks[0] as { text: string }).text += `\\n\\n[Attached file: ${att.filePath}]`;\n }\n }\n\n return this.connection.prompt({\n sessionId: this.sessionId,\n prompt: contentBlocks as any,\n });\n }\n\n async cancel(): Promise<void> {\n await this.connection.cancel({ sessionId: this.sessionId });\n }\n\n async destroy(): Promise<void> {\n // Cleanup terminals\n for (const [, t] of this.terminals) {\n t.process.kill(\"SIGKILL\");\n }\n this.terminals.clear();\n\n // Kill agent subprocess\n this.child.kill(\"SIGTERM\");\n setTimeout(() => {\n if (!this.child.killed) this.child.kill(\"SIGKILL\");\n }, 10_000);\n }\n}\n","import type { AgentDefinition } from \"./types.js\";\nimport { AgentInstance } from \"./agent-instance.js\";\nimport type { AgentCatalog } from \"./agent-catalog.js\";\n\nexport class AgentManager {\n constructor(private catalog: AgentCatalog) {}\n\n getAvailableAgents(): AgentDefinition[] {\n const installed = this.catalog.getInstalledEntries();\n return Object.entries(installed).map(([key, agent]) => ({\n name: key,\n command: agent.command,\n args: agent.args,\n env: agent.env,\n }));\n }\n\n getAgent(name: string): AgentDefinition | undefined {\n return this.catalog.resolve(name);\n }\n\n async spawn(\n agentName: string,\n workingDirectory: string,\n ): Promise<AgentInstance> {\n const agentDef = this.getAgent(agentName);\n if (!agentDef) throw new Error(`Agent \"${agentName}\" is not installed. Run \"openacp agents install ${agentName}\" to add it.`);\n return AgentInstance.spawn(agentDef, workingDirectory);\n }\n\n async resume(\n agentName: string,\n workingDirectory: string,\n agentSessionId: string,\n ): Promise<AgentInstance> {\n const agentDef = this.getAgent(agentName);\n if (!agentDef) throw new Error(`Agent \"${agentName}\" is not installed. Run \"openacp agents install ${agentName}\" to add it.`);\n return AgentInstance.resume(agentDef, workingDirectory, agentSessionId);\n }\n}\n","import type { Attachment } from './types.js'\n\n/**\n * Serial prompt queue — ensures prompts are processed one at a time.\n */\nexport class PromptQueue {\n private queue: Array<{ text: string; attachments?: Attachment[]; resolve: () => void }> = []\n private processing = false\n private abortController: AbortController | null = null\n\n constructor(\n private processor: (text: string, attachments?: Attachment[]) => Promise<void>,\n private onError?: (err: unknown) => void,\n ) {}\n\n async enqueue(text: string, attachments?: Attachment[]): Promise<void> {\n if (this.processing) {\n return new Promise<void>((resolve) => {\n this.queue.push({ text, attachments, resolve })\n })\n }\n await this.process(text, attachments)\n }\n\n private async process(text: string, attachments?: Attachment[]): Promise<void> {\n this.processing = true\n this.abortController = new AbortController()\n const { signal } = this.abortController\n try {\n await Promise.race([\n this.processor(text, attachments),\n new Promise<never>((_, reject) => {\n signal.addEventListener('abort', () => reject(new Error('Prompt aborted')), { once: true })\n }),\n ])\n } catch (err) {\n // Only forward non-abort errors to onError handler\n if (!(err instanceof Error && err.message === 'Prompt aborted')) {\n this.onError?.(err)\n }\n } finally {\n this.abortController = null\n this.processing = false\n this.drainNext()\n }\n }\n\n private drainNext(): void {\n const next = this.queue.shift()\n if (next) {\n this.process(next.text, next.attachments).then(next.resolve)\n }\n }\n\n clear(): void {\n // Abort the currently running prompt so the queue can drain\n if (this.abortController) {\n this.abortController.abort()\n }\n // Resolve pending promises so callers don't hang\n for (const item of this.queue) {\n item.resolve()\n }\n this.queue = []\n }\n\n get pending(): number {\n return this.queue.length\n }\n\n get isProcessing(): boolean {\n return this.processing\n }\n}\n","import type { PermissionRequest } from \"./types.js\";\n\nconst DEFAULT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n\n/**\n * Encapsulates pending permission state with a typed Promise API.\n */\nexport class PermissionGate {\n private request?: PermissionRequest;\n private resolveFn?: (optionId: string) => void;\n private rejectFn?: (reason: Error) => void;\n private settled = false;\n private timeoutTimer?: ReturnType<typeof setTimeout>;\n private timeoutMs: number;\n\n constructor(timeoutMs?: number) {\n this.timeoutMs = timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n setPending(request: PermissionRequest): Promise<string> {\n this.request = request;\n this.settled = false;\n this.clearTimeout();\n\n return new Promise<string>((resolve, reject) => {\n this.resolveFn = resolve;\n this.rejectFn = reject;\n\n this.timeoutTimer = setTimeout(() => {\n this.reject(\"Permission request timed out (no response received)\");\n }, this.timeoutMs);\n });\n }\n\n resolve(optionId: string): void {\n if (this.settled || !this.resolveFn) return;\n this.settled = true;\n this.clearTimeout();\n this.resolveFn(optionId);\n this.cleanup();\n }\n\n reject(reason?: string): void {\n if (this.settled || !this.rejectFn) return;\n this.settled = true;\n this.clearTimeout();\n this.rejectFn(new Error(reason ?? \"Permission rejected\"));\n this.cleanup();\n }\n\n get isPending(): boolean {\n return !!this.request && !this.settled;\n }\n\n get currentRequest(): PermissionRequest | undefined {\n return this.isPending ? this.request : undefined;\n }\n\n /** The request ID of the current pending request, undefined after settlement */\n get requestId(): string | undefined {\n return this.request?.id;\n }\n\n private clearTimeout(): void {\n if (this.timeoutTimer) {\n clearTimeout(this.timeoutTimer);\n this.timeoutTimer = undefined;\n }\n }\n\n private cleanup(): void {\n this.request = undefined;\n this.resolveFn = undefined;\n this.rejectFn = undefined;\n }\n}\n","import { nanoid } from \"nanoid\";\nimport type { AgentInstance } from \"./agent-instance.js\";\nimport type { AgentEvent, Attachment, PermissionRequest, SessionStatus } from \"./types.js\";\nimport { TypedEmitter } from \"./typed-emitter.js\";\nimport { PromptQueue } from \"./prompt-queue.js\";\nimport { PermissionGate } from \"./permission-gate.js\";\nimport { createChildLogger, createSessionLogger, type Logger } from \"./log.js\";\nimport type { SpeechService } from \"./speech/index.js\";\nimport * as fs from \"node:fs\";\nconst moduleLog = createChildLogger({ module: \"session\" });\n\n// TTS constants\nexport const TTS_PROMPT_INSTRUCTION = `\\n\\nAdditionally, include a [TTS]...[/TTS] block with a spoken-friendly summary of your response. Focus on key information, decisions the user needs to make, or actions required. The agent decides what to say and how long. Respond in the same language the user is using. This instruction applies to this message only.`;\nexport const TTS_BLOCK_REGEX = /\\[TTS\\]([\\s\\S]*?)\\[\\/TTS\\]/;\nexport const TTS_MAX_LENGTH = 5000;\nexport const TTS_TIMEOUT_MS = 30_000;\n\n// Valid state transitions: from → Set<to>\nconst VALID_TRANSITIONS: Record<SessionStatus, Set<SessionStatus>> = {\n initializing: new Set([\"active\", \"error\"]),\n active: new Set([\"error\", \"finished\", \"cancelled\"]),\n error: new Set([\"active\"]),\n cancelled: new Set([\"active\"]),\n finished: new Set(),\n};\n\nexport interface SessionEvents {\n agent_event: (event: AgentEvent) => void;\n permission_request: (request: PermissionRequest) => void;\n session_end: (reason: string) => void;\n status_change: (from: SessionStatus, to: SessionStatus) => void;\n named: (name: string) => void;\n error: (error: Error) => void;\n}\n\nexport class Session extends TypedEmitter<SessionEvents> {\n id: string;\n channelId: string;\n threadId: string = \"\";\n agentName: string;\n workingDirectory: string;\n agentInstance: AgentInstance;\n agentSessionId: string = \"\";\n private _status: SessionStatus = \"initializing\";\n name?: string;\n createdAt: Date = new Date();\n voiceMode: \"off\" | \"next\" | \"on\" = \"off\";\n dangerousMode: boolean = false;\n archiving: boolean = false;\n promptCount: number = 0;\n log: Logger;\n\n readonly permissionGate = new PermissionGate();\n private readonly queue: PromptQueue;\n private speechService?: SpeechService;\n private pendingContext: string | null = null;\n\n constructor(opts: {\n id?: string;\n channelId: string;\n agentName: string;\n workingDirectory: string;\n agentInstance: AgentInstance;\n speechService?: SpeechService;\n }) {\n super();\n this.id = opts.id || nanoid(12);\n this.channelId = opts.channelId;\n this.agentName = opts.agentName;\n this.workingDirectory = opts.workingDirectory;\n this.agentInstance = opts.agentInstance;\n this.speechService = opts.speechService;\n this.log = createSessionLogger(this.id, moduleLog);\n this.log.info({ agentName: this.agentName }, \"Session created\");\n\n this.queue = new PromptQueue(\n (text, attachments) => this.processPrompt(text, attachments),\n (err) => {\n this.fail(\"Prompt execution failed\");\n this.log.error({ err }, \"Prompt execution failed\");\n },\n );\n }\n\n // --- State Machine ---\n\n get status(): SessionStatus {\n return this._status;\n }\n\n\n /** Transition to active — from initializing, error, or cancelled */\n activate(): void {\n this.transition(\"active\");\n }\n\n /** Transition to error — from initializing or active */\n fail(reason: string): void {\n this.transition(\"error\");\n this.emit(\"error\", new Error(reason));\n }\n\n /** Transition to finished — from active only. Emits session_end for backward compat. */\n finish(reason?: string): void {\n this.transition(\"finished\");\n this.emit(\"session_end\", reason ?? \"completed\");\n }\n\n /** Transition to cancelled — from active only (terminal session cancel) */\n markCancelled(): void {\n this.transition(\"cancelled\");\n }\n\n private transition(to: SessionStatus): void {\n const from = this._status;\n const allowed = VALID_TRANSITIONS[from];\n if (!allowed?.has(to)) {\n throw new Error(\n `Invalid session transition: ${from} → ${to}`,\n );\n }\n this._status = to;\n this.log.debug({ from, to }, \"Session status transition\");\n this.emit(\"status_change\", from, to);\n }\n\n /** Number of prompts waiting in queue */\n get queueDepth(): number {\n return this.queue.pending;\n }\n\n get promptRunning(): boolean {\n return this.queue.isProcessing;\n }\n\n // --- Context Injection ---\n\n setContext(markdown: string): void {\n this.pendingContext = markdown;\n }\n\n // --- Voice Mode ---\n\n setVoiceMode(mode: \"off\" | \"next\" | \"on\"): void {\n this.voiceMode = mode;\n this.log.info({ voiceMode: mode }, \"TTS mode changed\");\n }\n\n // --- Public API ---\n\n async enqueuePrompt(text: string, attachments?: Attachment[]): Promise<void> {\n await this.queue.enqueue(text, attachments);\n }\n\n private async processPrompt(text: string, attachments?: Attachment[]): Promise<void> {\n if (text === \"\\x00__warmup__\") {\n await this.runWarmup();\n return;\n }\n\n this.promptCount++;\n\n if (this._status === \"initializing\") {\n this.activate();\n }\n const promptStart = Date.now();\n this.log.debug(\"Prompt execution started\");\n\n // Context injection: prepend on first real prompt only\n if (this.pendingContext) {\n text = `[CONVERSATION HISTORY - This is context from previous sessions, not current conversation]\\n\\n${this.pendingContext}\\n\\n[END CONVERSATION HISTORY]\\n\\n${text}`;\n this.pendingContext = null;\n this.log.debug(\"Context injected into prompt\");\n }\n\n // STT: transcribe audio attachments if agent doesn't support audio\n const processed = await this.maybeTranscribeAudio(text, attachments);\n\n // TTS: determine if TTS is active for this prompt\n const ttsActive =\n this.voiceMode !== \"off\" &&\n !!this.speechService?.isTTSAvailable();\n\n // TTS: inject prompt instruction\n if (ttsActive) {\n processed.text += TTS_PROMPT_INSTRUCTION;\n if (this.voiceMode === \"next\") {\n this.voiceMode = \"off\";\n }\n }\n\n // TTS: set up text accumulator before prompting\n let accumulatedText = \"\";\n const accumulatorListener = ttsActive\n ? (event: AgentEvent) => {\n if (event.type === \"text\") {\n accumulatedText += event.content;\n }\n }\n : null;\n\n if (accumulatorListener) {\n this.on(\"agent_event\", accumulatorListener);\n }\n\n try {\n await this.agentInstance.prompt(processed.text, processed.attachments);\n } finally {\n if (accumulatorListener) {\n this.off(\"agent_event\", accumulatorListener);\n }\n }\n\n this.log.info(\n { durationMs: Date.now() - promptStart },\n \"Prompt execution completed\",\n );\n\n // TTS: fire-and-forget post-response synthesis\n if (ttsActive && accumulatedText) {\n this.processTTSResponse(accumulatedText).catch((err) => {\n this.log.warn({ err }, \"TTS post-processing failed\");\n });\n }\n\n if (!this.name) {\n await this.autoName();\n }\n }\n\n private async maybeTranscribeAudio(\n text: string,\n attachments?: Attachment[],\n ): Promise<{ text: string; attachments?: Attachment[] }> {\n if (!attachments?.length || !this.speechService) {\n return { text, attachments };\n }\n\n const hasAudioCapability = this.agentInstance.promptCapabilities?.audio === true;\n if (hasAudioCapability) {\n return { text, attachments };\n }\n\n if (!this.speechService.isSTTAvailable()) {\n return { text, attachments };\n }\n\n let transcribedText = text;\n const remainingAttachments: Attachment[] = [];\n\n for (const att of attachments) {\n if (att.type !== \"audio\") {\n remainingAttachments.push(att);\n continue;\n }\n\n try {\n const audioPath = att.originalFilePath || att.filePath;\n const audioMime = att.originalFilePath ? \"audio/ogg\" : att.mimeType;\n const audioBuffer = await fs.promises.readFile(audioPath);\n const result = await this.speechService.transcribe(audioBuffer, audioMime);\n this.log.info({ provider: \"stt\", duration: result.duration }, \"Voice transcribed\");\n // Notify user of transcription result\n this.emit(\"agent_event\", {\n type: \"system_message\",\n message: `🎤 You said: ${result.text}`,\n });\n // Strip [Audio: ...] placeholder since we have the transcription\n transcribedText = transcribedText.replace(/\\[Audio:\\s*[^\\]]*\\]\\s*/g, \"\").trim();\n transcribedText = transcribedText\n ? `${transcribedText}\\n${result.text}`\n : result.text;\n } catch (err) {\n this.log.warn({ err }, \"STT transcription failed, keeping audio attachment\");\n this.emit(\"agent_event\", {\n type: \"error\",\n message: `Voice transcription failed: ${(err as Error).message}`,\n });\n remainingAttachments.push(att);\n }\n }\n\n return {\n text: transcribedText,\n attachments: remainingAttachments.length > 0 ? remainingAttachments : undefined,\n };\n }\n\n private async processTTSResponse(responseText: string): Promise<void> {\n const match = TTS_BLOCK_REGEX.exec(responseText);\n if (!match?.[1]) {\n this.log.debug(\"No [TTS] block found in response, skipping synthesis\");\n return;\n }\n\n let ttsText = match[1].trim();\n if (!ttsText) return;\n\n if (ttsText.length > TTS_MAX_LENGTH) {\n ttsText = ttsText.slice(0, TTS_MAX_LENGTH);\n }\n\n try {\n const timeoutPromise = new Promise<never>((_, reject) =>\n setTimeout(() => reject(new Error(\"TTS synthesis timed out\")), TTS_TIMEOUT_MS),\n );\n const result = await Promise.race([\n this.speechService!.synthesize(ttsText),\n timeoutPromise,\n ]);\n const base64 = result.audioBuffer.toString(\"base64\");\n this.emit(\"agent_event\", {\n type: \"audio_content\",\n data: base64,\n mimeType: result.mimeType,\n });\n this.log.info(\"TTS synthesis completed\");\n } catch (err) {\n this.log.warn({ err }, \"TTS synthesis failed, skipping\");\n }\n }\n\n // NOTE: This injects a summary prompt into the agent's conversation history.\n private async autoName(): Promise<void> {\n let title = \"\";\n\n // Temporarily remove all agent_event listeners so auto-name output\n // is not forwarded to the adapter. Add a capture-only listener instead.\n const captureHandler = (event: AgentEvent) => {\n if (event.type === \"text\") title += event.content;\n // Swallow all other events from auto-name prompt\n };\n\n // Pause the session emitter so agent_event emissions from SessionBridge\n // don't reach the adapter during auto-name. The AgentInstance emitter\n // stays active — we just intercept with our capture handler.\n this.pause((event) => event !== \"agent_event\");\n this.agentInstance.on(\"agent_event\", captureHandler);\n\n try {\n await this.agentInstance.prompt(\n \"Summarize this conversation in max 5 words for a topic title. Reply ONLY with the title, nothing else.\",\n );\n this.name = title.trim().slice(0, 50) || `Session ${this.id.slice(0, 6)}`;\n this.log.info({ name: this.name }, \"Session auto-named\");\n\n // Emit named event — SessionBridge listens to rename the thread\n this.emit(\"named\", this.name);\n } catch {\n this.name = `Session ${this.id.slice(0, 6)}`;\n } finally {\n this.agentInstance.off(\"agent_event\", captureHandler);\n // Discard buffered auto-name agent_events, then resume normal delivery\n this.clearBuffer();\n this.resume();\n }\n }\n\n async generateSummary(timeoutMs = 15000): Promise<string> {\n let summary = \"\";\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const captureHandler = (event: AgentEvent) => {\n if (event.type === \"text\") summary += event.content;\n };\n\n this.pause((event) => event !== \"agent_event\");\n this.agentInstance.on(\"agent_event\", captureHandler);\n\n try {\n const promptPromise = this.agentInstance.prompt(\n \"Summarize what you've accomplished so far in this session in 2-3 sentences. Include: key files changed, decisions made, and current status. Reply ONLY with the summary, nothing else.\",\n );\n const timeoutPromise = new Promise<void>((_, reject) => {\n timer = setTimeout(() => reject(new Error(\"summary timeout\")), timeoutMs);\n });\n await Promise.race([promptPromise, timeoutPromise]);\n return summary.trim().slice(0, 500);\n } catch {\n this.log.warn(\"Failed to generate session summary\");\n return \"\";\n } finally {\n if (timer) clearTimeout(timer);\n this.agentInstance.off(\"agent_event\", captureHandler);\n this.clearBuffer();\n this.resume();\n }\n }\n\n /** Fire-and-forget warm-up: primes model cache while user types their first message */\n async warmup(): Promise<void> {\n // Route through PromptQueue to prevent concurrent prompt execution.\n // Any user prompts arriving during warmup will be queued and drained after.\n await this.queue.enqueue(\"\\x00__warmup__\");\n }\n\n private async runWarmup(): Promise<void> {\n // Pause events but let commands_update pass through\n this.pause((_event, args) => {\n const agentEvent = args[0] as AgentEvent;\n return agentEvent?.type === \"commands_update\";\n });\n\n try {\n const start = Date.now();\n await this.agentInstance.prompt('Reply with only \"ready\".');\n this.activate();\n this.log.info({ durationMs: Date.now() - start }, \"Warm-up complete\");\n } catch (err) {\n this.log.error({ err }, \"Warm-up failed\");\n } finally {\n this.clearBuffer();\n this.resume();\n }\n }\n\n /** Cancel the current prompt and clear the queue. Stays in active state. */\n async abortPrompt(): Promise<void> {\n this.queue.clear();\n this.log.info(\"Prompt aborted\");\n await this.agentInstance.cancel();\n }\n\n async destroy(): Promise<void> {\n this.log.info(\"Session destroyed\");\n await this.agentInstance.destroy();\n }\n}\n","import type { AgentManager } from \"./agent-manager.js\";\nimport { Session } from \"./session.js\";\nimport type { SessionStore } from \"./session-store.js\";\nimport type { EventBus } from \"./event-bus.js\";\n\nexport class SessionManager {\n private sessions: Map<string, Session> = new Map();\n private store: SessionStore | null;\n private eventBus?: EventBus;\n\n setEventBus(eventBus: EventBus): void {\n this.eventBus = eventBus;\n }\n\n constructor(store: SessionStore | null = null) {\n this.store = store;\n }\n\n async createSession(\n channelId: string,\n agentName: string,\n workingDirectory: string,\n agentManager: AgentManager,\n ): Promise<Session> {\n const agentInstance = await agentManager.spawn(agentName, workingDirectory);\n const session = new Session({\n channelId,\n agentName,\n workingDirectory,\n agentInstance,\n });\n this.sessions.set(session.id, session);\n session.agentSessionId = session.agentInstance.sessionId;\n\n if (this.store) {\n await this.store.save({\n sessionId: session.id,\n agentSessionId: session.agentInstance.sessionId,\n agentName: session.agentName,\n workingDir: session.workingDirectory,\n channelId,\n status: session.status,\n createdAt: session.createdAt.toISOString(),\n lastActiveAt: new Date().toISOString(),\n name: session.name,\n dangerousMode: false,\n platform: {},\n });\n }\n\n return session;\n }\n\n getSession(sessionId: string): Session | undefined {\n return this.sessions.get(sessionId);\n }\n\n getSessionByThread(channelId: string, threadId: string): Session | undefined {\n for (const session of this.sessions.values()) {\n if (session.channelId === channelId && session.threadId === threadId) {\n return session;\n }\n }\n return undefined;\n }\n\n getSessionByAgentSessionId(agentSessionId: string): Session | undefined {\n for (const session of this.sessions.values()) {\n if (session.agentSessionId === agentSessionId) {\n return session;\n }\n }\n return undefined;\n }\n\n getRecordByAgentSessionId(\n agentSessionId: string,\n ): import(\"./types.js\").SessionRecord | undefined {\n return this.store?.findByAgentSessionId(agentSessionId);\n }\n\n getRecordByThread(\n channelId: string,\n threadId: string,\n ): import(\"./types.js\").SessionRecord | undefined {\n return this.store?.findByPlatform(\n channelId,\n (p) => String(p.topicId) === threadId || p.threadId === threadId,\n );\n }\n\n registerSession(session: Session): void {\n this.sessions.set(session.id, session);\n }\n\n async patchRecord(\n sessionId: string,\n patch: Partial<import(\"./types.js\").SessionRecord>,\n ): Promise<void> {\n if (!this.store) return;\n const record = this.store.get(sessionId);\n if (record) {\n await this.store.save({ ...record, ...patch });\n } else if (patch.sessionId) {\n // Initial save — treat patch as full record\n await this.store.save(patch as import(\"./types.js\").SessionRecord);\n }\n }\n\n getSessionRecord(\n sessionId: string,\n ): import(\"./types.js\").SessionRecord | undefined {\n return this.store?.get(sessionId);\n }\n\n async cancelSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (session) {\n await session.abortPrompt();\n session.markCancelled();\n }\n if (this.store) {\n const record = this.store.get(sessionId);\n if (record && record.status !== \"cancelled\") {\n await this.store.save({ ...record, status: \"cancelled\" });\n }\n }\n }\n\n listSessions(channelId?: string): Session[] {\n const all = Array.from(this.sessions.values());\n if (channelId) return all.filter((s) => s.channelId === channelId);\n return all;\n }\n\n listRecords(filter?: {\n statuses?: string[];\n }): import(\"./types.js\").SessionRecord[] {\n if (!this.store) return [];\n let records = this.store.list();\n if (filter?.statuses?.length) {\n records = records.filter((r) => filter.statuses!.includes(r.status));\n }\n return records;\n }\n\n async removeRecord(sessionId: string): Promise<void> {\n if (!this.store) return;\n await this.store.remove(sessionId);\n this.eventBus?.emit(\"session:deleted\", { sessionId });\n }\n\n async destroyAll(): Promise<void> {\n if (this.store) {\n for (const session of this.sessions.values()) {\n const record = this.store.get(session.id);\n if (record) {\n await this.store.save({ ...record, status: \"finished\" });\n }\n }\n }\n for (const session of this.sessions.values()) {\n await session.destroy();\n }\n this.sessions.clear();\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { OggOpusDecoder } from \"ogg-opus-decoder\";\nimport wav from \"node-wav\";\nimport type { Attachment } from \"./types.js\";\n\nconst MIME_TO_EXT: Record<string, string> = {\n \"image/jpeg\": \".jpg\",\n \"image/png\": \".png\",\n \"image/gif\": \".gif\",\n \"image/webp\": \".webp\",\n \"image/svg+xml\": \".svg\",\n \"audio/ogg\": \".ogg\",\n \"audio/mpeg\": \".mp3\",\n \"audio/wav\": \".wav\",\n \"audio/webm\": \".webm\",\n \"audio/mp4\": \".m4a\",\n \"video/mp4\": \".mp4\",\n \"video/webm\": \".webm\",\n \"application/pdf\": \".pdf\",\n \"text/plain\": \".txt\",\n};\n\nconst EXT_TO_MIME: Record<string, string> = {\n \".jpg\": \"image/jpeg\",\n \".jpeg\": \"image/jpeg\",\n \".png\": \"image/png\",\n \".gif\": \"image/gif\",\n \".webp\": \"image/webp\",\n \".svg\": \"image/svg+xml\",\n \".ogg\": \"audio/ogg\",\n \".oga\": \"audio/ogg\",\n \".mp3\": \"audio/mpeg\",\n \".wav\": \"audio/wav\",\n \".m4a\": \"audio/mp4\",\n \".mp4\": \"video/mp4\",\n \".pdf\": \"application/pdf\",\n \".txt\": \"text/plain\",\n};\n\nfunction classifyMime(mimeType: string): Attachment[\"type\"] {\n if (mimeType.startsWith(\"image/\")) return \"image\";\n if (mimeType.startsWith(\"audio/\")) return \"audio\";\n return \"file\";\n}\n\nexport class FileService {\n constructor(private baseDir: string) {}\n\n async saveFile(\n sessionId: string,\n fileName: string,\n data: Buffer,\n mimeType: string,\n ): Promise<Attachment> {\n const sessionDir = path.join(this.baseDir, sessionId);\n await fs.promises.mkdir(sessionDir, { recursive: true });\n\n const safeName = `${Date.now()}-${fileName.replace(/[^a-zA-Z0-9._-]/g, \"_\")}`;\n const filePath = path.join(sessionDir, safeName);\n await fs.promises.writeFile(filePath, data);\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName,\n mimeType,\n size: data.length,\n };\n }\n\n async resolveFile(filePath: string): Promise<Attachment | null> {\n try {\n const stat = await fs.promises.stat(filePath);\n if (!stat.isFile()) return null;\n\n const ext = path.extname(filePath).toLowerCase();\n const mimeType = EXT_TO_MIME[ext] || \"application/octet-stream\";\n\n return {\n type: classifyMime(mimeType),\n filePath,\n fileName: path.basename(filePath),\n mimeType,\n size: stat.size,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Convert OGG Opus audio to WAV format.\n * Telegram voice messages use OGG Opus which many AI agents can't read.\n */\n async convertOggToWav(oggData: Buffer): Promise<Buffer> {\n const decoder = new OggOpusDecoder();\n await decoder.ready;\n try {\n const { channelData, sampleRate } = await decoder.decode(new Uint8Array(oggData));\n const wavData = wav.encode(channelData, { sampleRate, float: true, bitDepth: 32 });\n return Buffer.from(wavData);\n } finally {\n decoder.free();\n }\n }\n\n static extensionFromMime(mimeType: string): string {\n return MIME_TO_EXT[mimeType] || \".bin\";\n }\n}\n","import type { Session } from \"./session.js\";\nimport type { ChannelAdapter } from \"./channel.js\";\nimport type { MessageTransformer } from \"./message-transformer.js\";\nimport type { NotificationManager } from \"./notification.js\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { AgentEvent, PermissionRequest, SessionStatus } from \"./types.js\";\nimport type { EventBus } from \"./event-bus.js\";\nimport { FileService } from \"./file-service.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"session-bridge\" });\n\nexport interface BridgeDeps {\n messageTransformer: MessageTransformer;\n notificationManager: NotificationManager;\n sessionManager: SessionManager;\n eventBus?: EventBus;\n fileService?: FileService;\n}\n\nexport class SessionBridge {\n private connected = false;\n private agentEventHandler?: (event: AgentEvent) => void;\n private sessionEventHandler?: (event: AgentEvent) => void;\n private statusChangeHandler?: (\n from: SessionStatus,\n to: SessionStatus,\n ) => void;\n private namedHandler?: (name: string) => void;\n\n constructor(\n private session: Session,\n private adapter: ChannelAdapter,\n private deps: BridgeDeps,\n ) {}\n\n connect(): void {\n if (this.connected) return;\n this.connected = true;\n\n this.wireAgentToSession();\n this.wireSessionToAdapter();\n this.wirePermissions();\n this.wireLifecycle();\n }\n\n disconnect(): void {\n if (!this.connected) return;\n this.connected = false;\n\n if (this.agentEventHandler) {\n this.session.agentInstance.off(\"agent_event\", this.agentEventHandler);\n }\n if (this.sessionEventHandler) {\n this.session.off(\"agent_event\", this.sessionEventHandler);\n }\n if (this.statusChangeHandler) {\n this.session.off(\"status_change\", this.statusChangeHandler);\n }\n if (this.namedHandler) {\n this.session.off(\"named\", this.namedHandler);\n }\n\n // Reset agent callbacks to no-op\n this.session.agentInstance.onPermissionRequest = async () => \"\";\n }\n\n private wireAgentToSession(): void {\n this.agentEventHandler = (event: AgentEvent) => {\n this.session.emit(\"agent_event\", event);\n };\n this.session.agentInstance.on(\"agent_event\", this.agentEventHandler);\n }\n\n private wireSessionToAdapter(): void {\n const session = this.session;\n const ctx = {\n get id() {\n return session.id;\n },\n get workingDirectory() {\n return session.workingDirectory;\n },\n };\n\n this.sessionEventHandler = (event: AgentEvent) => {\n switch (event.type) {\n case \"text\":\n case \"thought\":\n case \"tool_call\":\n case \"tool_update\":\n case \"plan\":\n case \"usage\":\n this.adapter.sendMessage(\n this.session.id,\n this.deps.messageTransformer.transform(event, ctx),\n );\n break;\n\n case \"session_end\":\n this.session.finish(event.reason);\n this.adapter.cleanupSkillCommands(this.session.id);\n this.adapter.sendMessage(\n this.session.id,\n this.deps.messageTransformer.transform(event),\n );\n this.deps.notificationManager.notify(this.session.channelId, {\n sessionId: this.session.id,\n sessionName: this.session.name,\n type: \"completed\",\n summary: `Session \"${this.session.name || this.session.id}\" completed\\n⏱ ${Math.round((Date.now() - this.session.createdAt.getTime()) / 60000)} min · 💬 ${this.session.promptCount} prompts`,\n });\n break;\n\n case \"error\":\n this.session.fail(event.message);\n this.adapter.cleanupSkillCommands(this.session.id);\n this.adapter.sendMessage(\n this.session.id,\n this.deps.messageTransformer.transform(event),\n );\n this.deps.notificationManager.notify(this.session.channelId, {\n sessionId: this.session.id,\n sessionName: this.session.name,\n type: \"error\",\n summary: event.message,\n });\n break;\n\n case \"image_content\": {\n if (this.deps.fileService) {\n const fs = this.deps.fileService;\n const sid = this.session.id;\n const { data, mimeType } = event;\n const buffer = Buffer.from(data, \"base64\");\n const ext = FileService.extensionFromMime(mimeType);\n fs.saveFile(sid, `agent-image${ext}`, buffer, mimeType)\n .then((att) => {\n this.adapter.sendMessage(sid, {\n type: \"attachment\",\n text: \"\",\n attachment: att,\n });\n })\n .catch((err) => log.error({ err }, \"Failed to save agent image\"));\n }\n break;\n }\n case \"audio_content\": {\n if (this.deps.fileService) {\n const fs = this.deps.fileService;\n const sid = this.session.id;\n const { data, mimeType } = event;\n const buffer = Buffer.from(data, \"base64\");\n const ext = FileService.extensionFromMime(mimeType);\n fs.saveFile(sid, `agent-audio${ext}`, buffer, mimeType)\n .then((att) => {\n this.adapter.sendMessage(sid, {\n type: \"attachment\",\n text: \"\",\n attachment: att,\n });\n })\n .catch((err) => log.error({ err }, \"Failed to save agent audio\"));\n }\n break;\n }\n\n case \"commands_update\":\n log.debug({ commands: event.commands }, \"Commands available\");\n this.adapter.sendSkillCommands(this.session.id, event.commands);\n break;\n\n case \"system_message\":\n this.adapter.sendMessage(\n this.session.id,\n this.deps.messageTransformer.transform(event),\n );\n break;\n }\n\n this.deps.eventBus?.emit(\"agent:event\", {\n sessionId: this.session.id,\n event,\n });\n };\n\n this.session.on(\"agent_event\", this.sessionEventHandler);\n }\n\n private wirePermissions(): void {\n this.session.agentInstance.onPermissionRequest = async (\n request: PermissionRequest,\n ) => {\n this.session.emit(\"permission_request\", request);\n this.deps.eventBus?.emit(\"permission:request\", {\n sessionId: this.session.id,\n permission: request,\n });\n\n // Auto-approve openacp CLI commands\n if (request.description.toLowerCase().includes(\"openacp\")) {\n const allowOption = request.options.find((o) => o.isAllow);\n if (allowOption) {\n log.info(\n { sessionId: this.session.id, requestId: request.id },\n \"Auto-approving openacp command\",\n );\n return allowOption.id;\n }\n }\n\n // Dangerous mode: auto-approve all permissions\n if (this.session.dangerousMode) {\n const allowOption = request.options.find((o) => o.isAllow);\n if (allowOption) {\n log.info(\n { sessionId: this.session.id, requestId: request.id, optionId: allowOption.id },\n \"Dangerous mode: auto-approving permission\",\n );\n return allowOption.id;\n }\n }\n\n // Set pending BEFORE sending UI to avoid race condition\n const promise = this.session.permissionGate.setPending(request);\n\n // Send permission UI to session topic\n await this.adapter.sendPermissionRequest(this.session.id, request);\n\n // Wait for user response — adapter resolves this promise\n return promise;\n };\n }\n\n private wireLifecycle(): void {\n // Persist status changes and auto-disconnect on terminal states\n this.statusChangeHandler = (from: SessionStatus, to: SessionStatus) => {\n this.deps.sessionManager.patchRecord(this.session.id, {\n status: to,\n lastActiveAt: new Date().toISOString(),\n });\n this.deps.eventBus?.emit(\"session:updated\", {\n sessionId: this.session.id,\n status: to,\n });\n\n // Auto-disconnect on terminal states\n if (to === \"finished\" || to === \"cancelled\") {\n // Disconnect on next tick so current event handlers can complete\n queueMicrotask(() => this.disconnect());\n }\n };\n this.session.on(\"status_change\", this.statusChangeHandler);\n\n // Persist and relay name changes\n this.namedHandler = (name: string) => {\n this.deps.sessionManager.patchRecord(this.session.id, { name });\n this.deps.eventBus?.emit(\"session:updated\", {\n sessionId: this.session.id,\n name,\n });\n this.adapter.renameSessionThread(this.session.id, name);\n };\n this.session.on(\"named\", this.namedHandler);\n }\n}\n","import type { ChannelAdapter } from './channel.js'\nimport type { NotificationMessage } from './types.js'\n\nexport class NotificationManager {\n constructor(private adapters: Map<string, ChannelAdapter>) {}\n\n async notify(channelId: string, notification: NotificationMessage): Promise<void> {\n const adapter = this.adapters.get(channelId)\n if (adapter) {\n await adapter.sendNotification(notification)\n }\n }\n\n async notifyAll(notification: NotificationMessage): Promise<void> {\n for (const adapter of this.adapters.values()) {\n await adapter.sendNotification(notification)\n }\n }\n}\n","export interface FileInfo {\n filePath: string\n content: string\n oldContent?: string\n}\n\n/**\n * Extract file path and content from ACP tool_call/tool_update content.\n *\n * ACP content formats observed:\n * - Diff block: [{ type: \"diff\", path: \"...\", oldText: \"...\", newText: \"...\" }]\n * - Content wrapper: [{ type: \"content\", content: { type: \"text\", text: \"...\" } }]\n * - Text block: { type: \"text\", text: \"...\" }\n * - rawInput: { file_path: \"...\", content: \"...\" }\n */\nexport function extractFileInfo(\n name: string,\n kind: string | undefined,\n content: unknown,\n rawInput?: unknown,\n meta?: unknown,\n): FileInfo | null {\n // Only process file-related tool kinds\n if (kind && !['read', 'edit', 'write'].includes(kind)) return null\n\n let info: Partial<FileInfo> | null = null\n\n // 1. Try _meta.claudeCode.toolResponse (Claude Code puts raw file data here)\n if (meta) {\n const m = meta as Record<string, unknown>\n const claudeCode = m?.claudeCode as Record<string, unknown> | undefined\n const tr = claudeCode?.toolResponse as Record<string, unknown> | undefined\n // Read tool: toolResponse.file.filePath + toolResponse.file.content\n const file = tr?.file as Record<string, unknown> | undefined\n if (typeof file?.filePath === 'string' && typeof file?.content === 'string') {\n info = { filePath: file.filePath, content: file.content }\n }\n // Write/Edit tool: toolResponse.filePath + toolResponse.content (direct)\n if (!info && typeof tr?.filePath === 'string' && typeof tr?.content === 'string') {\n info = { filePath: tr.filePath, content: tr.content }\n }\n }\n\n // 2. Try rawInput for file path + content from regular content\n if (!info && rawInput && typeof rawInput === 'object') {\n const ri = rawInput as Record<string, unknown>\n const filePath = ri?.file_path || ri?.filePath || ri?.path\n if (typeof filePath === 'string') {\n // Try to get content from the content field (including oldContent for diffs)\n const parsed = content ? parseContent(content) : null\n const riContent = typeof ri?.content === 'string' ? ri.content : undefined\n info = { filePath, content: parsed?.content || riContent, oldContent: parsed?.oldContent }\n }\n }\n\n // 3. Try to extract from known ACP content patterns\n if (!info && content) {\n info = parseContent(content)\n }\n\n if (!info) return null\n\n // Infer file path from tool name if not in content\n if (!info.filePath) {\n const pathMatch = name.match(/(?:Read|Edit|Write|View)\\s+(.+)/i)\n if (pathMatch) info.filePath = pathMatch[1].trim()\n }\n\n if (!info.filePath || !info.content) return null\n return info as FileInfo\n}\n\nfunction parseContent(content: unknown): Partial<FileInfo> | null {\n if (typeof content === 'string') {\n return { content }\n }\n\n if (Array.isArray(content)) {\n // Array of content blocks — try each\n for (const block of content) {\n const result = parseContent(block)\n if (result?.content || result?.filePath) return result\n }\n return null\n }\n\n if (typeof content === 'object' && content !== null) {\n const c = content as Record<string, unknown>\n\n // ACP diff block: { type: 'diff', path: '...', oldText: '...', newText: '...' }\n if (c.type === 'diff' && typeof c.path === 'string') {\n const newText = c.newText as string | null | undefined\n const oldText = c.oldText as string | null | undefined\n if (newText) {\n return {\n filePath: c.path as string,\n content: newText,\n oldContent: oldText ?? undefined,\n }\n }\n }\n\n // ACP content wrapper: { type: 'content', content: { type: 'text', text: '...' } }\n if (c.type === 'content' && c.content) {\n return parseContent(c.content)\n }\n\n // ACP text block: { type: 'text', text: '...' }\n if (c.type === 'text' && typeof c.text === 'string') {\n return { content: c.text, filePath: c.filePath as string | undefined }\n }\n\n // Direct fields\n if (typeof c.text === 'string') {\n return { content: c.text, filePath: c.filePath as string | undefined }\n }\n\n // Tool input with file path: { file_path: '...', content: '...' }\n if (typeof c.file_path === 'string' || typeof c.filePath === 'string' || typeof c.path === 'string') {\n const filePath = (c.file_path || c.filePath || c.path) as string\n const fileContent = (c.content || c.text || c.output || c.newText) as string | undefined\n if (typeof fileContent === 'string') {\n return {\n filePath,\n content: fileContent,\n oldContent: (c.old_content || c.oldText) as string | undefined,\n }\n }\n }\n\n // Nested input/output\n if (c.input) {\n const result = parseContent(c.input)\n if (result) return result\n }\n if (c.output) {\n const result = parseContent(c.output)\n if (result) return result\n }\n }\n\n return null\n}\n","import type { AgentEvent, OutgoingMessage } from \"./types.js\";\nimport type { TunnelService } from \"../tunnel/tunnel-service.js\";\nimport { extractFileInfo } from \"../tunnel/extract-file-info.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"message-transformer\" });\n\nexport class MessageTransformer {\n constructor(private tunnelService?: TunnelService) {}\n\n transform(\n event: AgentEvent,\n sessionContext?: { id: string; workingDirectory: string },\n ): OutgoingMessage {\n switch (event.type) {\n case \"text\":\n return { type: \"text\", text: event.content };\n case \"thought\":\n return { type: \"thought\", text: event.content };\n case \"tool_call\": {\n const meta = event.meta as Record<string, unknown> | undefined;\n const metadata: Record<string, unknown> = {\n id: event.id,\n name: event.name,\n kind: event.kind,\n status: event.status,\n content: event.content,\n locations: event.locations,\n rawInput: event.rawInput,\n displaySummary: meta?.displaySummary,\n displayTitle: meta?.displayTitle,\n displayKind: meta?.displayKind,\n };\n this.enrichWithViewerLinks(event, metadata, sessionContext);\n return { type: \"tool_call\", text: event.name, metadata };\n }\n case \"tool_update\": {\n const meta = event.meta as Record<string, unknown> | undefined;\n const metadata: Record<string, unknown> = {\n id: event.id,\n name: event.name,\n kind: event.kind,\n status: event.status,\n content: event.content,\n rawInput: event.rawInput,\n displaySummary: meta?.displaySummary,\n displayTitle: meta?.displayTitle,\n displayKind: meta?.displayKind,\n };\n this.enrichWithViewerLinks(event, metadata, sessionContext);\n return { type: \"tool_update\", text: \"\", metadata };\n }\n case \"plan\":\n return {\n type: \"plan\",\n text: \"\",\n metadata: { entries: event.entries },\n };\n case \"usage\":\n return {\n type: \"usage\",\n text: \"\",\n metadata: {\n tokensUsed: event.tokensUsed,\n contextSize: event.contextSize,\n cost: event.cost,\n },\n };\n case \"session_end\":\n return { type: \"session_end\", text: `Done (${event.reason})` };\n case \"error\":\n return { type: \"error\", text: event.message };\n case \"system_message\":\n return { type: \"system_message\", text: event.message };\n default:\n return { type: \"text\", text: \"\" };\n }\n }\n\n private enrichWithViewerLinks(\n event: AgentEvent & { type: \"tool_call\" | \"tool_update\" },\n metadata: Record<string, unknown>,\n sessionContext?: { id: string; workingDirectory: string },\n ): void {\n if (!this.tunnelService || !sessionContext) return;\n\n const name = \"name\" in event ? event.name || \"\" : \"\";\n const kind = \"kind\" in event ? event.kind : undefined;\n\n log.debug(\n { name, kind, status: event.status, hasContent: !!event.content },\n \"enrichWithViewerLinks: inspecting event\",\n );\n\n const fileInfo = extractFileInfo(\n name,\n kind,\n event.content,\n event.rawInput,\n event.meta,\n );\n if (!fileInfo) return;\n\n log.info(\n {\n name,\n kind,\n filePath: fileInfo.filePath,\n hasOldContent: !!fileInfo.oldContent,\n },\n \"enrichWithViewerLinks: extracted file info\",\n );\n\n const store = this.tunnelService.getStore();\n const viewerLinks: Record<string, string> = {};\n\n // For edits/writes with diff data (oldText + newText)\n if (fileInfo.oldContent) {\n const id = store.storeDiff(\n sessionContext.id,\n fileInfo.filePath,\n fileInfo.oldContent,\n fileInfo.content,\n sessionContext.workingDirectory,\n );\n if (id) viewerLinks.diff = this.tunnelService.diffUrl(id);\n }\n\n // Always store as file view (new file creation or read)\n const id = store.storeFile(\n sessionContext.id,\n fileInfo.filePath,\n fileInfo.content,\n sessionContext.workingDirectory,\n );\n if (id) viewerLinks.file = this.tunnelService.fileUrl(id);\n\n if (Object.keys(viewerLinks).length > 0) {\n metadata.viewerLinks = viewerLinks;\n metadata.viewerFilePath = fileInfo.filePath;\n }\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { UsageRecord, UsageSummary } from \"./types.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"usage-store\" });\n\ninterface StoreFile {\n version: number;\n records: UsageRecord[];\n}\n\nconst DEBOUNCE_MS = 2000;\n\nexport class UsageStore {\n private records: UsageRecord[] = [];\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private cleanupInterval: ReturnType<typeof setInterval> | null = null;\n private flushHandler: (() => void) | null = null;\n\n constructor(\n private filePath: string,\n private retentionDays: number,\n ) {\n this.load();\n this.cleanup();\n\n this.cleanupInterval = setInterval(\n () => this.cleanup(),\n 24 * 60 * 60 * 1000,\n );\n\n this.flushHandler = () => {\n try {\n this.flushSync();\n } catch {\n // Best effort — don't block other exit handlers (e.g., session store flush)\n }\n };\n process.on(\"SIGTERM\", this.flushHandler);\n process.on(\"SIGINT\", this.flushHandler);\n process.on(\"exit\", this.flushHandler);\n }\n\n append(record: UsageRecord): void {\n this.records.push(record);\n this.scheduleDiskWrite();\n }\n\n query(period: \"today\" | \"week\" | \"month\" | \"all\"): UsageSummary {\n const cutoff = this.getCutoff(period);\n const filtered = cutoff\n ? this.records.filter((r) => new Date(r.timestamp).getTime() >= cutoff)\n : this.records;\n\n const totalTokens = filtered.reduce((sum, r) => sum + r.tokensUsed, 0);\n const totalCost = filtered.reduce(\n (sum, r) => sum + (r.cost?.amount ?? 0),\n 0,\n );\n const sessionIds = new Set(filtered.map((r) => r.sessionId));\n const currency =\n filtered.find((r) => r.cost?.currency)?.cost?.currency ?? \"USD\";\n\n return {\n period,\n totalTokens,\n totalCost,\n currency,\n sessionCount: sessionIds.size,\n recordCount: filtered.length,\n };\n }\n\n getMonthlyTotal(): { totalCost: number; currency: string } {\n const now = new Date();\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n const cutoff = startOfMonth.getTime();\n\n const filtered = this.records.filter(\n (r) => new Date(r.timestamp).getTime() >= cutoff,\n );\n const totalCost = filtered.reduce(\n (sum, r) => sum + (r.cost?.amount ?? 0),\n 0,\n );\n const currency =\n filtered.find((r) => r.cost?.currency)?.cost?.currency ?? \"USD\";\n\n return { totalCost, currency };\n }\n\n cleanup(): void {\n const cutoff =\n Date.now() - this.retentionDays * 24 * 60 * 60 * 1000;\n const before = this.records.length;\n this.records = this.records.filter(\n (r) => new Date(r.timestamp).getTime() >= cutoff,\n );\n const removed = before - this.records.length;\n if (removed > 0) {\n log.info({ removed }, \"Cleaned up expired usage records\");\n this.scheduleDiskWrite();\n }\n }\n\n flushSync(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n const data: StoreFile = { version: 1, records: this.records };\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2));\n }\n\n destroy(): void {\n if (this.debounceTimer) this.flushSync();\n if (this.cleanupInterval) clearInterval(this.cleanupInterval);\n if (this.flushHandler) {\n process.removeListener(\"SIGTERM\", this.flushHandler);\n process.removeListener(\"SIGINT\", this.flushHandler);\n process.removeListener(\"exit\", this.flushHandler);\n this.flushHandler = null;\n }\n }\n\n private load(): void {\n if (!fs.existsSync(this.filePath)) return;\n try {\n const raw = JSON.parse(\n fs.readFileSync(this.filePath, \"utf-8\"),\n ) as StoreFile;\n if (raw.version !== 1) {\n log.warn(\n { version: raw.version },\n \"Unknown usage store version, skipping load\",\n );\n return;\n }\n this.records = raw.records || [];\n log.debug({ count: this.records.length }, \"Loaded usage records\");\n } catch (err) {\n log.error({ err }, \"Failed to load usage store, backing up corrupt file\");\n try {\n fs.copyFileSync(this.filePath, this.filePath + \".bak\");\n } catch {\n /* best effort */\n }\n this.records = [];\n }\n }\n\n private getCutoff(\n period: \"today\" | \"week\" | \"month\" | \"all\",\n ): number | null {\n const now = new Date();\n switch (period) {\n case \"today\": {\n const start = new Date(now);\n start.setHours(0, 0, 0, 0);\n return start.getTime();\n }\n case \"week\":\n return Date.now() - 7 * 24 * 60 * 60 * 1000;\n case \"month\": {\n // Use current calendar month (1st of month), consistent with getMonthlyTotal()\n const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);\n return startOfMonth.getTime();\n }\n case \"all\":\n return null;\n }\n }\n\n private scheduleDiskWrite(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.flushSync();\n }, DEBOUNCE_MS);\n }\n}\n","import type { UsageConfig } from \"./config.js\";\nimport type { UsageStore } from \"./usage-store.js\";\n\nexport class UsageBudget {\n private lastNotifiedStatus: \"ok\" | \"warning\" | \"exceeded\" = \"ok\";\n private lastNotifiedMonth: number;\n\n constructor(\n private store: UsageStore,\n private config: UsageConfig,\n private now: () => Date = () => new Date(),\n ) {\n this.lastNotifiedMonth = this.now().getMonth();\n }\n\n check(): { status: \"ok\" | \"warning\" | \"exceeded\"; message?: string } {\n if (!this.config.monthlyBudget) {\n return { status: \"ok\" };\n }\n\n // Reset de-duplication at month boundary\n const currentMonth = this.now().getMonth();\n if (currentMonth !== this.lastNotifiedMonth) {\n this.lastNotifiedStatus = \"ok\";\n this.lastNotifiedMonth = currentMonth;\n }\n\n const { totalCost } = this.store.getMonthlyTotal();\n const budget = this.config.monthlyBudget;\n const threshold = this.config.warningThreshold;\n\n let status: \"ok\" | \"warning\" | \"exceeded\";\n if (totalCost >= budget) {\n status = \"exceeded\";\n } else if (totalCost >= threshold * budget) {\n status = \"warning\";\n } else {\n status = \"ok\";\n }\n\n // Only emit message on status change (prevents spam)\n let message: string | undefined;\n if (status !== \"ok\" && status !== this.lastNotifiedStatus) {\n const pct = Math.round((totalCost / budget) * 100);\n const filled = Math.round(Math.min(totalCost / budget, 1) * 10);\n const bar = \"▓\".repeat(filled) + \"░\".repeat(10 - filled);\n\n if (status === \"warning\") {\n message =\n `⚠️ <b>Budget Warning</b>\\n` +\n `Monthly usage: $${totalCost.toFixed(2)} / $${budget.toFixed(2)} (${pct}%)\\n` +\n `${bar} ${pct}%`;\n } else {\n message =\n `🚨 <b>Budget Exceeded</b>\\n` +\n `Monthly usage: $${totalCost.toFixed(2)} / $${budget.toFixed(2)} (${pct}%)\\n` +\n `${bar} ${pct}%\\n` +\n `Sessions are NOT blocked — this is a warning only.`;\n }\n }\n\n this.lastNotifiedStatus = status;\n return { status, message };\n }\n\n getStatus(): {\n status: \"ok\" | \"warning\" | \"exceeded\";\n used: number;\n budget: number;\n percent: number;\n } {\n const { totalCost } = this.store.getMonthlyTotal();\n const budget = this.config.monthlyBudget ?? 0;\n\n let status: \"ok\" | \"warning\" | \"exceeded\" = \"ok\";\n if (budget > 0) {\n if (totalCost >= budget) {\n status = \"exceeded\";\n } else if (totalCost >= this.config.warningThreshold * budget) {\n status = \"warning\";\n }\n }\n\n const percent = budget > 0 ? Math.round((totalCost / budget) * 100) : 0;\n return { status, used: totalCost, budget, percent };\n }\n}\n","import type { ConfigManager } from \"./config.js\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { IncomingMessage } from \"./types.js\";\n\nexport class SecurityGuard {\n constructor(\n private configManager: ConfigManager,\n private sessionManager: SessionManager,\n ) {}\n\n checkAccess(message: IncomingMessage):\n | { allowed: true }\n | { allowed: false; reason: string }\n {\n const config = this.configManager.get();\n if (config.security.allowedUserIds.length > 0) {\n const userId = String(message.userId);\n if (!config.security.allowedUserIds.includes(userId)) {\n return { allowed: false, reason: \"Unauthorized user\" };\n }\n }\n const active = this.sessionManager.listSessions()\n .filter(s => s.status === \"active\" || s.status === \"initializing\");\n if (active.length >= config.security.maxConcurrentSessions) {\n return { allowed: false, reason: `Session limit reached (${config.security.maxConcurrentSessions})` };\n }\n return { allowed: true };\n }\n}\n","import { nanoid } from \"nanoid\";\nimport type { AgentManager } from \"./agent-manager.js\";\nimport type { SessionManager } from \"./session-manager.js\";\nimport type { SpeechService } from \"./speech/index.js\";\nimport type { EventBus } from \"./event-bus.js\";\nimport type { UsageStore } from \"./usage-store.js\";\nimport type { UsageBudget } from \"./usage-budget.js\";\nimport type { NotificationManager } from \"./notification.js\";\nimport type { TunnelService } from \"../tunnel/tunnel-service.js\";\nimport type { AgentEvent, UsageRecord } from \"./types.js\";\nimport { Session } from \"./session.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"session-factory\" });\n\nexport interface SessionCreateParams {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n resumeAgentSessionId?: string;\n existingSessionId?: string;\n initialName?: string;\n}\n\nexport interface SideEffectDeps {\n usageStore?: UsageStore | null;\n usageBudget?: UsageBudget | null;\n notificationManager: NotificationManager;\n tunnelService?: TunnelService;\n}\n\nexport class SessionFactory {\n constructor(\n private agentManager: AgentManager,\n private sessionManager: SessionManager,\n private speechService: SpeechService,\n private eventBus: EventBus,\n ) {}\n\n async create(params: SessionCreateParams): Promise<Session> {\n // 1. Spawn or resume agent\n const agentInstance = params.resumeAgentSessionId\n ? await this.agentManager.resume(\n params.agentName,\n params.workingDirectory,\n params.resumeAgentSessionId,\n )\n : await this.agentManager.spawn(\n params.agentName,\n params.workingDirectory,\n );\n\n // 2. Create Session instance\n const session = new Session({\n id: params.existingSessionId,\n channelId: params.channelId,\n agentName: params.agentName,\n workingDirectory: params.workingDirectory,\n agentInstance,\n speechService: this.speechService,\n });\n session.agentSessionId = agentInstance.sessionId;\n if (params.initialName) {\n session.name = params.initialName;\n }\n\n // 3. Register in SessionManager\n this.sessionManager.registerSession(session);\n this.eventBus.emit(\"session:created\", {\n sessionId: session.id,\n agent: session.agentName,\n status: session.status,\n });\n\n return session;\n }\n\n wireSideEffects(session: Session, deps: SideEffectDeps): void {\n // Wire usage tracking\n if (deps.usageStore) {\n const usageStore = deps.usageStore;\n const usageBudget = deps.usageBudget;\n const notificationManager = deps.notificationManager;\n\n session.on(\"agent_event\", (event: AgentEvent) => {\n if (event.type !== \"usage\") return;\n const record: UsageRecord = {\n id: nanoid(),\n sessionId: session.id,\n agentName: session.agentName,\n tokensUsed: event.tokensUsed ?? 0,\n contextSize: event.contextSize ?? 0,\n cost: event.cost,\n timestamp: new Date().toISOString(),\n };\n usageStore.append(record);\n\n if (usageBudget) {\n const result = usageBudget.check();\n if (result.message) {\n notificationManager.notifyAll({\n sessionId: session.id,\n sessionName: session.name,\n type: \"budget_warning\",\n summary: result.message,\n });\n }\n }\n });\n }\n\n // Clean up user tunnels when session ends\n session.on(\"status_change\", (_from, to) => {\n if ((to === \"finished\" || to === \"cancelled\") && deps.tunnelService) {\n deps.tunnelService\n .stopBySession(session.id)\n .then((stopped) => {\n for (const entry of stopped) {\n deps.notificationManager\n .notifyAll({\n sessionId: session.id,\n sessionName: session.name,\n type: \"completed\",\n summary: `Tunnel stopped: port ${entry.port}${entry.label ? ` (${entry.label})` : \"\"} — session ended`,\n })\n .catch(() => {});\n }\n })\n .catch(() => {});\n }\n });\n }\n}\n","import { TypedEmitter } from \"./typed-emitter.js\";\nimport type { AgentEvent, PermissionRequest, SessionStatus } from \"./types.js\";\n\nexport interface EventBusEvents {\n \"session:created\": (data: {\n sessionId: string;\n agent: string;\n status: SessionStatus;\n }) => void;\n \"session:updated\": (data: {\n sessionId: string;\n status?: SessionStatus;\n name?: string;\n dangerousMode?: boolean;\n }) => void;\n \"session:deleted\": (data: { sessionId: string }) => void;\n \"agent:event\": (data: { sessionId: string; event: AgentEvent }) => void;\n \"permission:request\": (data: {\n sessionId: string;\n permission: PermissionRequest;\n }) => void;\n}\n\nexport class EventBus extends TypedEmitter<EventBusEvents> {}\n","import type { STTProvider, TTSProvider, STTOptions, STTResult, TTSOptions, TTSResult, SpeechServiceConfig } from './types.js';\n\nexport class SpeechService {\n private sttProviders = new Map<string, STTProvider>();\n private ttsProviders = new Map<string, TTSProvider>();\n\n constructor(private config: SpeechServiceConfig) {}\n\n registerSTTProvider(name: string, provider: STTProvider): void {\n this.sttProviders.set(name, provider);\n }\n\n registerTTSProvider(name: string, provider: TTSProvider): void {\n this.ttsProviders.set(name, provider);\n }\n\n isSTTAvailable(): boolean {\n const { provider, providers } = this.config.stt;\n return provider !== null && providers[provider]?.apiKey !== undefined;\n }\n\n isTTSAvailable(): boolean {\n const provider = this.config.tts.provider;\n return provider !== null && this.ttsProviders.has(provider);\n }\n\n async transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult> {\n const providerName = this.config.stt.provider;\n if (!providerName || !this.config.stt.providers[providerName]?.apiKey) {\n throw new Error(\"STT not configured. Set speech.stt.provider and API key in config.\");\n }\n const provider = this.sttProviders.get(providerName);\n if (!provider) {\n throw new Error(`STT provider \"${providerName}\" not registered. Available: ${[...this.sttProviders.keys()].join(\", \") || \"none\"}`);\n }\n return provider.transcribe(audioBuffer, mimeType, options);\n }\n\n async synthesize(text: string, options?: TTSOptions): Promise<TTSResult> {\n const providerName = this.config.tts.provider;\n if (!providerName) {\n throw new Error(\"TTS not configured. Set speech.tts.provider in config.\");\n }\n const provider = this.ttsProviders.get(providerName);\n if (!provider) {\n throw new Error(`TTS provider \"${providerName}\" not registered. Available: ${[...this.ttsProviders.keys()].join(\", \") || \"none\"}`);\n }\n return provider.synthesize(text, options);\n }\n\n updateConfig(config: SpeechServiceConfig): void {\n this.config = config;\n }\n}\n","import type { STTProvider, STTOptions, STTResult } from '../types.js';\n\nconst GROQ_API_URL = \"https://api.groq.com/openai/v1/audio/transcriptions\";\n\nexport class GroqSTT implements STTProvider {\n readonly name = \"groq\";\n\n constructor(\n private apiKey: string,\n private defaultModel: string = \"whisper-large-v3-turbo\",\n ) {}\n\n async transcribe(audioBuffer: Buffer, mimeType: string, options?: STTOptions): Promise<STTResult> {\n const ext = mimeToExt(mimeType);\n const form = new FormData();\n form.append(\"file\", new Blob([new Uint8Array(audioBuffer)], { type: mimeType }), `audio${ext}`);\n form.append(\"model\", options?.model || this.defaultModel);\n form.append(\"response_format\", \"verbose_json\");\n if (options?.language) {\n form.append(\"language\", options.language);\n }\n\n const resp = await fetch(GROQ_API_URL, {\n method: \"POST\",\n headers: { Authorization: `Bearer ${this.apiKey}` },\n body: form,\n });\n\n if (!resp.ok) {\n const body = await resp.text();\n if (resp.status === 401) {\n throw new Error(\"Invalid Groq API key. Check your key at console.groq.com.\");\n }\n if (resp.status === 413) {\n throw new Error(\"Audio file too large for Groq API (max 25MB).\");\n }\n if (resp.status === 429) {\n throw new Error(\"Groq rate limit exceeded. Free tier: 28,800 seconds/day. Try again later.\");\n }\n throw new Error(`Groq STT error (${resp.status}): ${body}`);\n }\n\n const data = await resp.json() as { text: string; language?: string; duration?: number };\n return {\n text: data.text,\n language: data.language,\n duration: data.duration,\n };\n }\n}\n\nfunction mimeToExt(mimeType: string): string {\n const map: Record<string, string> = {\n \"audio/ogg\": \".ogg\",\n \"audio/wav\": \".wav\",\n \"audio/mpeg\": \".mp3\",\n \"audio/mp4\": \".m4a\",\n \"audio/webm\": \".webm\",\n \"audio/flac\": \".flac\",\n };\n return map[mimeType] || \".bin\";\n}\n","import type { TTSProvider, TTSOptions, TTSResult } from '../types.js';\n\nconst DEFAULT_VOICE = \"en-US-AriaNeural\";\n\nexport class EdgeTTS implements TTSProvider {\n readonly name = \"edge-tts\";\n private voice: string;\n\n constructor(voice?: string) {\n this.voice = voice || DEFAULT_VOICE;\n }\n\n async synthesize(text: string, options?: TTSOptions): Promise<TTSResult> {\n const { MsEdgeTTS, OUTPUT_FORMAT } = await import(\"msedge-tts\");\n const tts = new MsEdgeTTS();\n\n const voice = options?.voice || this.voice;\n const format = OUTPUT_FORMAT.AUDIO_24KHZ_48KBITRATE_MONO_MP3;\n\n await tts.setMetadata(voice, format);\n const { audioStream } = tts.toStream(text);\n\n const chunks: Buffer[] = [];\n for await (const chunk of audioStream) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n\n tts.close();\n\n return {\n audioBuffer: Buffer.concat(chunks),\n mimeType: \"audio/mpeg\",\n };\n }\n}\n","import * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult } from \"./context-provider.js\";\nimport { ContextCache } from \"./context-cache.js\";\n\nexport class ContextManager {\n private providers: ContextProvider[] = [];\n private cache: ContextCache;\n\n constructor() {\n this.cache = new ContextCache(path.join(os.homedir(), \".openacp\", \"cache\", \"entire\"));\n }\n\n register(provider: ContextProvider): void {\n this.providers.push(provider);\n }\n\n async getProvider(repoPath: string): Promise<ContextProvider | null> {\n for (const provider of this.providers) {\n if (await provider.isAvailable(repoPath)) return provider;\n }\n return null;\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult | null> {\n const provider = await this.getProvider(query.repoPath);\n if (!provider) return null;\n return provider.listSessions(query);\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult | null> {\n const queryKey = `${query.type}:${query.value}:${options?.limit ?? \"\"}:${options?.maxTokens ?? \"\"}`;\n const cached = this.cache.get(query.repoPath, queryKey);\n if (cached) return cached;\n\n const provider = await this.getProvider(query.repoPath);\n if (!provider) return null;\n const result = await provider.buildContext(query, options);\n if (result) this.cache.set(query.repoPath, queryKey, result);\n return result;\n }\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as crypto from \"node:crypto\";\nimport type { ContextResult } from \"./context-provider.js\";\n\nconst DEFAULT_TTL_MS = 60 * 60 * 1000;\n\nexport class ContextCache {\n constructor(private cacheDir: string, private ttlMs: number = DEFAULT_TTL_MS) {\n fs.mkdirSync(cacheDir, { recursive: true });\n }\n\n private keyHash(repoPath: string, queryKey: string): string {\n return crypto.createHash(\"sha256\").update(`${repoPath}:${queryKey}`).digest(\"hex\").slice(0, 16);\n }\n\n private filePath(repoPath: string, queryKey: string): string {\n return path.join(this.cacheDir, `${this.keyHash(repoPath, queryKey)}.json`);\n }\n\n get(repoPath: string, queryKey: string): ContextResult | null {\n const fp = this.filePath(repoPath, queryKey);\n try {\n const stat = fs.statSync(fp);\n if (Date.now() - stat.mtimeMs > this.ttlMs) { fs.unlinkSync(fp); return null; }\n return JSON.parse(fs.readFileSync(fp, \"utf-8\")) as ContextResult;\n } catch { return null; }\n }\n\n set(repoPath: string, queryKey: string, result: ContextResult): void {\n fs.writeFileSync(this.filePath(repoPath, queryKey), JSON.stringify(result));\n }\n}\n","// NOTE: This interface is designed around Entire as the first provider.\n// It may evolve when additional providers (Cursor history, Zed, etc.) are added.\n// Providers may only support a subset of query types and should return empty results\n// for unsupported types rather than throwing.\n\nexport interface ContextProvider {\n readonly name: string;\n isAvailable(repoPath: string): Promise<boolean>;\n listSessions(query: ContextQuery): Promise<SessionListResult>;\n buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult>;\n}\n\nexport interface ContextQuery {\n repoPath: string;\n type: \"branch\" | \"commit\" | \"pr\" | \"latest\" | \"checkpoint\" | \"session\";\n value: string;\n}\n\nexport interface ContextOptions {\n maxTokens?: number;\n limit?: number;\n}\n\nexport interface SessionInfo {\n checkpointId: string;\n sessionIndex: string;\n transcriptPath: string;\n createdAt: string;\n endedAt: string;\n branch: string;\n agent: string;\n turnCount: number;\n filesTouched: string[];\n sessionId: string;\n}\n\nexport interface SessionListResult {\n sessions: SessionInfo[];\n estimatedTokens: number;\n}\n\nexport type ContextMode = \"full\" | \"balanced\" | \"compact\";\n\nexport interface ContextResult {\n markdown: string;\n tokenEstimate: number;\n sessionCount: number;\n totalTurns: number;\n mode: ContextMode;\n truncated: boolean;\n timeRange: { start: string; end: string };\n}\n\nexport const DEFAULT_MAX_TOKENS = 30_000;\nexport const TOKENS_PER_TURN_ESTIMATE = 400;\n","import { execFileSync } from \"child_process\";\nimport type { SessionInfo } from \"../context-provider.js\";\n\n// ─── Internal types ────────────────────────────────────────────────────────────\n\ninterface CheckpointMeta {\n checkpoint_id?: string;\n branch?: string;\n files_touched?: string[];\n sessions: Array<{\n metadata: string;\n transcript: string;\n }>;\n}\n\ninterface SessionMeta {\n session_id?: string;\n created_at?: string;\n branch?: string;\n agent?: string;\n files_touched?: string[];\n session_metrics?: {\n turn_count?: number;\n };\n}\n\n// ─── CheckpointReader ─────────────────────────────────────────────────────────\n\nconst ENTIRE_BRANCH = \"origin/entire/checkpoints/v1\";\nconst CHECKPOINT_ID_RE = /^[0-9a-f]{12}$/;\nconst SESSION_ID_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;\n\nexport class CheckpointReader {\n constructor(private readonly repoPath: string) {}\n\n // ─── Git execution ───────────────────────────────────────────────────────────\n\n /**\n * Run a git command in the repo directory.\n * Returns trimmed stdout on success, empty string on failure.\n */\n private git(...args: string[]): string {\n try {\n return execFileSync(\"git\", [\"-C\", this.repoPath, ...args], {\n encoding: \"utf-8\",\n }).trim();\n } catch {\n return \"\";\n }\n }\n\n // ─── Static helpers ──────────────────────────────────────────────────────────\n\n /**\n * Convert a 12-char checkpoint ID to its shard path: \"f634acf05138\" → \"f6/34acf05138\"\n */\n static shardPath(cpId: string): string {\n return `${cpId.slice(0, 2)}/${cpId.slice(2)}`;\n }\n\n /**\n * Returns true when value looks like a 12-char lowercase hex checkpoint ID.\n */\n static isCheckpointId(value: string): boolean {\n return CHECKPOINT_ID_RE.test(value);\n }\n\n /**\n * Returns true when value looks like a UUID (session ID).\n */\n static isSessionId(value: string): boolean {\n return SESSION_ID_RE.test(value);\n }\n\n /**\n * Parse checkpoint-level metadata JSON. Returns null on error.\n */\n static parseCheckpointMeta(json: string): CheckpointMeta | null {\n try {\n const parsed = JSON.parse(json) as CheckpointMeta;\n if (!parsed || typeof parsed !== \"object\") return null;\n if (!Array.isArray(parsed.sessions)) return null;\n return parsed;\n } catch {\n return null;\n }\n }\n\n /**\n * Extract Entire-Checkpoint trailer IDs from `git log --format=\"%H|%(trailers:...)\"` output.\n * Each line is: `<hash>|<trailer_value_or_empty>`. Returns only non-empty trailer values.\n * Uses the last pipe on each line to locate the trailer value, to be robust against\n * subject lines that contain pipes.\n */\n static parseCheckpointTrailers(output: string): string[] {\n const ids: string[] = [];\n for (const line of output.split(\"\\n\")) {\n const pipe = line.lastIndexOf(\"|\");\n if (pipe === -1) continue;\n const trailerId = line.slice(pipe + 1).trim();\n if (trailerId) ids.push(trailerId);\n }\n return ids;\n }\n\n // ─── Branch check ────────────────────────────────────────────────────────────\n\n async hasEntireBranch(): Promise<boolean> {\n const out = this.git(\"branch\", \"-r\");\n return out.includes(\"entire/checkpoints/v1\");\n }\n\n // ─── Core session fetching ───────────────────────────────────────────────────\n\n private listAllCheckpointIds(): string[] {\n const out = this.git(\n \"ls-tree\",\n \"-r\",\n ENTIRE_BRANCH,\n \"--name-only\"\n );\n if (!out) return [];\n\n const ids = new Set<string>();\n for (const file of out.split(\"\\n\")) {\n const parts = file.split(\"/\");\n // Checkpoint-level metadata: XX/YYYYYYYYYY/metadata.json (3 parts)\n if (parts.length === 3 && parts[2] === \"metadata.json\") {\n ids.add(parts[0] + parts[1]);\n }\n }\n return [...ids];\n }\n\n private fetchCheckpointMeta(cpId: string): CheckpointMeta | null {\n const shard = CheckpointReader.shardPath(cpId);\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${shard}/metadata.json`);\n if (!raw) return null;\n return CheckpointReader.parseCheckpointMeta(raw);\n }\n\n private fetchSessionMeta(metaPath: string): SessionMeta {\n const normalized = metaPath.startsWith(\"/\") ? metaPath.slice(1) : metaPath;\n const raw = this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n if (!raw) return {};\n try {\n return JSON.parse(raw) as SessionMeta;\n } catch {\n return {};\n }\n }\n\n /**\n * Build SessionInfo[] from a single checkpoint's metadata.\n */\n private buildSessionsForCheckpoint(\n cpId: string,\n cpMeta: CheckpointMeta\n ): SessionInfo[] {\n const sessions: SessionInfo[] = [];\n\n for (let idx = 0; idx < cpMeta.sessions.length; idx++) {\n const sess = cpMeta.sessions[idx];\n const transcriptPath = (sess.transcript ?? \"\").replace(/^\\//, \"\");\n const metaPath = sess.metadata ?? \"\";\n\n const smeta = this.fetchSessionMeta(metaPath);\n const createdAt = smeta.created_at ?? \"\";\n\n sessions.push({\n checkpointId: cpId,\n sessionIndex: String(idx),\n transcriptPath,\n createdAt,\n endedAt: createdAt, // will be filled from JSONL by conversation builder\n branch: smeta.branch ?? cpMeta.branch ?? \"\",\n agent: smeta.agent ?? \"\",\n turnCount: smeta.session_metrics?.turn_count ?? 0,\n filesTouched: smeta.files_touched ?? cpMeta.files_touched ?? [],\n sessionId: smeta.session_id ?? \"\",\n });\n }\n\n return sessions;\n }\n\n private getSessionsForCheckpoint(cpId: string): SessionInfo[] {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) return [];\n return this.buildSessionsForCheckpoint(cpId, meta);\n }\n\n // ─── Public resolvers ────────────────────────────────────────────────────────\n\n /**\n * All sessions recorded on a given branch, sorted by createdAt ascending.\n */\n async resolveByBranch(branchName: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n const meta = this.fetchCheckpointMeta(cpId);\n if (!meta) continue;\n if (meta.branch !== branchName) continue;\n sessions.push(...this.buildSessionsForCheckpoint(cpId, meta));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions linked to a specific commit via the Entire-Checkpoint git trailer.\n */\n async resolveByCommit(commitHash: string): Promise<SessionInfo[]> {\n const fullHash = this.git(\"rev-parse\", commitHash);\n if (!fullHash) return [];\n\n const cpId = this.git(\n \"log\",\n \"-1\",\n \"--format=%(trailers:key=Entire-Checkpoint,valueonly)\",\n fullHash\n );\n if (!cpId) return [];\n\n return this.getSessionsForCheckpoint(cpId.trim());\n }\n\n /**\n * All sessions from a merged PR (by number or GitHub URL).\n */\n async resolveByPr(prInput: string): Promise<SessionInfo[]> {\n let prNumber: string;\n\n if (/^\\d+$/.test(prInput)) {\n prNumber = prInput;\n } else {\n const m = /\\/pull\\/(\\d+)/.exec(prInput);\n if (!m) return [];\n prNumber = m[1];\n }\n\n const mergeOut = this.git(\n \"log\",\n \"--all\",\n \"--oneline\",\n \"--grep\",\n `Merge pull request #${prNumber}`\n );\n if (!mergeOut) return [];\n\n const mergeCommit = mergeOut.split(\"\\n\")[0].split(\" \")[0];\n\n const logOut = this.git(\n \"log\",\n \"--format=%H|%(trailers:key=Entire-Checkpoint,valueonly)\",\n `${mergeCommit}^2`,\n \"--not\",\n `${mergeCommit}^1`\n );\n if (!logOut) return [];\n\n const cpIds = CheckpointReader.parseCheckpointTrailers(logOut);\n const sessions: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n sessions.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n sessions.sort((a, b) => a.createdAt.localeCompare(b.createdAt));\n return sessions;\n }\n\n /**\n * Sessions matching a specific checkpoint ID.\n */\n async resolveByCheckpoint(checkpointId: string): Promise<SessionInfo[]> {\n return this.getSessionsForCheckpoint(checkpointId);\n }\n\n /**\n * Find a session by its UUID.\n */\n async resolveBySessionId(sessionId: string): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n\n for (const cpId of cpIds) {\n const sessions = this.getSessionsForCheckpoint(cpId);\n const match = sessions.find((s) => s.sessionId === sessionId);\n if (match) return [match];\n }\n\n return [];\n }\n\n /**\n * Latest N sessions across all checkpoints, sorted by createdAt descending.\n */\n async resolveLatest(count: number): Promise<SessionInfo[]> {\n const cpIds = this.listAllCheckpointIds();\n const all: SessionInfo[] = [];\n\n for (const cpId of cpIds) {\n all.push(...this.getSessionsForCheckpoint(cpId));\n }\n\n all.sort((a, b) => b.createdAt.localeCompare(a.createdAt));\n return all.slice(0, count);\n }\n\n /**\n * Read the full JSONL transcript content from the entire branch.\n */\n getTranscript(transcriptPath: string): string {\n const normalized = transcriptPath.startsWith(\"/\")\n ? transcriptPath.slice(1)\n : transcriptPath;\n return this.git(\"show\", `${ENTIRE_BRANCH}:${normalized}`);\n }\n}\n","const SYSTEM_TAG_PATTERNS: RegExp[] = [\n /<system-reminder>[\\s\\S]*?<\\/system-reminder>/g,\n /<local-command-caveat>[\\s\\S]*?<\\/local-command-caveat>/g,\n /<local-command-stdout>[\\s\\S]*?<\\/local-command-stdout>/g,\n /<command-name>[\\s\\S]*?<\\/command-name>/g,\n /<command-message>[\\s\\S]*?<\\/command-message>/g,\n /<user-prompt-submit-hook>[\\s\\S]*?<\\/user-prompt-submit-hook>/g,\n /<ide_selection>[\\s\\S]*?<\\/ide_selection>/g,\n /<ide_context>[\\s\\S]*?<\\/ide_context>/g,\n /<ide_opened_file>[\\s\\S]*?<\\/ide_opened_file>/g,\n /<cursor_context>[\\s\\S]*?<\\/cursor_context>/g,\n /<attached_files>[\\s\\S]*?<\\/attached_files>/g,\n /<repo_context>[\\s\\S]*?<\\/repo_context>/g,\n /<task-notification>[\\s\\S]*?<\\/task-notification>/g,\n];\n\nconst COMMAND_ARGS_RE = /<command-args>([\\s\\S]*?)<\\/command-args>/;\n\nexport function cleanSystemTags(text: string): string {\n const argsMatch = COMMAND_ARGS_RE.exec(text);\n const userArgs = argsMatch?.[1]?.trim() ?? \"\";\n text = text.replace(/<command-args>[\\s\\S]*?<\\/command-args>/g, \"\");\n for (const pat of SYSTEM_TAG_PATTERNS) {\n text = text.replace(new RegExp(pat.source, pat.flags), \"\");\n }\n text = text.trim();\n if (!text && userArgs) return userArgs;\n if (text && userArgs && text !== userArgs) return `${text}\\n${userArgs}`;\n return text || userArgs;\n}\n\nconst SKILL_INDICATORS = [\n \"Base directory for this skill:\",\n \"<HARD-GATE>\",\n \"## Checklist\",\n \"## Process Flow\",\n \"## Key Principles\",\n \"digraph brainstorming\",\n \"You MUST create a task for each\",\n];\n\nexport function isSkillPrompt(text: string): boolean {\n for (const indicator of SKILL_INDICATORS) {\n if (text.includes(indicator)) return true;\n }\n if (text.length > 2000) {\n const headerCount = (text.match(/## /g) || []).length;\n if (headerCount >= 3) return true;\n }\n return false;\n}\n\nexport function isNoiseMessage(text: string): boolean {\n const cleaned = cleanSystemTags(text);\n if (!cleaned) return true;\n if (/^(ready|ready\\.)$/i.test(cleaned)) return true;\n if (cleaned.includes(\"Tell your human partner that this command is deprecated\")) return true;\n if (cleaned.startsWith(\"Read the output file to retrieve the result:\")) return true;\n if (/^(opus|sonnet|haiku|claude)(\\[.*\\])?$/i.test(cleaned)) return true;\n return false;\n}\n","import type { ContextMode } from \"../context-provider.js\";\nimport { cleanSystemTags, isSkillPrompt, isNoiseMessage } from \"./message-cleaner.js\";\n\n// ─── Types ────────────────────────────────────────────────────────────────────\n\nexport interface AssistantPart {\n type: \"text\" | \"edit\" | \"write\";\n content?: string;\n file?: string;\n old?: string;\n new?: string;\n fileContent?: string;\n}\n\nexport interface Turn {\n userText: string;\n userTimestamp: string;\n assistantParts: AssistantPart[];\n}\n\nexport interface ParseResult {\n turns: Turn[];\n branch: string;\n firstTimestamp: string;\n lastTimestamp: string;\n}\n\nexport interface SessionMarkdownInput {\n markdown: string;\n startTime: string;\n endTime: string;\n agent: string;\n turns: number;\n branch: string;\n files: string[];\n}\n\n// ─── Mode selection ────────────────────────────────────────────────────────────\n\n/**\n * Select rendering mode based on total turn count.\n * ≤10 → full\n * 11-25 → balanced\n * >25 → compact\n */\nexport function selectMode(totalTurns: number): ContextMode {\n if (totalTurns <= 10) return \"full\";\n if (totalTurns <= 25) return \"balanced\";\n return \"compact\";\n}\n\n// ─── Token estimation ─────────────────────────────────────────────────────────\n\nexport function estimateTokens(text: string): number {\n return Math.floor(text.length / 4);\n}\n\n// ─── Path helpers ─────────────────────────────────────────────────────────────\n\nfunction shortenPath(fp: string): string {\n const parts = fp.split(\"/\");\n if (parts.length >= 2) return parts.slice(-2).join(\"/\");\n return fp;\n}\n\nfunction countLines(s: string): number {\n const trimmed = s.trim();\n if (!trimmed) return 0;\n return trimmed.split(\"\\n\").length;\n}\n\n// ─── Content extraction ───────────────────────────────────────────────────────\n\ntype ContentBlock = { type: string; [key: string]: unknown };\n\nfunction extractText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n return content\n .filter((b): b is ContentBlock => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"text\")\n .map((b) => (b as unknown as { text: string }).text)\n .join(\"\\n\");\n }\n return \"\";\n}\n\nfunction extractContentBlocks(content: unknown): ContentBlock[] {\n if (typeof content === \"string\") return [{ type: \"text\", text: content }];\n if (Array.isArray(content)) {\n return content.filter((b): b is ContentBlock => typeof b === \"object\" && b !== null);\n }\n return [];\n}\n\nfunction isToolResultOnly(content: unknown): boolean {\n if (typeof content === \"string\") return false;\n if (!Array.isArray(content)) return true;\n for (const block of content) {\n if (typeof block === \"object\" && block !== null) {\n const b = block as ContentBlock;\n if (b.type === \"text\" && typeof b.text === \"string\" && (b.text as string).trim()) return false;\n if (b.type === \"image\") return false;\n }\n }\n return true;\n}\n\nfunction hasImage(content: unknown): boolean {\n if (!Array.isArray(content)) return false;\n return content.some((b) => typeof b === \"object\" && b !== null && (b as ContentBlock).type === \"image\");\n}\n\n// ─── Format functions ─────────────────────────────────────────────────────────\n\nfunction formatEditFull(filePath: string, oldStr: string, newStr: string): string {\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n for (const line of oldStr.split(\"\\n\")) lines.push(`- ${line}`);\n for (const line of newStr.split(\"\\n\")) lines.push(`+ ${line}`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditBalanced(filePath: string, oldStr: string, newStr: string, maxDiffLines = 12): string {\n const oldLines = oldStr.split(\"\\n\");\n const newLines = newStr.split(\"\\n\");\n const total = oldLines.length + newLines.length;\n const lines: string[] = [];\n lines.push(`✏️ \\`${filePath}\\``);\n lines.push(\"```diff\");\n if (total <= maxDiffLines) {\n for (const line of oldLines) lines.push(`- ${line}`);\n for (const line of newLines) lines.push(`+ ${line}`);\n } else {\n const half = Math.floor(maxDiffLines / 2);\n for (const line of oldLines.slice(0, half)) lines.push(`- ${line}`);\n if (oldLines.length > half) lines.push(` ... (-${oldLines.length} lines total)`);\n for (const line of newLines.slice(0, half)) lines.push(`+ ${line}`);\n if (newLines.length > half) lines.push(` ... (+${newLines.length} lines total)`);\n }\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatEditCompact(filePath: string, oldStr: string, newStr: string): string {\n const oldLines = countLines(oldStr);\n const newLines = countLines(newStr);\n let firstNew = \"\";\n for (const line of newStr.split(\"\\n\")) {\n const stripped = line.trim();\n if (stripped && !stripped.startsWith(\"//\") && !stripped.startsWith(\"*\")) {\n firstNew = stripped.slice(0, 80);\n break;\n }\n }\n if (firstNew) {\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines): \\`${firstNew}\\``;\n }\n return `✏️ \\`${filePath}\\` (-${oldLines}/+${newLines} lines)`;\n}\n\nfunction formatWriteFull(filePath: string, content: string): string {\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\``);\n lines.push(\"```\");\n lines.push(content);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteBalanced(filePath: string, content: string, maxLines = 15): string {\n const contentLines = content.split(\"\\n\");\n const lines: string[] = [];\n lines.push(`📝 \\`${filePath}\\` (${contentLines.length} lines)`);\n lines.push(\"```\");\n for (const line of contentLines.slice(0, maxLines)) lines.push(line);\n if (contentLines.length > maxLines) lines.push(`... (${contentLines.length - maxLines} more lines)`);\n lines.push(\"```\");\n return lines.join(\"\\n\");\n}\n\nfunction formatWriteCompact(filePath: string, content: string): string {\n const numLines = countLines(content);\n return `📝 \\`${filePath}\\` (${numLines} lines written)`;\n}\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\ninterface RawEvent {\n type?: string;\n message?: { role?: string; content?: unknown };\n timestamp?: string;\n uuid?: string;\n parentUuid?: string | null;\n sessionId?: string;\n gitBranch?: string;\n}\n\nexport function parseJsonlToTurns(jsonl: string): ParseResult {\n const events: RawEvent[] = [];\n for (const rawLine of jsonl.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) continue;\n try {\n events.push(JSON.parse(line) as RawEvent);\n } catch {\n // skip invalid JSON lines\n }\n }\n\n // Extract gitBranch from first event that has it\n let branch = \"unknown\";\n for (const e of events) {\n if (e.gitBranch) {\n branch = e.gitBranch;\n break;\n }\n }\n\n const convEvents = events.filter((e) => e.type === \"user\" || e.type === \"assistant\");\n\n const turns: Turn[] = [];\n let currentTurn: Turn | null = null;\n\n for (const e of convEvents) {\n const etype = e.type;\n const content = e.message?.content ?? [];\n const ts = e.timestamp ?? \"\";\n\n if (etype === \"user\") {\n if (isToolResultOnly(content)) continue;\n\n const text = extractText(content);\n\n if (isSkillPrompt(text)) continue;\n if (isNoiseMessage(text)) continue;\n\n const cleaned = cleanSystemTags(text);\n if (!cleaned) continue;\n\n // Push previous turn if any\n if (currentTurn) turns.push(currentTurn);\n\n const imgSuffix = hasImage(content) ? \" [image]\" : \"\";\n currentTurn = {\n userText: cleaned + imgSuffix,\n userTimestamp: ts,\n assistantParts: [],\n };\n } else if (etype === \"assistant\" && currentTurn) {\n const blocks = extractContentBlocks(content);\n let pendingText: string | null = null;\n\n for (const block of blocks) {\n const btype = block.type;\n\n if (btype === \"text\") {\n const text = typeof block.text === \"string\" ? (block.text as string).trim() : \"\";\n if (text) pendingText = text;\n } else if (btype === \"tool_use\") {\n const name = typeof block.name === \"string\" ? block.name : \"\";\n const inp = (typeof block.input === \"object\" && block.input !== null ? block.input : {}) as Record<string, string>;\n\n if (name === \"Edit\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"edit\",\n file: shortenPath(inp.file_path ?? \"\"),\n old: inp.old_string ?? \"\",\n new: inp.new_string ?? \"\",\n });\n } else if (name === \"Write\") {\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n pendingText = null;\n }\n currentTurn.assistantParts.push({\n type: \"write\",\n file: shortenPath(inp.file_path ?? \"\"),\n fileContent: inp.content ?? \"\",\n });\n }\n // Skip Read, Bash, Grep, Glob, etc.\n }\n }\n\n if (pendingText) {\n currentTurn.assistantParts.push({ type: \"text\", content: pendingText });\n }\n }\n }\n\n if (currentTurn) turns.push(currentTurn);\n\n const firstTimestamp = turns[0]?.userTimestamp ?? \"\";\n const lastTimestamp = turns[turns.length - 1]?.userTimestamp ?? \"\";\n\n return { turns, branch, firstTimestamp, lastTimestamp };\n}\n\n// ─── Markdown builder ─────────────────────────────────────────────────────────\n\nexport function buildSessionMarkdown(turns: Turn[], mode: ContextMode): string {\n const out: string[] = [];\n\n for (let i = 0; i < turns.length; i++) {\n const turn = turns[i];\n const userText = turn.userText.trim();\n if (!userText) continue;\n\n out.push(`**User [${i + 1}]:**`);\n out.push(userText);\n out.push(\"\");\n\n let hasContent = false;\n\n for (const part of turn.assistantParts) {\n if (part.type === \"text\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n out.push(part.content ?? \"\");\n out.push(\"\");\n } else if (part.type === \"edit\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const oldStr = part.old ?? \"\";\n const newStr = part.new ?? \"\";\n if (mode === \"full\") {\n out.push(formatEditFull(file, oldStr, newStr));\n } else if (mode === \"balanced\") {\n out.push(formatEditBalanced(file, oldStr, newStr));\n } else {\n out.push(formatEditCompact(file, oldStr, newStr));\n }\n out.push(\"\");\n } else if (part.type === \"write\") {\n if (!hasContent) {\n out.push(\"**Assistant:**\");\n hasContent = true;\n }\n const file = part.file ?? \"\";\n const content = part.fileContent ?? \"\";\n if (mode === \"full\") {\n out.push(formatWriteFull(file, content));\n } else if (mode === \"balanced\") {\n out.push(formatWriteBalanced(file, content));\n } else {\n out.push(formatWriteCompact(file, content));\n }\n out.push(\"\");\n }\n }\n\n out.push(\"---\");\n out.push(\"\");\n }\n\n return out.join(\"\\n\");\n}\n\n// ─── Session merger ───────────────────────────────────────────────────────────\n\nconst DISCLAIMER = `> **Note:** This conversation history may contain outdated information. File contents, code, and project state may have changed since these sessions were recorded. Use this as context only — always verify against current files before acting.`;\n\nexport function mergeSessionsMarkdown(\n sessions: SessionMarkdownInput[],\n mode: ContextMode,\n title: string\n): string {\n // Sort sessions chronologically (oldest first)\n const sorted = [...sessions].sort((a, b) => a.startTime.localeCompare(b.startTime));\n\n const totalTurns = sorted.reduce((sum, s) => sum + s.turns, 0);\n const overallStart = sorted[0]?.startTime.slice(0, 16) ?? \"?\";\n const overallEnd = sorted[sorted.length - 1]?.endTime.slice(0, 16) ?? \"?\";\n\n const out: string[] = [];\n out.push(`# Conversation History from ${title}`);\n out.push(`${sorted.length} sessions | ${totalTurns} turns | ${overallStart} → ${overallEnd} | mode: ${mode}`);\n out.push(\"\");\n\n for (let i = 0; i < sorted.length; i++) {\n const s = sorted[i];\n const start = s.startTime.slice(0, 16);\n const end = s.endTime.slice(0, 16);\n out.push(`## Session Conversation History ${i + 1} — ${start} → ${end} (${s.agent}, ${s.turns} turns, branch: ${s.branch})`);\n out.push(\"\");\n out.push(s.markdown);\n }\n\n out.push(DISCLAIMER);\n out.push(\"\");\n\n return out.join(\"\\n\");\n}\n","import type { ContextProvider, ContextQuery, ContextOptions, ContextResult, SessionListResult, SessionInfo } from \"../context-provider.js\";\nimport type { ContextMode } from \"../context-provider.js\";\nimport { DEFAULT_MAX_TOKENS, TOKENS_PER_TURN_ESTIMATE } from \"../context-provider.js\";\nimport { CheckpointReader } from \"./checkpoint-reader.js\";\nimport { parseJsonlToTurns, buildSessionMarkdown, mergeSessionsMarkdown, selectMode, estimateTokens, type SessionMarkdownInput } from \"./conversation-builder.js\";\n\nexport class EntireProvider implements ContextProvider {\n readonly name = \"entire\";\n\n async isAvailable(repoPath: string): Promise<boolean> {\n return new CheckpointReader(repoPath).hasEntireBranch();\n }\n\n async listSessions(query: ContextQuery): Promise<SessionListResult> {\n const reader = new CheckpointReader(query.repoPath);\n const sessions = await this.resolveSessions(reader, query);\n const estimatedTokens = sessions.reduce((sum, s) => sum + s.turnCount * TOKENS_PER_TURN_ESTIMATE, 0);\n return { sessions, estimatedTokens };\n }\n\n async buildContext(query: ContextQuery, options?: ContextOptions): Promise<ContextResult> {\n const maxTokens = options?.maxTokens ?? DEFAULT_MAX_TOKENS;\n const reader = new CheckpointReader(query.repoPath);\n let sessions = await this.resolveSessions(reader, query);\n\n if (options?.limit && sessions.length > options.limit) {\n sessions = sessions.slice(-options.limit);\n }\n\n if (sessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n // Rebuild each session, cache parsed turns for potential re-render\n const parsedSessions: { session: SessionInfo; jsonl: string; }[] = [];\n for (const sess of sessions) {\n const jsonl = reader.getTranscript(sess.transcriptPath);\n if (jsonl) parsedSessions.push({ session: sess, jsonl });\n }\n\n if (parsedSessions.length === 0) {\n return { markdown: \"\", tokenEstimate: 0, sessionCount: 0, totalTurns: 0, mode: \"full\", truncated: false, timeRange: { start: \"\", end: \"\" } };\n }\n\n const totalTurns = parsedSessions.reduce((sum, ps) => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return sum + parsed.turns.length;\n }, 0);\n\n let mode = selectMode(totalTurns);\n const title = this.buildTitle(query);\n\n // Build markdown for each session\n let sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, mode);\n let merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n let tokens = estimateTokens(merged);\n\n // Auto-downgrade to compact if over budget\n if (tokens > maxTokens && mode !== \"compact\") {\n mode = \"compact\";\n sessionMarkdowns = this.buildSessionMarkdowns(parsedSessions, \"compact\");\n merged = mergeSessionsMarkdown(sessionMarkdowns, \"compact\", title);\n tokens = estimateTokens(merged);\n }\n\n // Truncate oldest sessions if still over budget\n let truncated = false;\n while (tokens > maxTokens && sessionMarkdowns.length > 1) {\n sessionMarkdowns = sessionMarkdowns.slice(1);\n truncated = true;\n merged = mergeSessionsMarkdown(sessionMarkdowns, mode, title);\n tokens = estimateTokens(merged);\n }\n\n const allTimes = sessionMarkdowns.flatMap(s => [s.startTime, s.endTime]).filter(Boolean).sort();\n const finalTurns = sessionMarkdowns.reduce((sum, s) => sum + s.turns, 0);\n\n return {\n markdown: merged,\n tokenEstimate: tokens,\n sessionCount: sessionMarkdowns.length,\n totalTurns: finalTurns,\n mode,\n truncated,\n timeRange: { start: allTimes[0] ?? \"\", end: allTimes[allTimes.length - 1] ?? \"\" },\n };\n }\n\n private buildSessionMarkdowns(parsedSessions: { session: SessionInfo; jsonl: string }[], mode: ContextMode): SessionMarkdownInput[] {\n return parsedSessions.map(ps => {\n const parsed = parseJsonlToTurns(ps.jsonl);\n return {\n markdown: buildSessionMarkdown(parsed.turns, mode),\n startTime: parsed.firstTimestamp,\n endTime: parsed.lastTimestamp,\n agent: ps.session.agent,\n turns: parsed.turns.length,\n branch: ps.session.branch,\n files: ps.session.filesTouched.map(f => f.split(\"/\").pop() ?? f),\n };\n });\n }\n\n private async resolveSessions(reader: CheckpointReader, query: ContextQuery): Promise<SessionInfo[]> {\n switch (query.type) {\n case \"branch\": return reader.resolveByBranch(query.value);\n case \"commit\": return reader.resolveByCommit(query.value);\n case \"pr\": return reader.resolveByPr(query.value);\n case \"checkpoint\": return reader.resolveByCheckpoint(query.value);\n case \"session\": return reader.resolveBySessionId(query.value);\n case \"latest\": return reader.resolveLatest(parseInt(query.value) || 5);\n default: return [];\n }\n }\n\n private buildTitle(query: ContextQuery): string {\n switch (query.type) {\n case \"pr\": return `PR #${query.value.replace(/.*\\/pull\\//, \"\")}`;\n case \"branch\": return `branch \\`${query.value}\\``;\n case \"commit\": return `commit \\`${query.value.slice(0, 8)}\\``;\n case \"checkpoint\": return `checkpoint \\`${query.value}\\``;\n case \"session\": return `session \\`${query.value.slice(0, 8)}...\\``;\n case \"latest\": return `latest ${query.value} sessions`;\n default: return \"unknown\";\n }\n }\n}\n","import path from \"node:path\";\nimport os from \"node:os\";\nimport { ConfigManager } from \"./config.js\";\nimport { AgentManager } from \"./agent-manager.js\";\nimport { SessionManager } from \"./session-manager.js\";\nimport { SessionBridge } from \"./session-bridge.js\";\nimport { NotificationManager } from \"./notification.js\";\nimport { ChannelAdapter } from \"./channel.js\";\nimport { Session } from \"./session.js\";\nimport { MessageTransformer } from \"./message-transformer.js\";\nimport { FileService } from \"./file-service.js\";\nimport { JsonFileSessionStore, type SessionStore } from \"./session-store.js\";\nimport { UsageStore } from \"./usage-store.js\";\nimport { UsageBudget } from \"./usage-budget.js\";\nimport { SecurityGuard } from \"./security-guard.js\";\nimport { SessionFactory } from \"./session-factory.js\";\nimport type { IncomingMessage } from \"./types.js\";\nimport type { TunnelService } from \"../tunnel/tunnel-service.js\";\nimport { getAgentCapabilities } from \"./agent-registry.js\";\nimport { AgentCatalog } from \"./agent-catalog.js\";\nimport { EventBus } from \"./event-bus.js\";\nimport { createChildLogger } from \"./log.js\";\nimport { SpeechService, GroqSTT, EdgeTTS } from \"./speech/index.js\";\nimport { ContextManager } from \"./context/context-manager.js\";\nimport { EntireProvider } from \"./context/entire/entire-provider.js\";\nimport type { ContextQuery, ContextOptions, ContextResult } from \"./context/context-provider.js\";\nconst log = createChildLogger({ module: \"core\" });\n\nexport class OpenACPCore {\n configManager: ConfigManager;\n agentCatalog: AgentCatalog;\n agentManager: AgentManager;\n sessionManager: SessionManager;\n notificationManager: NotificationManager;\n messageTransformer: MessageTransformer;\n fileService: FileService;\n readonly speechService: SpeechService;\n securityGuard: SecurityGuard;\n adapters: Map<string, ChannelAdapter> = new Map();\n /** Set by main.ts — triggers graceful shutdown with restart exit code */\n requestRestart: (() => Promise<void>) | null = null;\n private _tunnelService?: TunnelService;\n private sessionStore: SessionStore | null = null;\n private resumeLocks: Map<string, Promise<Session | null>> = new Map();\n eventBus: EventBus;\n sessionFactory: SessionFactory;\n readonly usageStore: UsageStore | null = null;\n readonly usageBudget: UsageBudget | null = null;\n readonly contextManager: ContextManager;\n\n constructor(configManager: ConfigManager) {\n this.configManager = configManager;\n const config = configManager.get();\n this.agentCatalog = new AgentCatalog();\n this.agentCatalog.load();\n this.agentManager = new AgentManager(this.agentCatalog);\n const storePath = path.join(os.homedir(), \".openacp\", \"sessions.json\");\n this.sessionStore = new JsonFileSessionStore(\n storePath,\n config.sessionStore.ttlDays,\n );\n this.sessionManager = new SessionManager(this.sessionStore);\n this.securityGuard = new SecurityGuard(configManager, this.sessionManager);\n this.notificationManager = new NotificationManager(this.adapters);\n\n // Usage tracking\n const usageConfig = config.usage;\n if (usageConfig.enabled) {\n const usagePath = path.join(os.homedir(), \".openacp\", \"usage.json\");\n this.usageStore = new UsageStore(usagePath, usageConfig.retentionDays);\n this.usageBudget = new UsageBudget(this.usageStore, usageConfig);\n }\n\n this.messageTransformer = new MessageTransformer();\n this.eventBus = new EventBus();\n this.sessionManager.setEventBus(this.eventBus);\n this.contextManager = new ContextManager();\n this.contextManager.register(new EntireProvider());\n this.fileService = new FileService(\n path.join(os.homedir(), \".openacp\", \"files\"),\n );\n\n // Initialize speech service — edge-tts is always available by default (free, no API key)\n const speechConfig = config.speech ?? {\n stt: { provider: null, providers: {} },\n tts: { provider: \"edge-tts\", providers: {} },\n };\n // Default TTS provider to edge-tts if not explicitly set\n if (speechConfig.tts.provider == null) {\n speechConfig.tts.provider = \"edge-tts\";\n }\n this.speechService = new SpeechService(speechConfig);\n\n // Register built-in STT providers\n const groqConfig = speechConfig.stt?.providers?.groq;\n if (groqConfig?.apiKey) {\n this.speechService.registerSTTProvider(\n \"groq\",\n new GroqSTT(groqConfig.apiKey, groqConfig.model),\n );\n }\n\n // Register built-in TTS providers — always register edge-tts (free, no config needed)\n {\n const edgeConfig = speechConfig.tts?.providers?.[\"edge-tts\"];\n const voice = edgeConfig?.voice as string | undefined;\n this.speechService.registerTTSProvider(\"edge-tts\", new EdgeTTS(voice));\n }\n\n this.sessionFactory = new SessionFactory(\n this.agentManager,\n this.sessionManager,\n this.speechService,\n this.eventBus,\n );\n\n // Hot-reload: handle config changes that need side effects\n this.configManager.on(\n \"config:changed\",\n async ({ path: configPath, value }: { path: string; value: unknown }) => {\n if (configPath === \"logging.level\" && typeof value === \"string\") {\n const { setLogLevel } = await import(\"./log.js\");\n setLogLevel(value);\n log.info({ level: value }, \"Log level changed at runtime\");\n }\n if (configPath.startsWith(\"speech.\")) {\n const newConfig = this.configManager.get();\n const newSpeechConfig = newConfig.speech ?? {\n stt: { provider: null, providers: {} },\n tts: { provider: null, providers: {} },\n };\n this.speechService.updateConfig(newSpeechConfig);\n const groqCfg = newSpeechConfig.stt?.providers?.groq;\n if (groqCfg?.apiKey) {\n this.speechService.registerSTTProvider(\n \"groq\",\n new GroqSTT(groqCfg.apiKey, groqCfg.model),\n );\n }\n // Re-register TTS providers on config change — always keep edge-tts available\n {\n const edgeConfig = newSpeechConfig.tts?.providers?.[\"edge-tts\"];\n const voice = edgeConfig?.voice as string | undefined;\n this.speechService.registerTTSProvider(\"edge-tts\", new EdgeTTS(voice));\n }\n log.info(\"Speech service config updated at runtime\");\n }\n },\n );\n }\n\n get tunnelService(): TunnelService | undefined {\n return this._tunnelService;\n }\n\n set tunnelService(service: TunnelService | undefined) {\n this._tunnelService = service;\n this.messageTransformer = new MessageTransformer(service);\n }\n\n registerAdapter(name: string, adapter: ChannelAdapter): void {\n this.adapters.set(name, adapter);\n }\n\n async start(): Promise<void> {\n this.agentCatalog.refreshRegistryIfStale().catch((err) => {\n log.warn({ err }, \"Background registry refresh failed\");\n });\n for (const adapter of this.adapters.values()) {\n await adapter.start();\n }\n }\n\n async stop(): Promise<void> {\n // 1. Notify users\n try {\n await this.notificationManager.notifyAll({\n sessionId: \"system\",\n type: \"error\",\n summary: \"OpenACP is shutting down\",\n });\n } catch {\n /* best effort */\n }\n\n // 2. Destroy all sessions\n await this.sessionManager.destroyAll();\n\n // 3. Stop adapters\n for (const adapter of this.adapters.values()) {\n await adapter.stop();\n }\n\n // 4. Cleanup usage store\n if (this.usageStore) {\n this.usageStore.destroy();\n }\n }\n\n // --- Summary ---\n\n async summarizeSession(sessionId: string): Promise<{ ok: true; summary: string } | { ok: false; error: string }> {\n // Active session — summarize directly\n const session = this.sessionManager.getSession(sessionId);\n if (session && session.status === \"active\") {\n try {\n const summary = await session.generateSummary();\n if (!summary) return { ok: false, error: \"Agent could not generate summary\" };\n return { ok: true, summary };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n }\n }\n\n // Ended session — respawn agent temporarily with conversation history\n const record = this.sessionManager.getSessionRecord(sessionId);\n if (!record?.agentSessionId) {\n return { ok: false, error: \"Session not found or has no agent history\" };\n }\n\n const caps = getAgentCapabilities(record.agentName);\n if (!caps.supportsResume) {\n return { ok: false, error: `Agent \"${record.agentName}\" does not support resume — cannot summarize ended session` };\n }\n\n let tempSession: Session | undefined;\n try {\n const agentInstance = await this.agentManager.resume(\n record.agentName,\n record.workingDir,\n record.agentSessionId,\n );\n\n tempSession = new Session({\n id: `summary-${sessionId}`,\n channelId: record.channelId,\n agentName: record.agentName,\n workingDirectory: record.workingDir,\n agentInstance,\n });\n tempSession.activate();\n\n const summary = await tempSession.generateSummary();\n if (!summary) return { ok: false, error: \"Agent could not generate summary\" };\n return { ok: true, summary };\n } catch (err) {\n return { ok: false, error: (err as Error).message };\n } finally {\n if (tempSession) {\n try { await tempSession.destroy(); } catch { /* best effort */ }\n }\n }\n }\n\n // --- Archive ---\n\n async archiveSession(sessionId: string): Promise<{ ok: true } | { ok: false; error: string }> {\n const session = this.sessionManager.getSession(sessionId);\n const record = this.sessionManager.getSessionRecord(sessionId);\n\n if (!session && !record) return { ok: false, error: \"Session not found\" };\n\n const channelId = session?.channelId ?? record?.channelId;\n if (!channelId) return { ok: false, error: \"No channel for session\" };\n\n const adapter = this.adapters.get(channelId);\n if (!adapter) return { ok: false, error: \"Adapter not found for session\" };\n\n try {\n // 1. Delete topic — if session is in memory use archiveSessionTopic (cleans up trackers),\n // otherwise use deleteSessionThread (looks up topicId from record)\n if (session) {\n await adapter.archiveSessionTopic(session.id);\n } else {\n await adapter.deleteSessionThread(sessionId);\n }\n\n // 2. Cancel the session if in memory (stop agent)\n if (session) {\n try {\n await this.sessionManager.cancelSession(sessionId);\n } catch {\n // Session may already be finished/cancelled\n } finally {\n // Clear archiving flag after cancel completes — prevents race window\n // where agent events try to send to deleted topic\n session.archiving = false;\n }\n }\n\n // 3. Remove session record\n await this.sessionManager.removeRecord(sessionId);\n\n return { ok: true };\n } catch (err) {\n // Clear archiving flag on error too\n if (session) session.archiving = false;\n return { ok: false, error: (err as Error).message };\n }\n }\n\n // --- Message Routing ---\n\n async handleMessage(message: IncomingMessage): Promise<void> {\n log.debug(\n {\n channelId: message.channelId,\n threadId: message.threadId,\n userId: message.userId,\n },\n \"Incoming message\",\n );\n\n // Security: check user access and session limits\n const access = this.securityGuard.checkAccess(message);\n if (!access.allowed) {\n log.warn({ userId: message.userId, reason: access.reason }, \"Access denied\");\n if (access.reason.includes(\"Session limit\")) {\n const adapter = this.adapters.get(message.channelId);\n if (adapter) {\n await adapter.sendMessage(message.threadId, {\n type: \"error\",\n text: `⚠️ ${access.reason}. Please cancel existing sessions with /cancel before starting new ones.`,\n });\n }\n }\n return;\n }\n\n // Find session by thread\n let session = this.sessionManager.getSessionByThread(\n message.channelId,\n message.threadId,\n );\n\n // Lazy resume: try to restore session from store\n if (!session) {\n session = (await this.lazyResume(message)) ?? undefined;\n }\n\n if (!session) {\n log.warn(\n { channelId: message.channelId, threadId: message.threadId },\n \"No session found for thread (in-memory miss + lazy resume returned null)\",\n );\n return;\n }\n\n // Update activity timestamp\n this.sessionManager.patchRecord(session.id, {\n lastActiveAt: new Date().toISOString(),\n });\n\n // Forward to session\n await session.enqueuePrompt(message.text, message.attachments);\n }\n\n // --- Unified Session Creation Pipeline ---\n\n async createSession(params: {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n resumeAgentSessionId?: string;\n existingSessionId?: string;\n createThread?: boolean;\n initialName?: string;\n }): Promise<Session> {\n // 1-3. Spawn/resume agent, create Session, register in SessionManager\n const session = await this.sessionFactory.create(params);\n\n // 4. Create thread if needed\n const adapter = this.adapters.get(params.channelId);\n if (params.createThread && adapter) {\n const threadId = await adapter.createSessionThread(\n session.id,\n params.initialName ?? `🔄 ${params.agentName} — New Session`,\n );\n session.threadId = threadId;\n }\n\n // 5. Connect SessionBridge\n if (adapter) {\n const bridge = this.createBridge(session, adapter);\n bridge.connect();\n }\n\n // 5b-5c. Wire usage tracking and tunnel cleanup\n this.sessionFactory.wireSideEffects(session, {\n usageStore: this.usageStore,\n usageBudget: this.usageBudget,\n notificationManager: this.notificationManager,\n tunnelService: this._tunnelService,\n });\n\n // 6. Persist initial record\n // Preserve existing platform data (e.g. topicId) when resuming an existing session\n const existingRecord = this.sessionStore?.get(session.id);\n const platform: Record<string, unknown> = {\n ...(existingRecord?.platform ?? {}),\n };\n if (session.threadId) {\n if (params.channelId === \"telegram\") {\n platform.topicId = Number(session.threadId);\n } else {\n platform.threadId = session.threadId;\n }\n }\n await this.sessionManager.patchRecord(session.id, {\n sessionId: session.id,\n agentSessionId: session.agentSessionId,\n agentName: params.agentName,\n workingDir: params.workingDirectory,\n channelId: params.channelId,\n status: session.status,\n createdAt: session.createdAt.toISOString(),\n lastActiveAt: new Date().toISOString(),\n name: session.name,\n platform,\n });\n\n log.info(\n { sessionId: session.id, agentName: params.agentName },\n \"Session created via pipeline\",\n );\n return session;\n }\n\n async handleNewSession(\n channelId: string,\n agentName?: string,\n workspacePath?: string,\n options?: { createThread?: boolean },\n ): Promise<Session> {\n const config = this.configManager.get();\n const resolvedAgent = agentName || config.defaultAgent;\n log.info({ channelId, agentName: resolvedAgent }, \"New session request\");\n const agentDef = this.agentCatalog.resolve(resolvedAgent);\n const resolvedWorkspace = this.configManager.resolveWorkspace(\n workspacePath || agentDef?.workingDirectory,\n );\n\n return this.createSession({\n channelId,\n agentName: resolvedAgent,\n workingDirectory: resolvedWorkspace,\n createThread: options?.createThread,\n });\n }\n\n async adoptSession(\n agentName: string,\n agentSessionId: string,\n cwd: string,\n channelId?: string,\n ): Promise<\n | {\n ok: true;\n sessionId: string;\n threadId: string;\n status: \"adopted\" | \"existing\";\n }\n | { ok: false; error: string; message: string }\n > {\n // 1. Validate agent supports resume\n const caps = getAgentCapabilities(agentName);\n if (!caps.supportsResume) {\n return {\n ok: false,\n error: \"agent_not_supported\",\n message: `Agent '${agentName}' does not support session resume`,\n };\n }\n\n const agentDef = this.agentManager.getAgent(agentName);\n if (!agentDef) {\n return {\n ok: false,\n error: \"agent_not_supported\",\n message: `Agent '${agentName}' not found`,\n };\n }\n\n // 2. Validate cwd\n const { existsSync } = await import(\"node:fs\");\n if (!existsSync(cwd)) {\n return {\n ok: false,\n error: \"invalid_cwd\",\n message: `Directory does not exist: ${cwd}`,\n };\n }\n\n // 3. Check session limit\n const maxSessions = this.configManager.get().security.maxConcurrentSessions;\n if (this.sessionManager.listSessions().length >= maxSessions) {\n return {\n ok: false,\n error: \"session_limit\",\n message: \"Maximum concurrent sessions reached\",\n };\n }\n\n // 4. Check if session already exists on the same channel\n const existingRecord =\n this.sessionManager.getRecordByAgentSessionId(agentSessionId);\n if (existingRecord) {\n const sameChannel = !channelId || existingRecord.channelId === channelId;\n const platform = existingRecord.platform as { topicId?: number; threadId?: string } | undefined;\n const existingThreadId = platform?.topicId ? String(platform.topicId) : platform?.threadId;\n if (existingThreadId && sameChannel) {\n const adapter = this.adapters.get(existingRecord.channelId) ?? this.adapters.values().next().value;\n if (adapter) {\n try {\n await adapter.sendMessage(existingRecord.sessionId, {\n type: \"text\",\n text: \"Session resumed from CLI.\",\n });\n } catch { /* Topic/thread may be deleted */ }\n }\n return {\n ok: true,\n sessionId: existingRecord.sessionId,\n threadId: existingThreadId,\n status: \"existing\",\n };\n }\n }\n\n // 5. Find adapter (explicit channel or default first)\n let adapterChannelId: string;\n if (channelId) {\n if (!this.adapters.has(channelId)) {\n const available = Array.from(this.adapters.keys()).join(\", \") || \"none\";\n return { ok: false, error: \"adapter_not_found\", message: `Adapter '${channelId}' is not connected. Available: ${available}` };\n }\n adapterChannelId = channelId;\n } else {\n const firstEntry = this.adapters.entries().next().value;\n if (!firstEntry) {\n return { ok: false, error: \"no_adapter\", message: \"No channel adapter registered\" };\n }\n adapterChannelId = firstEntry[0];\n }\n\n // 6. Create session via unified pipeline\n let session: Session;\n try {\n session = await this.createSession({\n channelId: adapterChannelId,\n agentName,\n workingDirectory: cwd,\n resumeAgentSessionId: agentSessionId,\n createThread: true,\n initialName: \"Adopted session\",\n });\n } catch (err) {\n return {\n ok: false,\n error: \"resume_failed\",\n message: `Failed to resume session: ${err instanceof Error ? err.message : String(err)}`,\n };\n }\n\n // 7. Update store with adopt-specific fields\n const adoptPlatform: Record<string, unknown> = {};\n if (adapterChannelId === 'telegram') {\n adoptPlatform.topicId = Number(session.threadId);\n } else {\n adoptPlatform.threadId = session.threadId;\n }\n await this.sessionManager.patchRecord(session.id, {\n originalAgentSessionId: agentSessionId,\n platform: adoptPlatform,\n });\n\n return {\n ok: true,\n sessionId: session.id,\n threadId: session.threadId,\n status: \"adopted\",\n };\n }\n\n async handleNewChat(\n channelId: string,\n currentThreadId: string,\n ): Promise<Session | null> {\n const currentSession = this.sessionManager.getSessionByThread(\n channelId,\n currentThreadId,\n );\n\n if (currentSession) {\n return this.handleNewSession(\n channelId,\n currentSession.agentName,\n currentSession.workingDirectory,\n );\n }\n\n // Fallback: look up from store (e.g. after restart before lazy resume)\n const record = this.sessionManager.getRecordByThread(\n channelId,\n currentThreadId,\n );\n if (!record || record.status === \"cancelled\" || record.status === \"error\")\n return null;\n\n return this.handleNewSession(\n channelId,\n record.agentName,\n record.workingDir,\n );\n }\n\n async createSessionWithContext(params: {\n channelId: string;\n agentName: string;\n workingDirectory: string;\n contextQuery: ContextQuery;\n contextOptions?: ContextOptions;\n createThread?: boolean;\n }): Promise<{ session: Session; contextResult: ContextResult | null }> {\n let contextResult: ContextResult | null = null;\n try {\n contextResult = await this.contextManager.buildContext(\n params.contextQuery,\n params.contextOptions,\n );\n } catch (err) {\n log.warn({ err }, \"Context building failed, proceeding without context\");\n }\n\n const session = await this.createSession({\n channelId: params.channelId,\n agentName: params.agentName,\n workingDirectory: params.workingDirectory,\n createThread: params.createThread,\n });\n\n if (contextResult) {\n session.setContext(contextResult.markdown);\n }\n\n return { session, contextResult };\n }\n\n // --- Lazy Resume ---\n\n /**\n * Get active session by thread, or attempt lazy resume from store.\n * Used by adapter command handlers that need a session but don't go through handleMessage().\n */\n async getOrResumeSession(channelId: string, threadId: string): Promise<Session | null> {\n const session = this.sessionManager.getSessionByThread(channelId, threadId);\n if (session) return session;\n return this.lazyResume({ channelId, threadId, userId: \"\", text: \"\" });\n }\n\n private async lazyResume(message: IncomingMessage): Promise<Session | null> {\n const store = this.sessionStore;\n if (!store) return null;\n\n const lockKey = `${message.channelId}:${message.threadId}`;\n\n // Check for existing resume in progress\n const existing = this.resumeLocks.get(lockKey);\n if (existing) return existing;\n\n const record = store.findByPlatform(\n message.channelId,\n (p) => String(p.topicId) === message.threadId,\n );\n if (!record) {\n log.debug(\n { threadId: message.threadId, channelId: message.channelId },\n \"No session record found for thread\",\n );\n return null;\n }\n\n // Don't resume errored sessions (cancelled sessions can still be resumed)\n if (record.status === \"error\") {\n log.debug(\n {\n threadId: message.threadId,\n sessionId: record.sessionId,\n status: record.status,\n },\n \"Skipping resume of error session\",\n );\n return null;\n }\n\n log.info(\n {\n threadId: message.threadId,\n sessionId: record.sessionId,\n status: record.status,\n },\n \"Lazy resume: found record, attempting resume\",\n );\n\n const resumePromise = (async (): Promise<Session | null> => {\n try {\n const session = await this.createSession({\n channelId: record.channelId,\n agentName: record.agentName,\n workingDirectory: record.workingDir,\n resumeAgentSessionId: record.agentSessionId,\n existingSessionId: record.sessionId,\n initialName: record.name,\n });\n session.threadId = message.threadId;\n session.activate();\n session.dangerousMode = record.dangerousMode ?? false;\n\n log.info(\n { sessionId: session.id, threadId: message.threadId },\n \"Lazy resume successful\",\n );\n return session;\n } catch (err) {\n log.error({ err, record }, \"Lazy resume failed\");\n // Send error feedback to user instead of silent drop\n const adapter = this.adapters.get(message.channelId);\n if (adapter) {\n try {\n await adapter.sendMessage(message.threadId, {\n type: \"error\",\n text: `⚠️ Failed to resume session: ${err instanceof Error ? err.message : String(err)}`,\n });\n } catch {\n /* best effort */\n }\n }\n return null;\n } finally {\n this.resumeLocks.delete(lockKey);\n }\n })();\n\n this.resumeLocks.set(lockKey, resumePromise);\n return resumePromise;\n }\n\n // --- Event Wiring ---\n\n /** Create a SessionBridge for the given session and adapter */\n createBridge(session: Session, adapter: ChannelAdapter): SessionBridge {\n return new SessionBridge(session, adapter, {\n messageTransformer: this.messageTransformer,\n notificationManager: this.notificationManager,\n sessionManager: this.sessionManager,\n eventBus: this.eventBus,\n fileService: this.fileService,\n });\n }\n}\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { SessionRecord } from \"./types.js\";\nimport { createChildLogger } from \"./log.js\";\n\nconst log = createChildLogger({ module: \"session-store\" });\n\nexport interface SessionStore {\n save(record: SessionRecord): Promise<void>;\n get(sessionId: string): SessionRecord | undefined;\n findByPlatform(\n channelId: string,\n predicate: (platform: Record<string, unknown>) => boolean,\n ): SessionRecord | undefined;\n findByAgentSessionId(agentSessionId: string): SessionRecord | undefined;\n list(channelId?: string): SessionRecord[];\n remove(sessionId: string): Promise<void>;\n}\n\ninterface StoreFile {\n version: number;\n sessions: Record<string, SessionRecord>;\n}\n\nconst DEBOUNCE_MS = 2000;\n\nexport class JsonFileSessionStore implements SessionStore {\n private records: Map<string, SessionRecord> = new Map();\n private filePath: string;\n private ttlDays: number;\n private debounceTimer: ReturnType<typeof setTimeout> | null = null;\n private cleanupInterval: ReturnType<typeof setInterval> | null = null;\n private flushHandler: (() => void) | null = null;\n\n constructor(filePath: string, ttlDays: number) {\n this.filePath = filePath;\n this.ttlDays = ttlDays;\n this.load();\n this.cleanup();\n\n // Daily cleanup for long-running instances\n this.cleanupInterval = setInterval(\n () => this.cleanup(),\n 24 * 60 * 60 * 1000,\n );\n\n // Force flush on shutdown\n this.flushHandler = () => this.flushSync();\n process.on(\"SIGTERM\", this.flushHandler);\n process.on(\"SIGINT\", this.flushHandler);\n process.on(\"exit\", this.flushHandler);\n }\n\n async save(record: SessionRecord): Promise<void> {\n this.records.set(record.sessionId, { ...record });\n this.scheduleDiskWrite();\n }\n\n get(sessionId: string): SessionRecord | undefined {\n return this.records.get(sessionId);\n }\n\n findByPlatform(\n channelId: string,\n predicate: (platform: Record<string, unknown>) => boolean,\n ): SessionRecord | undefined {\n for (const record of this.records.values()) {\n if (record.channelId === channelId && predicate(record.platform)) {\n return record;\n }\n }\n return undefined;\n }\n\n findByAgentSessionId(agentSessionId: string): SessionRecord | undefined {\n return [...this.records.values()].find(\n (r) =>\n r.agentSessionId === agentSessionId ||\n r.originalAgentSessionId === agentSessionId,\n );\n }\n\n list(channelId?: string): SessionRecord[] {\n const all = [...this.records.values()];\n if (channelId) return all.filter((r) => r.channelId === channelId);\n return all;\n }\n\n async remove(sessionId: string): Promise<void> {\n this.records.delete(sessionId);\n this.scheduleDiskWrite();\n }\n\n flushSync(): void {\n if (this.debounceTimer) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = null;\n }\n const data: StoreFile = {\n version: 1,\n sessions: Object.fromEntries(this.records),\n };\n const dir = path.dirname(this.filePath);\n if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.filePath, JSON.stringify(data, null, 2));\n }\n\n destroy(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n if (this.cleanupInterval) clearInterval(this.cleanupInterval);\n if (this.flushHandler) {\n process.removeListener(\"SIGTERM\", this.flushHandler);\n process.removeListener(\"SIGINT\", this.flushHandler);\n process.removeListener(\"exit\", this.flushHandler);\n this.flushHandler = null;\n }\n }\n\n private load(): void {\n if (!fs.existsSync(this.filePath)) return;\n try {\n const raw = JSON.parse(\n fs.readFileSync(this.filePath, \"utf-8\"),\n ) as StoreFile;\n if (raw.version !== 1) {\n log.warn(\n { version: raw.version },\n \"Unknown session store version, skipping load\",\n );\n return;\n }\n for (const [id, record] of Object.entries(raw.sessions)) {\n this.records.set(id, record);\n }\n log.debug({ count: this.records.size }, \"Loaded session records\");\n } catch (err) {\n log.error({ err }, \"Failed to load session store\");\n }\n }\n\n private cleanup(): void {\n const cutoff = Date.now() - this.ttlDays * 24 * 60 * 60 * 1000;\n let removed = 0;\n for (const [id, record] of this.records) {\n if (record.status === \"active\" || record.status === \"initializing\")\n continue;\n const lastActive = new Date(record.lastActiveAt).getTime();\n if (lastActive < cutoff) {\n this.records.delete(id);\n removed++;\n }\n }\n if (removed > 0) {\n log.info({ removed }, \"Cleaned up expired session records\");\n this.scheduleDiskWrite();\n }\n }\n\n private scheduleDiskWrite(): void {\n if (this.debounceTimer) clearTimeout(this.debounceTimer);\n this.debounceTimer = setTimeout(() => {\n this.flushSync();\n }, DEBOUNCE_MS);\n }\n}\n","import * as http from \"node:http\";\nimport type { EventBus, EventBusEvents } from \"./event-bus.js\";\n\ninterface SSEResponse extends http.ServerResponse {\n sessionFilter?: string;\n}\n\ninterface SessionStats {\n active: number;\n total: number;\n}\n\nexport class SSEManager {\n private sseConnections = new Set<http.ServerResponse>();\n private sseCleanupHandlers = new Map<http.ServerResponse, () => void>();\n private healthInterval?: ReturnType<typeof setInterval>;\n private boundHandlers: Array<{\n event: keyof EventBusEvents;\n handler: (data: unknown) => void;\n }> = [];\n\n constructor(\n private eventBus: EventBus | undefined,\n private getSessionStats: () => SessionStats,\n private startedAt: number,\n ) {}\n\n setup(): void {\n if (!this.eventBus) return;\n\n const events = [\n \"session:created\",\n \"session:updated\",\n \"session:deleted\",\n \"agent:event\",\n \"permission:request\",\n ] as const;\n\n for (const eventName of events) {\n const handler = (data: unknown) => {\n this.broadcast(eventName, data);\n };\n this.eventBus.on(eventName, handler);\n this.boundHandlers.push({ event: eventName, handler });\n }\n\n // Health heartbeat every 30s\n this.healthInterval = setInterval(() => {\n const mem = process.memoryUsage();\n const stats = this.getSessionStats();\n this.broadcast(\"health\", {\n uptime: Date.now() - this.startedAt,\n memory: {\n rss: mem.rss,\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n },\n sessions: stats,\n });\n }, 30_000);\n }\n\n handleRequest(req: http.IncomingMessage, res: http.ServerResponse): void {\n const parsedUrl = new URL(req.url || \"\", \"http://localhost\");\n const sessionFilter = parsedUrl.searchParams.get(\"sessionId\");\n\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n });\n res.flushHeaders();\n\n // Store filter metadata on the response for broadcast\n (res as SSEResponse).sessionFilter = sessionFilter ?? undefined;\n\n this.sseConnections.add(res);\n\n const cleanup = () => {\n this.sseConnections.delete(res);\n this.sseCleanupHandlers.delete(res);\n };\n this.sseCleanupHandlers.set(res, cleanup);\n req.on(\"close\", cleanup);\n }\n\n broadcast(event: string, data: unknown): void {\n const payload = `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n // Events that carry sessionId and should be filtered\n const sessionEvents = [\n \"agent:event\",\n \"permission:request\",\n \"session:updated\",\n ];\n for (const res of this.sseConnections) {\n const filter = (res as SSEResponse).sessionFilter;\n if (filter && sessionEvents.includes(event)) {\n const eventData = data as { sessionId: string };\n if (eventData.sessionId !== filter) continue;\n }\n try {\n if (res.writable) res.write(payload);\n } catch {\n /* connection closed */\n }\n }\n }\n\n stop(): void {\n if (this.healthInterval) clearInterval(this.healthInterval);\n\n // Remove only our own event bus listeners\n if (this.eventBus) {\n for (const { event, handler } of this.boundHandlers) {\n this.eventBus.off(event, handler);\n }\n }\n this.boundHandlers = [];\n\n // Copy to avoid modifying Map while iterating\n const entries = [...this.sseCleanupHandlers];\n for (const [res, cleanup] of entries) {\n res.end();\n cleanup();\n }\n }\n}\n\nexport type { SessionStats };\n","import * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst MIME_TYPES: Record<string, string> = {\n \".html\": \"text/html; charset=utf-8\",\n \".js\": \"application/javascript; charset=utf-8\",\n \".css\": \"text/css; charset=utf-8\",\n \".json\": \"application/json; charset=utf-8\",\n \".png\": \"image/png\",\n \".jpg\": \"image/jpeg\",\n \".svg\": \"image/svg+xml\",\n \".ico\": \"image/x-icon\",\n \".woff\": \"font/woff\",\n \".woff2\": \"font/woff2\",\n};\n\nexport class StaticServer {\n private uiDir: string | undefined;\n\n constructor(uiDir?: string) {\n this.uiDir = uiDir;\n\n if (!this.uiDir) {\n const __filename = fileURLToPath(import.meta.url);\n const candidate = path.resolve(path.dirname(__filename), \"../../ui/dist\");\n if (fs.existsSync(path.join(candidate, \"index.html\"))) {\n this.uiDir = candidate;\n }\n // Also check dist-publish layout\n if (!this.uiDir) {\n const publishCandidate = path.resolve(\n path.dirname(__filename),\n \"../ui\",\n );\n if (fs.existsSync(path.join(publishCandidate, \"index.html\"))) {\n this.uiDir = publishCandidate;\n }\n }\n }\n }\n\n isAvailable(): boolean {\n return this.uiDir !== undefined;\n }\n\n serve(req: http.IncomingMessage, res: http.ServerResponse): boolean {\n if (!this.uiDir) return false;\n\n const urlPath = (req.url || \"/\").split(\"?\")[0];\n const safePath = path.normalize(urlPath);\n\n // Try exact file match\n const filePath = path.join(this.uiDir, safePath);\n if (!filePath.startsWith(this.uiDir + path.sep) && filePath !== this.uiDir)\n return false; // path traversal guard\n\n if (fs.existsSync(filePath) && fs.statSync(filePath).isFile()) {\n const ext = path.extname(filePath);\n const contentType = MIME_TYPES[ext] ?? \"application/octet-stream\";\n // Vite-hashed assets get long cache, others get no-cache\n const isHashed = /\\.[a-zA-Z0-9]{8,}\\.(js|css)$/.test(filePath);\n const cacheControl = isHashed\n ? \"public, max-age=31536000, immutable\"\n : \"no-cache\";\n res.writeHead(200, {\n \"Content-Type\": contentType,\n \"Cache-Control\": cacheControl,\n });\n fs.createReadStream(filePath).pipe(res);\n return true;\n }\n\n // SPA fallback — serve index.html\n const indexPath = path.join(this.uiDir, \"index.html\");\n if (fs.existsSync(indexPath)) {\n res.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-cache\",\n });\n fs.createReadStream(indexPath).pipe(res);\n return true;\n }\n\n return false;\n }\n}\n","import * as http from \"node:http\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport * as os from \"node:os\";\nimport * as crypto from \"node:crypto\";\nimport { fileURLToPath } from \"node:url\";\nimport type { OpenACPCore } from \"../core.js\";\nimport type { TopicManager } from \"../topic-manager.js\";\nimport { createChildLogger } from \"../log.js\";\nimport { SSEManager } from \"../sse-manager.js\";\nimport { StaticServer } from \"../static-server.js\";\nimport { Router } from \"./router.js\";\nimport { registerHealthRoutes } from \"./routes/health.js\";\nimport { registerSessionRoutes } from \"./routes/sessions.js\";\nimport { registerConfigRoutes } from \"./routes/config.js\";\nimport { registerTopicRoutes } from \"./routes/topics.js\";\nimport { registerTunnelRoutes } from \"./routes/tunnel.js\";\nimport { registerAgentRoutes } from \"./routes/agents.js\";\nimport { registerNotifyRoutes } from \"./routes/notify.js\";\n\nconst log = createChildLogger({ module: \"api-server\" });\n\nconst DEFAULT_PORT_FILE = path.join(os.homedir(), \".openacp\", \"api.port\");\n\nlet cachedVersion: string | undefined;\n\nfunction getVersion(): string {\n if (cachedVersion) return cachedVersion;\n try {\n const __filename = fileURLToPath(import.meta.url);\n const pkgPath = path.resolve(\n path.dirname(__filename),\n \"../../../package.json\",\n );\n const pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n cachedVersion = pkg.version ?? \"0.0.0-dev\";\n } catch {\n cachedVersion = \"0.0.0-dev\";\n }\n return cachedVersion!;\n}\n\nexport interface ApiConfig {\n port: number;\n host: string;\n}\n\n/** Dependencies passed to route registration functions. */\nexport interface RouteDeps {\n core: OpenACPCore;\n topicManager?: TopicManager;\n startedAt: number;\n getVersion: () => string;\n sendJson: (res: http.ServerResponse, status: number, data: unknown) => void;\n readBody: (req: http.IncomingMessage) => Promise<string | null>;\n}\n\nexport class ApiServer {\n private server: http.Server | null = null;\n private actualPort: number = 0;\n private portFilePath: string;\n private startedAt = Date.now();\n private secret: string = \"\";\n private secretFilePath: string;\n private sseManager: SSEManager;\n private staticServer: StaticServer;\n private router: Router;\n\n constructor(\n private core: OpenACPCore,\n private config: ApiConfig,\n portFilePath?: string,\n private topicManager?: TopicManager,\n secretFilePath?: string,\n uiDir?: string,\n ) {\n this.portFilePath = portFilePath ?? DEFAULT_PORT_FILE;\n this.secretFilePath =\n secretFilePath ?? path.join(os.homedir(), \".openacp\", \"api-secret\");\n this.staticServer = new StaticServer(uiDir);\n this.sseManager = new SSEManager(\n core.eventBus,\n () => {\n const sessions = this.core.sessionManager.listSessions();\n return {\n active: sessions.filter(\n (s) => s.status === \"active\" || s.status === \"initializing\",\n ).length,\n total: sessions.length,\n };\n },\n this.startedAt,\n );\n\n this.router = new Router();\n const deps: RouteDeps = {\n core: this.core,\n topicManager: this.topicManager,\n startedAt: this.startedAt,\n getVersion,\n sendJson: this.sendJson.bind(this),\n readBody: this.readBody.bind(this),\n };\n\n registerHealthRoutes(this.router, deps);\n registerSessionRoutes(this.router, deps);\n registerConfigRoutes(this.router, deps);\n registerTopicRoutes(this.router, deps);\n registerTunnelRoutes(this.router, deps);\n registerAgentRoutes(this.router, deps);\n registerNotifyRoutes(this.router, deps);\n }\n\n async start(): Promise<void> {\n this.loadOrCreateSecret();\n this.server = http.createServer((req, res) => this.handleRequest(req, res));\n\n await new Promise<void>((resolve, reject) => {\n this.server!.on(\"error\", (err: NodeJS.ErrnoException) => {\n if (err.code === \"EADDRINUSE\") {\n log.warn(\n { port: this.config.port },\n \"API port in use, continuing without API server\",\n );\n this.server = null;\n // actualPort stays 0, port file not written\n resolve();\n } else {\n reject(err);\n }\n });\n\n this.server!.listen(this.config.port, this.config.host, () => {\n const addr = this.server!.address();\n if (addr && typeof addr === \"object\") {\n this.actualPort = addr.port;\n }\n this.writePortFile();\n log.info(\n { host: this.config.host, port: this.actualPort },\n \"API server listening\",\n );\n this.sseManager.setup();\n\n if (\n this.config.host !== \"127.0.0.1\" &&\n this.config.host !== \"localhost\"\n ) {\n log.warn(\n \"API server binding to non-localhost. Ensure api-secret file is secured.\",\n );\n }\n\n resolve();\n });\n });\n }\n\n async stop(): Promise<void> {\n this.sseManager.stop();\n this.removePortFile();\n if (this.server) {\n await new Promise<void>((resolve) => {\n this.server!.close(() => resolve());\n });\n this.server = null;\n }\n }\n\n getPort(): number {\n return this.actualPort;\n }\n\n getSecret(): string {\n return this.secret;\n }\n\n private writePortFile(): void {\n const dir = path.dirname(this.portFilePath);\n fs.mkdirSync(dir, { recursive: true });\n fs.writeFileSync(this.portFilePath, String(this.actualPort));\n }\n\n private removePortFile(): void {\n try {\n fs.unlinkSync(this.portFilePath);\n } catch {\n /* ignore */\n }\n }\n\n private loadOrCreateSecret(): void {\n const dir = path.dirname(this.secretFilePath);\n fs.mkdirSync(dir, { recursive: true });\n\n try {\n this.secret = fs.readFileSync(this.secretFilePath, \"utf-8\").trim();\n if (this.secret) {\n // Warn if file permissions are too open (like SSH does for private keys)\n try {\n const stat = fs.statSync(this.secretFilePath);\n const mode = stat.mode & 0o777;\n if (mode & 0o077) {\n log.warn(\n { path: this.secretFilePath, mode: \"0\" + mode.toString(8) },\n \"API secret file has insecure permissions (should be 0600). Run: chmod 600 %s\",\n this.secretFilePath,\n );\n }\n } catch {\n /* stat failed, skip check */\n }\n return;\n }\n } catch {\n // File doesn't exist, create it\n }\n\n this.secret = crypto.randomBytes(32).toString(\"hex\");\n fs.writeFileSync(this.secretFilePath, this.secret, { mode: 0o600 });\n }\n\n private authenticate(\n req: http.IncomingMessage,\n allowQueryParam = false,\n ): boolean {\n // Check Authorization header\n const authHeader = req.headers.authorization;\n if (authHeader?.startsWith(\"Bearer \")) {\n const token = authHeader.slice(7);\n if (\n token.length === this.secret.length &&\n crypto.timingSafeEqual(\n Buffer.from(token, \"utf-8\"),\n Buffer.from(this.secret, \"utf-8\"),\n )\n ) {\n return true;\n }\n }\n // Query param auth only for SSE (EventSource can't set headers)\n if (allowQueryParam) {\n const parsedUrl = new URL(req.url || \"\", \"http://localhost\");\n const qToken = parsedUrl.searchParams.get(\"token\");\n if (\n qToken &&\n qToken.length === this.secret.length &&\n crypto.timingSafeEqual(\n Buffer.from(qToken, \"utf-8\"),\n Buffer.from(this.secret, \"utf-8\"),\n )\n ) {\n return true;\n }\n }\n return false;\n }\n\n private async handleRequest(\n req: http.IncomingMessage,\n res: http.ServerResponse,\n ): Promise<void> {\n const method = req.method?.toUpperCase();\n const url = req.url || \"\";\n\n // Auth check: exempt health/version, SSE (has own auth), and non-/api/ routes (static files)\n if (url.startsWith(\"/api/\")) {\n const isExempt =\n method === \"GET\" &&\n (url === \"/api/health\" ||\n url === \"/api/version\" ||\n url.startsWith(\"/api/events\"));\n if (!isExempt && !this.authenticate(req)) {\n this.sendJson(res, 401, { error: \"Unauthorized\" });\n return;\n }\n }\n\n try {\n // SSE endpoint — handled separately (streaming connection)\n if (method === \"GET\" && url.startsWith(\"/api/events\")) {\n if (!this.authenticate(req, true)) {\n this.sendJson(res, 401, { error: \"Unauthorized\" });\n return;\n }\n this.sseManager.handleRequest(req, res);\n return; // Don't end the response — SSE keeps it open\n }\n\n // Try router for API routes\n if (url.startsWith(\"/api/\")) {\n const match = this.router.match(method!, url);\n if (match) {\n await match.handler(req, res, match.params);\n } else {\n this.sendJson(res, 404, { error: \"Not found\" });\n }\n return;\n }\n\n // Try static file serving (UI dashboard) for non-API routes\n if (!this.staticServer.serve(req, res)) {\n this.sendJson(res, 404, { error: \"Not found\" });\n }\n } catch (err) {\n log.error({ err }, \"API request error\");\n this.sendJson(res, 500, { error: \"Internal server error\" });\n }\n }\n\n private sendJson(\n res: http.ServerResponse,\n status: number,\n data: unknown,\n ): void {\n res.writeHead(status, { \"Content-Type\": \"application/json\" });\n res.end(JSON.stringify(data));\n }\n\n private readBody(req: http.IncomingMessage): Promise<string | null> {\n const MAX_BODY_SIZE = 1024 * 1024; // 1MB\n return new Promise((resolve) => {\n let data = \"\";\n let size = 0;\n let destroyed = false;\n req.on(\"data\", (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_SIZE && !destroyed) {\n destroyed = true;\n req.destroy();\n resolve(null);\n return;\n }\n if (!destroyed) data += chunk;\n });\n req.on(\"end\", () => {\n if (!destroyed) resolve(data);\n });\n req.on(\"error\", () => {\n if (!destroyed) resolve(\"\");\n });\n });\n }\n}\n","import type * as http from \"node:http\";\n\nexport type Handler = (\n req: http.IncomingMessage,\n res: http.ServerResponse,\n params: Record<string, string>,\n) => Promise<void>;\n\ninterface Route {\n method: string;\n pattern: RegExp;\n keys: string[];\n handler: Handler;\n}\n\nexport class Router {\n private routes: Route[] = [];\n\n get(path: string, handler: Handler): void {\n this.add(\"GET\", path, handler);\n }\n post(path: string, handler: Handler): void {\n this.add(\"POST\", path, handler);\n }\n put(path: string, handler: Handler): void {\n this.add(\"PUT\", path, handler);\n }\n patch(path: string, handler: Handler): void {\n this.add(\"PATCH\", path, handler);\n }\n delete(path: string, handler: Handler): void {\n this.add(\"DELETE\", path, handler);\n }\n\n match(\n method: string,\n url: string,\n ): { handler: Handler; params: Record<string, string> } | null {\n const pathname = url.split(\"?\")[0];\n for (const route of this.routes) {\n if (route.method !== method) continue;\n const m = pathname.match(route.pattern);\n if (!m) continue;\n const params: Record<string, string> = {};\n for (let i = 0; i < route.keys.length; i++) {\n params[route.keys[i]] = m[i + 1];\n }\n return { handler: route.handler, params };\n }\n return null;\n }\n\n private add(method: string, path: string, handler: Handler): void {\n const keys: string[] = [];\n const pattern = path.replace(/:(\\w+)/g, (_, key) => {\n keys.push(key);\n return \"([^/]+)\";\n });\n this.routes.push({\n method,\n pattern: new RegExp(`^${pattern}$`),\n keys,\n handler,\n });\n }\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\n\nexport function registerHealthRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/health\", async (_req, res) => {\n const activeSessions = deps.core.sessionManager.listSessions();\n const allRecords = deps.core.sessionManager.listRecords();\n const mem = process.memoryUsage();\n const tunnel = deps.core.tunnelService;\n\n deps.sendJson(res, 200, {\n status: \"ok\",\n uptime: Date.now() - deps.startedAt,\n version: deps.getVersion(),\n memory: {\n rss: mem.rss,\n heapUsed: mem.heapUsed,\n heapTotal: mem.heapTotal,\n },\n sessions: {\n active: activeSessions.filter(\n (s) => s.status === \"active\" || s.status === \"initializing\",\n ).length,\n total: allRecords.length,\n },\n adapters: Array.from(deps.core.adapters.keys()),\n tunnel: tunnel\n ? { enabled: true, url: tunnel.getPublicUrl() }\n : { enabled: false },\n });\n });\n\n router.get(\"/api/version\", async (_req, res) => {\n deps.sendJson(res, 200, { version: deps.getVersion() });\n });\n\n router.post(\"/api/restart\", async (_req, res) => {\n if (!deps.core.requestRestart) {\n deps.sendJson(res, 501, { error: \"Restart not available\" });\n return;\n }\n\n deps.sendJson(res, 200, { ok: true, message: \"Restarting...\" });\n setImmediate(() => deps.core.requestRestart!());\n });\n\n router.get(\"/api/adapters\", async (_req, res) => {\n const adapters = Array.from(deps.core.adapters.entries()).map(([name]) => ({\n name,\n type: \"built-in\" as const,\n }));\n deps.sendJson(res, 200, { adapters });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\nimport { createChildLogger } from \"../../log.js\";\n\nconst log = createChildLogger({ module: \"api-server\" });\n\nexport function registerSessionRoutes(router: Router, deps: RouteDeps): void {\n router.post(\"/api/sessions/adopt\", async (req, res) => {\n const body = await deps.readBody(req);\n if (body === null) {\n return deps.sendJson(res, 413, { error: \"Request body too large\" });\n }\n if (!body) {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Empty request body\",\n });\n }\n\n let parsed: { agent?: string; agentSessionId?: string; cwd?: string; channel?: string };\n try {\n parsed = JSON.parse(body);\n } catch {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Invalid JSON\",\n });\n }\n\n const { agent, agentSessionId, cwd, channel } = parsed;\n\n if (!agent || !agentSessionId) {\n return deps.sendJson(res, 400, {\n error: \"bad_request\",\n message: \"Missing required fields: agent, agentSessionId\",\n });\n }\n\n const result = await deps.core.adoptSession(\n agent,\n agentSessionId,\n cwd ?? process.cwd(),\n channel,\n );\n\n if (result.ok) {\n return deps.sendJson(res, 200, result);\n } else {\n const status =\n result.error === \"session_limit\"\n ? 429\n : result.error === \"agent_not_supported\"\n ? 400\n : 500;\n return deps.sendJson(res, status, result);\n }\n });\n\n router.post(\"/api/sessions\", async (req, res) => {\n const body = await deps.readBody(req);\n let agent: string | undefined;\n let workspace: string | undefined;\n\n if (body) {\n try {\n const parsed = JSON.parse(body);\n agent = parsed.agent;\n workspace = parsed.workspace;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n // Check max concurrent sessions\n const config = deps.core.configManager.get();\n const activeSessions = deps.core.sessionManager\n .listSessions()\n .filter((s) => s.status === \"active\" || s.status === \"initializing\");\n if (activeSessions.length >= config.security.maxConcurrentSessions) {\n deps.sendJson(res, 429, {\n error: `Max concurrent sessions (${config.security.maxConcurrentSessions}) reached. Cancel a session first.`,\n });\n return;\n }\n\n // Use the first registered adapter (e.g. Telegram) so API sessions appear in the channel\n const [adapterId, adapter] = deps.core.adapters.entries().next().value ?? [\n null,\n null,\n ];\n const channelId = adapterId ?? \"api\";\n\n const resolvedAgent = agent || config.defaultAgent;\n const resolvedWorkspace = deps.core.configManager.resolveWorkspace(\n workspace || config.agents[resolvedAgent]?.workingDirectory,\n );\n\n const session = await deps.core.createSession({\n channelId,\n agentName: resolvedAgent,\n workingDirectory: resolvedWorkspace,\n createThread: !!adapter,\n initialName: `🔄 ${resolvedAgent} — New Session`,\n });\n\n // If no adapter wired events (headless), auto-approve permissions\n if (!adapter) {\n session.agentInstance.onPermissionRequest = async (request) => {\n const allowOption = request.options.find((o) => o.isAllow);\n log.debug(\n {\n sessionId: session.id,\n permissionId: request.id,\n option: allowOption?.id,\n },\n \"Auto-approving permission for API session\",\n );\n return allowOption?.id ?? request.options[0]?.id ?? \"\";\n };\n }\n\n // Warmup in background so session moves from 'initializing' to 'active'\n session\n .warmup()\n .catch((err) =>\n log.warn({ err, sessionId: session.id }, \"API session warmup failed\"),\n );\n\n deps.sendJson(res, 200, {\n sessionId: session.id,\n agent: session.agentName,\n status: session.status,\n workspace: session.workingDirectory,\n });\n });\n\n router.post(\"/api/sessions/:sessionId/prompt\", async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n if (\n session.status === \"cancelled\" ||\n session.status === \"finished\" ||\n session.status === \"error\"\n ) {\n deps.sendJson(res, 400, { error: `Session is ${session.status}` });\n return;\n }\n\n const body = await deps.readBody(req);\n let prompt: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n prompt = parsed.prompt;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!prompt) {\n deps.sendJson(res, 400, { error: \"Missing prompt\" });\n return;\n }\n\n session.enqueuePrompt(prompt).catch(() => {});\n deps.sendJson(res, 200, {\n ok: true,\n sessionId,\n queueDepth: session.queueDepth,\n });\n });\n\n router.post(\n \"/api/sessions/:sessionId/permission\",\n async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n const body = await deps.readBody(req);\n let permissionId: string | undefined;\n let optionId: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n permissionId = parsed.permissionId;\n optionId = parsed.optionId;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!permissionId || !optionId) {\n deps.sendJson(res, 400, {\n error: \"Missing permissionId or optionId\",\n });\n return;\n }\n\n if (\n !session.permissionGate.isPending ||\n session.permissionGate.requestId !== permissionId\n ) {\n deps.sendJson(res, 400, {\n error: \"No matching pending permission request\",\n });\n return;\n }\n\n session.permissionGate.resolve(optionId);\n deps.sendJson(res, 200, { ok: true });\n },\n );\n\n router.patch(\n \"/api/sessions/:sessionId/dangerous\",\n async (req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n const body = await deps.readBody(req);\n let enabled: boolean | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n enabled = parsed.enabled;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (typeof enabled !== \"boolean\") {\n deps.sendJson(res, 400, { error: \"Missing enabled boolean\" });\n return;\n }\n\n session.dangerousMode = enabled;\n await deps.core.sessionManager.patchRecord(sessionId, {\n dangerousMode: enabled,\n });\n deps.sendJson(res, 200, { ok: true, dangerousMode: enabled });\n },\n );\n\n router.get(\"/api/sessions/:sessionId\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n\n deps.sendJson(res, 200, {\n session: {\n id: session.id,\n agent: session.agentName,\n status: session.status,\n name: session.name ?? null,\n workspace: session.workingDirectory,\n createdAt: session.createdAt.toISOString(),\n dangerousMode: session.dangerousMode,\n queueDepth: session.queueDepth,\n promptRunning: session.promptRunning,\n threadId: session.threadId,\n channelId: session.channelId,\n agentSessionId: session.agentSessionId,\n },\n });\n });\n\n router.post(\"/api/sessions/:sessionId/summary\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const result = await deps.core.summarizeSession(sessionId);\n if (result.ok) {\n deps.sendJson(res, 200, result);\n } else {\n deps.sendJson(res, 400, result);\n }\n });\n\n router.post(\"/api/sessions/:sessionId/archive\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const result = await deps.core.archiveSession(sessionId);\n if (result.ok) {\n deps.sendJson(res, 200, result);\n } else {\n deps.sendJson(res, 400, result);\n }\n });\n\n router.delete(\"/api/sessions/:sessionId\", async (_req, res, params) => {\n const sessionId = decodeURIComponent(params.sessionId);\n const session = deps.core.sessionManager.getSession(sessionId);\n if (!session) {\n deps.sendJson(res, 404, { error: `Session \"${sessionId}\" not found` });\n return;\n }\n await deps.core.sessionManager.cancelSession(sessionId);\n deps.sendJson(res, 200, { ok: true });\n });\n\n router.get(\"/api/sessions\", async (_req, res) => {\n const sessions = deps.core.sessionManager.listSessions();\n deps.sendJson(res, 200, {\n sessions: sessions.map((s) => ({\n id: s.id,\n agent: s.agentName,\n status: s.status,\n name: s.name ?? null,\n workspace: s.workingDirectory,\n createdAt: s.createdAt.toISOString(),\n dangerousMode: s.dangerousMode,\n queueDepth: s.queueDepth,\n promptRunning: s.promptRunning,\n lastActiveAt:\n deps.core.sessionManager.getSessionRecord(s.id)?.lastActiveAt ??\n null,\n })),\n });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\n\nconst SENSITIVE_KEYS = [\n \"botToken\",\n \"token\",\n \"apiKey\",\n \"secret\",\n \"password\",\n \"webhookSecret\",\n];\n\nfunction redactConfig(config: unknown): unknown {\n const redacted = structuredClone(config);\n redactDeep(redacted as Record<string, unknown>);\n return redacted;\n}\n\nfunction redactDeep(obj: Record<string, unknown>): void {\n for (const [key, value] of Object.entries(obj)) {\n if (SENSITIVE_KEYS.includes(key) && typeof value === \"string\") {\n obj[key] = \"***\";\n } else if (Array.isArray(value)) {\n for (const item of value) {\n if (item && typeof item === \"object\")\n redactDeep(item as Record<string, unknown>);\n }\n } else if (value && typeof value === \"object\") {\n redactDeep(value as Record<string, unknown>);\n }\n }\n}\n\nexport function registerConfigRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/config/editable\", async (_req, res) => {\n const { getSafeFields, resolveOptions, getConfigValue } =\n await import(\"../../config-registry.js\");\n const config = deps.core.configManager.get();\n const safeFields = getSafeFields();\n\n const fields = safeFields.map((def) => ({\n path: def.path,\n displayName: def.displayName,\n group: def.group,\n type: def.type,\n options: resolveOptions(def, config),\n value: getConfigValue(config, def.path),\n hotReload: def.hotReload,\n }));\n\n deps.sendJson(res, 200, { fields });\n });\n\n router.get(\"/api/config\", async (_req, res) => {\n const config = deps.core.configManager.get();\n deps.sendJson(res, 200, { config: redactConfig(config) });\n });\n\n router.patch(\"/api/config\", async (req, res) => {\n const body = await deps.readBody(req);\n let configPath: string | undefined;\n let value: unknown;\n\n if (body) {\n try {\n const parsed = JSON.parse(body);\n configPath = parsed.path;\n value = parsed.value;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!configPath) {\n deps.sendJson(res, 400, { error: \"Missing path\" });\n return;\n }\n\n // Block prototype pollution\n const BLOCKED_KEYS = new Set([\"__proto__\", \"constructor\", \"prototype\"]);\n const parts = configPath.split(\".\");\n if (parts.some((p) => BLOCKED_KEYS.has(p))) {\n deps.sendJson(res, 400, { error: \"Invalid config path\" });\n return;\n }\n\n // Enforce safe-fields scope — only fields marked 'safe' can be modified via API\n const { getFieldDef } = await import(\"../../config-registry.js\");\n const fieldDef = getFieldDef(configPath);\n if (!fieldDef || fieldDef.scope !== \"safe\") {\n deps.sendJson(res, 403, {\n error: \"This config field cannot be modified via the API\",\n });\n return;\n }\n\n // Pre-validate by cloning config and applying the change\n const currentConfig = deps.core.configManager.get();\n const cloned = structuredClone(currentConfig) as Record<string, unknown>;\n let target: Record<string, unknown> = cloned;\n for (let i = 0; i < parts.length - 1; i++) {\n const part = parts[i];\n if (\n target[part] &&\n typeof target[part] === \"object\" &&\n !Array.isArray(target[part])\n ) {\n target = target[part] as Record<string, unknown>;\n } else if (target[part] === undefined || target[part] === null) {\n // Create intermediate objects for new paths (e.g. speech.stt.providers.groq.apiKey)\n target[part] = {};\n target = target[part] as Record<string, unknown>;\n } else {\n deps.sendJson(res, 400, { error: \"Invalid config path\" });\n return;\n }\n }\n\n const lastKey = parts[parts.length - 1];\n target[lastKey] = value;\n\n // Validate with Zod\n const { ConfigSchema } = await import(\"../../config.js\");\n const result = ConfigSchema.safeParse(cloned);\n if (!result.success) {\n deps.sendJson(res, 400, {\n error: \"Validation failed\",\n details: result.error.issues.map((i) => ({\n path: i.path.join(\".\"),\n message: i.message,\n })),\n });\n return;\n }\n\n // Convert dot-path to nested object for save\n const updates: Record<string, unknown> = {};\n let updateTarget = updates;\n for (let i = 0; i < parts.length - 1; i++) {\n updateTarget[parts[i]] = {};\n updateTarget = updateTarget[parts[i]] as Record<string, unknown>;\n }\n updateTarget[lastKey] = value;\n\n await deps.core.configManager.save(updates, configPath);\n\n const { isHotReloadable } = await import(\"../../config-registry.js\");\n const needsRestart = !isHotReloadable(configPath!);\n\n deps.sendJson(res, 200, {\n ok: true,\n needsRestart,\n config: redactConfig(deps.core.configManager.get()),\n });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\n\nexport function registerTopicRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/topics\", async (req, res) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const url = req.url || \"\";\n const params = new URL(url, \"http://localhost\").searchParams;\n const statusParam = params.get(\"status\");\n const filter = statusParam\n ? { statuses: statusParam.split(\",\") }\n : undefined;\n const topics = deps.topicManager.listTopics(filter);\n deps.sendJson(res, 200, { topics });\n });\n\n router.post(\"/api/topics/cleanup\", async (req, res) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const body = await deps.readBody(req);\n let statuses: string[] | undefined;\n if (body) {\n try {\n statuses = JSON.parse(body).statuses;\n } catch {\n /* use defaults */\n }\n }\n const result = await deps.topicManager.cleanup(statuses);\n deps.sendJson(res, 200, result);\n });\n\n router.delete(\"/api/topics/:sessionId\", async (req, res, params) => {\n if (!deps.topicManager) {\n deps.sendJson(res, 501, { error: \"Topic management not available\" });\n return;\n }\n const sessionId = decodeURIComponent(params.sessionId);\n const url = req.url || \"\";\n const urlParams = new URL(url, \"http://localhost\").searchParams;\n const force = urlParams.get(\"force\") === \"true\";\n const result = await deps.topicManager.deleteTopic(\n sessionId,\n force ? { confirmed: true } : undefined,\n );\n if (result.ok) {\n deps.sendJson(res, 200, result);\n } else if (result.needsConfirmation) {\n deps.sendJson(res, 409, {\n error: \"Session is active\",\n needsConfirmation: true,\n session: result.session,\n });\n } else if (result.error === \"Cannot delete system topic\") {\n deps.sendJson(res, 403, { error: result.error });\n } else {\n deps.sendJson(res, 404, { error: result.error ?? \"Not found\" });\n }\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\n\nexport function registerTunnelRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/tunnel\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (tunnel) {\n deps.sendJson(res, 200, {\n enabled: true,\n url: tunnel.getPublicUrl(),\n provider: deps.core.configManager.get().tunnel.provider,\n });\n } else {\n deps.sendJson(res, 200, { enabled: false });\n }\n });\n\n router.get(\"/api/tunnel/list\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 200, []);\n return;\n }\n deps.sendJson(res, 200, tunnel.listTunnels());\n });\n\n router.post(\"/api/tunnel\", async (req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const body = await deps.readBody(req);\n if (body === null) {\n deps.sendJson(res, 413, { error: \"Request body too large\" });\n return;\n }\n if (!body) {\n deps.sendJson(res, 400, { error: \"Missing request body\" });\n return;\n }\n try {\n const { port, label, sessionId } = JSON.parse(body);\n if (!port || typeof port !== \"number\") {\n deps.sendJson(res, 400, {\n error: \"port is required and must be a number\",\n });\n return;\n }\n const entry = await tunnel.addTunnel(port, { label, sessionId });\n deps.sendJson(res, 200, entry);\n } catch (err) {\n deps.sendJson(res, 400, { error: (err as Error).message });\n }\n });\n\n router.delete(\"/api/tunnel/:port\", async (_req, res, params) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const port = parseInt(params.port, 10);\n try {\n await tunnel.stopTunnel(port);\n deps.sendJson(res, 200, { ok: true });\n } catch (err) {\n deps.sendJson(res, 400, { error: (err as Error).message });\n }\n });\n\n router.delete(\"/api/tunnel\", async (_req, res) => {\n const tunnel = deps.core.tunnelService;\n if (!tunnel) {\n deps.sendJson(res, 400, { error: \"Tunnel service is not enabled\" });\n return;\n }\n const count = tunnel.listTunnels().length;\n await tunnel.stopAllUser();\n deps.sendJson(res, 200, { ok: true, stopped: count });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\nimport { getAgentCapabilities } from \"../../agent-registry.js\";\n\nexport function registerAgentRoutes(router: Router, deps: RouteDeps): void {\n router.get(\"/api/agents\", async (_req, res) => {\n const agents = deps.core.agentManager.getAvailableAgents();\n const defaultAgent = deps.core.configManager.get().defaultAgent;\n const agentsWithCaps = agents.map((a) => ({\n ...a,\n capabilities: getAgentCapabilities(a.name),\n }));\n deps.sendJson(res, 200, { agents: agentsWithCaps, default: defaultAgent });\n });\n}\n","import type { Router } from \"../router.js\";\nimport type { RouteDeps } from \"../index.js\";\n\nexport function registerNotifyRoutes(router: Router, deps: RouteDeps): void {\n router.post(\"/api/notify\", async (req, res) => {\n const body = await deps.readBody(req);\n let message: string | undefined;\n if (body) {\n try {\n const parsed = JSON.parse(body);\n message = parsed.message;\n } catch {\n deps.sendJson(res, 400, { error: \"Invalid JSON body\" });\n return;\n }\n }\n\n if (!message) {\n deps.sendJson(res, 400, { error: \"Missing message\" });\n return;\n }\n\n await deps.core.notificationManager.notifyAll({\n sessionId: \"system\",\n type: \"completed\",\n summary: message,\n });\n deps.sendJson(res, 200, { ok: true });\n });\n}\n","import type { SessionManager } from './session-manager.js'\nimport type { IChannelAdapter } from './channel.js'\nimport type { SessionRecord } from './types.js'\nimport { createChildLogger } from './log.js'\n\nconst log = createChildLogger({ module: 'topic-manager' })\n\nexport interface TopicInfo {\n sessionId: string\n topicId: number | null\n name: string | null\n status: string\n agentName: string\n lastActiveAt: string\n}\n\nexport interface DeleteTopicResult {\n ok: boolean\n needsConfirmation?: boolean\n topicId?: number | null\n session?: { id: string; name: string | null; status: string }\n error?: string\n}\n\nexport interface CleanupResult {\n deleted: string[]\n failed: { sessionId: string; error: string }[]\n}\n\ninterface SystemTopicIds {\n notificationTopicId: number | null\n assistantTopicId: number | null\n}\n\nexport class TopicManager {\n constructor(\n private sessionManager: SessionManager,\n private adapter: IChannelAdapter | null,\n private systemTopicIds: SystemTopicIds,\n ) {}\n\n listTopics(filter?: { statuses?: string[] }): TopicInfo[] {\n const records = this.sessionManager.listRecords(filter)\n return records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => !filter?.statuses?.length || filter.statuses.includes(r.status))\n .map(r => ({\n sessionId: r.sessionId,\n topicId: (r.platform as Record<string, unknown>)?.topicId as number ?? null,\n name: r.name ?? null,\n status: r.status,\n agentName: r.agentName,\n lastActiveAt: r.lastActiveAt,\n }))\n }\n\n async deleteTopic(sessionId: string, options?: { confirmed?: boolean }): Promise<DeleteTopicResult> {\n const records = this.sessionManager.listRecords()\n const record = records.find(r => r.sessionId === sessionId)\n if (!record) return { ok: false, error: 'Session not found' }\n\n if (this.isSystemTopic(record)) return { ok: false, error: 'Cannot delete system topic' }\n\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive && !options?.confirmed) {\n return {\n ok: false,\n needsConfirmation: true,\n session: { id: record.sessionId, name: record.name ?? null, status: record.status },\n }\n }\n\n if (isActive) {\n await this.sessionManager.cancelSession(sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number ?? null\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread(sessionId)\n } catch (err) {\n log.warn({ err, sessionId, topicId }, 'Failed to delete platform thread, removing record anyway')\n }\n }\n\n await this.sessionManager.removeRecord(sessionId)\n return { ok: true, topicId }\n }\n\n async cleanup(statuses?: string[]): Promise<CleanupResult> {\n const targetStatuses = statuses?.length ? statuses : ['finished', 'error', 'cancelled']\n const records = this.sessionManager.listRecords({ statuses: targetStatuses })\n const targets = records\n .filter(r => !this.isSystemTopic(r))\n .filter(r => targetStatuses.includes(r.status))\n\n const deleted: string[] = []\n const failed: { sessionId: string; error: string }[] = []\n\n for (const record of targets) {\n try {\n // Cancel active/initializing sessions to prevent orphaned agent processes\n const isActive = record.status === 'active' || record.status === 'initializing'\n if (isActive) {\n await this.sessionManager.cancelSession(record.sessionId)\n }\n\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (this.adapter && topicId) {\n try {\n await this.adapter.deleteSessionThread(record.sessionId)\n } catch (err) {\n log.warn({ err, sessionId: record.sessionId }, 'Failed to delete platform thread during cleanup')\n }\n }\n await this.sessionManager.removeRecord(record.sessionId)\n deleted.push(record.sessionId)\n } catch (err) {\n failed.push({ sessionId: record.sessionId, error: err instanceof Error ? err.message : String(err) })\n }\n }\n\n return { deleted, failed }\n }\n\n private isSystemTopic(record: SessionRecord): boolean {\n const topicId = (record.platform as Record<string, unknown>)?.topicId as number | undefined\n if (!topicId) return false\n return topicId === this.systemTopicIds.notificationTopicId\n || topicId === this.systemTopicIds.assistantTopicId\n }\n}\n"],"mappings":"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","names":["resolve","resolve","resolve","resolve","fs","fs","path","log","fs","log","id","fs","path","log","path","fs","nanoid","log","nanoid","path","fs","path","execFileSync","path","os","fs","path","log","DEBOUNCE_MS","path","fs","log","path","os","setLogLevel","existsSync","fs","path","fs","path","os","crypto","fileURLToPath","path","log","getSafeFields","resolveOptions","getConfigValue","getFieldDef","isHotReloadable","log","fileURLToPath","resolve","log"]}