@openacp/cli 0.6.10 → 2026.326.3

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-LYF5PP5W.js +327 -0
  155. package/dist/plugin-create-LYF5PP5W.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,29 +1,15 @@
1
- import {
2
- buildActionKeyboard,
3
- detectAction,
4
- storeAction
5
- } from "./chunk-I7WC6E5S.js";
6
1
  import {
7
2
  handleNew,
8
3
  handleNewChat,
9
4
  handleNewSessionButton
10
- } from "./chunk-XANPHG7W.js";
11
- import {
12
- handleDangerous,
13
- handleDangerousButton,
14
- handleRestart,
15
- handleTTS,
16
- handleTTSButton,
17
- handleUpdate,
18
- handleVerbosity
19
- } from "./chunk-KIRH7TUJ.js";
5
+ } from "./chunk-QSDZDHNS.js";
20
6
  import {
21
7
  handleCancel,
22
8
  handleCleanupButton,
23
9
  handleHandoff,
24
10
  handleSessions,
25
11
  handleStatus
26
- } from "./chunk-4CTX774K.js";
12
+ } from "./chunk-GJOY37U7.js";
27
13
  import {
28
14
  buildDeepLink,
29
15
  createSessionThread,
@@ -31,24 +17,42 @@ import {
31
17
  ensureForums,
32
18
  ensureUnarchived,
33
19
  renameSessionThread
34
- } from "./chunk-BNLGTZ34.js";
20
+ } from "./chunk-O5RG4YZY.js";
35
21
  import {
36
22
  handleAgentButton,
37
23
  handleAgents,
38
24
  handleInstall
39
- } from "./chunk-J4SJTKIK.js";
25
+ } from "./chunk-NAM4ERUW.js";
40
26
  import {
41
27
  handleSettings,
42
28
  handleSettingsButton
43
- } from "./chunk-O7CPGUAI.js";
29
+ } from "./chunk-4KGLKKQK.js";
44
30
  import {
45
31
  handleDoctor,
46
32
  handleDoctorButton
47
- } from "./chunk-2HMQOC7N.js";
33
+ } from "./chunk-I3CGU5W7.js";
34
+ import {
35
+ buildActionKeyboard,
36
+ detectAction,
37
+ storeAction
38
+ } from "./chunk-HVBNCPAY.js";
39
+ import {
40
+ handleDangerous,
41
+ handleDangerousButton,
42
+ handleRestart,
43
+ handleTTS,
44
+ handleTTSButton,
45
+ handleUpdate,
46
+ handleVerbosity
47
+ } from "./chunk-MTSDOSXS.js";
48
48
  import {
49
49
  PRODUCT_GUIDE,
50
- dispatchMessage,
51
- evaluateNoise,
50
+ SendQueue,
51
+ ToolCallTracker
52
+ } from "./chunk-5ZOFBTOR.js";
53
+ import {
54
+ BaseRenderer,
55
+ MessagingAdapter,
52
56
  extractContentText,
53
57
  formatTokens,
54
58
  formatToolSummary,
@@ -58,93 +62,24 @@ import {
58
62
  splitMessage,
59
63
  stripCodeFences,
60
64
  truncateContent
61
- } from "./chunk-OWP7RZ62.js";
62
- import {
63
- ChannelAdapter
64
- } from "./chunk-LBIKITQT.js";
65
- import "./chunk-NVPG6JCL.js";
66
- import "./chunk-JHYXKVV2.js";
67
- import "./chunk-33RP6K2O.js";
65
+ } from "./chunk-V2M243KZ.js";
66
+ import "./chunk-L7YNNBI5.js";
67
+ import "./chunk-ODUM3D6X.js";
68
+ import "./chunk-QVMEF6FB.js";
68
69
  import {
70
+ createChildLogger,
69
71
  log
70
- } from "./chunk-GAK6PIBW.js";
72
+ } from "./chunk-XMMAGAT4.js";
71
73
  import "./chunk-VUNV25KB.js";
72
74
 
73
- // src/adapters/discord/adapter.ts
75
+ // src/plugins/discord/adapter.ts
74
76
  import {
75
77
  Client,
76
78
  GatewayIntentBits,
77
79
  MessageFlags
78
80
  } from "discord.js";
79
81
 
80
- // src/adapters/discord/send-queue.ts
81
- var DiscordSendQueue = class {
82
- items = [];
83
- processing = false;
84
- lastExec = 0;
85
- minInterval;
86
- constructor(minInterval = 1e3) {
87
- this.minInterval = minInterval;
88
- }
89
- enqueue(fn, opts) {
90
- const type = opts.type;
91
- const key = opts.key;
92
- return new Promise((resolve, reject) => {
93
- if (type === "text" && key) {
94
- const idx = this.items.findIndex(
95
- (item) => item.type === "text" && item.key === key
96
- );
97
- if (idx !== -1) {
98
- this.items[idx].resolve(void 0);
99
- this.items[idx] = { fn, type, key, resolve, reject };
100
- this.scheduleProcess();
101
- return;
102
- }
103
- }
104
- this.items.push({ fn, type, key, resolve, reject });
105
- this.scheduleProcess();
106
- });
107
- }
108
- onRateLimited() {
109
- log.warn("[DiscordSendQueue] Rate limited \u2014 dropping queued text items");
110
- const remaining = [];
111
- for (const item of this.items) {
112
- if (item.type === "text") {
113
- item.resolve(void 0);
114
- } else {
115
- remaining.push(item);
116
- }
117
- }
118
- this.items = remaining;
119
- }
120
- scheduleProcess() {
121
- if (this.processing) return;
122
- if (this.items.length === 0) return;
123
- const elapsed = Date.now() - this.lastExec;
124
- const delay = Math.max(0, this.minInterval - elapsed);
125
- this.processing = true;
126
- setTimeout(() => void this.processNext(), delay);
127
- }
128
- async processNext() {
129
- const item = this.items.shift();
130
- if (!item) {
131
- this.processing = false;
132
- return;
133
- }
134
- try {
135
- const result = await item.fn();
136
- item.resolve(result);
137
- } catch (err) {
138
- item.reject(err);
139
- } finally {
140
- this.lastExec = Date.now();
141
- this.processing = false;
142
- this.scheduleProcess();
143
- }
144
- }
145
- };
146
-
147
- // src/adapters/discord/formatting.ts
82
+ // src/plugins/discord/formatting.ts
148
83
  function formatViewerLinks(links, filePath) {
149
84
  if (!links) return "";
150
85
  const fileName = filePath ? filePath.split("/").pop() || filePath : "";
@@ -230,97 +165,164 @@ function splitMessage2(text, maxLength = 1800) {
230
165
  return splitMessage(text, maxLength);
231
166
  }
232
167
 
233
- // src/adapters/discord/tool-call-tracker.ts
234
- var ToolCallTracker = class {
168
+ // src/plugins/discord/renderer.ts
169
+ var DiscordRenderer = class extends BaseRenderer {
170
+ renderToolCall(content, verbosity) {
171
+ const meta = content.metadata ?? {};
172
+ return { body: formatToolCall(meta, verbosity), format: "markdown" };
173
+ }
174
+ renderToolUpdate(content, verbosity) {
175
+ const meta = content.metadata ?? {};
176
+ return { body: formatToolUpdate(meta, verbosity), format: "markdown" };
177
+ }
178
+ renderPlan(content, verbosity) {
179
+ const entries = content.metadata?.entries ?? [];
180
+ return { body: formatPlan(entries, verbosity), format: "markdown" };
181
+ }
182
+ renderUsage(content, verbosity) {
183
+ const meta = content.metadata;
184
+ return { body: formatUsage(meta ?? {}, verbosity), format: "markdown" };
185
+ }
186
+ renderError(content) {
187
+ return { body: `\u274C **Error:** ${content.text}`, format: "markdown" };
188
+ }
189
+ renderNotification(notification) {
190
+ const emoji = {
191
+ completed: "\u2705",
192
+ error: "\u274C",
193
+ permission: "\u{1F510}",
194
+ input_required: "\u{1F4AC}",
195
+ budget_warning: "\u26A0\uFE0F"
196
+ };
197
+ const icon = emoji[notification.type] || "\u2139\uFE0F";
198
+ const name = notification.sessionName ? ` **${notification.sessionName}**` : "";
199
+ let text = `${icon}${name}: ${notification.summary}`;
200
+ if (notification.deepLink) {
201
+ text += `
202
+ ${notification.deepLink}`;
203
+ }
204
+ return { body: text, format: "markdown" };
205
+ }
206
+ renderSystemMessage(content) {
207
+ return { body: content.text, format: "markdown" };
208
+ }
209
+ renderSessionEnd(_content) {
210
+ return { body: "\u2705 Done", format: "markdown" };
211
+ }
212
+ renderModeChange(content) {
213
+ const modeId = content.metadata?.modeId ?? "";
214
+ return { body: `\u{1F504} **Mode:** ${modeId}`, format: "markdown" };
215
+ }
216
+ renderConfigUpdate() {
217
+ return { body: "\u2699\uFE0F **Config updated**", format: "markdown" };
218
+ }
219
+ renderModelUpdate(content) {
220
+ const modelId = content.metadata?.modelId ?? "";
221
+ return { body: `\u{1F916} **Model:** ${modelId}`, format: "markdown" };
222
+ }
223
+ };
224
+
225
+ // src/plugins/discord/tool-call-tracker.ts
226
+ var log2 = createChildLogger({ module: "discord-tool-call-tracker" });
227
+ var DiscordToolCallTracker = class {
235
228
  constructor(sendQueue) {
236
229
  this.sendQueue = sendQueue;
237
230
  }
238
- sessions = /* @__PURE__ */ new Map();
231
+ tracker = new ToolCallTracker();
232
+ /** Platform-specific ready-promise + message per tool call, keyed by `${sessionId}:${toolId}`. */
233
+ platformState = /* @__PURE__ */ new Map();
239
234
  async trackNewCall(sessionId, thread, tool, verbosity = "medium") {
240
- if (!this.sessions.has(sessionId)) {
241
- this.sessions.set(sessionId, /* @__PURE__ */ new Map());
242
- }
243
235
  let resolveReady;
244
236
  const ready = new Promise((r) => {
245
237
  resolveReady = r;
246
238
  });
247
- const state = {
248
- message: void 0,
249
- name: tool.name,
250
- kind: tool.kind,
251
- rawInput: tool.rawInput,
252
- viewerLinks: tool.viewerLinks,
253
- viewerFilePath: tool.viewerFilePath,
254
- ready
255
- };
256
- this.sessions.get(sessionId).set(tool.id, state);
239
+ const key = `${sessionId}:${tool.id}`;
240
+ this.platformState.set(key, { message: void 0, ready });
241
+ this.tracker.track(sessionId, tool, "0");
257
242
  const content = formatToolCall(tool, verbosity);
258
243
  try {
259
244
  const msg = await this.sendQueue.enqueue(() => thread.send({ content }), {
260
245
  type: "other"
261
246
  });
262
- if (msg) state.message = msg;
247
+ if (msg) {
248
+ const state = this.platformState.get(key);
249
+ if (state) state.message = msg;
250
+ }
263
251
  } catch (err) {
264
- log.warn(
252
+ log2.warn(
265
253
  { err, toolId: tool.id },
266
- "[ToolCallTracker] trackNewCall() send failed"
254
+ "trackNewCall() send failed"
267
255
  );
268
256
  } finally {
269
257
  resolveReady();
270
258
  }
271
259
  }
272
260
  async updateCall(sessionId, update, verbosity = "medium") {
273
- const toolState = this.sessions.get(sessionId)?.get(update.id);
274
- if (!toolState) return;
275
- if (update.viewerLinks) toolState.viewerLinks = update.viewerLinks;
276
- if (update.viewerFilePath) toolState.viewerFilePath = update.viewerFilePath;
277
- if (update.name) toolState.name = update.name;
278
- if (update.kind) toolState.kind = update.kind;
261
+ const key = `${sessionId}:${update.id}`;
262
+ const state = this.platformState.get(key);
263
+ const tracked = this.tracker.update(sessionId, update.id, update.status, {
264
+ viewerLinks: update.viewerLinks,
265
+ viewerFilePath: update.viewerFilePath,
266
+ name: update.name,
267
+ kind: update.kind
268
+ });
269
+ if (!tracked) return;
279
270
  const isTerminal = update.status === "completed" || update.status === "failed";
280
271
  if (!isTerminal) return;
281
- await toolState.ready;
282
- if (!toolState.message) return;
283
- log.debug(
272
+ if (state) {
273
+ await state.ready;
274
+ }
275
+ if (!state?.message) return;
276
+ log2.debug(
284
277
  {
285
278
  toolId: update.id,
286
279
  status: update.status,
287
- hasViewerLinks: !!toolState.viewerLinks,
288
- name: toolState.name,
289
- msgId: toolState.message.id
280
+ hasViewerLinks: !!tracked.viewerLinks,
281
+ name: tracked.name,
282
+ msgId: state.message.id
290
283
  },
291
- "[ToolCallTracker] Tool completed, preparing edit"
284
+ "Tool completed, preparing edit"
292
285
  );
293
286
  const merged = {
294
- ...update,
295
- name: toolState.name,
296
- kind: toolState.kind,
297
- rawInput: toolState.rawInput,
298
- viewerLinks: toolState.viewerLinks,
299
- viewerFilePath: toolState.viewerFilePath
287
+ id: update.id,
288
+ name: tracked.name,
289
+ kind: tracked.kind,
290
+ rawInput: tracked.rawInput,
291
+ viewerLinks: tracked.viewerLinks,
292
+ viewerFilePath: tracked.viewerFilePath,
293
+ displaySummary: tracked.displaySummary,
294
+ displayTitle: tracked.displayTitle,
295
+ displayKind: tracked.displayKind,
296
+ status: update.status,
297
+ content: update.content
300
298
  };
301
299
  const content = formatToolUpdate(merged, verbosity);
302
300
  try {
303
- await this.sendQueue.enqueue(() => toolState.message.edit({ content }), {
301
+ await this.sendQueue.enqueue(() => state.message.edit({ content }), {
304
302
  type: "other"
305
303
  });
306
304
  } catch (err) {
307
- log.warn(
305
+ log2.warn(
308
306
  {
309
307
  err,
310
- msgId: toolState.message.id,
308
+ msgId: state.message.id,
311
309
  contentLen: content.length,
312
310
  hasViewerLinks: !!merged.viewerLinks
313
311
  },
314
- "[ToolCallTracker] Tool update edit failed"
312
+ "Tool update edit failed"
315
313
  );
316
314
  }
317
315
  }
318
316
  cleanup(sessionId) {
319
- this.sessions.delete(sessionId);
317
+ const active = this.tracker.getActive(sessionId);
318
+ for (const tool of active) {
319
+ this.platformState.delete(`${sessionId}:${tool.id}`);
320
+ }
321
+ this.tracker.clear(sessionId);
320
322
  }
321
323
  };
322
324
 
323
- // src/adapters/discord/streaming.ts
325
+ // src/plugins/discord/streaming.ts
324
326
  var FLUSH_INTERVAL = 5e3;
325
327
  var MAX_DISPLAY_LENGTH = 1900;
326
328
  var MessageDraft = class {
@@ -469,8 +471,8 @@ var MessageDraft = class {
469
471
  }
470
472
  };
471
473
 
472
- // src/adapters/discord/draft-manager.ts
473
- var DraftManager = class {
474
+ // src/plugins/discord/draft-manager.ts
475
+ var DiscordDraftManager = class {
474
476
  constructor(sendQueue) {
475
477
  this.sendQueue = sendQueue;
476
478
  }
@@ -530,7 +532,7 @@ var DraftManager = class {
530
532
  }
531
533
  };
532
534
 
533
- // src/adapters/discord/activity.ts
535
+ // src/plugins/discord/activity.ts
534
536
  import { EmbedBuilder } from "discord.js";
535
537
  var TYPING_REFRESH_MS = 8e3;
536
538
  var ThinkingIndicator = class {
@@ -731,7 +733,7 @@ var ActivityTracker = class {
731
733
  }
732
734
  };
733
735
 
734
- // src/adapters/discord/skill-command-manager.ts
736
+ // src/plugins/discord/skill-command-manager.ts
735
737
  var DISCORD_MSG_LIMIT = 1900;
736
738
  function buildSkillContent(commands) {
737
739
  const sorted = [...commands].sort((a, b) => a.name.localeCompare(b.name));
@@ -825,7 +827,7 @@ var SkillCommandManager = class {
825
827
  }
826
828
  };
827
829
 
828
- // src/adapters/discord/permissions.ts
830
+ // src/plugins/discord/permissions.ts
829
831
  import { ActionRowBuilder, ButtonBuilder, ButtonStyle } from "discord.js";
830
832
  import { nanoid } from "nanoid";
831
833
  var PermissionHandler = class {
@@ -912,10 +914,10 @@ ${request.description}`,
912
914
  }
913
915
  };
914
916
 
915
- // src/adapters/discord/commands/index.ts
917
+ // src/plugins/discord/commands/index.ts
916
918
  import { SlashCommandBuilder } from "discord.js";
917
919
 
918
- // src/adapters/discord/commands/menu.ts
920
+ // src/plugins/discord/commands/menu.ts
919
921
  import {
920
922
  ActionRowBuilder as ActionRowBuilder2,
921
923
  ButtonBuilder as ButtonBuilder2,
@@ -1006,12 +1008,12 @@ async function handleMenuButton(interaction, adapter) {
1006
1008
  try {
1007
1009
  switch (customId) {
1008
1010
  case "m:new": {
1009
- const { handleNew: handleNew2 } = await import("./new-session-FEO4J4VU.js");
1011
+ const { handleNew: handleNew2 } = await import("./new-session-AVQCNXRG.js");
1010
1012
  await interaction.followUp({ content: "Use `/new` to create a new session.", ephemeral: true });
1011
1013
  break;
1012
1014
  }
1013
1015
  case "m:sessions": {
1014
- const { handleSessions: handleSessions2 } = await import("./session-IUSI7P5S.js");
1016
+ const { handleSessions: handleSessions2 } = await import("./session-KZFA6Z26.js");
1015
1017
  await showSessionsList(interaction, adapter);
1016
1018
  break;
1017
1019
  }
@@ -1020,12 +1022,12 @@ async function handleMenuButton(interaction, adapter) {
1020
1022
  break;
1021
1023
  }
1022
1024
  case "m:agents": {
1023
- const { showAgentsList } = await import("./agents-QO7DKARJ.js");
1025
+ const { showAgentsList } = await import("./agents-BWU4MRRD.js");
1024
1026
  await showAgentsList(interaction, adapter);
1025
1027
  break;
1026
1028
  }
1027
1029
  case "m:settings": {
1028
- const { showSettingsInfo } = await import("./settings-RQPAM4KC.js");
1030
+ const { showSettingsInfo } = await import("./settings-MFYM7CZO.js");
1029
1031
  await showSettingsInfo(interaction, adapter);
1030
1032
  break;
1031
1033
  }
@@ -1034,7 +1036,7 @@ async function handleMenuButton(interaction, adapter) {
1034
1036
  break;
1035
1037
  }
1036
1038
  case "m:restart": {
1037
- const { handleRestart: handleRestart2 } = await import("./admin-6SYB6XCZ.js");
1039
+ const { handleRestart: handleRestart2 } = await import("./admin-GBPZFFAU.js");
1038
1040
  if (!adapter.core.requestRestart) {
1039
1041
  await interaction.followUp({ content: "\u26A0\uFE0F Restart not available.", ephemeral: true });
1040
1042
  } else {
@@ -1053,7 +1055,7 @@ async function handleMenuButton(interaction, adapter) {
1053
1055
  break;
1054
1056
  }
1055
1057
  case "m:doctor": {
1056
- const { runDoctorInline } = await import("./doctor-OLYBO3V3.js");
1058
+ const { runDoctorInline } = await import("./doctor-RF6BHMCC.js");
1057
1059
  await runDoctorInline(interaction, adapter);
1058
1060
  break;
1059
1061
  }
@@ -1130,7 +1132,7 @@ ${lines.join("\n")}${truncated}`,
1130
1132
  });
1131
1133
  }
1132
1134
 
1133
- // src/adapters/discord/commands/integrate.ts
1135
+ // src/plugins/discord/commands/integrate.ts
1134
1136
  async function handleIntegrate(interaction, _adapter) {
1135
1137
  await interaction.deferReply({ ephemeral: true });
1136
1138
  await interaction.editReply(
@@ -1148,7 +1150,7 @@ async function handleIntegrateButton(interaction, _adapter) {
1148
1150
  }
1149
1151
  }
1150
1152
 
1151
- // src/adapters/discord/commands/router.ts
1153
+ // src/plugins/discord/commands/router.ts
1152
1154
  async function handleSlashCommand(interaction, adapter) {
1153
1155
  const { commandName } = interaction;
1154
1156
  try {
@@ -1246,7 +1248,7 @@ async function setupButtonCallbacks(interaction, adapter) {
1246
1248
  return;
1247
1249
  }
1248
1250
  if (customId.startsWith("a:")) {
1249
- const { getAction, removeAction } = await import("./action-detect-P7ZE4NEM.js");
1251
+ const { getAction, removeAction } = await import("./action-detect-QPA775HB.js");
1250
1252
  const actionId = customId.slice(2);
1251
1253
  const action = getAction(actionId);
1252
1254
  if (!action) {
@@ -1329,15 +1331,15 @@ async function setupButtonCallbacks(interaction, adapter) {
1329
1331
  }
1330
1332
  }
1331
1333
  async function executeNewSession(interaction, adapter, agentName, workspace) {
1332
- const { executeNewSession: doExecute } = await import("./new-session-FEO4J4VU.js");
1334
+ const { executeNewSession: doExecute } = await import("./new-session-AVQCNXRG.js");
1333
1335
  await doExecute(interaction, adapter, agentName, workspace);
1334
1336
  }
1335
1337
  async function executeCancelSession(interaction, adapter) {
1336
- const { executeCancelSession: doCancel } = await import("./session-IUSI7P5S.js");
1338
+ const { executeCancelSession: doCancel } = await import("./session-KZFA6Z26.js");
1337
1339
  await doCancel(interaction, adapter);
1338
1340
  }
1339
1341
 
1340
- // src/adapters/discord/commands/index.ts
1342
+ // src/plugins/discord/commands/index.ts
1341
1343
  var SLASH_COMMANDS = [
1342
1344
  new SlashCommandBuilder().setName("new").setDescription("Create a new agent session").addStringOption(
1343
1345
  (o) => o.setName("agent").setDescription("Agent to use").setRequired(false)
@@ -1381,7 +1383,7 @@ async function registerSlashCommands(guild) {
1381
1383
  await guild.commands.set(SLASH_COMMANDS.map((cmd) => cmd.toJSON()));
1382
1384
  }
1383
1385
 
1384
- // src/adapters/discord/assistant.ts
1386
+ // src/plugins/discord/assistant.ts
1385
1387
  async function spawnAssistant(core, threadId) {
1386
1388
  const config = core.configManager.get();
1387
1389
  log.info({ agent: config.defaultAgent, threadId }, "[discord-assistant] Creating assistant session...");
@@ -1551,7 +1553,7 @@ openacp api restart # Restart daemon
1551
1553
  ${PRODUCT_GUIDE}`;
1552
1554
  }
1553
1555
 
1554
- // src/adapters/discord/media.ts
1556
+ // src/plugins/discord/media.ts
1555
1557
  var MAX_DOWNLOAD_SIZE = 100 * 1024 * 1024;
1556
1558
  var DISCORD_UPLOAD_LIMIT = 25 * 1024 * 1024;
1557
1559
  function isAttachmentTooLarge(size) {
@@ -1582,8 +1584,19 @@ async function downloadDiscordAttachment(url, fileName) {
1582
1584
  }
1583
1585
  }
1584
1586
 
1585
- // src/adapters/discord/adapter.ts
1586
- var DiscordAdapter = class extends ChannelAdapter {
1587
+ // src/plugins/discord/adapter.ts
1588
+ var DiscordAdapter = class extends MessagingAdapter {
1589
+ name = "discord";
1590
+ renderer = new DiscordRenderer();
1591
+ capabilities = {
1592
+ streaming: true,
1593
+ richFormatting: true,
1594
+ threads: true,
1595
+ reactions: true,
1596
+ fileUpload: true,
1597
+ voice: false
1598
+ };
1599
+ core;
1587
1600
  client;
1588
1601
  discordConfig;
1589
1602
  sendQueue;
@@ -1592,17 +1605,20 @@ var DiscordAdapter = class extends ChannelAdapter {
1592
1605
  skillManager;
1593
1606
  permissionHandler;
1594
1607
  sessionTrackers = /* @__PURE__ */ new Map();
1595
- get verbosity() {
1596
- return this.discordConfig.displayVerbosity ?? "medium";
1597
- }
1598
1608
  guild;
1599
1609
  forumChannel;
1600
1610
  notificationChannel;
1601
1611
  assistantSession = null;
1602
1612
  assistantInitializing = false;
1603
1613
  fileService;
1614
+ // Per-session thread context for concurrency safety in sendMessage handlers
1615
+ _sessionContexts = /* @__PURE__ */ new Map();
1604
1616
  constructor(core, config) {
1605
- super(core, config);
1617
+ super(
1618
+ { configManager: core.configManager },
1619
+ { ...config, maxMessageLength: 2e3, enabled: config.enabled ?? true }
1620
+ );
1621
+ this.core = core;
1606
1622
  this.discordConfig = config;
1607
1623
  this.client = new Client({
1608
1624
  intents: [
@@ -1611,9 +1627,9 @@ var DiscordAdapter = class extends ChannelAdapter {
1611
1627
  GatewayIntentBits.MessageContent
1612
1628
  ]
1613
1629
  });
1614
- this.sendQueue = new DiscordSendQueue();
1615
- this.toolTracker = new ToolCallTracker(this.sendQueue);
1616
- this.draftManager = new DraftManager(this.sendQueue);
1630
+ this.sendQueue = new SendQueue({ minInterval: 1e3 });
1631
+ this.toolTracker = new DiscordToolCallTracker(this.sendQueue);
1632
+ this.draftManager = new DiscordDraftManager(this.sendQueue);
1617
1633
  this.fileService = core.fileService;
1618
1634
  this.client.rest.on("rateLimited", (info) => {
1619
1635
  log.warn(
@@ -1699,14 +1715,84 @@ var DiscordAdapter = class extends ChannelAdapter {
1699
1715
  log.info("[DiscordAdapter] Stopped");
1700
1716
  }
1701
1717
  // ─── Interaction handler ──────────────────────────────────────────────────
1718
+ getCommandRegistry() {
1719
+ return this.core.lifecycleManager?.serviceRegistry?.get("command-registry");
1720
+ }
1702
1721
  setupInteractionHandler() {
1703
1722
  this.client.on("interactionCreate", async (interaction) => {
1704
1723
  try {
1705
1724
  if (interaction.isChatInputCommand()) {
1725
+ const registry = this.getCommandRegistry();
1726
+ if (registry) {
1727
+ const commandName = interaction.commandName;
1728
+ const def = registry.get(commandName);
1729
+ if (def) {
1730
+ const rawParts = [];
1731
+ for (const opt of interaction.options.data) {
1732
+ rawParts.push(String(opt.value ?? ""));
1733
+ }
1734
+ const channelId = interaction.channelId;
1735
+ const sessionId = this.core.sessionManager.getSessionByThread("discord", channelId)?.id ?? null;
1736
+ const response = await registry.execute(
1737
+ `/${commandName} ${rawParts.join(" ")}`.trim(),
1738
+ {
1739
+ raw: "",
1740
+ sessionId,
1741
+ channelId: "discord",
1742
+ userId: interaction.user.id,
1743
+ options: Object.fromEntries(
1744
+ interaction.options.data.map((o) => [o.name, String(o.value ?? "")])
1745
+ ),
1746
+ reply: async (content) => {
1747
+ if (typeof content === "string") {
1748
+ if (interaction.replied || interaction.deferred) {
1749
+ await interaction.editReply({ content });
1750
+ } else {
1751
+ await interaction.reply({ content });
1752
+ }
1753
+ }
1754
+ }
1755
+ }
1756
+ );
1757
+ if (response.type !== "silent") {
1758
+ await this.renderCommandResponse(response, interaction);
1759
+ } else if (!interaction.replied && !interaction.deferred) {
1760
+ await interaction.deferReply();
1761
+ }
1762
+ return;
1763
+ }
1764
+ }
1706
1765
  await handleSlashCommand(interaction, this);
1707
1766
  return;
1708
1767
  }
1709
1768
  if (interaction.isButton()) {
1769
+ if (interaction.customId.startsWith("c/")) {
1770
+ const registry = this.getCommandRegistry();
1771
+ if (registry) {
1772
+ const command = interaction.customId.slice(2);
1773
+ const channelId = interaction.channelId;
1774
+ const sessionId = this.core.sessionManager.getSessionByThread("discord", channelId)?.id ?? null;
1775
+ const response = await registry.execute(command, {
1776
+ raw: "",
1777
+ sessionId,
1778
+ channelId: "discord",
1779
+ userId: interaction.user.id,
1780
+ reply: async (content) => {
1781
+ if (typeof content === "string") {
1782
+ if (interaction.replied || interaction.deferred) {
1783
+ await interaction.editReply({ content });
1784
+ } else {
1785
+ await interaction.reply({ content, ephemeral: true });
1786
+ }
1787
+ }
1788
+ }
1789
+ });
1790
+ if (response.type !== "silent") {
1791
+ await this.renderCommandResponse(response, interaction);
1792
+ }
1793
+ return;
1794
+ }
1795
+ }
1710
1796
  const handled = await this.permissionHandler.handleButtonInteraction(interaction);
1711
1797
  if (!handled) {
1712
1798
  await setupButtonCallbacks(interaction, this);
@@ -1717,6 +1803,59 @@ var DiscordAdapter = class extends ChannelAdapter {
1717
1803
  }
1718
1804
  });
1719
1805
  }
1806
+ // ─── CommandRegistry response rendering ──────────────────────────────────
1807
+ async renderCommandResponse(response, interaction) {
1808
+ const reply = async (opts) => {
1809
+ if (interaction.replied || interaction.deferred) {
1810
+ await interaction.editReply(opts);
1811
+ } else {
1812
+ await interaction.reply(opts);
1813
+ }
1814
+ };
1815
+ switch (response.type) {
1816
+ case "text":
1817
+ await reply({ content: response.text });
1818
+ break;
1819
+ case "error":
1820
+ await reply({ content: `\u26A0\uFE0F ${response.message}`, ephemeral: true });
1821
+ break;
1822
+ case "menu": {
1823
+ const { ActionRowBuilder: ActionRowBuilder3, ButtonBuilder: ButtonBuilder3, ButtonStyle: ButtonStyle3, EmbedBuilder: EmbedBuilder2 } = await import("discord.js");
1824
+ const embed = new EmbedBuilder2().setTitle(response.title);
1825
+ const rows = [];
1826
+ for (let i = 0; i < response.options.length && rows.length < 5; i += 5) {
1827
+ const row = new ActionRowBuilder3();
1828
+ const slice = response.options.slice(i, i + 5);
1829
+ for (const opt of slice) {
1830
+ row.addComponents(
1831
+ new ButtonBuilder3().setCustomId(`c/${opt.command}`).setLabel(opt.label.slice(0, 80)).setStyle(ButtonStyle3.Secondary)
1832
+ );
1833
+ }
1834
+ rows.push(row);
1835
+ }
1836
+ await reply({ embeds: [embed], components: rows });
1837
+ break;
1838
+ }
1839
+ case "list": {
1840
+ const { EmbedBuilder: EmbedBuilder2 } = await import("discord.js");
1841
+ const desc = response.items.map((i) => `\u2022 **${i.label}**${i.detail ? ` \u2014 ${i.detail}` : ""}`).join("\n");
1842
+ const embed = new EmbedBuilder2().setTitle(response.title).setDescription(desc);
1843
+ await reply({ embeds: [embed] });
1844
+ break;
1845
+ }
1846
+ case "confirm": {
1847
+ const { ActionRowBuilder: ActionRowBuilder3, ButtonBuilder: ButtonBuilder3, ButtonStyle: ButtonStyle3 } = await import("discord.js");
1848
+ const row = new ActionRowBuilder3().addComponents(
1849
+ new ButtonBuilder3().setCustomId(`c/${response.onYes}`).setLabel("Yes").setStyle(ButtonStyle3.Success),
1850
+ new ButtonBuilder3().setCustomId(`c/${response.onNo || "noop"}`).setLabel("No").setStyle(ButtonStyle3.Secondary)
1851
+ );
1852
+ await reply({ content: response.question, components: [row] });
1853
+ break;
1854
+ }
1855
+ case "silent":
1856
+ break;
1857
+ }
1858
+ }
1720
1859
  // ─── Message handler ──────────────────────────────────────────────────────
1721
1860
  setupMessageHandler() {
1722
1861
  this.client.on("messageCreate", async (message) => {
@@ -1926,213 +2065,229 @@ var DiscordAdapter = class extends ChannelAdapter {
1926
2065
  }
1927
2066
  return this.sessionTrackers.get(sessionId);
1928
2067
  }
1929
- // --- MessageHandlers for dispatchMessage ---
1930
- messageHandlers = {
1931
- onThought: async (ctx, _content) => {
1932
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1933
- await tracker.onThought();
1934
- },
1935
- onText: async (ctx, content) => {
1936
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1937
- await tracker.onTextStart();
1938
- const draft = this.draftManager.getOrCreate(ctx.sessionId, ctx.thread);
1939
- draft.append(content.text);
1940
- this.draftManager.appendText(ctx.sessionId, content.text);
1941
- },
1942
- onToolCall: async (ctx, content) => {
1943
- const meta = content.metadata ?? {};
1944
- const toolName = String(meta.name ?? content.text ?? "Tool");
1945
- const toolKind = String(meta.kind ?? "other");
1946
- const noiseAction = evaluateNoise(toolName, toolKind, meta.rawInput);
1947
- if (noiseAction === "hide" && this.verbosity !== "high") return;
1948
- if (noiseAction === "collapse" && this.verbosity === "low") return;
1949
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1950
- await tracker.onToolCall();
1951
- await this.draftManager.finalize(
1952
- ctx.sessionId,
1953
- ctx.thread,
1954
- ctx.isAssistant
1955
- );
1956
- await this.toolTracker.trackNewCall(
1957
- ctx.sessionId,
1958
- ctx.thread,
1959
- {
1960
- id: String(meta.id ?? ""),
1961
- name: toolName,
1962
- kind: meta.kind,
1963
- status: String(meta.status ?? "running"),
1964
- content: meta.content,
1965
- rawInput: meta.rawInput,
1966
- viewerLinks: meta.viewerLinks,
1967
- viewerFilePath: meta.viewerFilePath,
1968
- displaySummary: meta.displaySummary,
1969
- displayTitle: meta.displayTitle,
1970
- displayKind: meta.displayKind
1971
- },
1972
- this.verbosity
1973
- );
1974
- },
1975
- onToolUpdate: async (ctx, content) => {
1976
- const meta = content.metadata ?? {};
1977
- await this.toolTracker.updateCall(
1978
- ctx.sessionId,
1979
- {
1980
- id: String(meta.id ?? ""),
1981
- name: content.text || String(meta.name ?? ""),
1982
- kind: meta.kind,
1983
- status: String(meta.status ?? "completed"),
1984
- content: meta.content,
1985
- rawInput: meta.rawInput,
1986
- viewerLinks: meta.viewerLinks,
1987
- viewerFilePath: meta.viewerFilePath,
1988
- displaySummary: meta.displaySummary,
1989
- displayTitle: meta.displayTitle,
1990
- displayKind: meta.displayKind
1991
- },
1992
- this.verbosity
2068
+ getSessionContext(sessionId) {
2069
+ const ctx = this._sessionContexts.get(sessionId);
2070
+ if (!ctx) {
2071
+ throw new Error(`No thread context stored for session ${sessionId}`);
2072
+ }
2073
+ return ctx;
2074
+ }
2075
+ // ─── sendMessage ──────────────────────────────────────────────────────────
2076
+ async sendMessage(sessionId, content) {
2077
+ if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
2078
+ return;
2079
+ }
2080
+ const thread = await this.getThread(sessionId);
2081
+ if (!thread) return;
2082
+ await ensureUnarchived(thread);
2083
+ this._sessionContexts.set(sessionId, {
2084
+ thread,
2085
+ isAssistant: this.assistantSession != null && sessionId === this.assistantSession.id
2086
+ });
2087
+ try {
2088
+ await super.sendMessage(sessionId, content);
2089
+ } finally {
2090
+ this._sessionContexts.delete(sessionId);
2091
+ }
2092
+ }
2093
+ // ─── Handler overrides ─────────────────────────────────────────────────────
2094
+ async handleThought(sessionId, _content, _verbosity) {
2095
+ const { thread } = this.getSessionContext(sessionId);
2096
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2097
+ await tracker.onThought();
2098
+ }
2099
+ async handleText(sessionId, content) {
2100
+ const { thread } = this.getSessionContext(sessionId);
2101
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2102
+ await tracker.onTextStart();
2103
+ const draft = this.draftManager.getOrCreate(sessionId, thread);
2104
+ draft.append(content.text);
2105
+ this.draftManager.appendText(sessionId, content.text);
2106
+ }
2107
+ async handleToolCall(sessionId, content, verbosity) {
2108
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2109
+ const meta = content.metadata ?? {};
2110
+ const toolName = String(meta.name ?? content.text ?? "Tool");
2111
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2112
+ await tracker.onToolCall();
2113
+ await this.draftManager.finalize(
2114
+ sessionId,
2115
+ thread,
2116
+ isAssistant
2117
+ );
2118
+ await this.toolTracker.trackNewCall(
2119
+ sessionId,
2120
+ thread,
2121
+ {
2122
+ id: String(meta.id ?? ""),
2123
+ name: toolName,
2124
+ kind: meta.kind,
2125
+ status: String(meta.status ?? "running"),
2126
+ content: meta.content,
2127
+ rawInput: meta.rawInput,
2128
+ viewerLinks: meta.viewerLinks,
2129
+ viewerFilePath: meta.viewerFilePath,
2130
+ displaySummary: meta.displaySummary,
2131
+ displayTitle: meta.displayTitle,
2132
+ displayKind: meta.displayKind
2133
+ },
2134
+ verbosity
2135
+ );
2136
+ }
2137
+ async handleToolUpdate(sessionId, content, verbosity) {
2138
+ const meta = content.metadata ?? {};
2139
+ await this.toolTracker.updateCall(
2140
+ sessionId,
2141
+ {
2142
+ id: String(meta.id ?? ""),
2143
+ name: content.text || String(meta.name ?? ""),
2144
+ kind: meta.kind,
2145
+ status: String(meta.status ?? "completed"),
2146
+ content: meta.content,
2147
+ rawInput: meta.rawInput,
2148
+ viewerLinks: meta.viewerLinks,
2149
+ viewerFilePath: meta.viewerFilePath,
2150
+ displaySummary: meta.displaySummary,
2151
+ displayTitle: meta.displayTitle,
2152
+ displayKind: meta.displayKind
2153
+ },
2154
+ verbosity
2155
+ );
2156
+ }
2157
+ async handlePlan(sessionId, content, verbosity) {
2158
+ const { thread } = this.getSessionContext(sessionId);
2159
+ const entries = content.metadata?.entries ?? [];
2160
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2161
+ await tracker.onPlan(entries, verbosity);
2162
+ }
2163
+ async handleUsage(sessionId, content, verbosity) {
2164
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2165
+ await this.draftManager.finalize(
2166
+ sessionId,
2167
+ thread,
2168
+ isAssistant
2169
+ );
2170
+ const meta = content.metadata ?? {};
2171
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2172
+ await tracker.sendUsage(
2173
+ {
2174
+ tokensUsed: meta.tokensUsed,
2175
+ contextSize: meta.contextSize,
2176
+ cost: meta.cost
2177
+ },
2178
+ verbosity
2179
+ );
2180
+ try {
2181
+ const deepLink = buildDeepLink(this.guild.id, thread.id);
2182
+ await this.sendNotification({
2183
+ sessionId,
2184
+ type: "completed",
2185
+ summary: content.text || "Session completed",
2186
+ deepLink
2187
+ });
2188
+ } catch {
2189
+ }
2190
+ }
2191
+ async handleSessionEnd(sessionId, _content) {
2192
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2193
+ await this.draftManager.finalize(
2194
+ sessionId,
2195
+ thread,
2196
+ isAssistant
2197
+ );
2198
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2199
+ await tracker.cleanup();
2200
+ this.toolTracker.cleanup(sessionId);
2201
+ this.sessionTrackers.delete(sessionId);
2202
+ await this.skillManager.cleanup(sessionId);
2203
+ try {
2204
+ await this.sendQueue.enqueue(
2205
+ () => thread.send({ content: "\u2705 Done" }),
2206
+ { type: "other" }
1993
2207
  );
1994
- },
1995
- onPlan: async (ctx, content) => {
1996
- const entries = content.metadata?.entries ?? [];
1997
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
1998
- await tracker.onPlan(entries, this.verbosity);
1999
- },
2000
- onUsage: async (ctx, content) => {
2001
- await this.draftManager.finalize(
2002
- ctx.sessionId,
2003
- ctx.thread,
2004
- ctx.isAssistant
2208
+ } catch {
2209
+ }
2210
+ }
2211
+ async handleError(sessionId, content) {
2212
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2213
+ await this.draftManager.finalize(
2214
+ sessionId,
2215
+ thread,
2216
+ isAssistant
2217
+ );
2218
+ const tracker = this.getOrCreateTracker(sessionId, thread);
2219
+ await tracker.cleanup();
2220
+ this.toolTracker.cleanup(sessionId);
2221
+ this.sessionTrackers.delete(sessionId);
2222
+ try {
2223
+ await this.sendQueue.enqueue(
2224
+ () => thread.send({ content: `\u274C Error: ${content.text}` }),
2225
+ { type: "other" }
2005
2226
  );
2006
- const meta = content.metadata ?? {};
2007
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
2008
- await tracker.sendUsage(
2227
+ } catch {
2228
+ }
2229
+ }
2230
+ async handleAttachment(sessionId, content) {
2231
+ if (!content.attachment) return;
2232
+ const { attachment } = content;
2233
+ const { thread, isAssistant } = this.getSessionContext(sessionId);
2234
+ await this.draftManager.finalize(
2235
+ sessionId,
2236
+ thread,
2237
+ isAssistant
2238
+ );
2239
+ if (isAttachmentTooLarge(attachment.size)) {
2240
+ log.warn(
2009
2241
  {
2010
- tokensUsed: meta.tokensUsed,
2011
- contextSize: meta.contextSize,
2012
- cost: meta.cost
2242
+ sessionId,
2243
+ fileName: attachment.fileName,
2244
+ size: attachment.size
2013
2245
  },
2014
- this.verbosity
2246
+ "[discord-media] File too large (>25MB)"
2015
2247
  );
2016
- try {
2017
- const deepLink = buildDeepLink(this.guild.id, ctx.thread.id);
2018
- await this.sendNotification({
2019
- sessionId: ctx.sessionId,
2020
- type: "completed",
2021
- summary: content.text || "Session completed",
2022
- deepLink
2023
- });
2024
- } catch {
2025
- }
2026
- },
2027
- onSessionEnd: async (ctx, _content) => {
2028
- await this.draftManager.finalize(
2029
- ctx.sessionId,
2030
- ctx.thread,
2031
- ctx.isAssistant
2032
- );
2033
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
2034
- await tracker.cleanup();
2035
- this.toolTracker.cleanup(ctx.sessionId);
2036
- this.sessionTrackers.delete(ctx.sessionId);
2037
- await this.skillManager.cleanup(ctx.sessionId);
2038
2248
  try {
2039
2249
  await this.sendQueue.enqueue(
2040
- () => ctx.thread.send({ content: "\u2705 Done" }),
2041
- { type: "other" }
2042
- );
2043
- } catch {
2044
- }
2045
- },
2046
- onError: async (ctx, content) => {
2047
- await this.draftManager.finalize(
2048
- ctx.sessionId,
2049
- ctx.thread,
2050
- ctx.isAssistant
2051
- );
2052
- const tracker = this.getOrCreateTracker(ctx.sessionId, ctx.thread);
2053
- await tracker.cleanup();
2054
- this.toolTracker.cleanup(ctx.sessionId);
2055
- this.sessionTrackers.delete(ctx.sessionId);
2056
- try {
2057
- await this.sendQueue.enqueue(
2058
- () => ctx.thread.send({ content: `\u274C Error: ${content.text}` }),
2250
+ () => thread.send({
2251
+ content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}`
2252
+ }),
2059
2253
  { type: "other" }
2060
2254
  );
2061
2255
  } catch {
2062
2256
  }
2063
- },
2064
- onAttachment: async (ctx, content) => {
2065
- if (!content.attachment) return;
2066
- const { attachment } = content;
2067
- await this.draftManager.finalize(
2068
- ctx.sessionId,
2069
- ctx.thread,
2070
- ctx.isAssistant
2257
+ return;
2258
+ }
2259
+ try {
2260
+ await this.sendQueue.enqueue(
2261
+ () => thread.send({
2262
+ files: [
2263
+ { attachment: attachment.filePath, name: attachment.fileName }
2264
+ ]
2265
+ }),
2266
+ { type: "other" }
2071
2267
  );
2072
- if (isAttachmentTooLarge(attachment.size)) {
2073
- log.warn(
2074
- {
2075
- sessionId: ctx.sessionId,
2076
- fileName: attachment.fileName,
2077
- size: attachment.size
2078
- },
2079
- "[discord-media] File too large (>25MB)"
2080
- );
2081
- try {
2082
- await this.sendQueue.enqueue(
2083
- () => ctx.thread.send({
2084
- content: `\u26A0\uFE0F File too large to send (${Math.round(attachment.size / 1024 / 1024)}MB): ${attachment.fileName}`
2085
- }),
2086
- { type: "other" }
2087
- );
2088
- } catch {
2089
- }
2090
- return;
2091
- }
2092
- try {
2093
- await this.sendQueue.enqueue(
2094
- () => ctx.thread.send({
2095
- files: [
2096
- { attachment: attachment.filePath, name: attachment.fileName }
2097
- ]
2098
- }),
2099
- { type: "other" }
2100
- );
2101
- if (attachment.type === "audio") {
2102
- const draft = this.draftManager.getDraft(ctx.sessionId);
2103
- if (draft) {
2104
- draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
2105
- });
2106
- }
2268
+ if (attachment.type === "audio") {
2269
+ const draft = this.draftManager.getDraft(sessionId);
2270
+ if (draft) {
2271
+ draft.stripPattern(/\[TTS\][\s\S]*?\[\/TTS\]/g).catch(() => {
2272
+ });
2107
2273
  }
2108
- } catch (err) {
2109
- log.error(
2110
- { err, sessionId: ctx.sessionId, fileName: attachment.fileName },
2111
- "[discord-media] Failed to send attachment"
2112
- );
2113
- }
2114
- },
2115
- onSystemMessage: async (ctx, content) => {
2116
- try {
2117
- await this.sendQueue.enqueue(
2118
- () => ctx.thread.send({ content: content.text }),
2119
- { type: "other" }
2120
- );
2121
- } catch {
2122
2274
  }
2275
+ } catch (err) {
2276
+ log.error(
2277
+ { err, sessionId, fileName: attachment.fileName },
2278
+ "[discord-media] Failed to send attachment"
2279
+ );
2123
2280
  }
2124
- };
2125
- // ─── sendMessage ──────────────────────────────────────────────────────────
2126
- async sendMessage(sessionId, content) {
2127
- if (this.assistantInitializing && this.assistantSession && sessionId === this.assistantSession.id) {
2128
- return;
2281
+ }
2282
+ async handleSystem(sessionId, content) {
2283
+ const { thread } = this.getSessionContext(sessionId);
2284
+ try {
2285
+ await this.sendQueue.enqueue(
2286
+ () => thread.send({ content: content.text }),
2287
+ { type: "other" }
2288
+ );
2289
+ } catch {
2129
2290
  }
2130
- const thread = await this.getThread(sessionId);
2131
- if (!thread) return;
2132
- await ensureUnarchived(thread);
2133
- const isAssistant = this.assistantSession != null && sessionId === this.assistantSession.id;
2134
- const ctx = { sessionId, thread, isAssistant };
2135
- await dispatchMessage(this.messageHandlers, ctx, content, this.verbosity);
2136
2291
  }
2137
2292
  // ─── sendPermissionRequest ────────────────────────────────────────────────
2138
2293
  async sendPermissionRequest(sessionId, request) {
@@ -2236,4 +2391,4 @@ ${notification.deepLink}`;
2236
2391
  export {
2237
2392
  DiscordAdapter
2238
2393
  };
2239
- //# sourceMappingURL=discord-OMC52Y54.js.map
2394
+ //# sourceMappingURL=adapter-77ZCVABT.js.map