agentix-cli 0.50.0 → 0.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (248) hide show
  1. package/apps/mac-voice/Sources/AgentXVoice/AgentClient.swift +67 -14
  2. package/apps/mac-voice/Sources/AgentXVoice/Config.swift +20 -3
  3. package/apps/mac-voice/Sources/AgentXVoice/Panel.swift +24 -31
  4. package/apps/mac-voice/Sources/AgentXVoice/Speech.swift +16 -2
  5. package/apps/mac-voice/Sources/AgentXVoice/StatusMenu.swift +173 -0
  6. package/apps/mac-voice/Sources/AgentXVoice/main.swift +62 -15
  7. package/dist/{App-KE4SURSS.js → App-QVNQ5BQK.js} +2 -2
  8. package/dist/{ChatApp-NNHIKXO2.js → ChatApp-CC57XC23.js} +2 -2
  9. package/dist/agent-ILH6ANOM.js +2 -0
  10. package/dist/{article-fields-L4D2BOGY.js → article-fields-PITN4NHA.js} +2 -2
  11. package/dist/{article-quality-44ONVGLN.js → article-quality-JFJMZWFQ.js} +2 -2
  12. package/dist/{audit-4245CX6P.js → audit-CMJ2TZ3K.js} +2 -2
  13. package/dist/{backfill-MTD2B62I.js → backfill-7TCF4SHG.js} +2 -2
  14. package/dist/{board-dashboard-RUOASCSQ.js → board-dashboard-XPPBRPQE.js} +117 -117
  15. package/dist/board-dashboard-XPPBRPQE.js.map +1 -0
  16. package/dist/{builtin-B67DMJ3M.js → builtin-W6KNX7RS.js} +2 -2
  17. package/dist/calibration-MCCVYGZQ.js +2 -0
  18. package/dist/{chunk-3SCPRYJB.js → chunk-2AXFYDWF.js} +2 -2
  19. package/dist/{chunk-4TITGMPX.js → chunk-2KQTE4XI.js} +2 -2
  20. package/dist/{chunk-QDE75R4U.js → chunk-6HAZ6YWI.js} +2 -2
  21. package/dist/{chunk-F4HZTZHW.js → chunk-72SZI2UW.js} +2 -2
  22. package/dist/{chunk-L2WSPY6S.js → chunk-7I7IEX4S.js} +2 -2
  23. package/dist/{chunk-OTW5MPFT.js → chunk-CAA546XN.js} +2 -2
  24. package/dist/{chunk-5XQCGPQJ.js → chunk-F7WY24UZ.js} +2 -2
  25. package/dist/{chunk-ZTEU5JVQ.js → chunk-FCPTN6NF.js} +2 -2
  26. package/dist/{chunk-AJONZWLT.js → chunk-FX3D7YON.js} +2 -2
  27. package/dist/{chunk-5ALS7SVV.js → chunk-H2TWRZC2.js} +2 -2
  28. package/dist/{chunk-WPMX3VGI.js → chunk-J3SOEFRE.js} +2 -2
  29. package/dist/{chunk-4NBWF4TL.js → chunk-JQR3NTHI.js} +2 -2
  30. package/dist/{chunk-OUZ7YVQZ.js → chunk-KFALP5NO.js} +2 -2
  31. package/dist/{chunk-Y6I3BYWV.js → chunk-LBMZP7TG.js} +95 -95
  32. package/dist/chunk-LBMZP7TG.js.map +1 -0
  33. package/dist/{chunk-WQLBJ2O5.js → chunk-PSDCRZZM.js} +6 -6
  34. package/dist/chunk-QIJLFPWE.js +2 -0
  35. package/dist/{chunk-PZCTCCC5.js → chunk-QP6XNTBB.js} +2 -2
  36. package/dist/{chunk-BH3GTCZ6.js → chunk-RGDKHYY2.js} +2 -2
  37. package/dist/{chunk-JVNFRS26.js → chunk-ROCUOXCW.js} +2 -2
  38. package/dist/{chunk-FULEQYM6.js → chunk-S7CVSKOX.js} +2 -2
  39. package/dist/chunk-S7CVSKOX.js.map +1 -0
  40. package/dist/{chunk-K33GIBSE.js → chunk-SIU6STB2.js} +2 -2
  41. package/dist/{chunk-P2ZYT5D6.js → chunk-SRCXUZM2.js} +5 -5
  42. package/dist/{chunk-P2ZYT5D6.js.map → chunk-SRCXUZM2.js.map} +1 -1
  43. package/dist/{chunk-LCIREYTD.js → chunk-SZJMS7K4.js} +2 -2
  44. package/dist/{chunk-AJ5RMU7X.js → chunk-TFVUOC2C.js} +2 -2
  45. package/dist/chunk-U67EG5IF.js +19 -0
  46. package/dist/chunk-U67EG5IF.js.map +1 -0
  47. package/dist/{chunk-BYD55JXH.js → chunk-UBRMOTBH.js} +181 -180
  48. package/dist/chunk-UBRMOTBH.js.map +1 -0
  49. package/dist/chunk-V7XZN3MQ.js +123 -0
  50. package/dist/chunk-V7XZN3MQ.js.map +1 -0
  51. package/dist/{chunk-NLZD2QKF.js → chunk-VMS3HVTT.js} +2 -2
  52. package/dist/{chunk-TUNQFPVA.js → chunk-WCMQRSVU.js} +2 -2
  53. package/dist/{chunk-OHA3J5ZV.js → chunk-WDQ3BPFS.js} +2 -2
  54. package/dist/{chunk-6VKCUMCN.js → chunk-WKTFP3SK.js} +2 -2
  55. package/dist/{chunk-Q7C3X3R6.js → chunk-WP6KLXTP.js} +2 -2
  56. package/dist/{chunk-IXUEJBHD.js → chunk-XZTR5MBJ.js} +2 -2
  57. package/dist/{chunk-W5C2GDNC.js → chunk-Y57CULGE.js} +2 -2
  58. package/dist/chunk-YE2BUU3Z.js +28 -0
  59. package/dist/chunk-YE2BUU3Z.js.map +1 -0
  60. package/dist/{chunk-TTL37CS5.js → chunk-YEV6W34S.js} +55 -55
  61. package/dist/{chunk-TTL37CS5.js.map → chunk-YEV6W34S.js.map} +1 -1
  62. package/dist/cli.js +1 -1
  63. package/dist/client-I7GAAM3T.js +2 -0
  64. package/dist/{compaction-PIZINFHR.js → compaction-NWPBPWY2.js} +4 -4
  65. package/dist/{config-R47ITLIY.js → config-TVW7UCKG.js} +2 -2
  66. package/dist/config-mutator-JHM53P5A.js +2 -0
  67. package/dist/{conflict-detector-ZPOT3M2C.js → conflict-detector-KS7OSS45.js} +2 -2
  68. package/dist/{context-planner-FJMU5WAT.js → context-planner-LJT5IKH6.js} +3 -3
  69. package/dist/debug-FTAGG7MN.js +2 -0
  70. package/dist/{discover-D4VVRNAI.js → discover-7YFQNYLC.js} +2 -2
  71. package/dist/doctor-CXFMV6PT.js +2 -0
  72. package/dist/{editor-chat-MOMQHMO4.js → editor-chat-V24MXQIB.js} +2 -2
  73. package/dist/{entry-triage-LK34TSQD.js → entry-triage-LZWMMLLN.js} +2 -2
  74. package/dist/{facts-YVEJOM7O.js → facts-4YPSHIXJ.js} +2 -2
  75. package/dist/{failure-candidates-ARRMFXRY.js → failure-candidates-RIXA3Y6D.js} +2 -2
  76. package/dist/heal-HVYQD3EZ.js +2 -0
  77. package/dist/index.d.ts +256 -6
  78. package/dist/index.js +2 -2
  79. package/dist/{ingest-whatsapp-NS4OWDOU.js → ingest-whatsapp-4POCTRTP.js} +2 -2
  80. package/dist/loader-EVHZ2R73.js +2 -0
  81. package/dist/loader-KKMG24O5.js +2 -0
  82. package/dist/memory-extract-MGGXIZTE.js +2 -0
  83. package/dist/{migrate-v2-V4WN2VVM.js → migrate-v2-5VGHWPBW.js} +2 -2
  84. package/dist/{ntfy-X7EPB3TG.js → ntfy-ZY2NPGBA.js} +2 -2
  85. package/dist/processes-CMTMB7LG.js +2 -0
  86. package/dist/program-ZCFMO4ZD.js +2 -0
  87. package/dist/{projects-api-QE6L65SK.js → projects-api-E337EQNV.js} +2 -2
  88. package/dist/{projects-mutate-MY7JTLSZ.js → projects-mutate-S5MY7V3V.js} +2 -2
  89. package/dist/promote-4T64VW5K.js +2 -0
  90. package/dist/proposals-O4B5LD5T.js +2 -0
  91. package/dist/providers-NRPX2FHP.js +2 -0
  92. package/dist/query-6IKL52WT.js +2 -0
  93. package/dist/{questions-4B4KSPXG.js → questions-2V2VGIT4.js} +2 -2
  94. package/dist/recipes-423CIPZ3.js +2 -0
  95. package/dist/registry-E4QUXHMQ.js +2 -0
  96. package/dist/{request-planner-PEAYYXAP.js → request-planner-BRLDCYU5.js} +2 -2
  97. package/dist/{review-candidates-W7NIHNAI.js → review-candidates-QWW5PDUU.js} +2 -2
  98. package/dist/{review-store-B4YE3EFK.js → review-store-PW3OBGZQ.js} +2 -2
  99. package/dist/{rotation-memo-QEO3COFH.js → rotation-memo-453FXKHQ.js} +2 -2
  100. package/dist/routing-DP6S7OJL.js +2 -0
  101. package/dist/runner-56G3N7M4.js +2 -0
  102. package/dist/schedule-tool-TPJ6GR47.js +2 -0
  103. package/dist/scheduler-7QPG6OTY.js +2 -0
  104. package/dist/seat-3KUNRM5Z.js +2 -0
  105. package/dist/{select-4XYRIZ5L.js → select-ILXHYJGD.js} +2 -2
  106. package/dist/shutdown-ZAF7RW25.js +2 -0
  107. package/dist/store-TWQPEM5V.js +2 -0
  108. package/dist/{subagent-2SJHSSJS.js → subagent-XY5N7TUU.js} +2 -2
  109. package/dist/{surface-usage-V2BX4SBD.js → surface-usage-HVVP22SA.js} +2 -2
  110. package/dist/timers-KK7GF77Y.js +2 -0
  111. package/dist/{tool-PAQ47HV2.js → tool-SF3BCY55.js} +2 -2
  112. package/dist/{triage-backtest-JNO7RKX7.js → triage-backtest-DLKYJSEB.js} +2 -2
  113. package/dist/types-DO3KLIBS.js +2 -0
  114. package/dist/types-S6NHM5C3.js +2 -0
  115. package/dist/{whatsapp-state-6D6FHHD2.js → whatsapp-state-LB3R32BK.js} +2 -2
  116. package/dist/wiki-WETANN3W.js +2 -0
  117. package/dist/{workspace-setup-G6KGWPHY.js → workspace-setup-42ARC42I.js} +2 -2
  118. package/package.json +1 -1
  119. package/dist/agent-RY7Z3IYY.js +0 -2
  120. package/dist/board-dashboard-RUOASCSQ.js.map +0 -1
  121. package/dist/calibration-ILS5OI44.js +0 -2
  122. package/dist/chunk-B5XHX44Y.js +0 -123
  123. package/dist/chunk-B5XHX44Y.js.map +0 -1
  124. package/dist/chunk-BYD55JXH.js.map +0 -1
  125. package/dist/chunk-EMI3VJLH.js +0 -28
  126. package/dist/chunk-EMI3VJLH.js.map +0 -1
  127. package/dist/chunk-FIOB3MEX.js +0 -2
  128. package/dist/chunk-FULEQYM6.js.map +0 -1
  129. package/dist/chunk-N2XXKFJ6.js +0 -19
  130. package/dist/chunk-N2XXKFJ6.js.map +0 -1
  131. package/dist/chunk-Y6I3BYWV.js.map +0 -1
  132. package/dist/client-JZTH46N2.js +0 -2
  133. package/dist/config-mutator-T6JGXJ26.js +0 -2
  134. package/dist/debug-3MEUO2P2.js +0 -2
  135. package/dist/doctor-2DMGAWMW.js +0 -2
  136. package/dist/heal-FVLBHYP7.js +0 -2
  137. package/dist/loader-4ZGTK7LD.js +0 -2
  138. package/dist/loader-BOKE5M5S.js +0 -2
  139. package/dist/memory-extract-OWTI6MN5.js +0 -2
  140. package/dist/processes-KUJJ7XE7.js +0 -2
  141. package/dist/program-KY5ZYPFN.js +0 -2
  142. package/dist/promote-57YNOVXV.js +0 -2
  143. package/dist/proposals-TX2HBBYV.js +0 -2
  144. package/dist/providers-KO2DODIO.js +0 -2
  145. package/dist/query-ZT7WXY2F.js +0 -2
  146. package/dist/recipes-7S4MC5OJ.js +0 -2
  147. package/dist/registry-LLAFJJN4.js +0 -2
  148. package/dist/routing-7LCO7UJ7.js +0 -2
  149. package/dist/runner-YRBVNYTY.js +0 -2
  150. package/dist/schedule-tool-ZD3VBUBW.js +0 -2
  151. package/dist/scheduler-GC3FQKXY.js +0 -2
  152. package/dist/seat-HR6QMAR2.js +0 -2
  153. package/dist/shutdown-6GCMKYAD.js +0 -2
  154. package/dist/store-MCOA6N4F.js +0 -2
  155. package/dist/timers-PCB4ZIBD.js +0 -2
  156. package/dist/types-H5ENIUIT.js +0 -2
  157. package/dist/types-OIFU3KSQ.js +0 -2
  158. package/dist/wiki-EREMPSAE.js +0 -2
  159. /package/dist/{App-KE4SURSS.js.map → App-QVNQ5BQK.js.map} +0 -0
  160. /package/dist/{ChatApp-NNHIKXO2.js.map → ChatApp-CC57XC23.js.map} +0 -0
  161. /package/dist/{agent-RY7Z3IYY.js.map → agent-ILH6ANOM.js.map} +0 -0
  162. /package/dist/{article-fields-L4D2BOGY.js.map → article-fields-PITN4NHA.js.map} +0 -0
  163. /package/dist/{article-quality-44ONVGLN.js.map → article-quality-JFJMZWFQ.js.map} +0 -0
  164. /package/dist/{audit-4245CX6P.js.map → audit-CMJ2TZ3K.js.map} +0 -0
  165. /package/dist/{backfill-MTD2B62I.js.map → backfill-7TCF4SHG.js.map} +0 -0
  166. /package/dist/{builtin-B67DMJ3M.js.map → builtin-W6KNX7RS.js.map} +0 -0
  167. /package/dist/{calibration-ILS5OI44.js.map → calibration-MCCVYGZQ.js.map} +0 -0
  168. /package/dist/{chunk-3SCPRYJB.js.map → chunk-2AXFYDWF.js.map} +0 -0
  169. /package/dist/{chunk-4TITGMPX.js.map → chunk-2KQTE4XI.js.map} +0 -0
  170. /package/dist/{chunk-QDE75R4U.js.map → chunk-6HAZ6YWI.js.map} +0 -0
  171. /package/dist/{chunk-F4HZTZHW.js.map → chunk-72SZI2UW.js.map} +0 -0
  172. /package/dist/{chunk-L2WSPY6S.js.map → chunk-7I7IEX4S.js.map} +0 -0
  173. /package/dist/{chunk-OTW5MPFT.js.map → chunk-CAA546XN.js.map} +0 -0
  174. /package/dist/{chunk-5XQCGPQJ.js.map → chunk-F7WY24UZ.js.map} +0 -0
  175. /package/dist/{chunk-ZTEU5JVQ.js.map → chunk-FCPTN6NF.js.map} +0 -0
  176. /package/dist/{chunk-AJONZWLT.js.map → chunk-FX3D7YON.js.map} +0 -0
  177. /package/dist/{chunk-5ALS7SVV.js.map → chunk-H2TWRZC2.js.map} +0 -0
  178. /package/dist/{chunk-WPMX3VGI.js.map → chunk-J3SOEFRE.js.map} +0 -0
  179. /package/dist/{chunk-4NBWF4TL.js.map → chunk-JQR3NTHI.js.map} +0 -0
  180. /package/dist/{chunk-OUZ7YVQZ.js.map → chunk-KFALP5NO.js.map} +0 -0
  181. /package/dist/{chunk-WQLBJ2O5.js.map → chunk-PSDCRZZM.js.map} +0 -0
  182. /package/dist/{chunk-FIOB3MEX.js.map → chunk-QIJLFPWE.js.map} +0 -0
  183. /package/dist/{chunk-PZCTCCC5.js.map → chunk-QP6XNTBB.js.map} +0 -0
  184. /package/dist/{chunk-BH3GTCZ6.js.map → chunk-RGDKHYY2.js.map} +0 -0
  185. /package/dist/{chunk-JVNFRS26.js.map → chunk-ROCUOXCW.js.map} +0 -0
  186. /package/dist/{chunk-K33GIBSE.js.map → chunk-SIU6STB2.js.map} +0 -0
  187. /package/dist/{chunk-LCIREYTD.js.map → chunk-SZJMS7K4.js.map} +0 -0
  188. /package/dist/{chunk-AJ5RMU7X.js.map → chunk-TFVUOC2C.js.map} +0 -0
  189. /package/dist/{chunk-NLZD2QKF.js.map → chunk-VMS3HVTT.js.map} +0 -0
  190. /package/dist/{chunk-TUNQFPVA.js.map → chunk-WCMQRSVU.js.map} +0 -0
  191. /package/dist/{chunk-OHA3J5ZV.js.map → chunk-WDQ3BPFS.js.map} +0 -0
  192. /package/dist/{chunk-6VKCUMCN.js.map → chunk-WKTFP3SK.js.map} +0 -0
  193. /package/dist/{chunk-Q7C3X3R6.js.map → chunk-WP6KLXTP.js.map} +0 -0
  194. /package/dist/{chunk-IXUEJBHD.js.map → chunk-XZTR5MBJ.js.map} +0 -0
  195. /package/dist/{chunk-W5C2GDNC.js.map → chunk-Y57CULGE.js.map} +0 -0
  196. /package/dist/{client-JZTH46N2.js.map → client-I7GAAM3T.js.map} +0 -0
  197. /package/dist/{compaction-PIZINFHR.js.map → compaction-NWPBPWY2.js.map} +0 -0
  198. /package/dist/{config-R47ITLIY.js.map → config-TVW7UCKG.js.map} +0 -0
  199. /package/dist/{config-mutator-T6JGXJ26.js.map → config-mutator-JHM53P5A.js.map} +0 -0
  200. /package/dist/{conflict-detector-ZPOT3M2C.js.map → conflict-detector-KS7OSS45.js.map} +0 -0
  201. /package/dist/{context-planner-FJMU5WAT.js.map → context-planner-LJT5IKH6.js.map} +0 -0
  202. /package/dist/{debug-3MEUO2P2.js.map → debug-FTAGG7MN.js.map} +0 -0
  203. /package/dist/{discover-D4VVRNAI.js.map → discover-7YFQNYLC.js.map} +0 -0
  204. /package/dist/{doctor-2DMGAWMW.js.map → doctor-CXFMV6PT.js.map} +0 -0
  205. /package/dist/{editor-chat-MOMQHMO4.js.map → editor-chat-V24MXQIB.js.map} +0 -0
  206. /package/dist/{entry-triage-LK34TSQD.js.map → entry-triage-LZWMMLLN.js.map} +0 -0
  207. /package/dist/{facts-YVEJOM7O.js.map → facts-4YPSHIXJ.js.map} +0 -0
  208. /package/dist/{failure-candidates-ARRMFXRY.js.map → failure-candidates-RIXA3Y6D.js.map} +0 -0
  209. /package/dist/{heal-FVLBHYP7.js.map → heal-HVYQD3EZ.js.map} +0 -0
  210. /package/dist/{ingest-whatsapp-NS4OWDOU.js.map → ingest-whatsapp-4POCTRTP.js.map} +0 -0
  211. /package/dist/{loader-4ZGTK7LD.js.map → loader-EVHZ2R73.js.map} +0 -0
  212. /package/dist/{loader-BOKE5M5S.js.map → loader-KKMG24O5.js.map} +0 -0
  213. /package/dist/{memory-extract-OWTI6MN5.js.map → memory-extract-MGGXIZTE.js.map} +0 -0
  214. /package/dist/{migrate-v2-V4WN2VVM.js.map → migrate-v2-5VGHWPBW.js.map} +0 -0
  215. /package/dist/{ntfy-X7EPB3TG.js.map → ntfy-ZY2NPGBA.js.map} +0 -0
  216. /package/dist/{processes-KUJJ7XE7.js.map → processes-CMTMB7LG.js.map} +0 -0
  217. /package/dist/{program-KY5ZYPFN.js.map → program-ZCFMO4ZD.js.map} +0 -0
  218. /package/dist/{projects-api-QE6L65SK.js.map → projects-api-E337EQNV.js.map} +0 -0
  219. /package/dist/{projects-mutate-MY7JTLSZ.js.map → projects-mutate-S5MY7V3V.js.map} +0 -0
  220. /package/dist/{promote-57YNOVXV.js.map → promote-4T64VW5K.js.map} +0 -0
  221. /package/dist/{proposals-TX2HBBYV.js.map → proposals-O4B5LD5T.js.map} +0 -0
  222. /package/dist/{providers-KO2DODIO.js.map → providers-NRPX2FHP.js.map} +0 -0
  223. /package/dist/{query-ZT7WXY2F.js.map → query-6IKL52WT.js.map} +0 -0
  224. /package/dist/{questions-4B4KSPXG.js.map → questions-2V2VGIT4.js.map} +0 -0
  225. /package/dist/{recipes-7S4MC5OJ.js.map → recipes-423CIPZ3.js.map} +0 -0
  226. /package/dist/{registry-LLAFJJN4.js.map → registry-E4QUXHMQ.js.map} +0 -0
  227. /package/dist/{request-planner-PEAYYXAP.js.map → request-planner-BRLDCYU5.js.map} +0 -0
  228. /package/dist/{review-candidates-W7NIHNAI.js.map → review-candidates-QWW5PDUU.js.map} +0 -0
  229. /package/dist/{review-store-B4YE3EFK.js.map → review-store-PW3OBGZQ.js.map} +0 -0
  230. /package/dist/{rotation-memo-QEO3COFH.js.map → rotation-memo-453FXKHQ.js.map} +0 -0
  231. /package/dist/{routing-7LCO7UJ7.js.map → routing-DP6S7OJL.js.map} +0 -0
  232. /package/dist/{runner-YRBVNYTY.js.map → runner-56G3N7M4.js.map} +0 -0
  233. /package/dist/{schedule-tool-ZD3VBUBW.js.map → schedule-tool-TPJ6GR47.js.map} +0 -0
  234. /package/dist/{scheduler-GC3FQKXY.js.map → scheduler-7QPG6OTY.js.map} +0 -0
  235. /package/dist/{seat-HR6QMAR2.js.map → seat-3KUNRM5Z.js.map} +0 -0
  236. /package/dist/{select-4XYRIZ5L.js.map → select-ILXHYJGD.js.map} +0 -0
  237. /package/dist/{shutdown-6GCMKYAD.js.map → shutdown-ZAF7RW25.js.map} +0 -0
  238. /package/dist/{store-MCOA6N4F.js.map → store-TWQPEM5V.js.map} +0 -0
  239. /package/dist/{subagent-2SJHSSJS.js.map → subagent-XY5N7TUU.js.map} +0 -0
  240. /package/dist/{surface-usage-V2BX4SBD.js.map → surface-usage-HVVP22SA.js.map} +0 -0
  241. /package/dist/{timers-PCB4ZIBD.js.map → timers-KK7GF77Y.js.map} +0 -0
  242. /package/dist/{tool-PAQ47HV2.js.map → tool-SF3BCY55.js.map} +0 -0
  243. /package/dist/{triage-backtest-JNO7RKX7.js.map → triage-backtest-DLKYJSEB.js.map} +0 -0
  244. /package/dist/{types-H5ENIUIT.js.map → types-DO3KLIBS.js.map} +0 -0
  245. /package/dist/{types-OIFU3KSQ.js.map → types-S6NHM5C3.js.map} +0 -0
  246. /package/dist/{whatsapp-state-6D6FHHD2.js.map → whatsapp-state-LB3R32BK.js.map} +0 -0
  247. /package/dist/{wiki-EREMPSAE.js.map → wiki-WETANN3W.js.map} +0 -0
  248. /package/dist/{workspace-setup-G6KGWPHY.js.map → workspace-setup-42ARC42I.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import{a as Qt}from"./chunk-7WDJW37G.js";import{a as C,b as Zt,c as ea,d as ta,e as aa,f as ae,g as be,h as Ve,i as Le,j as na,k as ra,l as sa,m as ia,n as la}from"./chunk-TUNQFPVA.js";import{a as oa}from"./chunk-Z3IP66SL.js";import{a as he,c as $,d as P,i as Ie,j as $e,k as J,l as q,m as je,n as Jt,o as Vt,p as Yt}from"./chunk-4BNQSUWV.js";import{C as Ft,E as me,F as Se,G as Te,H as Ce,I as Ae,J as Ut,K as Wt,L as Gt,M as Me,O as Xt,R as Kt,a as jt,c as Ee,d as Je,e as Lt,i as Rt,u as Ot,v as Ht,w as Nt,x as Bt}from"./chunk-EMI3VJLH.js";import{g as It,h as $t}from"./chunk-PZCTCCC5.js";import{a as zt,b as qt}from"./chunk-LQRBGQIR.js";import{o as Pt,r as Dt}from"./chunk-FULEQYM6.js";import"./chunk-OHA3J5ZV.js";import"./chunk-3SCPRYJB.js";import"./chunk-AQASR6KR.js";import{a as Tt,c as Xe,d as Ke,h as Ct,i as At,j as Mt}from"./chunk-N2XXKFJ6.js";import"./chunk-N6EWZGIX.js";import"./chunk-Q7C3X3R6.js";import"./chunk-DP7RTNDM.js";import"./chunk-5XQCGPQJ.js";import"./chunk-B5XHX44Y.js";import"./chunk-AFRHKA7B.js";import"./chunk-NLZD2QKF.js";import"./chunk-HRBKSZ34.js";import"./chunk-IXUEJBHD.js";import{b as St}from"./chunk-JVNFRS26.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-AJ5RMU7X.js";import"./chunk-2GIDVZ4H.js";import"./chunk-4NBWF4TL.js";import"./chunk-F4HZTZHW.js";import"./chunk-AJONZWLT.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import{a as _t,b as Et,c as Xn,m as K,p as Ge}from"./chunk-P2ZYT5D6.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";function Ye(t,e,a=Date.now()){let n=Math.max(0,a-(t.updatedAt||a)),r=t.clientId?e[t.clientId]:void 0;if(!r)return{score:n/864e5,ageMs:n,rising:!1,overdue:!1};let o=n/(r*6e4);return{score:1e3+o,ageMs:n,rising:!0,overdue:o>=1}}function da(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:Ye(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}var V={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',alert:'<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',gavel:'<path d="M12 3 6 9"/><path d="m9 6 6 6"/><path d="M15 9 9 15"/><path d="m12 12 6 6"/><path d="M4 21h10"/>',loop:'<path d="M17 2l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 22l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>',broom:'<path d="M3 21h18"/><path d="M12 3v9"/><path d="m7 12 5-3 5 3-1.5 6h-7Z"/>',server:'<rect x="2" y="3" width="20" height="7" rx="2"/><rect x="2" y="14" width="20" height="7" rx="2"/><path d="M6 6.5h.01"/><path d="M6 17.5h.01"/>',inbox:'<path d="M21 12h-6l-2 3h-2l-2-3H3"/><path d="M5 5h14l2 7v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Z"/>',cross:'<circle cx="12" cy="12" r="9"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/>',file:'<path d="M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7Z"/><path d="M14 2v5h5"/>',search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',chev:'<path d="m6 9 6 6 6-6"/>',chevr:'<path d="m9 6 6 6-6 6"/>',ext:'<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',pulse:'<path d="M3 12h4l3-8 4 16 3-8h4"/>',plug:'<path d="M9 2v6"/><path d="M15 2v6"/><path d="M6 8h12v3a6 6 0 0 1-12 0Z"/><path d="M12 17v5"/>',check:'<path d="M20 6 9 17l-5-5"/>',route:'<circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h6a4 4 0 0 0 0-8H9a4 4 0 0 1 0-8h6"/>',branch:'<circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="8" r="3"/><path d="M18 11v1a3 3 0 0 1-3 3H9"/><path d="M6 9v6"/>',send:'<path d="M22 2 11 13"/><path d="M22 2l-7 20-4-9-9-4Z"/>',msg:'<path d="M21 11.5a8.4 8.4 0 0 1-12.9 7.5L3 21l2-5.1A8.4 8.4 0 1 1 21 11.5Z"/>',code:'<path d="m9 18-6-6 6-6"/><path d="m15 6 6 6-6 6"/>',hash:'<path d="M4 9h16"/><path d="M4 15h16"/><path d="M10 3 8 21"/><path d="M16 3l-2 18"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',trace:'<path d="M4 4v16h16"/><path d="m7 15 4-4 3 3 5-6"/>'},ce=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",Re=(t,e,a,n="")=>'<div class="ax-sec-label"><h3>'+ce(t,13)+e+(a?'<span class="ax-sec-label__n" id="'+a+'"></span>':"")+"</h3>"+n+"</div>";function ca(t={}){return $({title:"AgentX \xB7 Monitor",activeTab:"monitor",subtitle:"Monitor",peers:t.peers,body:`<div class="bf">
1
+ import{a as Zt}from"./chunk-7WDJW37G.js";import{a as C,b as ea,c as ta,d as aa,e as na,f as ae,g as ye,h as Ye,i as Re,j as ra,k as oa,l as ia,m as la,n as da}from"./chunk-WCMQRSVU.js";import{a as sa}from"./chunk-Z3IP66SL.js";import{a as ge,c as $,d as P,i as $e,j as je,k as J,l as q,m as Le,n as Vt,o as Yt,p as Qt}from"./chunk-4BNQSUWV.js";import{B as ce,C as Bt,D as zt,I as Ut,K as he,L as Te,M as Ce,N as Ae,O as Me,P as Wt,Q as Gt,R as Xt,S as Ie,U as Kt,X as Jt,a as Lt,c as Se,d as Ve,e as Rt,i as Pt,u as Ht,v as Nt}from"./chunk-YE2BUU3Z.js";import{g as $t,h as jt}from"./chunk-QP6XNTBB.js";import{a as qt,b as Ft}from"./chunk-LQRBGQIR.js";import{o as Dt,r as Ot}from"./chunk-S7CVSKOX.js";import"./chunk-WDQ3BPFS.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import{a as Ct,c as Ke,d as Je,h as At,i as Mt,j as It}from"./chunk-U67EG5IF.js";import"./chunk-N6EWZGIX.js";import"./chunk-WP6KLXTP.js";import"./chunk-DP7RTNDM.js";import"./chunk-F7WY24UZ.js";import"./chunk-V7XZN3MQ.js";import"./chunk-AFRHKA7B.js";import"./chunk-VMS3HVTT.js";import"./chunk-HRBKSZ34.js";import"./chunk-XZTR5MBJ.js";import{b as Tt}from"./chunk-ROCUOXCW.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-TFVUOC2C.js";import"./chunk-2GIDVZ4H.js";import"./chunk-JQR3NTHI.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-SZJMS7K4.js";import"./chunk-7I7IEX4S.js";import{a as Et,b as St,c as Kn,m as K,p as Xe}from"./chunk-SRCXUZM2.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";function Qe(t,e,a=Date.now()){let n=Math.max(0,a-(t.updatedAt||a)),r=t.clientId?e[t.clientId]:void 0;if(!r)return{score:n/864e5,ageMs:n,rising:!1,overdue:!1};let o=n/(r*6e4);return{score:1e3+o,ageMs:n,rising:!0,overdue:o>=1}}function ca(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:Qe(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}var V={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',alert:'<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',gavel:'<path d="M12 3 6 9"/><path d="m9 6 6 6"/><path d="M15 9 9 15"/><path d="m12 12 6 6"/><path d="M4 21h10"/>',loop:'<path d="M17 2l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 22l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>',broom:'<path d="M3 21h18"/><path d="M12 3v9"/><path d="m7 12 5-3 5 3-1.5 6h-7Z"/>',server:'<rect x="2" y="3" width="20" height="7" rx="2"/><rect x="2" y="14" width="20" height="7" rx="2"/><path d="M6 6.5h.01"/><path d="M6 17.5h.01"/>',inbox:'<path d="M21 12h-6l-2 3h-2l-2-3H3"/><path d="M5 5h14l2 7v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Z"/>',cross:'<circle cx="12" cy="12" r="9"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/>',file:'<path d="M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7Z"/><path d="M14 2v5h5"/>',search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',chev:'<path d="m6 9 6 6 6-6"/>',chevr:'<path d="m9 6 6 6-6 6"/>',ext:'<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',pulse:'<path d="M3 12h4l3-8 4 16 3-8h4"/>',plug:'<path d="M9 2v6"/><path d="M15 2v6"/><path d="M6 8h12v3a6 6 0 0 1-12 0Z"/><path d="M12 17v5"/>',check:'<path d="M20 6 9 17l-5-5"/>',route:'<circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h6a4 4 0 0 0 0-8H9a4 4 0 0 1 0-8h6"/>',branch:'<circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="8" r="3"/><path d="M18 11v1a3 3 0 0 1-3 3H9"/><path d="M6 9v6"/>',send:'<path d="M22 2 11 13"/><path d="M22 2l-7 20-4-9-9-4Z"/>',msg:'<path d="M21 11.5a8.4 8.4 0 0 1-12.9 7.5L3 21l2-5.1A8.4 8.4 0 1 1 21 11.5Z"/>',code:'<path d="m9 18-6-6 6-6"/><path d="m15 6 6 6-6 6"/>',hash:'<path d="M4 9h16"/><path d="M4 15h16"/><path d="M10 3 8 21"/><path d="M16 3l-2 18"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',trace:'<path d="M4 4v16h16"/><path d="m7 15 4-4 3 3 5-6"/>'},pe=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",Pe=(t,e,a,n="")=>'<div class="ax-sec-label"><h3>'+pe(t,13)+e+(a?'<span class="ax-sec-label__n" id="'+a+'"></span>':"")+"</h3>"+n+"</div>";function pa(t={}){return $({title:"AgentX \xB7 Monitor",activeTab:"monitor",subtitle:"Monitor",peers:t.peers,body:`<div class="bf">
2
2
 
3
3
  <div class="bf-head">
4
4
  <div>
@@ -7,8 +7,8 @@ import{a as Qt}from"./chunk-7WDJW37G.js";import{a as C,b as Zt,c as ea,d as ta,e
7
7
  </div>
8
8
  <div class="bf-sync">
9
9
  <span class="bf-sync__t" id="synced">Gathering&hellip;</span>
10
- <a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${ce(V.pulse,13)} Activity</a>
11
- <button class="ax-btn" id="refresh" title="Refresh now">${ce(V.refresh)} Refresh</button>
10
+ <a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${pe(V.pulse,13)} Activity</a>
11
+ <button class="ax-btn" id="refresh" title="Refresh now">${pe(V.refresh)} Refresh</button>
12
12
  </div>
13
13
  </div>
14
14
 
@@ -21,24 +21,24 @@ import{a as Qt}from"./chunk-7WDJW37G.js";import{a as C,b as Zt,c as ea,d as ta,e
21
21
 
22
22
  <div class="bf-grid">
23
23
  <section class="bf-col">
24
- ${Re(V.alert,"Only you","you-count",'<span class="bf-why">needs your authority, your relationship, or something the system cannot know</span><button class="ax-btn ax-btn--sm" id="clear-actions" title="Mark every open action done on every node">Clear all</button>')}
24
+ ${Pe(V.alert,"Only you","you-count",'<span class="bf-why">needs your authority, your relationship, or something the system cannot know</span><button class="ax-btn ax-btn--sm" id="clear-actions" title="Mark every open action done on every node">Clear all</button>')}
25
25
  <div id="you" class="bf-col"></div>
26
26
 
27
- ${Re(V.plug,"Agents can handle","agents-count",'<span class="bf-why">no human needed &mdash; not yet automatic</span>')}
27
+ ${Pe(V.plug,"Agents can handle","agents-count",'<span class="bf-why">no human needed &mdash; not yet automatic</span>')}
28
28
  <div id="agents" class="bf-col"></div>
29
29
  <button class="ax-btn ax-btn--sm" id="more-actions" hidden></button>
30
30
 
31
31
  <div id="handled"></div>
32
32
  </section>
33
33
  <aside class="bf-col">
34
- ${Re(V.pulse,"In motion","run-count")}
34
+ ${Pe(V.pulse,"In motion","run-count")}
35
35
  <div id="running" class="bf-col"></div>
36
36
  </aside>
37
37
  </div>
38
38
 
39
- ${Re(V.file,"Session briefings","brief-count")}
39
+ ${Pe(V.file,"Session briefings","brief-count")}
40
40
  <div class="bf-toolbar">
41
- <div class="bf-search">${ce(V.search)}
41
+ <div class="bf-search">${pe(V.search)}
42
42
  <input id="search" type="search" placeholder="Search sessions&hellip;" aria-label="Search sessions">
43
43
  </div>
44
44
  <div class="bf-filters" id="filters" role="group" aria-label="Filter briefings"></div>
@@ -46,15 +46,15 @@ ${Re(V.file,"Session briefings","brief-count")}
46
46
  <div id="reviews" class="bf-col"></div>
47
47
 
48
48
  <section class="ax-panel bf-connect">
49
- <div class="bf-connect__head">${ce(V.plug,17)}<h2>Connect a CLI session</h2>
49
+ <div class="bf-connect__head">${pe(V.plug,17)}<h2>Connect a CLI session</h2>
50
50
  <span class="bf-connect__note">Daemon-owned processes only</span></div>
51
51
  <div class="bf-discover">
52
52
  <div class="ax-field"><label for="node">Node</label><select id="node"></select></div>
53
- <button class="ax-btn" id="discover">${ce(V.search)} Discover CLIs</button>
53
+ <button class="ax-btn" id="discover">${pe(V.search)} Discover CLIs</button>
54
54
  </div>
55
55
  <div class="bf-cli" id="discovered"></div>
56
56
  <details class="bf-manual">
57
- <summary>${ce(V.chev,12)} Register manually</summary>
57
+ <summary>${pe(V.chev,12)} Register manually</summary>
58
58
  <div class="bf-forms">
59
59
  <form id="register" class="bf-form">
60
60
  <div class="ax-sec-label"><h3>Register a session</h3></div>
@@ -85,7 +85,7 @@ ${Re(V.file,"Session briefings","brief-count")}
85
85
  </div>
86
86
  </details>
87
87
  </section>
88
- </div>`,css:Kn,scripts:`<script>${he({decayOf:Ye,rankByDecay:da})}const ICON = ${JSON.stringify(V)};${Jn}</script>`})}var Kn=`
88
+ </div>`,css:Jn,scripts:`<script>${ge({decayOf:Qe,rankByDecay:ca})}const ICON = ${JSON.stringify(V)};${Vn}</script>`})}var Jn=`
89
89
  .bf{max-width:1240px;margin:0 auto;padding:22px 24px 48px}
90
90
  .bf-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
91
91
  .bf :focus-visible{outline:2px solid var(--ax-accent);outline-offset:2px;border-radius:4px}
@@ -361,7 +361,7 @@ button.bf-tag.is-on{background:color-mix(in oklch,var(--ax-accent) 14%,transpare
361
361
  .bf{padding:16px 14px 36px}
362
362
  .bf-head{flex-direction:column;gap:14px;align-items:stretch}
363
363
  .bf-sync{justify-content:space-between}
364
- }`,Jn=String.raw`
364
+ }`,Vn=String.raw`
365
365
  (function(){
366
366
  const $=id=>document.getElementById(id), esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
367
367
  const ic=(n,s)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+(s||14)+'" height="'+(s||14)+'" aria-hidden="true">'+ICON[n]+'</svg>';
@@ -776,22 +776,22 @@ if(document.querySelector('form :focus'))return;
776
776
  if(document.querySelector('.bf-trace[open]'))return; // don't yank an open trace
777
777
  refresh();
778
778
  },15000);
779
- })();`;function Qe(t,e=20*6e4,a=6){let n=[...t].sort((l,c)=>l.startedAt-c.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let l of n){let c=l.startedAt+Math.max(l.durationMs||0,0),p=r[r.length-1];p&&l.startedAt-p.to<=e?(p.to=Math.max(p.to,c),p.runs++):r.push({from:l.startedAt,to:c,runs:1})}for(;r.length>a;){let l=0,c=1/0;for(let p=1;p<r.length;p++){let m=r[p].from-r[p-1].to;m<c&&(c=m,l=p)}r[l-1].to=r[l].to,r[l-1].runs+=r[l].runs,r.splice(l,1)}let o=r.reduce((l,c)=>l+c.runs,0)||1,s=r.map(l=>({from:l.from,to:Math.max(l.to,l.from+1),weight:l.runs/o,runs:l.runs})),i=r.slice(1).map((l,c)=>l.from-r[c].to);return{bands:s,gaps:i}}function Ze(t){let e=[];for(let a of t.sort((n,r)=>n.startedAt-r.startedAt)){let n=a.startedAt+Math.max(a.durationMs||0,0),r=e.findIndex(o=>o<=a.startedAt);r===-1?(r=e.length,e.push(n)):e[r]=n,a.track=r}return Math.max(e.length,1)}function pa(t,e=[],a){let{bands:n,gaps:r}=Qe(t,a);if(!n.length)return{bands:[],gaps:[],lanes:[],from:0,to:0};let o=new Map;for(let l of e){let c=o.get(l.runId);c?c.push(l):o.set(l.runId,[l])}let s=new Map;for(let l of t){let c=n.findIndex(w=>l.startedAt>=w.from&&l.startedAt<=w.to);if(c===-1)continue;let p=n[c],m=p.to-p.from||1,h=(l.startedAt-p.from)/m*100,_=Math.min(Math.max((l.durationMs||0)/m*100,1.2),100-h),S=s.get(l.laneKey)??{key:l.laneKey,label:l.laneLabel,sub:l.laneSub,tracks:1,runs:[]};S.runs.push({...l,band:c,track:0,left:h,width:_,marks:o.get(l.id)??[]}),s.set(l.laneKey,S)}let i=[...s.values()];for(let l of i)l.tracks=Math.max(...n.map((c,p)=>Ze(l.runs.filter(m=>m.band===p))),1);return i.sort((l,c)=>c.runs.length-l.runs.length||l.label.localeCompare(c.label)),{bands:n,gaps:r,lanes:i,from:n[0].from,to:n[n.length-1].to}}import{createHash as Vn}from"crypto";import{readFileSync as Yn,statSync as Qn}from"fs";import{resolve as Zn,dirname as er}from"path";import{fileURLToPath as tr}from"url";var ua=new Map;function Pe(t){let e=ua.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=er(tr(import.meta.url)),r=Zn(n,"web",t),o=Qn(r),s=o.size<8e6?Vn("sha1").update(Yn(r)).digest("hex").slice(0,10):`${o.size}-${Math.floor(o.mtimeMs)}`;a=`/assets/${t}?v=${s}`}catch{}return ua.set(t,a),a}var ee={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',bot:'<rect x="4" y="8" width="16" height="12" rx="2"/><path d="M12 8V5M9 14h.01M15 14h.01"/>',user:'<circle cx="12" cy="8" r="3.5"/><path d="M5 21a7 7 0 0 1 14 0"/>',folder:'<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>',map:'<path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2z"/><path d="M9 4v14M15 6v14"/>',timeline:'<path d="M3 6h10M7 12h14M3 18h8"/>',mesh:'<circle cx="5" cy="19" r="2.5"/><circle cx="19" cy="19" r="2.5"/><circle cx="12" cy="5" r="2.5"/><path d="M7 17.5l4-10M17 17.5l-4-10"/>',route:'<circle cx="6" cy="6" r="3"/><circle cx="18" cy="18" r="3"/><path d="M9 6h6a3 3 0 0 1 0 6H9a3 3 0 0 0 0 6h6"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',x:'<path d="M18 6L6 18M6 6l12 12"/>',alert:'<path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/>'},De=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",ar=[["agent","Agent",ee.bot],["client","Client",ee.user],["project","Project",ee.folder],["channel","Channel",ee.route],["node","Node",ee.mesh]],ma={timeline:"Every run on the mesh, from task traces. The axis breaks over silence &mdash; quiet stretches are labelled, not drawn.",map:"The fleet as a transit map: projects are lines, agents are stations, work in flight is a train. Live."};function ha(t={}){let e=t.view==="map"?"map":"timeline",a=e==="map";return $({title:"AgentX \xB7 Activity",activeTab:"activity",subtitle:"Activity",peers:t.peers,body:`<div class="ac">
779
+ })();`;function Ze(t,e=20*6e4,a=6){let n=[...t].sort((l,c)=>l.startedAt-c.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let l of n){let c=l.startedAt+Math.max(l.durationMs||0,0),p=r[r.length-1];p&&l.startedAt-p.to<=e?(p.to=Math.max(p.to,c),p.runs++):r.push({from:l.startedAt,to:c,runs:1})}for(;r.length>a;){let l=0,c=1/0;for(let p=1;p<r.length;p++){let m=r[p].from-r[p-1].to;m<c&&(c=m,l=p)}r[l-1].to=r[l].to,r[l-1].runs+=r[l].runs,r.splice(l,1)}let o=r.reduce((l,c)=>l+c.runs,0)||1,s=r.map(l=>({from:l.from,to:Math.max(l.to,l.from+1),weight:l.runs/o,runs:l.runs})),i=r.slice(1).map((l,c)=>l.from-r[c].to);return{bands:s,gaps:i}}function et(t){let e=[];for(let a of t.sort((n,r)=>n.startedAt-r.startedAt)){let n=a.startedAt+Math.max(a.durationMs||0,0),r=e.findIndex(o=>o<=a.startedAt);r===-1?(r=e.length,e.push(n)):e[r]=n,a.track=r}return Math.max(e.length,1)}function ua(t,e=[],a){let{bands:n,gaps:r}=Ze(t,a);if(!n.length)return{bands:[],gaps:[],lanes:[],from:0,to:0};let o=new Map;for(let l of e){let c=o.get(l.runId);c?c.push(l):o.set(l.runId,[l])}let s=new Map;for(let l of t){let c=n.findIndex(w=>l.startedAt>=w.from&&l.startedAt<=w.to);if(c===-1)continue;let p=n[c],m=p.to-p.from||1,h=(l.startedAt-p.from)/m*100,_=Math.min(Math.max((l.durationMs||0)/m*100,1.2),100-h),S=s.get(l.laneKey)??{key:l.laneKey,label:l.laneLabel,sub:l.laneSub,tracks:1,runs:[]};S.runs.push({...l,band:c,track:0,left:h,width:_,marks:o.get(l.id)??[]}),s.set(l.laneKey,S)}let i=[...s.values()];for(let l of i)l.tracks=Math.max(...n.map((c,p)=>et(l.runs.filter(m=>m.band===p))),1);return i.sort((l,c)=>c.runs.length-l.runs.length||l.label.localeCompare(c.label)),{bands:n,gaps:r,lanes:i,from:n[0].from,to:n[n.length-1].to}}import{createHash as Yn}from"crypto";import{readFileSync as Qn,statSync as Zn}from"fs";import{resolve as er,dirname as tr}from"path";import{fileURLToPath as ar}from"url";var ma=new Map;function De(t){let e=ma.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=tr(ar(import.meta.url)),r=er(n,"web",t),o=Zn(r),s=o.size<8e6?Yn("sha1").update(Qn(r)).digest("hex").slice(0,10):`${o.size}-${Math.floor(o.mtimeMs)}`;a=`/assets/${t}?v=${s}`}catch{}return ma.set(t,a),a}var ee={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',bot:'<rect x="4" y="8" width="16" height="12" rx="2"/><path d="M12 8V5M9 14h.01M15 14h.01"/>',user:'<circle cx="12" cy="8" r="3.5"/><path d="M5 21a7 7 0 0 1 14 0"/>',folder:'<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>',map:'<path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2z"/><path d="M9 4v14M15 6v14"/>',timeline:'<path d="M3 6h10M7 12h14M3 18h8"/>',mesh:'<circle cx="5" cy="19" r="2.5"/><circle cx="19" cy="19" r="2.5"/><circle cx="12" cy="5" r="2.5"/><path d="M7 17.5l4-10M17 17.5l-4-10"/>',route:'<circle cx="6" cy="6" r="3"/><circle cx="18" cy="18" r="3"/><path d="M9 6h6a3 3 0 0 1 0 6H9a3 3 0 0 0 0 6h6"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',x:'<path d="M18 6L6 18M6 6l12 12"/>',alert:'<path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/>'},Oe=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",nr=[["agent","Agent",ee.bot],["client","Client",ee.user],["project","Project",ee.folder],["channel","Channel",ee.route],["node","Node",ee.mesh]],ha={timeline:"Every run on the mesh, from task traces. The axis breaks over silence &mdash; quiet stretches are labelled, not drawn.",map:"The fleet as a transit map: projects are lines, agents are stations, work in flight is a train. Live."};function ga(t={}){let e=t.view==="map"?"map":"timeline",a=e==="map";return $({title:"AgentX \xB7 Activity",activeTab:"activity",subtitle:"Activity",peers:t.peers,body:`<div class="ac">
780
780
 
781
781
  <div class="ac-head">
782
782
  <div>
783
783
  <div class="ac-kicker">Operations</div>
784
784
  <h1>What ran, where, and what it decided</h1>
785
- <p class="ac-sub" id="sub">${ma[e]}</p>
785
+ <p class="ac-sub" id="sub">${ha[e]}</p>
786
786
  </div>
787
787
  <div class="ac-tools">
788
788
  <div class="ac-seg" id="view" role="radiogroup" aria-label="View">
789
- ${[["timeline","Timeline",ee.timeline],["map","Map",ee.map]].map(([n,r,o])=>`<button type="button" role="radio" data-value="${n}" aria-checked="${n===e}"${n===e?' class="is-on"':""}>${De(o,13)}${r}</button>`).join("")}
789
+ ${[["timeline","Timeline",ee.timeline],["map","Map",ee.map]].map(([n,r,o])=>`<button type="button" role="radio" data-value="${n}" aria-checked="${n===e}"${n===e?' class="is-on"':""}>${Oe(o,13)}${r}</button>`).join("")}
790
790
  </div>
791
791
  <div class="ac-seg" id="hours" role="radiogroup" aria-label="Window">
792
792
  ${[["6","6h"],["24","24h"],["72","3d"],["168","7d"]].map(([n,r],o)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${o===1}"${o===1?' class="is-on"':""}>${r}</button>`).join("")}
793
793
  </div>
794
- <button class="ax-btn ax-btn--sm" id="refresh"${a?" hidden":""}>${De(ee.refresh,13)} Refresh</button>
794
+ <button class="ax-btn ax-btn--sm" id="refresh"${a?" hidden":""}>${Oe(ee.refresh,13)} Refresh</button>
795
795
  </div>
796
796
  </div>
797
797
 
@@ -799,14 +799,14 @@ refresh();
799
799
  <div class="ac-bar">
800
800
  <span class="ac-lbl">Lanes by</span>
801
801
  <div class="ac-seg" id="persp" role="radiogroup" aria-label="Perspective">
802
- ${ar.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${De(o,13)}${r}</button>`).join("")}
802
+ ${nr.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${Oe(o,13)}${r}</button>`).join("")}
803
803
  </div>
804
804
  <div class="ac-key">
805
805
  <span class="ac-k"><i class="ac-d ac-d--decision"></i>decision</span>
806
806
  <span class="ac-k"><i class="ac-d ac-d--warning"></i>warning</span>
807
807
  <span class="ac-k"><i class="ac-d ac-d--recommendation"></i>friction</span>
808
808
  <span class="ac-k"><i class="ac-d ac-d--later"></i>do later</span>
809
- <span class="ac-k">${De(ee.x,11)}canceled</span>
809
+ <span class="ac-k">${Oe(ee.x,11)}canceled</span>
810
810
  </div>
811
811
  </div>
812
812
 
@@ -816,10 +816,10 @@ refresh();
816
816
  </div>
817
817
 
818
818
  <div id="view-map" class="ac-map"${a?"":" hidden"}>
819
- <div id="ax-fleet-root" data-hours="24" data-src="${Pe("activity-graph.global.js")}"></div>
819
+ <div id="ax-fleet-root" data-hours="24" data-src="${De("activity-graph.global.js")}"></div>
820
820
  </div>
821
821
 
822
- </div>`,css:nr,scripts:`<script>${he({computeBands:Qe,packTracks:Ze,buildTimeline:pa})}const ICON = ${JSON.stringify(ee)};const SUB = ${JSON.stringify(ma)};${rr}</script>`})}var nr=`
822
+ </div>`,css:rr,scripts:`<script>${ge({computeBands:Ze,packTracks:et,buildTimeline:ua})}const ICON = ${JSON.stringify(ee)};const SUB = ${JSON.stringify(ha)};${or}</script>`})}var rr=`
823
823
  .ac{max-width:1440px;margin:0 auto;padding:22px 24px 48px}
824
824
  .ac :focus-visible{outline:2px solid var(--ax-accent);outline-offset:2px;border-radius:4px}
825
825
  .ac-head{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin-bottom:14px}
@@ -905,7 +905,7 @@ refresh();
905
905
  @media (max-width:640px){.ac{padding:16px 16px 32px}.ac-head{flex-direction:column;gap:10px}
906
906
  .ac-tools{flex-wrap:wrap;padding-top:0}.ac-map{height:calc(100vh - 250px);margin:0 -16px;
907
907
  border-left:none;border-right:none;border-radius:0}}
908
- `,rr=String.raw`
908
+ `,or=String.raw`
909
909
  const $=id=>document.getElementById(id);
910
910
  const esc=s=>String(s==null?'':s).replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
911
911
  const ic=(n,s)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+(s||14)+'" height="'+(s||14)+'" aria-hidden="true">'+ICON[n]+'</svg>';
@@ -1022,7 +1022,7 @@ history.replaceState(null,'',u);
1022
1022
  if(v==='map')ensureMap();else if(!loaded){loaded=true;load();}}
1023
1023
  $('view').addEventListener('click',e=>{const b=e.target.closest('button[data-value]');if(!b||b.dataset.value===view)return;show(b.dataset.value);});
1024
1024
  show(view);
1025
- `;function ga(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return $({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:or,scripts:`<script src="${Pe("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var or=`
1025
+ `;function fa(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return $({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:sr,scripts:`<script src="${De("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var sr=`
1026
1026
  /* Preload the fonts the redesign's CSS references. Placed in the shell so
1027
1027
  * they start fetching while the React bundle is still parsing. */
1028
1028
  @import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif&display=swap");
@@ -1043,10 +1043,10 @@ body { margin: 0; overflow: hidden; }
1043
1043
  font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
1044
1044
  text-align: center;
1045
1045
  }
1046
- `;Xn();import{createServer as xi}from"http";import{appendFileSync as vi,existsSync as qn,mkdirSync as bi}from"fs";import{readFile as yi}from"fs/promises";import{fileURLToPath as wi}from"url";import{dirname as ki,resolve as _e}from"path";var fa='/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */\n!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?e(Object(i),!0).forEach(function(t){var e,n;e=o,t=i[n=t],n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function i(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};for(var n,o={},i=Object.keys(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function r(t){return function(t){if(Array.isArray(t))return l(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),s=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),n=t(/iP(ad|od|hone)/i),c=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1};function h(t,e,n){t.addEventListener(e,n,!y&&d)}function f(t,e,n){t.removeEventListener(e,n,!y&&d)}function p(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=v(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];o;){var r=X(o)[n];if(!("top"===n||"left"===n?r<=i:i<=r))return o;if(o===O())break;o=M(o,!1)}return!1}function B(t,e,n,o){for(var i=0,r=0,a=t.children;r<a.length;){if("none"!==a[r].style.display&&a[r]!==Ft.ghost&&(o||a[r]!==Ft.dragged)&&P(a[r],n.draggable,t,!1)){if(i===e)return a[r];i++}r++}return null}function F(t,e){for(var n=t.lastElementChild;n&&(n===Ft.ghost||"none"===R(n,"display")||e&&!p(n,e));)n=n.previousElementSibling;return n||null}function j(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||t===Ft.clone||e&&!p(t,e)||n++;return n}function E(t){var e=0,n=0,o=O();if(t)do{var i=v(t),r=i.a,i=i.d}while(e+=t.scrollLeft*r,n+=t.scrollTop*i,t!==o&&(t=t.parentNode));return[e,n]}function M(t,e){if(!t||!t.getBoundingClientRect)return O();var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=R(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return O();if(o||e)return n;o=!0}}}while(n=n.parentNode);return O()}function D(t,e){return Math.round(t.top)===Math.round(e.top)&&Math.round(t.left)===Math.round(e.left)&&Math.round(t.height)===Math.round(e.height)&&Math.round(t.width)===Math.round(e.width)}function S(e,n){return function(){var t;g||(1===(t=arguments).length?e.call(this,t[0]):e.apply(this,t),g=setTimeout(function(){g=void 0},n))}}function H(t,e,n){t.scrollLeft+=e,t.scrollTop+=n}function _(t){var e=window.Polymer,n=window.jQuery||window.Zepto;return e&&e.dom?e.dom(t).cloneNode(!0):n?n(t).clone(!0)[0]:t.cloneNode(!0)}function C(t,e){R(t,"position","absolute"),R(t,"top",e.top),R(t,"left",e.left),R(t,"width",e.width),R(t,"height",e.height)}function T(t){R(t,"position",""),R(t,"top",""),R(t,"left",""),R(t,"width",""),R(t,"height","")}function L(n,o,i){var r={};return Array.from(n.children).forEach(function(t){var e;P(t,o.draggable,n,!1)&&!t.animated&&t!==i&&(e=X(t),r.left=Math.min(null!==(t=r.left)&&void 0!==t?t:1/0,e.left),r.top=Math.min(null!==(t=r.top)&&void 0!==t?t:1/0,e.top),r.right=Math.max(null!==(t=r.right)&&void 0!==t?t:-1/0,e.right),r.bottom=Math.max(null!==(t=r.bottom)&&void 0!==t?t:-1/0,e.bottom))}),r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}var K="Sortable"+(new Date).getTime();function x(){var e,o=[];return{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(t){var e,n;"none"!==R(t,"display")&&t!==Ft.ghost&&(o.push({target:t,rect:X(t)}),e=I({},o[o.length-1].rect),!t.thisAnimationDuration||(n=v(t,!0))&&(e.top-=n.f,e.left-=n.e),t.fromRect=e)})},addAnimationState:function(t){o.push(t)},removeAnimationState:function(t){o.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var o in e)if(e.hasOwnProperty(o)&&e[o]===t[n][o])return Number(n);return-1}(o,{target:t}),1)},animateAll:function(t){var c=this;if(!this.options.animation)return clearTimeout(e),void("function"==typeof t&&t());var u=!1,d=0;o.forEach(function(t){var e=0,n=t.target,o=n.fromRect,i=X(n),r=n.prevFromRect,a=n.prevToRect,l=t.rect,s=v(n,!0);s&&(i.top-=s.f,i.left-=s.e),n.toRect=i,n.thisAnimationDuration&&D(r,i)&&!D(o,i)&&(l.top-i.top)/(l.left-i.left)==(o.top-i.top)/(o.left-i.left)&&(t=l,s=r,r=a,a=c.options,e=Math.sqrt(Math.pow(s.top-t.top,2)+Math.pow(s.left-t.left,2))/Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2))*a.animation),D(i,o)||(n.prevFromRect=o,n.prevToRect=i,e=e||c.options.animation,c.animate(n,l,i,e)),e&&(u=!0,d=Math.max(d,e),clearTimeout(n.animationResetTimer),n.animationResetTimer=setTimeout(function(){n.animationTime=0,n.prevFromRect=null,n.fromRect=null,n.prevToRect=null,n.thisAnimationDuration=null},e),n.thisAnimationDuration=e)}),clearTimeout(e),u?e=setTimeout(function(){"function"==typeof t&&t()},d):"function"==typeof t&&t(),o=[]},animate:function(t,e,n,o){var i,r;o&&(R(t,"transition",""),R(t,"transform",""),i=(r=v(this.el))&&r.a,r=r&&r.d,i=(e.left-n.left)/(i||1),r=(e.top-n.top)/(r||1),t.animatingX=!!i,t.animatingY=!!r,R(t,"transform","translate3d("+i+"px,"+r+"px,0)"),this.forRepaintDummy=t.offsetWidth,R(t,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),R(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout(function(){R(t,"transition",""),R(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1},o))}}}var A=[],N={initializeByDefault:!0},W={mount:function(e){for(var t in N)!N.hasOwnProperty(t)||t in e||(e[t]=N[t]);A.forEach(function(t){if(t.pluginName===e.pluginName)throw"Sortable: Cannot mount plugin ".concat(e.pluginName," more than once")}),A.push(e)},pluginEvent:function(e,n,o){var t=this;this.eventCanceled=!1,o.cancel=function(){t.eventCanceled=!0};var i=e+"Global";A.forEach(function(t){n[t.pluginName]&&(n[t.pluginName][i]&&n[t.pluginName][i](I({sortable:n},o)),n.options[t.pluginName]&&n[t.pluginName][e]&&n[t.pluginName][e](I({sortable:n},o)))})},initializePlugins:function(n,o,i,t){for(var e in A.forEach(function(t){var e=t.pluginName;(n.options[e]||t.initializeByDefault)&&((t=new t(n,o,n.options)).sortable=n,t.options=n.options,n[e]=t,a(i,t.defaults))}),n.options){var r;n.options.hasOwnProperty(e)&&(void 0!==(r=this.modifyOption(n,e,n.options[e]))&&(n.options[e]=r))}},getEventProperties:function(e,n){var o={};return A.forEach(function(t){"function"==typeof t.eventProperties&&a(o,t.eventProperties.call(n[t.pluginName],e))}),o},modifyOption:function(e,n,o){var i;return A.forEach(function(t){e[t.pluginName]&&t.optionListeners&&"function"==typeof t.optionListeners[n]&&(i=t.optionListeners[n].call(e[t.pluginName],o))}),i}};function z(t){var e=t.sortable,n=t.rootEl,o=t.name,i=t.targetEl,r=t.cloneEl,a=t.toEl,l=t.fromEl,s=t.oldIndex,c=t.newIndex,u=t.oldDraggableIndex,d=t.newDraggableIndex,h=t.originalEvent,f=t.putSortable,p=t.extraEventProperties;if(e=e||n&&n[K]){var g,m=e.options,t="on"+o.charAt(0).toUpperCase()+o.substr(1);!window.CustomEvent||y||w?(g=document.createEvent("Event")).initEvent(o,!0,!0):g=new CustomEvent(o,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=l||n,g.item=i||n,g.clone=r,g.oldIndex=s,g.newIndex=c,g.oldDraggableIndex=u,g.newDraggableIndex=d,g.originalEvent=h,g.pullMode=f?f.lastPutMode:void 0;var v,b=I(I({},p),W.getEventProperties(o,e));for(v in b)g[v]=b[v];n&&n.dispatchEvent(g),m[t]&&m[t].call(e,g)}}function G(t,e){var n=(o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{}).evt,o=i(o,U);W.pluginEvent.bind(Ft)(t,e,I({dragEl:V,parentEl:Z,ghostEl:$,rootEl:Q,nextEl:J,lastDownEl:tt,cloneEl:et,cloneHidden:nt,dragStarted:gt,putSortable:st,activeSortable:Ft.active,originalEvent:n,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at,hideGhostForTarget:Rt,unhideGhostForTarget:Xt,cloneNowHidden:function(){nt=!0},cloneNowShown:function(){nt=!1},dispatchSortableEvent:function(t){q({sortable:e,name:t,originalEvent:n})}},o))}var U=["evt"];function q(t){z(I({putSortable:st,cloneEl:et,targetEl:V,rootEl:Q,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at},t))}var V,Z,$,Q,J,tt,et,nt,ot,it,rt,at,lt,st,ct,ut,dt,ht,ft,pt,gt,mt,vt,bt,yt,wt=!1,Et=!1,Dt=[],St=!1,_t=!1,Ct=[],Tt=!1,xt=[],Ot="undefined"!=typeof document,Mt=n,At=w||y?"cssFloat":"float",Nt=Ot&&!c&&!n&&"draggable"in document.createElement("div"),It=function(){if(Ot){if(y)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Pt=function(t,e){var n=R(t),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),i=B(t,0,e),r=B(t,1,e),a=i&&R(i),l=r&&R(r),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+X(i).width,t=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+X(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(i&&a.float&&"none"!==a.float){e="left"===a.float?"left":"right";return!r||"both"!==l.clear&&l.clear!==e?"horizontal":"vertical"}return i&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||o<=s&&"none"===n[At]||r&&"none"===n[At]&&o<s+t)?"vertical":"horizontal"},kt=function(t){function l(r,a){return function(t,e,n,o){var i=t.options.group.name&&e.options.group.name&&t.options.group.name===e.options.group.name;if(null==r&&(a||i))return!0;if(null==r||!1===r)return!1;if(a&&"clone"===r)return r;if("function"==typeof r)return l(r(t,e,n,o),a)(t,e,n,o);e=(a?t:e).options.group.name;return!0===r||"string"==typeof r&&r===e||r.join&&-1<r.indexOf(e)}}var e={},n=t.group;n&&"object"==o(n)||(n={name:n}),e.name=n.name,e.checkPull=l(n.pull,!0),e.checkPut=l(n.put),e.revertClone=n.revertClone,t.group=e},Rt=function(){!It&&$&&R($,"display","none")},Xt=function(){!It&&$&&R($,"display","")};Ot&&!c&&document.addEventListener("click",function(t){if(Et)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),Et=!1},!0);function Yt(t){if(V){t=t.touches?t.touches[0]:t;var e=(i=t.clientX,r=t.clientY,Dt.some(function(t){var e=t[K].options.emptyInsertThreshold;if(e&&!F(t)){var n=X(t),o=i>=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))<n)return;this._onDragStart(t,!0)}$&&(r?(r.e+=a-(dt||0),r.f+=l-(ht||0)):r={a:1,b:0,c:0,d:1,e:a,f:l},r="matrix(".concat(r.a,",").concat(r.b,",").concat(r.c,",").concat(r.d,",").concat(r.e,",").concat(r.f,")"),R($,"webkitTransform",r),R($,"mozTransform",r),R($,"msTransform",r),R($,"transform",r),dt=a,ht=l,ut=i),t.cancelable&&t.preventDefault()}},_appendGhost:function(){if(!$){var t=this.options.fallbackOnBody?document.body:Q,e=X(V,!0,Mt,!0,t),n=this.options;if(Mt){for(yt=t;"static"===R(yt,"position")&&"none"===R(yt,"transform")&&yt!==document;)yt=yt.parentNode;yt!==document.body&&yt!==document.documentElement?(yt===document&&(yt=O()),e.top+=yt.scrollTop,e.left+=yt.scrollLeft):yt=O(),Ct=E(yt)}k($=V.cloneNode(!0),n.ghostClass,!1),k($,n.fallbackClass,!0),k($,n.dragClass,!0),R($,"transition",""),R($,"transform",""),R($,"box-sizing","border-box"),R($,"margin",0),R($,"top",e.top),R($,"left",e.left),R($,"width",e.width),R($,"height",e.height),R($,"opacity","0.8"),R($,"position",Mt?"absolute":"fixed"),R($,"zIndex","100000"),R($,"pointerEvents","none"),Ft.ghost=$,t.appendChild($),R($,"transform-origin",ft/parseInt($.style.width)*100+"% "+pt/parseInt($.style.height)*100+"%")}},_onDragStart:function(t,e){var n=this,o=t.dataTransfer,i=n.options;G("dragStart",this,{evt:t}),Ft.eventCanceled?this._onDrop():(G("setupClone",this),Ft.eventCanceled||((et=_(V)).removeAttribute("id"),et.draggable=!1,et.style["will-change"]="",this._hideClone(),k(et,this.options.chosenClass,!1),Ft.clone=et),n.cloneId=Kt(function(){G("clone",n),Ft.eventCanceled||(n.options.removeCloneOnHide||Q.insertBefore(et,V),n._hideClone(),q({sortable:n,name:"clone"}))}),e||k(V,i.dragClass,!0),e?(Et=!0,n._loopId=setInterval(n._emulateDragOver,50)):(f(document,"mouseup",n._onDrop),f(document,"touchend",n._onDrop),f(document,"touchcancel",n._onDrop),o&&(o.effectAllowed="move",i.setData&&i.setData.call(n,o,V)),h(document,"drop",n),R(V,"transform","translateZ(0)")),wt=!0,n._dragStartId=Kt(n._dragStarted.bind(n,e,t)),h(document,"selectstart",n),gt=!0,u&&R(document.body,"user-select","none"))},_onDragOver:function(n){var o,i,r,t,e,a=this.el,l=n.target,s=this.options,c=s.group,u=Ft.active,d=lt===c,h=s.sort,f=st||u,p=this,g=!1;if(!Tt){if(void 0!==n.preventDefault&&n.cancelable&&n.preventDefault(),l=P(l,s.draggable,a,!0),O("dragOver"),Ft.eventCanceled)return g;if(V.contains(n.target)||l.animated&&l.animatingX&&l.animatingY||p._ignoreWhileAnimating===l)return A(!1);if(Et=!1,u&&!s.disabled&&(d?h||(i=Z!==Q):st===this||(this.lastPutMode=lt.checkPull(this,u,V,n))&&c.checkPut(this,u,V,n))){if(r="vertical"===this._getDirection(n,l),o=X(V),O("dragOverValid"),Ft.eventCanceled)return g;if(i)return Z=Q,M(),this._hideClone(),O("revert"),Ft.eventCanceled||(J?Q.insertBefore(V,J):Q.appendChild(V)),A(!0);var m=F(a,s.draggable);if(m&&(S=n,c=r,x=X(F((D=this).el,D.options.draggable)),D=L(D.el,D.options,$),!(c?S.clientX>D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientY<C.top&&t.clientX<C.right:t.clientY<_.top-10||t.clientY<C.bottom&&t.clientX<C.left)){var v=B(a,0,s,!0);if(v===V)return A(!1);if(E=X(l=v),!1!==jt(Q,a,V,o,l,E,n,!1))return M(),a.insertBefore(V,v),Z=a,N(),A(!0)}else if(l.parentNode===a){var b,y,w,E=X(l),D=V.parentNode!==a,S=(S=V.animated&&V.toRect||o,x=l.animated&&l.toRect||E,_=(e=r)?S.left:S.top,t=e?S.right:S.bottom,C=e?S.width:S.height,v=e?x.left:x.top,S=e?x.right:x.bottom,x=e?x.width:x.height,!(_===v||t===S||_+C/2===v+x/2)),_=r?"top":"left",C=Y(l,"top","top")||Y(V,"top","top"),v=C?C.scrollTop:void 0;if(mt!==l&&(y=E[_],St=!1,_t=!S&&s.invertSwap||D),0!==(b=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,t=o?n.top:n.left,o=o?n.bottom:n.right,n=!1;if(!a)if(l&&bt<c*i){if(St=!St&&(1===vt?t+c*r/2<s:s<o-c*r/2)?!0:St)n=!0;else if(1===vt?s<t+bt:o-bt<s)return-vt}else if(t+c*(1-i)/2<s&&s<o-c*(1-i)/2)return function(t){return j(V)<j(t)?1:-1}(e);if((n=n||a)&&(s<t+c*r/2||o-c*r/2<s))return t+c/2<s?1:-1;return 0}(n,l,E,r,S?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,_t,mt===l)))for(var T=j(V);(w=Z.children[T-=b])&&("none"===R(w,"display")||w===$););if(0===b||w===l)return A(!1);vt=b;var x=(mt=l).nextElementSibling,D=!1,S=jt(Q,a,V,o,l,E,n,D=1===b);if(!1!==S)return 1!==S&&-1!==S||(D=1===S),Tt=!0,setTimeout(Lt,30),M(),D&&!x?a.appendChild(V):l.parentNode.insertBefore(V,D?x:l),C&&H(C,0,v-C.scrollTop),Z=V.parentNode,void 0===y||_t||(bt=Math.abs(y-X(l)[_])),N(),A(!0)}}else{if(m===V)return A(!1);if((l=m&&a===n.target?m:l)&&(E=X(l)),!1!==jt(Q,a,V,o,l,E,n,!!l))return M(),m&&m.nextSibling?a.insertBefore(V,m.nextSibling):a.appendChild(V),Z=a,N(),A(!0)}if(a.contains(V))return A(!1)}return!1}function O(t,e){G(t,p,I({evt:n,isOwner:d,axis:r?"vertical":"horizontal",revert:i,dragRect:o,targetRect:E,canSort:h,fromSortable:f,target:l,completed:A,onMove:function(t,e){return jt(Q,a,V,o,t,X(t),n,e)},changed:N},e))}function M(){O("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return O("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==f&&(k(V,(st||u).options.ghostClass,!1),k(V,s.ghostClass,!0)),st!==p&&p!==Ft.active?st=p:p===Ft.active&&st&&(st=null),f===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){O("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(l===V&&!V.animated||l===a&&!l.animated)&&(mt=null),s.dragoverBubble||n.rootEl||l===document||(V.parentNode[K]._isOutsideThisEl(n.target),t||Yt(n)),!s.dragoverBubble&&n.stopPropagation&&n.stopPropagation(),g=!0}function N(){it=j(V),at=j(V,s.draggable),q({sortable:p,name:"change",toEl:a,newIndex:it,newDraggableIndex:at,originalEvent:n})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){f(document,"mousemove",this._onTouchMove),f(document,"touchmove",this._onTouchMove),f(document,"pointermove",this._onTouchMove),f(document,"dragover",Yt),f(document,"mousemove",Yt),f(document,"touchmove",Yt)},_offUpEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._onDrop),f(t,"touchend",this._onDrop),f(t,"pointerup",this._onDrop),f(t,"touchcancel",this._onDrop),f(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;it=j(V),at=j(V,n.draggable),G("drop",this,{evt:t}),Z=V&&V.parentNode,it=j(V),at=j(V,n.draggable),Ft.eventCanceled||(St=_t=wt=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Wt(this.cloneId),Wt(this._dragStartId),this.nativeDraggable&&(f(document,"drop",this),f(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&R(document.body,"user-select",""),R(V,"transform",""),t&&(gt&&(t.cancelable&&t.preventDefault(),n.dropBubble||t.stopPropagation()),$&&$.parentNode&&$.parentNode.removeChild($),(Q===Z||st&&"clone"!==st.lastPutMode)&&et&&et.parentNode&&et.parentNode.removeChild(et),V&&(this.nativeDraggable&&f(V,"dragend",this),Ht(V),V.style["will-change"]="",gt&&!wt&&k(V,(st||this).options.ghostClass,!1),k(V,this.options.chosenClass,!1),q({sortable:this,name:"unchoose",toEl:Z,newIndex:null,newDraggableIndex:null,originalEvent:t}),Q!==Z?(0<=it&&(q({rootEl:Z,name:"add",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"remove",toEl:Z,originalEvent:t}),q({rootEl:Z,name:"sort",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),st&&st.save()):it!==ot&&0<=it&&(q({sortable:this,name:"update",toEl:Z,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),Ft.active&&(null!=it&&-1!==it||(it=ot,at=rt),q({sortable:this,name:"end",toEl:Z,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){G("nulling",this),Q=V=Z=$=J=et=tt=nt=ct=ut=gt=it=at=ot=rt=mt=vt=st=lt=Ft.dragged=Ft.ghost=Ft.clone=Ft.active=null,xt.forEach(function(t){t.checked=!0}),xt.length=dt=ht=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":V&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move");t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,o=0,i=n.length,r=this.options;o<i;o++)P(t=n[o],r.draggable,this.el,!1)&&e.push(t.getAttribute(r.dataIdAttr)||function(t){var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;for(;n--;)o+=e.charCodeAt(n);return o.toString(36)}(t));return e},sort:function(t,e){var n={},o=this.el;this.toArray().forEach(function(t,e){e=o.children[e];P(e,this.options.draggable,o,!1)&&(n[t]=e)},this),e&&this.captureAnimationState(),t.forEach(function(t){n[t]&&(o.removeChild(n[t]),o.appendChild(n[t]))}),e&&this.animateAll()},save:function(){var t=this.options.store;t&&t.set&&t.set(this)},closest:function(t,e){return P(t,e||this.options.draggable,this.el,!1)},option:function(t,e){var n=this.options;if(void 0===e)return n[t];var o=W.modifyOption(this,t,e);n[t]=void 0!==o?o:e,"group"===t&&kt(n)},destroy:function(){G("destroy",this);var t=this.el;t[K]=null,f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart),f(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),this._onDrop(),this._disableDelayedDragEvents(),Dt.splice(Dt.indexOf(this.el),1),this.el=t=null},_hideClone:function(){nt||(G("hideClone",this),Ft.eventCanceled||(R(et,"display","none"),this.options.removeCloneOnHide&&et.parentNode&&et.parentNode.removeChild(et),nt=!0))},_showClone:function(t){"clone"===t.lastPutMode?nt&&(G("showClone",this),Ft.eventCanceled||(V.parentNode!=Q||this.options.group.revertClone?J?Q.insertBefore(et,J):Q.appendChild(et):Q.insertBefore(et,V),this.options.group.revertClone&&this.animate(V,et),R(et,"display",""),nt=!1)):this._hideClone()}},Ot&&h(document,"touchmove",function(t){(Ft.active||wt)&&t.cancelable&&t.preventDefault()}),Ft.utils={on:h,off:f,css:R,find:b,is:function(t,e){return!!P(t,e,t,!1)},extend:function(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},throttle:S,closest:P,toggleClass:k,clone:_,index:j,nextTick:Kt,cancelNextTick:Wt,detectDirection:Pt,getChild:B},Ft.get=function(t){return t[K]},Ft.mount=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];(e=e[0].constructor===Array?e[0]:e).forEach(function(t){if(!t.prototype||!t.prototype.constructor)throw"Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(t));t.utils&&(Ft.utils=I(I({},Ft.utils),t.utils)),W.mount(t)})},Ft.create=function(t,e){return new Ft(t,e)};var zt,Gt,Ut,qt,Vt,Zt,$t=[],Qt=!(Ft.version="1.15.2");function Jt(){$t.forEach(function(t){clearInterval(t.pid)}),$t=[]}function te(){clearInterval(Zt)}var ee,ne=S(function(n,t,e,o){if(t.scroll){var i,r=(n.touches?n.touches[0]:n).clientX,a=(n.touches?n.touches[0]:n).clientY,l=t.scrollSensitivity,s=t.scrollSpeed,c=O(),u=!1;Gt!==e&&(Gt=e,Jt(),zt=t.scroll,i=t.scrollFn,!0===zt&&(zt=M(e,!0)));var d=0,h=zt;do{var f=h,p=X(f),g=p.top,m=p.bottom,v=p.left,b=p.right,y=p.width,w=p.height,E=void 0,D=void 0,S=f.scrollWidth,_=f.scrollHeight,C=R(f),T=f.scrollLeft,p=f.scrollTop,D=f===c?(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX||"visible"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY||"visible"===C.overflowY)):(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY)),T=E&&(Math.abs(b-r)<=l&&T+y<S)-(Math.abs(v-r)<=l&&!!T),p=D&&(Math.abs(m-a)<=l&&p+w<_)-(Math.abs(g-a)<=l&&!!p);if(!$t[d])for(var x=0;x<=d;x++)$t[x]||($t[x]={});$t[d].vx==T&&$t[d].vy==p&&$t[d].el===f||($t[d].el=f,$t[d].vx=T,$t[d].vy=p,clearInterval($t[d].pid),0==T&&0==p||(u=!0,$t[d].pid=setInterval(function(){o&&0===this.layer&&Ft.active._onTouchMove(Vt);var t=$t[this.layer].vy?$t[this.layer].vy*s:0,e=$t[this.layer].vx?$t[this.layer].vx*s:0;"function"==typeof i&&"continue"!==i.call(Ft.dragged.parentNode[K],e,t,n,Vt,$t[this.layer].el)||H($t[this.layer].el,e,t)}.bind({layer:d}),24))),d++}while(t.bubbleScroll&&h!==c&&(h=M(h,!1)));Qt=u}},30),c=function(t){var e=t.originalEvent,n=t.putSortable,o=t.dragEl,i=t.activeSortable,r=t.dispatchSortableEvent,a=t.hideGhostForTarget,t=t.unhideGhostForTarget;e&&(i=n||i,a(),e=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:e,e=document.elementFromPoint(e.clientX,e.clientY),t(),i&&!i.el.contains(e)&&(r("spill"),this.onSpill({dragEl:o,putSortable:n})))};function oe(){}function ie(){}oe.prototype={startIndex:null,dragStart:function(t){t=t.oldDraggableIndex;this.startIndex=t},onSpill:function(t){var e=t.dragEl,n=t.putSortable;this.sortable.captureAnimationState(),n&&n.captureAnimationState();t=B(this.sortable.el,this.startIndex,this.options);t?this.sortable.el.insertBefore(e,t):this.sortable.el.appendChild(e),this.sortable.animateAll(),n&&n.animateAll()},drop:c},a(oe,{pluginName:"revertOnSpill"}),ie.prototype={onSpill:function(t){var e=t.dragEl,t=t.putSortable||this.sortable;t.captureAnimationState(),e.parentNode&&e.parentNode.removeChild(e),t.animateAll()},drop:c},a(ie,{pluginName:"removeOnSpill"});var re,ae,le,se,ce,ue=[],de=[],he=!1,fe=!1,pe=!1;function ge(n,o){de.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)})}function me(){ue.forEach(function(t){t!==le&&t.parentNode&&t.parentNode.removeChild(t)})}return Ft.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){t=t.originalEvent;this.sortable.nativeDraggable?h(document,"dragover",this._handleAutoScroll):this.options.supportPointer?h(document,"pointermove",this._handleFallbackAutoScroll):t.touches?h(document,"touchmove",this._handleFallbackAutoScroll):h(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){t=t.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?f(document,"dragover",this._handleAutoScroll):(f(document,"pointermove",this._handleFallbackAutoScroll),f(document,"touchmove",this._handleFallbackAutoScroll),f(document,"mousemove",this._handleFallbackAutoScroll)),te(),Jt(),clearTimeout(g),g=void 0},nulling:function(){Vt=Gt=zt=Qt=Zt=Ut=qt=null,$t.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(e,n){var o,i=this,r=(e.touches?e.touches[0]:e).clientX,a=(e.touches?e.touches[0]:e).clientY,t=document.elementFromPoint(r,a);Vt=e,n||this.options.forceAutoScrollFallback||w||y||u?(ne(e,this.options,t,n),o=M(t,!0),!Qt||Zt&&r===Ut&&a===qt||(Zt&&te(),Zt=setInterval(function(){var t=M(document.elementFromPoint(r,a),!0);t!==o&&(o=t,Jt()),ne(e,i.options,t,n)},10),Ut=r,qt=a)):this.options.bubbleScroll&&M(t,!0)!==O()?ne(e,this.options,M(t,!1),!1):Jt()}},a(t,{pluginName:"scroll",initializeByDefault:!0})}),Ft.mount(ie,oe),Ft.mount(new function(){function t(){this.defaults={swapClass:"sortable-swap-highlight"}}return t.prototype={dragStart:function(t){t=t.dragEl;ee=t},dragOverValid:function(t){var e=t.completed,n=t.target,o=t.onMove,i=t.activeSortable,r=t.changed,a=t.cancel;i.options.swap&&(t=this.sortable.el,i=this.options,n&&n!==t&&(t=ee,ee=!1!==o(n)?(k(n,i.swapClass,!0),n):null,t&&t!==ee&&k(t,i.swapClass,!1)),r(),e(!0),a())},drop:function(t){var e,n,o=t.activeSortable,i=t.putSortable,r=t.dragEl,a=i||this.sortable,l=this.options;ee&&k(ee,l.swapClass,!1),ee&&(l.swap||i&&i.options.swap)&&r!==ee&&(a.captureAnimationState(),a!==o&&o.captureAnimationState(),n=ee,t=(e=r).parentNode,l=n.parentNode,t&&l&&!t.isEqualNode(n)&&!l.isEqualNode(e)&&(i=j(e),r=j(n),t.isEqualNode(l)&&i<r&&r++,t.insertBefore(n,t.children[i]),l.insertBefore(e,l.children[r])),a.animateAll(),a!==o&&o.animateAll())},nulling:function(){ee=null}},a(t,{pluginName:"swap",eventProperties:function(){return{swapItem:ee}}})}),Ft.mount(new function(){function t(o){for(var t in this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this));o.options.avoidImplicitDeselect||(o.options.supportPointer?h(document,"pointerup",this._deselectMultiDrag):(h(document,"mouseup",this._deselectMultiDrag),h(document,"touchend",this._deselectMultiDrag))),h(document,"keydown",this._checkKeyDown),h(document,"keyup",this._checkKeyUp),this.defaults={selectedClass:"sortable-selected",multiDragKey:null,avoidImplicitDeselect:!1,setData:function(t,e){var n="";ue.length&&ae===o?ue.forEach(function(t,e){n+=(e?", ":"")+t.textContent}):n=e.textContent,t.setData("Text",n)}}}return t.prototype={multiDragKeyDown:!1,isMultiDrag:!1,delayStartGlobal:function(t){t=t.dragEl;le=t},delayEnded:function(){this.isMultiDrag=~ue.indexOf(le)},setupClone:function(t){var e=t.sortable,t=t.cancel;if(this.isMultiDrag){for(var n=0;n<ue.length;n++)de.push(_(ue[n])),de[n].sortableIndex=ue[n].sortableIndex,de[n].draggable=!1,de[n].style["will-change"]="",k(de[n],this.options.selectedClass,!1),ue[n]===le&&k(de[n],this.options.chosenClass,!1);e._hideClone(),t()}},clone:function(t){var e=t.sortable,n=t.rootEl,o=t.dispatchSortableEvent,t=t.cancel;this.isMultiDrag&&(this.options.removeCloneOnHide||ue.length&&ae===e&&(ge(!0,n),o("clone"),t()))},showClone:function(t){var e=t.cloneNowShown,n=t.rootEl,t=t.cancel;this.isMultiDrag&&(ge(!1,n),de.forEach(function(t){R(t,"display","")}),e(),ce=!1,t())},hideClone:function(t){var e=this,n=(t.sortable,t.cloneNowHidden),t=t.cancel;this.isMultiDrag&&(de.forEach(function(t){R(t,"display","none"),e.options.removeCloneOnHide&&t.parentNode&&t.parentNode.removeChild(t)}),n(),ce=!0,t())},dragStartGlobal:function(t){t.sortable;!this.isMultiDrag&&ae&&ae.multiDrag._deselectMultiDrag(),ue.forEach(function(t){t.sortableIndex=j(t)}),ue=ue.sort(function(t,e){return t.sortableIndex-e.sortableIndex}),pe=!0},dragStarted:function(t){var e,n=this,t=t.sortable;this.isMultiDrag&&(this.options.sort&&(t.captureAnimationState(),this.options.animation&&(ue.forEach(function(t){t!==le&&R(t,"position","absolute")}),e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&C(t,e)}),he=fe=!0)),t.animateAll(function(){he=fe=!1,n.options.animation&&ue.forEach(function(t){T(t)}),n.options.sort&&me()}))},dragOver:function(t){var e=t.target,n=t.completed,t=t.cancel;fe&&~ue.indexOf(e)&&(n(!1),t())},revert:function(t){var n,o,e=t.fromSortable,i=t.rootEl,r=t.sortable,a=t.dragRect;1<ue.length&&(ue.forEach(function(t){r.addAnimationState({target:t,rect:fe?X(t):a}),T(t),t.fromRect=a,e.removeAnimationState(t)}),fe=!1,n=!this.options.removeCloneOnHide,o=i,ue.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)}))},dragOverCompleted:function(t){var e,n=t.sortable,o=t.isOwner,i=t.insertion,r=t.activeSortable,a=t.parentEl,l=t.putSortable,t=this.options;i&&(o&&r._hideClone(),he=!1,t.animation&&1<ue.length&&(fe||!o&&!r.options.sort&&!l)&&(e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&(C(t,e),a.appendChild(t))}),fe=!0),o||(fe||me(),1<ue.length?(o=ce,r._showClone(n),r.options.animation&&!ce&&o&&de.forEach(function(t){r.addAnimationState({target:t,rect:se}),t.fromRect=se,t.thisAnimationDuration=null})):r._showClone(n)))},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,t=t.activeSortable;ue.forEach(function(t){t.thisAnimationDuration=null}),t.options.animation&&!n&&t.multiDrag.isMultiDrag&&(se=a({},e),e=v(le,!0),se.top-=e.f,se.left-=e.e)},dragOverAnimationComplete:function(){fe&&(fe=!1,me())},drop:function(t){var e=t.originalEvent,n=t.rootEl,o=t.parentEl,i=t.sortable,r=t.dispatchSortableEvent,a=t.oldIndex,l=t.putSortable,s=l||this.sortable;if(e){var c,u,d,h=this.options,f=o.children;if(!pe)if(h.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),k(le,h.selectedClass,!~ue.indexOf(le)),~ue.indexOf(le))ue.splice(ue.indexOf(le),1),re=null,z({sortable:i,rootEl:n,name:"deselect",targetEl:le,originalEvent:e});else{if(ue.push(le),z({sortable:i,rootEl:n,name:"select",targetEl:le,originalEvent:e}),e.shiftKey&&re&&i.el.contains(re)){var p=j(re),t=j(le);if(~p&&~t&&p!==t)for(var g,m=p<t?(g=p,t):(g=t,p+1);g<m;g++)~ue.indexOf(f[g])||(k(f[g],h.selectedClass,!0),ue.push(f[g]),z({sortable:i,rootEl:n,name:"select",targetEl:f[g],originalEvent:e}))}else re=le;ae=s}pe&&this.isMultiDrag&&(fe=!1,(o[K].options.sort||o!==n)&&1<ue.length&&(c=X(le),u=j(le,":not(."+this.options.selectedClass+")"),!he&&h.animation&&(le.thisAnimationDuration=null),s.captureAnimationState(),he||(h.animation&&(le.fromRect=c,ue.forEach(function(t){var e;t.thisAnimationDuration=null,t!==le&&(e=fe?X(t):c,t.fromRect=e,s.addAnimationState({target:t,rect:e}))})),me(),ue.forEach(function(t){f[u]?o.insertBefore(t,f[u]):o.appendChild(t),u++}),a===j(le)&&(d=!1,ue.forEach(function(t){t.sortableIndex!==j(t)&&(d=!0)}),d&&(r("update"),r("sort")))),ue.forEach(function(t){T(t)}),s.animateAll()),ae=s),(n===o||l&&"clone"!==l.lastPutMode)&&de.forEach(function(t){t.parentNode&&t.parentNode.removeChild(t)})}},nullingGlobal:function(){this.isMultiDrag=pe=!1,de.length=0},destroyGlobal:function(){this._deselectMultiDrag(),f(document,"pointerup",this._deselectMultiDrag),f(document,"mouseup",this._deselectMultiDrag),f(document,"touchend",this._deselectMultiDrag),f(document,"keydown",this._checkKeyDown),f(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==pe&&pe||ae!==this.sortable||t&&P(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;ue.length;){var e=ue[0];k(e,this.options.selectedClass,!1),ue.shift(),z({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvent:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},a(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[K];e&&e.options.multiDrag&&!~ue.indexOf(t)&&(ae&&ae!==e&&(ae.multiDrag._deselectMultiDrag(),ae=e),k(t,e.options.selectedClass,!0),ue.push(t))},deselect:function(t){var e=t.parentNode[K],n=ue.indexOf(t);e&&e.options.multiDrag&&~n&&(k(t,e.options.selectedClass,!1),ue.splice(n,1))}},eventProperties:function(){var n=this,o=[],i=[];return ue.forEach(function(t){var e;o.push({multiDragElement:t,index:t.sortableIndex}),e=fe&&t!==le?-1:fe?j(t,":not(."+n.options.selectedClass+")"):j(t),i.push({multiDragElement:t,index:e})}),{items:r(ue),clones:[].concat(de),oldIndicies:o,newIndicies:i}},optionListeners:{multiDragKey:function(t){return"ctrl"===(t=t.toLowerCase())?t="Control":1<t.length&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}),Ft});';import{existsSync as Oe,readFileSync as va,writeFileSync as ba,rmSync as gl,mkdirSync as pr,copyFileSync as ur,readdirSync as mr}from"fs";import{resolve as ge}from"path";Ge();var te={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>',actions:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>'};function xa(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=Ie({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+$e([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return $({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+ir()+Jt,css:dr,scripts:`${e}<script>${Vt}
1047
- ${Yt}
1048
- ${sr}
1049
- ${cr}</script>`})}var sr=`
1046
+ `;import{createServer as vi}from"http";import{appendFileSync as bi,existsSync as Fn,mkdirSync as yi}from"fs";import{readFile as wi}from"fs/promises";import{fileURLToPath as ki}from"url";import{dirname as _i,resolve as Ee}from"path";Kn();var xa='/*! Sortable 1.15.2 - MIT | git://github.com/SortableJS/Sortable.git */\n!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t=t||self).Sortable=e()}(this,function(){"use strict";function e(e,t){var n,o=Object.keys(e);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(e),t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)),o}function I(o){for(var t=1;t<arguments.length;t++){var i=null!=arguments[t]?arguments[t]:{};t%2?e(Object(i),!0).forEach(function(t){var e,n;e=o,t=i[n=t],n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(i)):e(Object(i)).forEach(function(t){Object.defineProperty(o,t,Object.getOwnPropertyDescriptor(i,t))})}return o}function o(t){return(o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}function a(){return(a=Object.assign||function(t){for(var e=1;e<arguments.length;e++){var n,o=arguments[e];for(n in o)Object.prototype.hasOwnProperty.call(o,n)&&(t[n]=o[n])}return t}).apply(this,arguments)}function i(t,e){if(null==t)return{};var n,o=function(t,e){if(null==t)return{};for(var n,o={},i=Object.keys(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||(o[n]=t[n]);return o}(t,e);if(Object.getOwnPropertySymbols)for(var i=Object.getOwnPropertySymbols(t),r=0;r<i.length;r++)n=i[r],0<=e.indexOf(n)||Object.prototype.propertyIsEnumerable.call(t,n)&&(o[n]=t[n]);return o}function r(t){return function(t){if(Array.isArray(t))return l(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(t){if("string"==typeof t)return l(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);return"Map"===(n="Object"===n&&t.constructor?t.constructor.name:n)||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?l(t,e):void 0}}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function l(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,o=new Array(e);n<e;n++)o[n]=t[n];return o}function t(t){if("undefined"!=typeof window&&window.navigator)return!!navigator.userAgent.match(t)}var y=t(/(?:Trident.*rv[ :]?11\\.|msie|iemobile|Windows Phone)/i),w=t(/Edge/i),s=t(/firefox/i),u=t(/safari/i)&&!t(/chrome/i)&&!t(/android/i),n=t(/iP(ad|od|hone)/i),c=t(/chrome/i)&&t(/android/i),d={capture:!1,passive:!1};function h(t,e,n){t.addEventListener(e,n,!y&&d)}function f(t,e,n){t.removeEventListener(e,n,!y&&d)}function p(t,e){if(e&&(">"===e[0]&&(e=e.substring(1)),t))try{if(t.matches)return t.matches(e);if(t.msMatchesSelector)return t.msMatchesSelector(e);if(t.webkitMatchesSelector)return t.webkitMatchesSelector(e)}catch(t){return}}function P(t,e,n,o){if(t){n=n||document;do{if(null!=e&&(">"!==e[0]||t.parentNode===n)&&p(t,e)||o&&t===n)return t}while(t!==n&&(t=(i=t).host&&i!==document&&i.host.nodeType?i.host:i.parentNode))}var i;return null}var g,m=/\\s+/g;function k(t,e,n){var o;t&&e&&(t.classList?t.classList[n?"add":"remove"](e):(o=(" "+t.className+" ").replace(m," ").replace(" "+e+" "," "),t.className=(o+(n?" "+e:"")).replace(m," ")))}function R(t,e,n){var o=t&&t.style;if(o){if(void 0===n)return document.defaultView&&document.defaultView.getComputedStyle?n=document.defaultView.getComputedStyle(t,""):t.currentStyle&&(n=t.currentStyle),void 0===e?n:n[e];o[e=!(e in o||-1!==e.indexOf("webkit"))?"-webkit-"+e:e]=n+("string"==typeof n?"":"px")}}function v(t,e){var n="";if("string"==typeof t)n=t;else do{var o=R(t,"transform")}while(o&&"none"!==o&&(n=o+" "+n),!e&&(t=t.parentNode));var i=window.DOMMatrix||window.WebKitCSSMatrix||window.CSSMatrix||window.MSCSSMatrix;return i&&new i(n)}function b(t,e,n){if(t){var o=t.getElementsByTagName(e),i=0,r=o.length;if(n)for(;i<r;i++)n(o[i],i);return o}return[]}function O(){var t=document.scrollingElement;return t||document.documentElement}function X(t,e,n,o,i){if(t.getBoundingClientRect||t===window){var r,a,l,s,c,u,d=t!==window&&t.parentNode&&t!==O()?(a=(r=t.getBoundingClientRect()).top,l=r.left,s=r.bottom,c=r.right,u=r.height,r.width):(l=a=0,s=window.innerHeight,c=window.innerWidth,u=window.innerHeight,window.innerWidth);if((e||n)&&t!==window&&(i=i||t.parentNode,!y))do{if(i&&i.getBoundingClientRect&&("none"!==R(i,"transform")||n&&"static"!==R(i,"position"))){var h=i.getBoundingClientRect();a-=h.top+parseInt(R(i,"border-top-width")),l-=h.left+parseInt(R(i,"border-left-width")),s=a+r.height,c=l+r.width;break}}while(i=i.parentNode);return o&&t!==window&&(o=(e=v(i||t))&&e.a,t=e&&e.d,e&&(s=(a/=t)+(u/=t),c=(l/=o)+(d/=o))),{top:a,left:l,bottom:s,right:c,width:d,height:u}}}function Y(t,e,n){for(var o=M(t,!0),i=X(t)[e];o;){var r=X(o)[n];if(!("top"===n||"left"===n?r<=i:i<=r))return o;if(o===O())break;o=M(o,!1)}return!1}function B(t,e,n,o){for(var i=0,r=0,a=t.children;r<a.length;){if("none"!==a[r].style.display&&a[r]!==Ft.ghost&&(o||a[r]!==Ft.dragged)&&P(a[r],n.draggable,t,!1)){if(i===e)return a[r];i++}r++}return null}function F(t,e){for(var n=t.lastElementChild;n&&(n===Ft.ghost||"none"===R(n,"display")||e&&!p(n,e));)n=n.previousElementSibling;return n||null}function j(t,e){var n=0;if(!t||!t.parentNode)return-1;for(;t=t.previousElementSibling;)"TEMPLATE"===t.nodeName.toUpperCase()||t===Ft.clone||e&&!p(t,e)||n++;return n}function E(t){var e=0,n=0,o=O();if(t)do{var i=v(t),r=i.a,i=i.d}while(e+=t.scrollLeft*r,n+=t.scrollTop*i,t!==o&&(t=t.parentNode));return[e,n]}function M(t,e){if(!t||!t.getBoundingClientRect)return O();var n=t,o=!1;do{if(n.clientWidth<n.scrollWidth||n.clientHeight<n.scrollHeight){var i=R(n);if(n.clientWidth<n.scrollWidth&&("auto"==i.overflowX||"scroll"==i.overflowX)||n.clientHeight<n.scrollHeight&&("auto"==i.overflowY||"scroll"==i.overflowY)){if(!n.getBoundingClientRect||n===document.body)return O();if(o||e)return n;o=!0}}}while(n=n.parentNode);return O()}function D(t,e){return Math.round(t.top)===Math.round(e.top)&&Math.round(t.left)===Math.round(e.left)&&Math.round(t.height)===Math.round(e.height)&&Math.round(t.width)===Math.round(e.width)}function S(e,n){return function(){var t;g||(1===(t=arguments).length?e.call(this,t[0]):e.apply(this,t),g=setTimeout(function(){g=void 0},n))}}function H(t,e,n){t.scrollLeft+=e,t.scrollTop+=n}function _(t){var e=window.Polymer,n=window.jQuery||window.Zepto;return e&&e.dom?e.dom(t).cloneNode(!0):n?n(t).clone(!0)[0]:t.cloneNode(!0)}function C(t,e){R(t,"position","absolute"),R(t,"top",e.top),R(t,"left",e.left),R(t,"width",e.width),R(t,"height",e.height)}function T(t){R(t,"position",""),R(t,"top",""),R(t,"left",""),R(t,"width",""),R(t,"height","")}function L(n,o,i){var r={};return Array.from(n.children).forEach(function(t){var e;P(t,o.draggable,n,!1)&&!t.animated&&t!==i&&(e=X(t),r.left=Math.min(null!==(t=r.left)&&void 0!==t?t:1/0,e.left),r.top=Math.min(null!==(t=r.top)&&void 0!==t?t:1/0,e.top),r.right=Math.max(null!==(t=r.right)&&void 0!==t?t:-1/0,e.right),r.bottom=Math.max(null!==(t=r.bottom)&&void 0!==t?t:-1/0,e.bottom))}),r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}var K="Sortable"+(new Date).getTime();function x(){var e,o=[];return{captureAnimationState:function(){o=[],this.options.animation&&[].slice.call(this.el.children).forEach(function(t){var e,n;"none"!==R(t,"display")&&t!==Ft.ghost&&(o.push({target:t,rect:X(t)}),e=I({},o[o.length-1].rect),!t.thisAnimationDuration||(n=v(t,!0))&&(e.top-=n.f,e.left-=n.e),t.fromRect=e)})},addAnimationState:function(t){o.push(t)},removeAnimationState:function(t){o.splice(function(t,e){for(var n in t)if(t.hasOwnProperty(n))for(var o in e)if(e.hasOwnProperty(o)&&e[o]===t[n][o])return Number(n);return-1}(o,{target:t}),1)},animateAll:function(t){var c=this;if(!this.options.animation)return clearTimeout(e),void("function"==typeof t&&t());var u=!1,d=0;o.forEach(function(t){var e=0,n=t.target,o=n.fromRect,i=X(n),r=n.prevFromRect,a=n.prevToRect,l=t.rect,s=v(n,!0);s&&(i.top-=s.f,i.left-=s.e),n.toRect=i,n.thisAnimationDuration&&D(r,i)&&!D(o,i)&&(l.top-i.top)/(l.left-i.left)==(o.top-i.top)/(o.left-i.left)&&(t=l,s=r,r=a,a=c.options,e=Math.sqrt(Math.pow(s.top-t.top,2)+Math.pow(s.left-t.left,2))/Math.sqrt(Math.pow(s.top-r.top,2)+Math.pow(s.left-r.left,2))*a.animation),D(i,o)||(n.prevFromRect=o,n.prevToRect=i,e=e||c.options.animation,c.animate(n,l,i,e)),e&&(u=!0,d=Math.max(d,e),clearTimeout(n.animationResetTimer),n.animationResetTimer=setTimeout(function(){n.animationTime=0,n.prevFromRect=null,n.fromRect=null,n.prevToRect=null,n.thisAnimationDuration=null},e),n.thisAnimationDuration=e)}),clearTimeout(e),u?e=setTimeout(function(){"function"==typeof t&&t()},d):"function"==typeof t&&t(),o=[]},animate:function(t,e,n,o){var i,r;o&&(R(t,"transition",""),R(t,"transform",""),i=(r=v(this.el))&&r.a,r=r&&r.d,i=(e.left-n.left)/(i||1),r=(e.top-n.top)/(r||1),t.animatingX=!!i,t.animatingY=!!r,R(t,"transform","translate3d("+i+"px,"+r+"px,0)"),this.forRepaintDummy=t.offsetWidth,R(t,"transition","transform "+o+"ms"+(this.options.easing?" "+this.options.easing:"")),R(t,"transform","translate3d(0,0,0)"),"number"==typeof t.animated&&clearTimeout(t.animated),t.animated=setTimeout(function(){R(t,"transition",""),R(t,"transform",""),t.animated=!1,t.animatingX=!1,t.animatingY=!1},o))}}}var A=[],N={initializeByDefault:!0},W={mount:function(e){for(var t in N)!N.hasOwnProperty(t)||t in e||(e[t]=N[t]);A.forEach(function(t){if(t.pluginName===e.pluginName)throw"Sortable: Cannot mount plugin ".concat(e.pluginName," more than once")}),A.push(e)},pluginEvent:function(e,n,o){var t=this;this.eventCanceled=!1,o.cancel=function(){t.eventCanceled=!0};var i=e+"Global";A.forEach(function(t){n[t.pluginName]&&(n[t.pluginName][i]&&n[t.pluginName][i](I({sortable:n},o)),n.options[t.pluginName]&&n[t.pluginName][e]&&n[t.pluginName][e](I({sortable:n},o)))})},initializePlugins:function(n,o,i,t){for(var e in A.forEach(function(t){var e=t.pluginName;(n.options[e]||t.initializeByDefault)&&((t=new t(n,o,n.options)).sortable=n,t.options=n.options,n[e]=t,a(i,t.defaults))}),n.options){var r;n.options.hasOwnProperty(e)&&(void 0!==(r=this.modifyOption(n,e,n.options[e]))&&(n.options[e]=r))}},getEventProperties:function(e,n){var o={};return A.forEach(function(t){"function"==typeof t.eventProperties&&a(o,t.eventProperties.call(n[t.pluginName],e))}),o},modifyOption:function(e,n,o){var i;return A.forEach(function(t){e[t.pluginName]&&t.optionListeners&&"function"==typeof t.optionListeners[n]&&(i=t.optionListeners[n].call(e[t.pluginName],o))}),i}};function z(t){var e=t.sortable,n=t.rootEl,o=t.name,i=t.targetEl,r=t.cloneEl,a=t.toEl,l=t.fromEl,s=t.oldIndex,c=t.newIndex,u=t.oldDraggableIndex,d=t.newDraggableIndex,h=t.originalEvent,f=t.putSortable,p=t.extraEventProperties;if(e=e||n&&n[K]){var g,m=e.options,t="on"+o.charAt(0).toUpperCase()+o.substr(1);!window.CustomEvent||y||w?(g=document.createEvent("Event")).initEvent(o,!0,!0):g=new CustomEvent(o,{bubbles:!0,cancelable:!0}),g.to=a||n,g.from=l||n,g.item=i||n,g.clone=r,g.oldIndex=s,g.newIndex=c,g.oldDraggableIndex=u,g.newDraggableIndex=d,g.originalEvent=h,g.pullMode=f?f.lastPutMode:void 0;var v,b=I(I({},p),W.getEventProperties(o,e));for(v in b)g[v]=b[v];n&&n.dispatchEvent(g),m[t]&&m[t].call(e,g)}}function G(t,e){var n=(o=2<arguments.length&&void 0!==arguments[2]?arguments[2]:{}).evt,o=i(o,U);W.pluginEvent.bind(Ft)(t,e,I({dragEl:V,parentEl:Z,ghostEl:$,rootEl:Q,nextEl:J,lastDownEl:tt,cloneEl:et,cloneHidden:nt,dragStarted:gt,putSortable:st,activeSortable:Ft.active,originalEvent:n,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at,hideGhostForTarget:Rt,unhideGhostForTarget:Xt,cloneNowHidden:function(){nt=!0},cloneNowShown:function(){nt=!1},dispatchSortableEvent:function(t){q({sortable:e,name:t,originalEvent:n})}},o))}var U=["evt"];function q(t){z(I({putSortable:st,cloneEl:et,targetEl:V,rootEl:Q,oldIndex:ot,oldDraggableIndex:rt,newIndex:it,newDraggableIndex:at},t))}var V,Z,$,Q,J,tt,et,nt,ot,it,rt,at,lt,st,ct,ut,dt,ht,ft,pt,gt,mt,vt,bt,yt,wt=!1,Et=!1,Dt=[],St=!1,_t=!1,Ct=[],Tt=!1,xt=[],Ot="undefined"!=typeof document,Mt=n,At=w||y?"cssFloat":"float",Nt=Ot&&!c&&!n&&"draggable"in document.createElement("div"),It=function(){if(Ot){if(y)return!1;var t=document.createElement("x");return t.style.cssText="pointer-events:auto","auto"===t.style.pointerEvents}}(),Pt=function(t,e){var n=R(t),o=parseInt(n.width)-parseInt(n.paddingLeft)-parseInt(n.paddingRight)-parseInt(n.borderLeftWidth)-parseInt(n.borderRightWidth),i=B(t,0,e),r=B(t,1,e),a=i&&R(i),l=r&&R(r),s=a&&parseInt(a.marginLeft)+parseInt(a.marginRight)+X(i).width,t=l&&parseInt(l.marginLeft)+parseInt(l.marginRight)+X(r).width;if("flex"===n.display)return"column"===n.flexDirection||"column-reverse"===n.flexDirection?"vertical":"horizontal";if("grid"===n.display)return n.gridTemplateColumns.split(" ").length<=1?"vertical":"horizontal";if(i&&a.float&&"none"!==a.float){e="left"===a.float?"left":"right";return!r||"both"!==l.clear&&l.clear!==e?"horizontal":"vertical"}return i&&("block"===a.display||"flex"===a.display||"table"===a.display||"grid"===a.display||o<=s&&"none"===n[At]||r&&"none"===n[At]&&o<s+t)?"vertical":"horizontal"},kt=function(t){function l(r,a){return function(t,e,n,o){var i=t.options.group.name&&e.options.group.name&&t.options.group.name===e.options.group.name;if(null==r&&(a||i))return!0;if(null==r||!1===r)return!1;if(a&&"clone"===r)return r;if("function"==typeof r)return l(r(t,e,n,o),a)(t,e,n,o);e=(a?t:e).options.group.name;return!0===r||"string"==typeof r&&r===e||r.join&&-1<r.indexOf(e)}}var e={},n=t.group;n&&"object"==o(n)||(n={name:n}),e.name=n.name,e.checkPull=l(n.pull,!0),e.checkPut=l(n.put),e.revertClone=n.revertClone,t.group=e},Rt=function(){!It&&$&&R($,"display","none")},Xt=function(){!It&&$&&R($,"display","")};Ot&&!c&&document.addEventListener("click",function(t){if(Et)return t.preventDefault(),t.stopPropagation&&t.stopPropagation(),t.stopImmediatePropagation&&t.stopImmediatePropagation(),Et=!1},!0);function Yt(t){if(V){t=t.touches?t.touches[0]:t;var e=(i=t.clientX,r=t.clientY,Dt.some(function(t){var e=t[K].options.emptyInsertThreshold;if(e&&!F(t)){var n=X(t),o=i>=n.left-e&&i<=n.right+e,e=r>=n.top-e&&r<=n.bottom+e;return o&&e?a=t:void 0}}),a);if(e){var n,o={};for(n in t)t.hasOwnProperty(n)&&(o[n]=t[n]);o.target=o.rootEl=e,o.preventDefault=void 0,o.stopPropagation=void 0,e[K]._onDragOver(o)}}var i,r,a}function Bt(t){V&&V.parentNode[K]._isOutsideThisEl(t.target)}function Ft(t,e){if(!t||!t.nodeType||1!==t.nodeType)throw"Sortable: `el` must be an HTMLElement, not ".concat({}.toString.call(t));this.el=t,this.options=e=a({},e),t[K]=this;var n,o,i={group:null,sort:!0,disabled:!1,store:null,handle:null,draggable:/^[uo]l$/i.test(t.nodeName)?">li":">*",swapThreshold:1,invertSwap:!1,invertedSwapThreshold:null,removeCloneOnHide:!0,direction:function(){return Pt(t,this.options)},ghostClass:"sortable-ghost",chosenClass:"sortable-chosen",dragClass:"sortable-drag",ignore:"a, img",filter:null,preventOnFilter:!0,animation:0,easing:null,setData:function(t,e){t.setData("Text",e.textContent)},dropBubble:!1,dragoverBubble:!1,dataIdAttr:"data-id",delay:0,delayOnTouchOnly:!1,touchStartThreshold:(Number.parseInt?Number:window).parseInt(window.devicePixelRatio,10)||1,forceFallback:!1,fallbackClass:"sortable-fallback",fallbackOnBody:!1,fallbackTolerance:0,fallbackOffset:{x:0,y:0},supportPointer:!1!==Ft.supportPointer&&"PointerEvent"in window&&!u,emptyInsertThreshold:5};for(n in W.initializePlugins(this,t,i),i)n in e||(e[n]=i[n]);for(o in kt(e),this)"_"===o.charAt(0)&&"function"==typeof this[o]&&(this[o]=this[o].bind(this));this.nativeDraggable=!e.forceFallback&&Nt,this.nativeDraggable&&(this.options.touchStartThreshold=1),e.supportPointer?h(t,"pointerdown",this._onTapStart):(h(t,"mousedown",this._onTapStart),h(t,"touchstart",this._onTapStart)),this.nativeDraggable&&(h(t,"dragover",this),h(t,"dragenter",this)),Dt.push(this.el),e.store&&e.store.get&&this.sort(e.store.get(this)||[]),a(this,x())}function jt(t,e,n,o,i,r,a,l){var s,c,u=t[K],d=u.options.onMove;return!window.CustomEvent||y||w?(s=document.createEvent("Event")).initEvent("move",!0,!0):s=new CustomEvent("move",{bubbles:!0,cancelable:!0}),s.to=e,s.from=t,s.dragged=n,s.draggedRect=o,s.related=i||e,s.relatedRect=r||X(e),s.willInsertAfter=l,s.originalEvent=a,t.dispatchEvent(s),c=d?d.call(u,s,a):c}function Ht(t){t.draggable=!1}function Lt(){Tt=!1}function Kt(t){return setTimeout(t,0)}function Wt(t){return clearTimeout(t)}Ft.prototype={constructor:Ft,_isOutsideThisEl:function(t){this.el.contains(t)||t===this.el||(mt=null)},_getDirection:function(t,e){return"function"==typeof this.options.direction?this.options.direction.call(this,t,e,V):this.options.direction},_onTapStart:function(e){if(e.cancelable){var n=this,o=this.el,t=this.options,i=t.preventOnFilter,r=e.type,a=e.touches&&e.touches[0]||e.pointerType&&"touch"===e.pointerType&&e,l=(a||e).target,s=e.target.shadowRoot&&(e.path&&e.path[0]||e.composedPath&&e.composedPath()[0])||l,c=t.filter;if(!function(t){xt.length=0;var e=t.getElementsByTagName("input"),n=e.length;for(;n--;){var o=e[n];o.checked&&xt.push(o)}}(o),!V&&!(/mousedown|pointerdown/.test(r)&&0!==e.button||t.disabled)&&!s.isContentEditable&&(this.nativeDraggable||!u||!l||"SELECT"!==l.tagName.toUpperCase())&&!((l=P(l,t.draggable,o,!1))&&l.animated||tt===l)){if(ot=j(l),rt=j(l,t.draggable),"function"==typeof c){if(c.call(this,e,l,this))return q({sortable:n,rootEl:s,name:"filter",targetEl:l,toEl:o,fromEl:o}),G("filter",n,{evt:e}),void(i&&e.cancelable&&e.preventDefault())}else if(c=c&&c.split(",").some(function(t){if(t=P(s,t.trim(),o,!1))return q({sortable:n,rootEl:t,name:"filter",targetEl:l,fromEl:o,toEl:o}),G("filter",n,{evt:e}),!0}))return void(i&&e.cancelable&&e.preventDefault());t.handle&&!P(s,t.handle,o,!1)||this._prepareDragStart(e,a,l)}}},_prepareDragStart:function(t,e,n){var o,i=this,r=i.el,a=i.options,l=r.ownerDocument;n&&!V&&n.parentNode===r&&(o=X(n),Q=r,Z=(V=n).parentNode,J=V.nextSibling,tt=n,lt=a.group,ct={target:Ft.dragged=V,clientX:(e||t).clientX,clientY:(e||t).clientY},ft=ct.clientX-o.left,pt=ct.clientY-o.top,this._lastX=(e||t).clientX,this._lastY=(e||t).clientY,V.style["will-change"]="all",o=function(){G("delayEnded",i,{evt:t}),Ft.eventCanceled?i._onDrop():(i._disableDelayedDragEvents(),!s&&i.nativeDraggable&&(V.draggable=!0),i._triggerDragStart(t,e),q({sortable:i,name:"choose",originalEvent:t}),k(V,a.chosenClass,!0))},a.ignore.split(",").forEach(function(t){b(V,t.trim(),Ht)}),h(l,"dragover",Yt),h(l,"mousemove",Yt),h(l,"touchmove",Yt),h(l,"mouseup",i._onDrop),h(l,"touchend",i._onDrop),h(l,"touchcancel",i._onDrop),s&&this.nativeDraggable&&(this.options.touchStartThreshold=4,V.draggable=!0),G("delayStart",this,{evt:t}),!a.delay||a.delayOnTouchOnly&&!e||this.nativeDraggable&&(w||y)?o():Ft.eventCanceled?this._onDrop():(h(l,"mouseup",i._disableDelayedDrag),h(l,"touchend",i._disableDelayedDrag),h(l,"touchcancel",i._disableDelayedDrag),h(l,"mousemove",i._delayedDragTouchMoveHandler),h(l,"touchmove",i._delayedDragTouchMoveHandler),a.supportPointer&&h(l,"pointermove",i._delayedDragTouchMoveHandler),i._dragStartTimer=setTimeout(o,a.delay)))},_delayedDragTouchMoveHandler:function(t){t=t.touches?t.touches[0]:t;Math.max(Math.abs(t.clientX-this._lastX),Math.abs(t.clientY-this._lastY))>=Math.floor(this.options.touchStartThreshold/(this.nativeDraggable&&window.devicePixelRatio||1))&&this._disableDelayedDrag()},_disableDelayedDrag:function(){V&&Ht(V),clearTimeout(this._dragStartTimer),this._disableDelayedDragEvents()},_disableDelayedDragEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._disableDelayedDrag),f(t,"touchend",this._disableDelayedDrag),f(t,"touchcancel",this._disableDelayedDrag),f(t,"mousemove",this._delayedDragTouchMoveHandler),f(t,"touchmove",this._delayedDragTouchMoveHandler),f(t,"pointermove",this._delayedDragTouchMoveHandler)},_triggerDragStart:function(t,e){e=e||"touch"==t.pointerType&&t,!this.nativeDraggable||e?this.options.supportPointer?h(document,"pointermove",this._onTouchMove):h(document,e?"touchmove":"mousemove",this._onTouchMove):(h(V,"dragend",this),h(Q,"dragstart",this._onDragStart));try{document.selection?Kt(function(){document.selection.empty()}):window.getSelection().removeAllRanges()}catch(t){}},_dragStarted:function(t,e){var n;wt=!1,Q&&V?(G("dragStarted",this,{evt:e}),this.nativeDraggable&&h(document,"dragover",Bt),n=this.options,t||k(V,n.dragClass,!1),k(V,n.ghostClass,!0),Ft.active=this,t&&this._appendGhost(),q({sortable:this,name:"start",originalEvent:e})):this._nulling()},_emulateDragOver:function(){if(ut){this._lastX=ut.clientX,this._lastY=ut.clientY,Rt();for(var t=document.elementFromPoint(ut.clientX,ut.clientY),e=t;t&&t.shadowRoot&&(t=t.shadowRoot.elementFromPoint(ut.clientX,ut.clientY))!==e;)e=t;if(V.parentNode[K]._isOutsideThisEl(t),e)do{if(e[K])if(e[K]._onDragOver({clientX:ut.clientX,clientY:ut.clientY,target:t,rootEl:e})&&!this.options.dragoverBubble)break}while(e=(t=e).parentNode);Xt()}},_onTouchMove:function(t){if(ct){var e=this.options,n=e.fallbackTolerance,o=e.fallbackOffset,i=t.touches?t.touches[0]:t,r=$&&v($,!0),a=$&&r&&r.a,l=$&&r&&r.d,e=Mt&&yt&&E(yt),a=(i.clientX-ct.clientX+o.x)/(a||1)+(e?e[0]-Ct[0]:0)/(a||1),l=(i.clientY-ct.clientY+o.y)/(l||1)+(e?e[1]-Ct[1]:0)/(l||1);if(!Ft.active&&!wt){if(n&&Math.max(Math.abs(i.clientX-this._lastX),Math.abs(i.clientY-this._lastY))<n)return;this._onDragStart(t,!0)}$&&(r?(r.e+=a-(dt||0),r.f+=l-(ht||0)):r={a:1,b:0,c:0,d:1,e:a,f:l},r="matrix(".concat(r.a,",").concat(r.b,",").concat(r.c,",").concat(r.d,",").concat(r.e,",").concat(r.f,")"),R($,"webkitTransform",r),R($,"mozTransform",r),R($,"msTransform",r),R($,"transform",r),dt=a,ht=l,ut=i),t.cancelable&&t.preventDefault()}},_appendGhost:function(){if(!$){var t=this.options.fallbackOnBody?document.body:Q,e=X(V,!0,Mt,!0,t),n=this.options;if(Mt){for(yt=t;"static"===R(yt,"position")&&"none"===R(yt,"transform")&&yt!==document;)yt=yt.parentNode;yt!==document.body&&yt!==document.documentElement?(yt===document&&(yt=O()),e.top+=yt.scrollTop,e.left+=yt.scrollLeft):yt=O(),Ct=E(yt)}k($=V.cloneNode(!0),n.ghostClass,!1),k($,n.fallbackClass,!0),k($,n.dragClass,!0),R($,"transition",""),R($,"transform",""),R($,"box-sizing","border-box"),R($,"margin",0),R($,"top",e.top),R($,"left",e.left),R($,"width",e.width),R($,"height",e.height),R($,"opacity","0.8"),R($,"position",Mt?"absolute":"fixed"),R($,"zIndex","100000"),R($,"pointerEvents","none"),Ft.ghost=$,t.appendChild($),R($,"transform-origin",ft/parseInt($.style.width)*100+"% "+pt/parseInt($.style.height)*100+"%")}},_onDragStart:function(t,e){var n=this,o=t.dataTransfer,i=n.options;G("dragStart",this,{evt:t}),Ft.eventCanceled?this._onDrop():(G("setupClone",this),Ft.eventCanceled||((et=_(V)).removeAttribute("id"),et.draggable=!1,et.style["will-change"]="",this._hideClone(),k(et,this.options.chosenClass,!1),Ft.clone=et),n.cloneId=Kt(function(){G("clone",n),Ft.eventCanceled||(n.options.removeCloneOnHide||Q.insertBefore(et,V),n._hideClone(),q({sortable:n,name:"clone"}))}),e||k(V,i.dragClass,!0),e?(Et=!0,n._loopId=setInterval(n._emulateDragOver,50)):(f(document,"mouseup",n._onDrop),f(document,"touchend",n._onDrop),f(document,"touchcancel",n._onDrop),o&&(o.effectAllowed="move",i.setData&&i.setData.call(n,o,V)),h(document,"drop",n),R(V,"transform","translateZ(0)")),wt=!0,n._dragStartId=Kt(n._dragStarted.bind(n,e,t)),h(document,"selectstart",n),gt=!0,u&&R(document.body,"user-select","none"))},_onDragOver:function(n){var o,i,r,t,e,a=this.el,l=n.target,s=this.options,c=s.group,u=Ft.active,d=lt===c,h=s.sort,f=st||u,p=this,g=!1;if(!Tt){if(void 0!==n.preventDefault&&n.cancelable&&n.preventDefault(),l=P(l,s.draggable,a,!0),O("dragOver"),Ft.eventCanceled)return g;if(V.contains(n.target)||l.animated&&l.animatingX&&l.animatingY||p._ignoreWhileAnimating===l)return A(!1);if(Et=!1,u&&!s.disabled&&(d?h||(i=Z!==Q):st===this||(this.lastPutMode=lt.checkPull(this,u,V,n))&&c.checkPut(this,u,V,n))){if(r="vertical"===this._getDirection(n,l),o=X(V),O("dragOverValid"),Ft.eventCanceled)return g;if(i)return Z=Q,M(),this._hideClone(),O("revert"),Ft.eventCanceled||(J?Q.insertBefore(V,J):Q.appendChild(V)),A(!0);var m=F(a,s.draggable);if(m&&(S=n,c=r,x=X(F((D=this).el,D.options.draggable)),D=L(D.el,D.options,$),!(c?S.clientX>D.right+10||S.clientY>x.bottom&&S.clientX>x.left:S.clientY>D.bottom+10||S.clientX>x.right&&S.clientY>x.top)||m.animated)){if(m&&(t=n,e=r,C=X(B((_=this).el,0,_.options,!0)),_=L(_.el,_.options,$),e?t.clientX<_.left-10||t.clientY<C.top&&t.clientX<C.right:t.clientY<_.top-10||t.clientY<C.bottom&&t.clientX<C.left)){var v=B(a,0,s,!0);if(v===V)return A(!1);if(E=X(l=v),!1!==jt(Q,a,V,o,l,E,n,!1))return M(),a.insertBefore(V,v),Z=a,N(),A(!0)}else if(l.parentNode===a){var b,y,w,E=X(l),D=V.parentNode!==a,S=(S=V.animated&&V.toRect||o,x=l.animated&&l.toRect||E,_=(e=r)?S.left:S.top,t=e?S.right:S.bottom,C=e?S.width:S.height,v=e?x.left:x.top,S=e?x.right:x.bottom,x=e?x.width:x.height,!(_===v||t===S||_+C/2===v+x/2)),_=r?"top":"left",C=Y(l,"top","top")||Y(V,"top","top"),v=C?C.scrollTop:void 0;if(mt!==l&&(y=E[_],St=!1,_t=!S&&s.invertSwap||D),0!==(b=function(t,e,n,o,i,r,a,l){var s=o?t.clientY:t.clientX,c=o?n.height:n.width,t=o?n.top:n.left,o=o?n.bottom:n.right,n=!1;if(!a)if(l&&bt<c*i){if(St=!St&&(1===vt?t+c*r/2<s:s<o-c*r/2)?!0:St)n=!0;else if(1===vt?s<t+bt:o-bt<s)return-vt}else if(t+c*(1-i)/2<s&&s<o-c*(1-i)/2)return function(t){return j(V)<j(t)?1:-1}(e);if((n=n||a)&&(s<t+c*r/2||o-c*r/2<s))return t+c/2<s?1:-1;return 0}(n,l,E,r,S?1:s.swapThreshold,null==s.invertedSwapThreshold?s.swapThreshold:s.invertedSwapThreshold,_t,mt===l)))for(var T=j(V);(w=Z.children[T-=b])&&("none"===R(w,"display")||w===$););if(0===b||w===l)return A(!1);vt=b;var x=(mt=l).nextElementSibling,D=!1,S=jt(Q,a,V,o,l,E,n,D=1===b);if(!1!==S)return 1!==S&&-1!==S||(D=1===S),Tt=!0,setTimeout(Lt,30),M(),D&&!x?a.appendChild(V):l.parentNode.insertBefore(V,D?x:l),C&&H(C,0,v-C.scrollTop),Z=V.parentNode,void 0===y||_t||(bt=Math.abs(y-X(l)[_])),N(),A(!0)}}else{if(m===V)return A(!1);if((l=m&&a===n.target?m:l)&&(E=X(l)),!1!==jt(Q,a,V,o,l,E,n,!!l))return M(),m&&m.nextSibling?a.insertBefore(V,m.nextSibling):a.appendChild(V),Z=a,N(),A(!0)}if(a.contains(V))return A(!1)}return!1}function O(t,e){G(t,p,I({evt:n,isOwner:d,axis:r?"vertical":"horizontal",revert:i,dragRect:o,targetRect:E,canSort:h,fromSortable:f,target:l,completed:A,onMove:function(t,e){return jt(Q,a,V,o,t,X(t),n,e)},changed:N},e))}function M(){O("dragOverAnimationCapture"),p.captureAnimationState(),p!==f&&f.captureAnimationState()}function A(t){return O("dragOverCompleted",{insertion:t}),t&&(d?u._hideClone():u._showClone(p),p!==f&&(k(V,(st||u).options.ghostClass,!1),k(V,s.ghostClass,!0)),st!==p&&p!==Ft.active?st=p:p===Ft.active&&st&&(st=null),f===p&&(p._ignoreWhileAnimating=l),p.animateAll(function(){O("dragOverAnimationComplete"),p._ignoreWhileAnimating=null}),p!==f&&(f.animateAll(),f._ignoreWhileAnimating=null)),(l===V&&!V.animated||l===a&&!l.animated)&&(mt=null),s.dragoverBubble||n.rootEl||l===document||(V.parentNode[K]._isOutsideThisEl(n.target),t||Yt(n)),!s.dragoverBubble&&n.stopPropagation&&n.stopPropagation(),g=!0}function N(){it=j(V),at=j(V,s.draggable),q({sortable:p,name:"change",toEl:a,newIndex:it,newDraggableIndex:at,originalEvent:n})}},_ignoreWhileAnimating:null,_offMoveEvents:function(){f(document,"mousemove",this._onTouchMove),f(document,"touchmove",this._onTouchMove),f(document,"pointermove",this._onTouchMove),f(document,"dragover",Yt),f(document,"mousemove",Yt),f(document,"touchmove",Yt)},_offUpEvents:function(){var t=this.el.ownerDocument;f(t,"mouseup",this._onDrop),f(t,"touchend",this._onDrop),f(t,"pointerup",this._onDrop),f(t,"touchcancel",this._onDrop),f(document,"selectstart",this)},_onDrop:function(t){var e=this.el,n=this.options;it=j(V),at=j(V,n.draggable),G("drop",this,{evt:t}),Z=V&&V.parentNode,it=j(V),at=j(V,n.draggable),Ft.eventCanceled||(St=_t=wt=!1,clearInterval(this._loopId),clearTimeout(this._dragStartTimer),Wt(this.cloneId),Wt(this._dragStartId),this.nativeDraggable&&(f(document,"drop",this),f(e,"dragstart",this._onDragStart)),this._offMoveEvents(),this._offUpEvents(),u&&R(document.body,"user-select",""),R(V,"transform",""),t&&(gt&&(t.cancelable&&t.preventDefault(),n.dropBubble||t.stopPropagation()),$&&$.parentNode&&$.parentNode.removeChild($),(Q===Z||st&&"clone"!==st.lastPutMode)&&et&&et.parentNode&&et.parentNode.removeChild(et),V&&(this.nativeDraggable&&f(V,"dragend",this),Ht(V),V.style["will-change"]="",gt&&!wt&&k(V,(st||this).options.ghostClass,!1),k(V,this.options.chosenClass,!1),q({sortable:this,name:"unchoose",toEl:Z,newIndex:null,newDraggableIndex:null,originalEvent:t}),Q!==Z?(0<=it&&(q({rootEl:Z,name:"add",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"remove",toEl:Z,originalEvent:t}),q({rootEl:Z,name:"sort",toEl:Z,fromEl:Q,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),st&&st.save()):it!==ot&&0<=it&&(q({sortable:this,name:"update",toEl:Z,originalEvent:t}),q({sortable:this,name:"sort",toEl:Z,originalEvent:t})),Ft.active&&(null!=it&&-1!==it||(it=ot,at=rt),q({sortable:this,name:"end",toEl:Z,originalEvent:t}),this.save())))),this._nulling()},_nulling:function(){G("nulling",this),Q=V=Z=$=J=et=tt=nt=ct=ut=gt=it=at=ot=rt=mt=vt=st=lt=Ft.dragged=Ft.ghost=Ft.clone=Ft.active=null,xt.forEach(function(t){t.checked=!0}),xt.length=dt=ht=0},handleEvent:function(t){switch(t.type){case"drop":case"dragend":this._onDrop(t);break;case"dragenter":case"dragover":V&&(this._onDragOver(t),function(t){t.dataTransfer&&(t.dataTransfer.dropEffect="move");t.cancelable&&t.preventDefault()}(t));break;case"selectstart":t.preventDefault()}},toArray:function(){for(var t,e=[],n=this.el.children,o=0,i=n.length,r=this.options;o<i;o++)P(t=n[o],r.draggable,this.el,!1)&&e.push(t.getAttribute(r.dataIdAttr)||function(t){var e=t.tagName+t.className+t.src+t.href+t.textContent,n=e.length,o=0;for(;n--;)o+=e.charCodeAt(n);return o.toString(36)}(t));return e},sort:function(t,e){var n={},o=this.el;this.toArray().forEach(function(t,e){e=o.children[e];P(e,this.options.draggable,o,!1)&&(n[t]=e)},this),e&&this.captureAnimationState(),t.forEach(function(t){n[t]&&(o.removeChild(n[t]),o.appendChild(n[t]))}),e&&this.animateAll()},save:function(){var t=this.options.store;t&&t.set&&t.set(this)},closest:function(t,e){return P(t,e||this.options.draggable,this.el,!1)},option:function(t,e){var n=this.options;if(void 0===e)return n[t];var o=W.modifyOption(this,t,e);n[t]=void 0!==o?o:e,"group"===t&&kt(n)},destroy:function(){G("destroy",this);var t=this.el;t[K]=null,f(t,"mousedown",this._onTapStart),f(t,"touchstart",this._onTapStart),f(t,"pointerdown",this._onTapStart),this.nativeDraggable&&(f(t,"dragover",this),f(t,"dragenter",this)),Array.prototype.forEach.call(t.querySelectorAll("[draggable]"),function(t){t.removeAttribute("draggable")}),this._onDrop(),this._disableDelayedDragEvents(),Dt.splice(Dt.indexOf(this.el),1),this.el=t=null},_hideClone:function(){nt||(G("hideClone",this),Ft.eventCanceled||(R(et,"display","none"),this.options.removeCloneOnHide&&et.parentNode&&et.parentNode.removeChild(et),nt=!0))},_showClone:function(t){"clone"===t.lastPutMode?nt&&(G("showClone",this),Ft.eventCanceled||(V.parentNode!=Q||this.options.group.revertClone?J?Q.insertBefore(et,J):Q.appendChild(et):Q.insertBefore(et,V),this.options.group.revertClone&&this.animate(V,et),R(et,"display",""),nt=!1)):this._hideClone()}},Ot&&h(document,"touchmove",function(t){(Ft.active||wt)&&t.cancelable&&t.preventDefault()}),Ft.utils={on:h,off:f,css:R,find:b,is:function(t,e){return!!P(t,e,t,!1)},extend:function(t,e){if(t&&e)for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t},throttle:S,closest:P,toggleClass:k,clone:_,index:j,nextTick:Kt,cancelNextTick:Wt,detectDirection:Pt,getChild:B},Ft.get=function(t){return t[K]},Ft.mount=function(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];(e=e[0].constructor===Array?e[0]:e).forEach(function(t){if(!t.prototype||!t.prototype.constructor)throw"Sortable: Mounted plugin must be a constructor function, not ".concat({}.toString.call(t));t.utils&&(Ft.utils=I(I({},Ft.utils),t.utils)),W.mount(t)})},Ft.create=function(t,e){return new Ft(t,e)};var zt,Gt,Ut,qt,Vt,Zt,$t=[],Qt=!(Ft.version="1.15.2");function Jt(){$t.forEach(function(t){clearInterval(t.pid)}),$t=[]}function te(){clearInterval(Zt)}var ee,ne=S(function(n,t,e,o){if(t.scroll){var i,r=(n.touches?n.touches[0]:n).clientX,a=(n.touches?n.touches[0]:n).clientY,l=t.scrollSensitivity,s=t.scrollSpeed,c=O(),u=!1;Gt!==e&&(Gt=e,Jt(),zt=t.scroll,i=t.scrollFn,!0===zt&&(zt=M(e,!0)));var d=0,h=zt;do{var f=h,p=X(f),g=p.top,m=p.bottom,v=p.left,b=p.right,y=p.width,w=p.height,E=void 0,D=void 0,S=f.scrollWidth,_=f.scrollHeight,C=R(f),T=f.scrollLeft,p=f.scrollTop,D=f===c?(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX||"visible"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY||"visible"===C.overflowY)):(E=y<S&&("auto"===C.overflowX||"scroll"===C.overflowX),w<_&&("auto"===C.overflowY||"scroll"===C.overflowY)),T=E&&(Math.abs(b-r)<=l&&T+y<S)-(Math.abs(v-r)<=l&&!!T),p=D&&(Math.abs(m-a)<=l&&p+w<_)-(Math.abs(g-a)<=l&&!!p);if(!$t[d])for(var x=0;x<=d;x++)$t[x]||($t[x]={});$t[d].vx==T&&$t[d].vy==p&&$t[d].el===f||($t[d].el=f,$t[d].vx=T,$t[d].vy=p,clearInterval($t[d].pid),0==T&&0==p||(u=!0,$t[d].pid=setInterval(function(){o&&0===this.layer&&Ft.active._onTouchMove(Vt);var t=$t[this.layer].vy?$t[this.layer].vy*s:0,e=$t[this.layer].vx?$t[this.layer].vx*s:0;"function"==typeof i&&"continue"!==i.call(Ft.dragged.parentNode[K],e,t,n,Vt,$t[this.layer].el)||H($t[this.layer].el,e,t)}.bind({layer:d}),24))),d++}while(t.bubbleScroll&&h!==c&&(h=M(h,!1)));Qt=u}},30),c=function(t){var e=t.originalEvent,n=t.putSortable,o=t.dragEl,i=t.activeSortable,r=t.dispatchSortableEvent,a=t.hideGhostForTarget,t=t.unhideGhostForTarget;e&&(i=n||i,a(),e=e.changedTouches&&e.changedTouches.length?e.changedTouches[0]:e,e=document.elementFromPoint(e.clientX,e.clientY),t(),i&&!i.el.contains(e)&&(r("spill"),this.onSpill({dragEl:o,putSortable:n})))};function oe(){}function ie(){}oe.prototype={startIndex:null,dragStart:function(t){t=t.oldDraggableIndex;this.startIndex=t},onSpill:function(t){var e=t.dragEl,n=t.putSortable;this.sortable.captureAnimationState(),n&&n.captureAnimationState();t=B(this.sortable.el,this.startIndex,this.options);t?this.sortable.el.insertBefore(e,t):this.sortable.el.appendChild(e),this.sortable.animateAll(),n&&n.animateAll()},drop:c},a(oe,{pluginName:"revertOnSpill"}),ie.prototype={onSpill:function(t){var e=t.dragEl,t=t.putSortable||this.sortable;t.captureAnimationState(),e.parentNode&&e.parentNode.removeChild(e),t.animateAll()},drop:c},a(ie,{pluginName:"removeOnSpill"});var re,ae,le,se,ce,ue=[],de=[],he=!1,fe=!1,pe=!1;function ge(n,o){de.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)})}function me(){ue.forEach(function(t){t!==le&&t.parentNode&&t.parentNode.removeChild(t)})}return Ft.mount(new function(){function t(){for(var t in this.defaults={scroll:!0,forceAutoScrollFallback:!1,scrollSensitivity:30,scrollSpeed:10,bubbleScroll:!0},this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this))}return t.prototype={dragStarted:function(t){t=t.originalEvent;this.sortable.nativeDraggable?h(document,"dragover",this._handleAutoScroll):this.options.supportPointer?h(document,"pointermove",this._handleFallbackAutoScroll):t.touches?h(document,"touchmove",this._handleFallbackAutoScroll):h(document,"mousemove",this._handleFallbackAutoScroll)},dragOverCompleted:function(t){t=t.originalEvent;this.options.dragOverBubble||t.rootEl||this._handleAutoScroll(t)},drop:function(){this.sortable.nativeDraggable?f(document,"dragover",this._handleAutoScroll):(f(document,"pointermove",this._handleFallbackAutoScroll),f(document,"touchmove",this._handleFallbackAutoScroll),f(document,"mousemove",this._handleFallbackAutoScroll)),te(),Jt(),clearTimeout(g),g=void 0},nulling:function(){Vt=Gt=zt=Qt=Zt=Ut=qt=null,$t.length=0},_handleFallbackAutoScroll:function(t){this._handleAutoScroll(t,!0)},_handleAutoScroll:function(e,n){var o,i=this,r=(e.touches?e.touches[0]:e).clientX,a=(e.touches?e.touches[0]:e).clientY,t=document.elementFromPoint(r,a);Vt=e,n||this.options.forceAutoScrollFallback||w||y||u?(ne(e,this.options,t,n),o=M(t,!0),!Qt||Zt&&r===Ut&&a===qt||(Zt&&te(),Zt=setInterval(function(){var t=M(document.elementFromPoint(r,a),!0);t!==o&&(o=t,Jt()),ne(e,i.options,t,n)},10),Ut=r,qt=a)):this.options.bubbleScroll&&M(t,!0)!==O()?ne(e,this.options,M(t,!1),!1):Jt()}},a(t,{pluginName:"scroll",initializeByDefault:!0})}),Ft.mount(ie,oe),Ft.mount(new function(){function t(){this.defaults={swapClass:"sortable-swap-highlight"}}return t.prototype={dragStart:function(t){t=t.dragEl;ee=t},dragOverValid:function(t){var e=t.completed,n=t.target,o=t.onMove,i=t.activeSortable,r=t.changed,a=t.cancel;i.options.swap&&(t=this.sortable.el,i=this.options,n&&n!==t&&(t=ee,ee=!1!==o(n)?(k(n,i.swapClass,!0),n):null,t&&t!==ee&&k(t,i.swapClass,!1)),r(),e(!0),a())},drop:function(t){var e,n,o=t.activeSortable,i=t.putSortable,r=t.dragEl,a=i||this.sortable,l=this.options;ee&&k(ee,l.swapClass,!1),ee&&(l.swap||i&&i.options.swap)&&r!==ee&&(a.captureAnimationState(),a!==o&&o.captureAnimationState(),n=ee,t=(e=r).parentNode,l=n.parentNode,t&&l&&!t.isEqualNode(n)&&!l.isEqualNode(e)&&(i=j(e),r=j(n),t.isEqualNode(l)&&i<r&&r++,t.insertBefore(n,t.children[i]),l.insertBefore(e,l.children[r])),a.animateAll(),a!==o&&o.animateAll())},nulling:function(){ee=null}},a(t,{pluginName:"swap",eventProperties:function(){return{swapItem:ee}}})}),Ft.mount(new function(){function t(o){for(var t in this)"_"===t.charAt(0)&&"function"==typeof this[t]&&(this[t]=this[t].bind(this));o.options.avoidImplicitDeselect||(o.options.supportPointer?h(document,"pointerup",this._deselectMultiDrag):(h(document,"mouseup",this._deselectMultiDrag),h(document,"touchend",this._deselectMultiDrag))),h(document,"keydown",this._checkKeyDown),h(document,"keyup",this._checkKeyUp),this.defaults={selectedClass:"sortable-selected",multiDragKey:null,avoidImplicitDeselect:!1,setData:function(t,e){var n="";ue.length&&ae===o?ue.forEach(function(t,e){n+=(e?", ":"")+t.textContent}):n=e.textContent,t.setData("Text",n)}}}return t.prototype={multiDragKeyDown:!1,isMultiDrag:!1,delayStartGlobal:function(t){t=t.dragEl;le=t},delayEnded:function(){this.isMultiDrag=~ue.indexOf(le)},setupClone:function(t){var e=t.sortable,t=t.cancel;if(this.isMultiDrag){for(var n=0;n<ue.length;n++)de.push(_(ue[n])),de[n].sortableIndex=ue[n].sortableIndex,de[n].draggable=!1,de[n].style["will-change"]="",k(de[n],this.options.selectedClass,!1),ue[n]===le&&k(de[n],this.options.chosenClass,!1);e._hideClone(),t()}},clone:function(t){var e=t.sortable,n=t.rootEl,o=t.dispatchSortableEvent,t=t.cancel;this.isMultiDrag&&(this.options.removeCloneOnHide||ue.length&&ae===e&&(ge(!0,n),o("clone"),t()))},showClone:function(t){var e=t.cloneNowShown,n=t.rootEl,t=t.cancel;this.isMultiDrag&&(ge(!1,n),de.forEach(function(t){R(t,"display","")}),e(),ce=!1,t())},hideClone:function(t){var e=this,n=(t.sortable,t.cloneNowHidden),t=t.cancel;this.isMultiDrag&&(de.forEach(function(t){R(t,"display","none"),e.options.removeCloneOnHide&&t.parentNode&&t.parentNode.removeChild(t)}),n(),ce=!0,t())},dragStartGlobal:function(t){t.sortable;!this.isMultiDrag&&ae&&ae.multiDrag._deselectMultiDrag(),ue.forEach(function(t){t.sortableIndex=j(t)}),ue=ue.sort(function(t,e){return t.sortableIndex-e.sortableIndex}),pe=!0},dragStarted:function(t){var e,n=this,t=t.sortable;this.isMultiDrag&&(this.options.sort&&(t.captureAnimationState(),this.options.animation&&(ue.forEach(function(t){t!==le&&R(t,"position","absolute")}),e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&C(t,e)}),he=fe=!0)),t.animateAll(function(){he=fe=!1,n.options.animation&&ue.forEach(function(t){T(t)}),n.options.sort&&me()}))},dragOver:function(t){var e=t.target,n=t.completed,t=t.cancel;fe&&~ue.indexOf(e)&&(n(!1),t())},revert:function(t){var n,o,e=t.fromSortable,i=t.rootEl,r=t.sortable,a=t.dragRect;1<ue.length&&(ue.forEach(function(t){r.addAnimationState({target:t,rect:fe?X(t):a}),T(t),t.fromRect=a,e.removeAnimationState(t)}),fe=!1,n=!this.options.removeCloneOnHide,o=i,ue.forEach(function(t,e){e=o.children[t.sortableIndex+(n?Number(e):0)];e?o.insertBefore(t,e):o.appendChild(t)}))},dragOverCompleted:function(t){var e,n=t.sortable,o=t.isOwner,i=t.insertion,r=t.activeSortable,a=t.parentEl,l=t.putSortable,t=this.options;i&&(o&&r._hideClone(),he=!1,t.animation&&1<ue.length&&(fe||!o&&!r.options.sort&&!l)&&(e=X(le,!1,!0,!0),ue.forEach(function(t){t!==le&&(C(t,e),a.appendChild(t))}),fe=!0),o||(fe||me(),1<ue.length?(o=ce,r._showClone(n),r.options.animation&&!ce&&o&&de.forEach(function(t){r.addAnimationState({target:t,rect:se}),t.fromRect=se,t.thisAnimationDuration=null})):r._showClone(n)))},dragOverAnimationCapture:function(t){var e=t.dragRect,n=t.isOwner,t=t.activeSortable;ue.forEach(function(t){t.thisAnimationDuration=null}),t.options.animation&&!n&&t.multiDrag.isMultiDrag&&(se=a({},e),e=v(le,!0),se.top-=e.f,se.left-=e.e)},dragOverAnimationComplete:function(){fe&&(fe=!1,me())},drop:function(t){var e=t.originalEvent,n=t.rootEl,o=t.parentEl,i=t.sortable,r=t.dispatchSortableEvent,a=t.oldIndex,l=t.putSortable,s=l||this.sortable;if(e){var c,u,d,h=this.options,f=o.children;if(!pe)if(h.multiDragKey&&!this.multiDragKeyDown&&this._deselectMultiDrag(),k(le,h.selectedClass,!~ue.indexOf(le)),~ue.indexOf(le))ue.splice(ue.indexOf(le),1),re=null,z({sortable:i,rootEl:n,name:"deselect",targetEl:le,originalEvent:e});else{if(ue.push(le),z({sortable:i,rootEl:n,name:"select",targetEl:le,originalEvent:e}),e.shiftKey&&re&&i.el.contains(re)){var p=j(re),t=j(le);if(~p&&~t&&p!==t)for(var g,m=p<t?(g=p,t):(g=t,p+1);g<m;g++)~ue.indexOf(f[g])||(k(f[g],h.selectedClass,!0),ue.push(f[g]),z({sortable:i,rootEl:n,name:"select",targetEl:f[g],originalEvent:e}))}else re=le;ae=s}pe&&this.isMultiDrag&&(fe=!1,(o[K].options.sort||o!==n)&&1<ue.length&&(c=X(le),u=j(le,":not(."+this.options.selectedClass+")"),!he&&h.animation&&(le.thisAnimationDuration=null),s.captureAnimationState(),he||(h.animation&&(le.fromRect=c,ue.forEach(function(t){var e;t.thisAnimationDuration=null,t!==le&&(e=fe?X(t):c,t.fromRect=e,s.addAnimationState({target:t,rect:e}))})),me(),ue.forEach(function(t){f[u]?o.insertBefore(t,f[u]):o.appendChild(t),u++}),a===j(le)&&(d=!1,ue.forEach(function(t){t.sortableIndex!==j(t)&&(d=!0)}),d&&(r("update"),r("sort")))),ue.forEach(function(t){T(t)}),s.animateAll()),ae=s),(n===o||l&&"clone"!==l.lastPutMode)&&de.forEach(function(t){t.parentNode&&t.parentNode.removeChild(t)})}},nullingGlobal:function(){this.isMultiDrag=pe=!1,de.length=0},destroyGlobal:function(){this._deselectMultiDrag(),f(document,"pointerup",this._deselectMultiDrag),f(document,"mouseup",this._deselectMultiDrag),f(document,"touchend",this._deselectMultiDrag),f(document,"keydown",this._checkKeyDown),f(document,"keyup",this._checkKeyUp)},_deselectMultiDrag:function(t){if(!(void 0!==pe&&pe||ae!==this.sortable||t&&P(t.target,this.options.draggable,this.sortable.el,!1)||t&&0!==t.button))for(;ue.length;){var e=ue[0];k(e,this.options.selectedClass,!1),ue.shift(),z({sortable:this.sortable,rootEl:this.sortable.el,name:"deselect",targetEl:e,originalEvent:t})}},_checkKeyDown:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!0)},_checkKeyUp:function(t){t.key===this.options.multiDragKey&&(this.multiDragKeyDown=!1)}},a(t,{pluginName:"multiDrag",utils:{select:function(t){var e=t.parentNode[K];e&&e.options.multiDrag&&!~ue.indexOf(t)&&(ae&&ae!==e&&(ae.multiDrag._deselectMultiDrag(),ae=e),k(t,e.options.selectedClass,!0),ue.push(t))},deselect:function(t){var e=t.parentNode[K],n=ue.indexOf(t);e&&e.options.multiDrag&&~n&&(k(t,e.options.selectedClass,!1),ue.splice(n,1))}},eventProperties:function(){var n=this,o=[],i=[];return ue.forEach(function(t){var e;o.push({multiDragElement:t,index:t.sortableIndex}),e=fe&&t!==le?-1:fe?j(t,":not(."+n.options.selectedClass+")"):j(t),i.push({multiDragElement:t,index:e})}),{items:r(ue),clones:[].concat(de),oldIndicies:o,newIndicies:i}},optionListeners:{multiDragKey:function(t){return"ctrl"===(t=t.toLowerCase())?t="Control":1<t.length&&(t=t.charAt(0).toUpperCase()+t.substr(1)),t}}})}),Ft});';import{existsSync as He,readFileSync as ba,writeFileSync as ya,rmSync as fl,mkdirSync as ur,copyFileSync as mr,readdirSync as hr}from"fs";import{resolve as fe}from"path";Xe();var te={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>',actions:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>'};function va(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=$e({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+je([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return $({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+lr()+Vt,css:cr,scripts:`${e}<script>${Yt}
1047
+ ${Qt}
1048
+ ${ir}
1049
+ ${pr}</script>`})}var ir=`
1050
1050
  (function(){
1051
1051
  function fmt(n) { return n == null ? '\u2014' : String(n); }
1052
1052
  async function refresh() {
@@ -1107,8 +1107,8 @@ ${cr}</script>`})}var sr=`
1107
1107
  refresh();
1108
1108
  // Refresh again after the main admin script has had a chance to mutate config.
1109
1109
  document.addEventListener('ax-config-saved', refresh);
1110
- })();`;function ir(){let t=qt().business?`<button data-tab="business">Business</button>
1111
- `:"";return lr.replace("__BUSINESS_TABS__",t)}var lr=`
1110
+ })();`;function lr(){let t=Ft().business?`<button data-tab="business">Business</button>
1111
+ `:"";return dr.replace("__BUSINESS_TABS__",t)}var dr=`
1112
1112
  <div id="peer-banner" class="peer-banner">
1113
1113
  <span class="label">Managing</span>
1114
1114
  <span class="name" id="peer-banner-name">\u2014</span>
@@ -1360,10 +1360,10 @@ ${cr}</script>`})}var sr=`
1360
1360
  </div>
1361
1361
  </details>
1362
1362
 
1363
- <div id="ch-chatapps-label">${je({label:"Chat apps"})}</div>
1363
+ <div id="ch-chatapps-label">${Le({label:"Chat apps"})}</div>
1364
1364
  <div class="ax-connectors" id="ch-chatapps"></div>
1365
1365
 
1366
- <div id="ch-devtools-label">${je({label:"Developer tools",rightHtml:'<span class="ax-pill">Send events from GitHub, GitLab, Sentry, etc.</span>'})}</div>
1366
+ <div id="ch-devtools-label">${Le({label:"Developer tools",rightHtml:'<span class="ax-pill">Send events from GitHub, GitLab, Sentry, etc.</span>'})}</div>
1367
1367
  <div class="ax-connectors" id="ch-devtools"></div>
1368
1368
 
1369
1369
  <!-- Active-channel configuration panes. One shows at a time; clicking
@@ -1502,7 +1502,7 @@ ${cr}</script>`})}var sr=`
1502
1502
  ${q({icon:te.mesh,title:"Mesh",lead:"Link this AgentX to other machines so they share work. Good for teams running AgentX on multiple laptops or a mix of laptop + server."})}
1503
1503
  <div id="mesh-hero" class="ax-mesh-hero"></div>
1504
1504
  ${J({persistKey:"mesh",bodyHtml:"<b>Do I need mesh?</b> Only if you're running AgentX in more than one place. Solo users on one laptop can skip this entirely."})}
1505
- ${je({label:"Connected peers"})}
1505
+ ${Le({label:"Connected peers"})}
1506
1506
  <div id="mesh-peers" class="ax-stack"></div>
1507
1507
  <div class="add-form">
1508
1508
  <h3>Add a peer</h3>
@@ -1529,7 +1529,7 @@ ${cr}</script>`})}var sr=`
1529
1529
  </section>
1530
1530
 
1531
1531
  <section id="tab-business" class="tab">
1532
- ${q({icon:te.tokens,title:"Business layer",lead:"Org chart, projects, and contact map \u2014 the data that drives PM gating and activity-graph attribution. Mirrors <code>agentx business</code>."})}
1532
+ ${q({icon:te.tokens,title:"Business layer",lead:"Org chart, projects, and contact map \u2014 the data that drives PM gating and activity-graph attribution. Same as agentx business in the terminal."})}
1533
1533
  ${J({persistKey:"business",bodyHtml:'<b>Three concepts.</b> The <b>org chart</b> is who reports to whom (<code>reportsTo</code>). <b>Projects</b> map an id to a PM and client (drives the PM gate and lets the activity graph attribute work to the right client). The <b>contact map</b> tells the activity graph which client a Telegram/WhatsApp chat belongs to \u2014 without it, free-text channels fall into the catch-all "internal" bucket. Editing here writes to <code>agentx.json</code>; restart the daemon (or POST /reload) for the change to take effect.'})}
1534
1534
 
1535
1535
  <div class="ax-stack" style="margin-top:14px">
@@ -1617,7 +1617,7 @@ ${cr}</script>`})}var sr=`
1617
1617
  </section>
1618
1618
 
1619
1619
  <section id="tab-boards-cfg" class="tab">
1620
- ${q({icon:te.tokens,title:"Kanban boards",lead:"Configure the boards rendered on the home page. Mirrors <code>agentx board add/edit/remove</code> + <code>agentx board column</code>. Source is GitLab today; backlog/wiki sources land when the schema unlocks them."})}
1620
+ ${q({icon:te.tokens,title:"Kanban boards",lead:"Configure the boards rendered on the home page. Same as agentx board add, edit, remove and column in the terminal. Source is GitLab today; backlog/wiki sources land when the schema unlocks them."})}
1621
1621
  ${J({persistKey:"boards-cfg",bodyHtml:'<b>Two layers.</b> A board points to one or more GitLab projects (<code>source.projects</code>) and optionally filters by a primary tool label. Inside each board, <b>columns</b> map drag-drop actions to scoped-labels (e.g. dropping a card on "Doing" adds <code>Status::Doing</code>). The default flow is Open \u2192 To Do \u2192 Doing \u2192 On Hold \u2192 Review \u2192 Closed; override per-board with the column controls below.'})}
1622
1622
 
1623
1623
  <div class="ax-stack" style="margin-top:14px">
@@ -1642,7 +1642,7 @@ ${cr}</script>`})}var sr=`
1642
1642
  </section>
1643
1643
 
1644
1644
  <section id="tab-actions" class="tab">
1645
- ${q({icon:te.actions,title:"Action registry",lead:"Reusable shell commands and HTTP calls. Workflows invoke them by id; the dashboard runs them on demand for smoke-tests. Mirrors <code>agentx actions</code>."})}
1645
+ ${q({icon:te.actions,title:"Action registry",lead:"Reusable shell commands and HTTP calls. Workflows invoke them by id; the dashboard runs them on demand for smoke-tests. Same as agentx actions in the terminal."})}
1646
1646
  ${J({persistKey:"actions",bodyHtml:"<b>Two flavors.</b> <code>shell</code> runs a templated command on the daemon host (cwd + extra env vars supported). <code>http</code> calls a URL with templated method/headers/body. Inputs are typed (string / number / boolean) and fill <code>{{name}}</code> markers; <code>$VAR</code> resolves against the daemon's process env. Output capped at 32KB."})}
1647
1647
 
1648
1648
  <div class="ax-stack" style="margin-top:14px">
@@ -1745,7 +1745,7 @@ ${cr}</script>`})}var sr=`
1745
1745
  <div class="hint-block">Every setting is documented in the <code>docs/reference/config.md</code> reference. Invalid JSON is refused; schema-level errors only surface after the daemon tries to use the new config.</div>
1746
1746
  </section>
1747
1747
  </main>
1748
- `,dr=`
1748
+ `,cr=`
1749
1749
 
1750
1750
  /* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
1751
1751
  nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
@@ -1953,7 +1953,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
1953
1953
  .peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
1954
1954
  padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
1955
1955
  .peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
1956
- `,cr=`
1956
+ `,pr=`
1957
1957
  const $ = (id) => document.getElementById(id);
1958
1958
  let state = null;
1959
1959
 
@@ -4760,11 +4760,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
4760
4760
  })();
4761
4761
 
4762
4762
  refresh();
4763
- `;function ya(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(xa({peers:a,localToken:n}))}async function wa(t,e){let a=at();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function ka(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Cr(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await hr(t),r={"GET /api/admin/state":()=>fr(),"POST /api/admin/agents":()=>kr(n),"PATCH /api/admin/agents":()=>_r(n),"DELETE /api/admin/agents":()=>Er(n),"POST /api/admin/agents/access":()=>xr(n),"POST /api/admin/channels/telegram":()=>Sr(n),"DELETE /api/admin/channels/telegram":()=>Jr(n),"POST /api/admin/channels/telegram/toggle":()=>Vr(n),"POST /api/admin/crons":()=>Yr(n),"DELETE /api/admin/crons":()=>Qr(n),"POST /api/admin/config/raw":()=>Zr(n),"GET /api/admin/tokens":()=>vr(),"POST /api/admin/tokens":()=>br(n),"DELETE /api/admin/tokens":()=>yr(n),"POST /api/admin/agents/test":()=>wr(n),"POST /api/admin/agents/integrations":()=>Lr(n),"DELETE /api/admin/agents/integrations":()=>Rr(n),"PATCH /api/admin/agents/integrations":()=>Pr(n),"PATCH /api/admin/channels/telegram":()=>Tr(n),"POST /api/admin/channels/slack":()=>qr(n),"POST /api/admin/channels/slack/toggle":()=>Fr(n),"POST /api/admin/channels/discord":()=>Ur(n),"POST /api/admin/channels/discord/toggle":()=>Wr(n),"POST /api/admin/channels/gitlab":()=>Gr(n),"POST /api/admin/channels/gitlab/toggle":()=>Xr(n),"GET /api/admin/channels/whatsapp/state":()=>ye("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>ye("/webrtc/history"),"POST /api/admin/actions":()=>mo(n),"DELETE /api/admin/actions":()=>ho(n),"POST /api/admin/actions/run":()=>go(n),"GET /api/admin/channels/whatsapp/chats":()=>ye("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>ye("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>ne("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Kr(n),"POST /api/admin/webhooks":()=>Dr(n),"PATCH /api/admin/webhooks":()=>Or(n),"DELETE /api/admin/webhooks":()=>zr(n),"POST /api/admin/mesh/peers":()=>Hr(n),"DELETE /api/admin/mesh/peers":()=>Nr(n),"POST /api/admin/mesh/toggle":()=>Br(n),"GET /api/admin/files":()=>Ar(t),"GET /api/admin/files/read":()=>Mr(t),"PUT /api/admin/files":()=>Ir(n),"POST /api/admin/files/skill":()=>$r(n),"DELETE /api/admin/files/skill":()=>jr(n),"POST /api/admin/business/orgchart":()=>eo(n),"DELETE /api/admin/business/orgchart":()=>to(n),"POST /api/admin/business/project":()=>ao(n),"DELETE /api/admin/business/project":()=>oo(n),"POST /api/admin/business/client":()=>no(n),"DELETE /api/admin/business/client":()=>ro(n),"POST /api/admin/business/contact":()=>so(n),"DELETE /api/admin/business/contact":()=>io(n),"POST /api/admin/boards":()=>lo(n),"DELETE /api/admin/boards":()=>co(n),"POST /api/admin/boards/columns":()=>po(n),"DELETE /api/admin/boards/columns":()=>uo(n),"POST /api/admin/notifications":()=>xo(n),"POST /api/admin/screen":()=>vo(n),"POST /api/admin/webhooks/triggers":()=>bo(n),"POST /api/admin/mesh/health":()=>fo(n),"GET /api/admin/projects":()=>ye("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>ne("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>ne("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>ne("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>ne("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>ne("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>ne("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>ne("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>ne("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){et(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();et(e,200,i)}catch(n){et(e,400,{error:n.message||"admin op failed"})}}function et(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function hr(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function gr(t){let e=ge(process.cwd(),t);if(!Oe(e))return[];let a=[];for(let n of mr(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(va(ge(e,n.name),"utf-8")))}catch{}return a}function at(){let t=ge(process.cwd(),"agentx.json");return Oe(t)?JSON.parse(va(t,"utf-8")):null}function fr(){let t=at();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([d,u])=>({id:d,name:u.name,tier:u.tier,model:u.model,mentions:u.mentions||[],workspace:u.workspace,access:u.access||"private",systemPrompt:u.systemPrompt||"",maxConcurrent:u.maxConcurrent??1,maxExecutionMinutes:u.maxExecutionMinutes??20,permissionMode:u.permissionMode||"default",integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(g=>{let f=g.credentials||{},b={};for(let[x,y]of Object.entries(f))typeof y=="string"&&/^[A-Z][A-Z0-9_]*$/.test(y)?b[x]=process.env[y]?"set":"unset":typeof y=="string"&&(b[x]="literal");return{kind:g.kind,label:g.label,enabled:g.enabled!==!1,credentials:f,credStatus:b,metadata:g.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([d,u])=>({id:d,botUsername:u.botUsername||"",agentBinding:u.agentBinding||"",botTokenRef:u.token||""}))},r={enabled:!!t.channels?.slack?.enabled,botTokenRef:t.channels?.slack?.botToken||"",appTokenRef:t.channels?.slack?.appToken||"",agentBinding:t.channels?.slack?.agentBinding||""},o={enabled:!!t.channels?.discord?.enabled,tokenRef:t.channels?.discord?.token||"",agentBinding:t.channels?.discord?.agentBinding||""},s={enabled:!!t.channels?.gitlab?.enabled,host:t.channels?.gitlab?.host||"",webhookPort:t.channels?.gitlab?.webhookPort||18810,tokenRef:t.channels?.gitlab?.token||"",routeCount:Array.isArray(t.channels?.gitlab?.routes)?t.channels.gitlab.routes.length:0,agentMappingCount:Array.isArray(t.channels?.gitlab?.agentMappings)?t.channels.gitlab.agentMappings.length:0},i={enabled:!!t.channels?.whatsapp?.enabled,sessionDir:t.channels?.whatsapp?.sessionDir||".agentx/whatsapp-sessions",routeCount:Array.isArray(t.channels?.whatsapp?.routes)?t.channels.whatsapp.routes.length:0},l=Object.entries(t.crons||{}).map(([d,u])=>({id:d,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(d=>({id:d.id,source:d.source,agentId:d.agentId,secretEnv:d.secretEnv||"",description:d.description||"",enabled:d.enabled!==!1,triggers:d.triggers&&typeof d.triggers=="object"?d.triggers:{},defaultWorkflow:d.defaultWorkflow||""})):[],p={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(d=>({url:d.url,name:d.name,hasToken:!!d.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},m=t.dashboard?.daemonUrl||"http://localhost:18800",h=t.business||{},_={enabled:!!h.enabled,timezone:h.timezone||"UTC",orgChart:h.orgChart||{},projects:Array.isArray(h.projects)?h.projects:[],contactMap:Array.isArray(h.contactMap)?h.contactMap:[],clients:h.clients&&typeof h.clients=="object"?h.clients:{}},S=t.notifications||{},w={longTaskThreshold:S.longTaskThreshold??30,destination:S.destination||null,on:{taskComplete:S.on?.taskComplete!==!1,taskError:S.on?.taskError!==!1,taskQueued:!!S.on?.taskQueued},local:Pt(S.local),ntfy:sa(t.channels?.ntfy)},E=[];try{E=gr(".agentx/actions").filter(u=>u&&typeof u=="object"&&u.id).map(u=>({id:u.id,title:u.title,kind:u.kind,description:u.description||"",inputs:Array.isArray(u.inputs)?u.inputs:[],timeoutMs:u.timeoutMs??3e4,command:u.kind==="shell"?u.command:void 0,url:u.kind==="http"?u.url:void 0,method:u.kind==="http"?u.method:void 0})).sort((u,g)=>u.id.localeCompare(g.id))}catch{}let T=(Array.isArray(t.boards)?t.boards:[]).map(d=>({id:d.id,name:d.name,source:d.source||{type:"gitlab",projects:[]},primaryToolLabel:d.primaryToolLabel||"",timeRangeDays:d.timeRangeDays??30,closedWindowDays:d.closedWindowDays??30,columns:Array.isArray(d.columns)?d.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,crons:l,webhooks:c,mesh:p,daemonUrl:m,nodeName:t.node?.name,business:_,boards:T,notifications:w,screen:Xt(t.screen),actions:E}}function xr(t){let e=String(t?.id||"").trim(),a=t?.access==="public"?"public":"private";if(!e)throw new Error("Agent id is required.");let{summary:n}=C(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);return r.agents[e].access=a,`agent "${e}" is now ${a}`});return{summary:n}}function vr(){return new ae().list().map(t=>({id:t.id,name:t.name,prefix:t.prefix,scopes:t.scopes,createdAt:t.createdAt,expiresAt:t.expiresAt,revokedAt:t.revokedAt,lastUsedAt:t.lastUsedAt}))}function br(t){let e=String(t?.name||"").trim(),a=Array.isArray(t?.scopes)?t.scopes.map(String):[],n=t?.expiresInDays?Number(t.expiresInDays):void 0,{token:r,record:o}=new ae().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function yr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new ae().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function wr(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let p=K();r=p.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=p.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),c;try{c=JSON.parse(l)}catch{c={content:l}}if(!i.ok)throw new Error(c?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:c}}function kr(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(t?.tier)?t.tier:"claude-code",r=Ea(t?.triggerWords),o=t?.model?String(t.model).trim():void 0,s=t?.personality?String(t.personality).trim():void 0;if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Agent id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Agent name is required.");if(r.length===0)throw new Error("At least one trigger word is required.");let i=ge(process.cwd(),"agents",e),{summary:l}=C(p=>{if(p.agents=p.agents||{},p.agents[e])throw new Error(`Agent "${e}" already exists.`);let m={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(m.model=o),s&&(m.systemPrompt=s.slice(0,400)),p.agents[e]=m,`added agent "${e}"`}),c=ge(i,"CLAUDE.md");if(!Oe(c))try{pr(i,{recursive:!0}),ba(c,`# ${a}
4763
+ `;function wa(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(va({peers:a,localToken:n}))}async function ka(t,e){let a=nt();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function _a(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Ar(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await gr(t),r={"GET /api/admin/state":()=>xr(),"POST /api/admin/agents":()=>_r(n),"PATCH /api/admin/agents":()=>Er(n),"DELETE /api/admin/agents":()=>Sr(n),"POST /api/admin/agents/access":()=>vr(n),"POST /api/admin/channels/telegram":()=>Tr(n),"DELETE /api/admin/channels/telegram":()=>Vr(n),"POST /api/admin/channels/telegram/toggle":()=>Yr(n),"POST /api/admin/crons":()=>Qr(n),"DELETE /api/admin/crons":()=>Zr(n),"POST /api/admin/config/raw":()=>eo(n),"GET /api/admin/tokens":()=>br(),"POST /api/admin/tokens":()=>yr(n),"DELETE /api/admin/tokens":()=>wr(n),"POST /api/admin/agents/test":()=>kr(n),"POST /api/admin/agents/integrations":()=>Rr(n),"DELETE /api/admin/agents/integrations":()=>Pr(n),"PATCH /api/admin/agents/integrations":()=>Dr(n),"PATCH /api/admin/channels/telegram":()=>Cr(n),"POST /api/admin/channels/slack":()=>Fr(n),"POST /api/admin/channels/slack/toggle":()=>Ur(n),"POST /api/admin/channels/discord":()=>Wr(n),"POST /api/admin/channels/discord/toggle":()=>Gr(n),"POST /api/admin/channels/gitlab":()=>Xr(n),"POST /api/admin/channels/gitlab/toggle":()=>Kr(n),"GET /api/admin/channels/whatsapp/state":()=>we("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>we("/webrtc/history"),"POST /api/admin/actions":()=>ho(n),"DELETE /api/admin/actions":()=>go(n),"POST /api/admin/actions/run":()=>fo(n),"GET /api/admin/channels/whatsapp/chats":()=>we("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>we("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>ne("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Jr(n),"POST /api/admin/webhooks":()=>Or(n),"PATCH /api/admin/webhooks":()=>Hr(n),"DELETE /api/admin/webhooks":()=>qr(n),"POST /api/admin/mesh/peers":()=>Nr(n),"DELETE /api/admin/mesh/peers":()=>Br(n),"POST /api/admin/mesh/toggle":()=>zr(n),"GET /api/admin/files":()=>Mr(t),"GET /api/admin/files/read":()=>Ir(t),"PUT /api/admin/files":()=>$r(n),"POST /api/admin/files/skill":()=>jr(n),"DELETE /api/admin/files/skill":()=>Lr(n),"POST /api/admin/business/orgchart":()=>to(n),"DELETE /api/admin/business/orgchart":()=>ao(n),"POST /api/admin/business/project":()=>no(n),"DELETE /api/admin/business/project":()=>so(n),"POST /api/admin/business/client":()=>ro(n),"DELETE /api/admin/business/client":()=>oo(n),"POST /api/admin/business/contact":()=>io(n),"DELETE /api/admin/business/contact":()=>lo(n),"POST /api/admin/boards":()=>co(n),"DELETE /api/admin/boards":()=>po(n),"POST /api/admin/boards/columns":()=>uo(n),"DELETE /api/admin/boards/columns":()=>mo(n),"POST /api/admin/notifications":()=>vo(n),"POST /api/admin/screen":()=>bo(n),"POST /api/admin/webhooks/triggers":()=>yo(n),"POST /api/admin/mesh/health":()=>xo(n),"GET /api/admin/projects":()=>we("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>ne("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>ne("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>ne("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>ne("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>ne("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>ne("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>ne("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>ne("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){tt(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();tt(e,200,i)}catch(n){tt(e,400,{error:n.message||"admin op failed"})}}function tt(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function gr(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function fr(t){let e=fe(process.cwd(),t);if(!He(e))return[];let a=[];for(let n of hr(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(ba(fe(e,n.name),"utf-8")))}catch{}return a}function nt(){let t=fe(process.cwd(),"agentx.json");return He(t)?JSON.parse(ba(t,"utf-8")):null}function xr(){let t=nt();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([d,u])=>({id:d,name:u.name,tier:u.tier,model:u.model,mentions:u.mentions||[],workspace:u.workspace,access:u.access||"private",systemPrompt:u.systemPrompt||"",maxConcurrent:u.maxConcurrent??1,maxExecutionMinutes:u.maxExecutionMinutes??20,permissionMode:u.permissionMode||"default",integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(g=>{let f=g.credentials||{},b={};for(let[x,y]of Object.entries(f))typeof y=="string"&&/^[A-Z][A-Z0-9_]*$/.test(y)?b[x]=process.env[y]?"set":"unset":typeof y=="string"&&(b[x]="literal");return{kind:g.kind,label:g.label,enabled:g.enabled!==!1,credentials:f,credStatus:b,metadata:g.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([d,u])=>({id:d,botUsername:u.botUsername||"",agentBinding:u.agentBinding||"",botTokenRef:u.token||""}))},r={enabled:!!t.channels?.slack?.enabled,botTokenRef:t.channels?.slack?.botToken||"",appTokenRef:t.channels?.slack?.appToken||"",agentBinding:t.channels?.slack?.agentBinding||""},o={enabled:!!t.channels?.discord?.enabled,tokenRef:t.channels?.discord?.token||"",agentBinding:t.channels?.discord?.agentBinding||""},s={enabled:!!t.channels?.gitlab?.enabled,host:t.channels?.gitlab?.host||"",webhookPort:t.channels?.gitlab?.webhookPort||18810,tokenRef:t.channels?.gitlab?.token||"",routeCount:Array.isArray(t.channels?.gitlab?.routes)?t.channels.gitlab.routes.length:0,agentMappingCount:Array.isArray(t.channels?.gitlab?.agentMappings)?t.channels.gitlab.agentMappings.length:0},i={enabled:!!t.channels?.whatsapp?.enabled,sessionDir:t.channels?.whatsapp?.sessionDir||".agentx/whatsapp-sessions",routeCount:Array.isArray(t.channels?.whatsapp?.routes)?t.channels.whatsapp.routes.length:0},l=Object.entries(t.crons||{}).map(([d,u])=>({id:d,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(d=>({id:d.id,source:d.source,agentId:d.agentId,secretEnv:d.secretEnv||"",description:d.description||"",enabled:d.enabled!==!1,triggers:d.triggers&&typeof d.triggers=="object"?d.triggers:{},defaultWorkflow:d.defaultWorkflow||""})):[],p={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(d=>({url:d.url,name:d.name,hasToken:!!d.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},m=t.dashboard?.daemonUrl||"http://localhost:18800",h=t.business||{},_={enabled:!!h.enabled,timezone:h.timezone||"UTC",orgChart:h.orgChart||{},projects:Array.isArray(h.projects)?h.projects:[],contactMap:Array.isArray(h.contactMap)?h.contactMap:[],clients:h.clients&&typeof h.clients=="object"?h.clients:{}},S=t.notifications||{},w={longTaskThreshold:S.longTaskThreshold??30,destination:S.destination||null,on:{taskComplete:S.on?.taskComplete!==!1,taskError:S.on?.taskError!==!1,taskQueued:!!S.on?.taskQueued},local:Dt(S.local),ntfy:ia(t.channels?.ntfy)},E=[];try{E=fr(".agentx/actions").filter(u=>u&&typeof u=="object"&&u.id).map(u=>({id:u.id,title:u.title,kind:u.kind,description:u.description||"",inputs:Array.isArray(u.inputs)?u.inputs:[],timeoutMs:u.timeoutMs??3e4,command:u.kind==="shell"?u.command:void 0,url:u.kind==="http"?u.url:void 0,method:u.kind==="http"?u.method:void 0})).sort((u,g)=>u.id.localeCompare(g.id))}catch{}let T=(Array.isArray(t.boards)?t.boards:[]).map(d=>({id:d.id,name:d.name,source:d.source||{type:"gitlab",projects:[]},primaryToolLabel:d.primaryToolLabel||"",timeRangeDays:d.timeRangeDays??30,closedWindowDays:d.closedWindowDays??30,columns:Array.isArray(d.columns)?d.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,crons:l,webhooks:c,mesh:p,daemonUrl:m,nodeName:t.node?.name,business:_,boards:T,notifications:w,screen:Kt(t.screen),actions:E}}function vr(t){let e=String(t?.id||"").trim(),a=t?.access==="public"?"public":"private";if(!e)throw new Error("Agent id is required.");let{summary:n}=C(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);return r.agents[e].access=a,`agent "${e}" is now ${a}`});return{summary:n}}function br(){return new ae().list().map(t=>({id:t.id,name:t.name,prefix:t.prefix,scopes:t.scopes,createdAt:t.createdAt,expiresAt:t.expiresAt,revokedAt:t.revokedAt,lastUsedAt:t.lastUsedAt}))}function yr(t){let e=String(t?.name||"").trim(),a=Array.isArray(t?.scopes)?t.scopes.map(String):[],n=t?.expiresInDays?Number(t.expiresInDays):void 0,{token:r,record:o}=new ae().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function wr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new ae().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function kr(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let p=K();r=p.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=p.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),c;try{c=JSON.parse(l)}catch{c={content:l}}if(!i.ok)throw new Error(c?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:c}}function _r(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(t?.tier)?t.tier:"claude-code",r=Sa(t?.triggerWords),o=t?.model?String(t.model).trim():void 0,s=t?.personality?String(t.personality).trim():void 0;if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Agent id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Agent name is required.");if(r.length===0)throw new Error("At least one trigger word is required.");let i=fe(process.cwd(),"agents",e),{summary:l}=C(p=>{if(p.agents=p.agents||{},p.agents[e])throw new Error(`Agent "${e}" already exists.`);let m={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(m.model=o),s&&(m.systemPrompt=s.slice(0,400)),p.agents[e]=m,`added agent "${e}"`}),c=fe(i,"CLAUDE.md");if(!He(c))try{ur(i,{recursive:!0}),ya(c,`# ${a}
4764
4764
 
4765
4765
  ${s||"You are "+a+"."}
4766
- `)}catch{}return{summary:l}}function _r(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=C(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);let o=r.agents[e];return typeof a.name=="string"&&a.name.trim()&&(o.name=a.name.trim()),typeof a.model=="string"&&(o.model=a.model.trim()||void 0),typeof a.tier=="string"&&["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(a.tier)&&(o.tier=a.tier),typeof a.systemPrompt=="string"&&(o.systemPrompt=a.systemPrompt.trim()||void 0),Array.isArray(a.mentions)?o.mentions=a.mentions.map(s=>String(s).trim()).filter(Boolean):typeof a.triggerWords=="string"&&(o.mentions=Ea(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function Er(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=C(n=>{if(!n.agents||!n.agents[e])throw new Error(`Agent "${e}" not found.`);if(delete n.agents[e],n.channels?.telegram?.accounts)for(let r of Object.keys(n.channels.telegram.accounts))n.channels.telegram.accounts[r]?.agentBinding===e&&(n.channels.telegram.accounts[r].agentBinding="");return`removed agent "${e}"`});return{summary:a}}function Sr(t){let e=String(t?.id||"").trim(),a=String(t?.agentBinding||"").trim(),n=String(t?.botUsername||"").trim(),r=String(t?.botTokenEnv||"").trim();if(!e)throw new Error("Account id is required.");if(!a)throw new Error("Choose an agent to bind this account to.");if(!r)throw new Error("Bot token env-var name is required (e.g. TG_SUPPORT_BOT_TOKEN).");let{summary:o}=C(s=>{if(s.channels=s.channels||{},s.channels.telegram=s.channels.telegram||{enabled:!0,accounts:{},policy:{dm:"pair",group:"mention-required"}},s.channels.telegram.enabled=!0,s.channels.telegram.accounts=s.channels.telegram.accounts||{},s.channels.telegram.accounts[e])throw new Error(`Telegram account "${e}" already exists.`);if(!s.agents?.[a])throw new Error(`Unknown agent "${a}".`);return s.channels.telegram.accounts[e]={token:"${"+r+"}",agentBinding:a},`added telegram account "${e}"`});return{summary:o,hint:`Add ${r}=<bot-token> to your .env file.`}}function Tr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=C(r=>{let o=r.channels?.telegram?.accounts?.[e];if(!o)throw new Error(`Account "${e}" not found.`);if(typeof a.agentBinding=="string"&&a.agentBinding.trim()){if(!r.agents?.[a.agentBinding])throw new Error(`Unknown agent "${a.agentBinding}".`);o.agentBinding=a.agentBinding.trim()}return typeof a.botUsername=="string"&&(o.botUsername=a.botUsername.trim()),typeof a.botTokenEnv=="string"&&a.botTokenEnv.trim()&&(o.token="${"+a.botTokenEnv.trim()+"}"),`updated telegram account "${e}"`});return{summary:n}}async function ye(t){let{url:e,headers:a}=nt(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function ne(t,e){let{url:a,headers:n}=nt(),r=await fetch(a+t,{method:"POST",headers:{...n,"Content-Type":"application/json"},body:JSON.stringify(e||{})}),o=await r.text();if(!r.ok)throw new Error(`daemon ${r.status}: ${o.slice(0,200)}`);try{return JSON.parse(o)}catch{return{raw:o}}}async function Cr(t,e){try{let{url:a,headers:n}=nt(),r=await fetch(a+e,{headers:n}),o=await r.text();t.writeHead(r.status,{"Content-Type":r.headers.get("content-type")||"image/svg+xml","Cache-Control":"no-store"}),t.end(o)}catch(a){t.writeHead(502,{"Content-Type":"text/plain; charset=utf-8"}),t.end("daemon unreachable: "+(a?.message||"unknown"))}}function nt(){let t="http://127.0.0.1:18800",e={};try{let a=K();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function we(t){let a=at()?.agents?.[t];if(!a)throw new Error(`Unknown agent "${t}".`);if(!a.workspace)throw new Error(`Agent "${t}" has no workspace configured.`);return a.workspace}function tt(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Ar(t){let e=tt(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=me(we(e));return{agentId:e,...a}}function Mr(t){let e=tt(t,"agent").trim(),a=tt(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Se(we(e),a)}function Ir(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=Te(we(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function $r(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=Ce(we(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function jr(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=Ae(we(e),a);return{summary:`removed skill "${a}"`,...n}}function Lr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a)throw new Error("kind is required");if(!n)throw new Error("label is required");let r={},o=t?.credentials||{};for(let l of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[l];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${l} must be uppercase identifier (got "${c}")`);r[l]=c.trim()}}if(o.auth==="keyring"&&(r.auth="keyring"),typeof o.sessionDir=="string"&&o.sessionDir.trim()&&(r.sessionDir=o.sessionDir.trim()),Object.keys(r).length===0)throw new Error("at least one credential field required");let s={};for(let[l,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[l]=c);let{summary:i}=C(l=>{if(!l.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(l.agents[e].integrations=Array.isArray(l.agents[e].integrations)?l.agents[e].integrations:[],l.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return l.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:i}}function Rr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let{summary:r}=C(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let i=s.integrations||[],l=i.findIndex(c=>c.kind===a&&c.label===n);if(l===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return i.splice(l,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function Pr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let r=t?.patch||{},{summary:o}=C(s=>{let i=s.agents?.[e];if(!i)throw new Error(`Unknown agent "${e}"`);let c=(i.integrations||[]).find(p=>p.kind===a&&p.label===n);if(!c)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(c.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(c.metadata={...c.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var _a=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function Dr(t){let e=String(t?.id||"").trim(),a=String(t?.source||"").trim(),n=String(t?.agentId||"").trim(),r=String(t?.secretEnv||"").trim(),o=String(t?.description||"").trim(),s=String(t?.node||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Webhook id must be lowercase (letters, digits, -, _).");if(!_a.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:i}=C(l=>{if(s){if(!(l.mesh?.peers||[]).find(m=>m.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(p=>p.id===e))throw new Error(`Webhook "${e}" already exists.`);let c={id:e,source:a,agentId:n,enabled:!0};return r&&(c.secretEnv=r),o&&(c.description=o),s&&(c.node=s),l.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function Or(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=C(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&_a.includes(a.source)&&(o.source=a.source),typeof a.agentId=="string"&&a.agentId.trim()){if(!r.agents?.[a.agentId])throw new Error(`Unknown agent "${a.agentId}".`);o.agentId=a.agentId.trim()}return typeof a.secretEnv=="string"&&(o.secretEnv=a.secretEnv.trim()||void 0),typeof a.description=="string"&&(o.description=a.description.trim()||void 0),typeof a.enabled=="boolean"&&(o.enabled=a.enabled),`updated webhook "${e}"`});return{summary:n}}function Hr(t){let e=String(t?.url||"").trim().replace(/\/+$/,""),a=String(t?.name||"").trim(),n=String(t?.token||"").trim()||void 0;if(!e||!/^https?:\/\//.test(e))throw new Error("Peer URL must start with http:// or https://");if(!a)throw new Error("Peer name is required.");let{summary:r}=C(o=>{if(o.mesh=o.mesh||{enabled:!0,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},o.mesh.enabled=!0,o.mesh.peers=Array.isArray(o.mesh.peers)?o.mesh.peers:[],o.mesh.peers.find(i=>i.url===e))throw new Error(`Peer at ${e} already registered.`);let s={url:e,name:a};return n&&(s.token=n),o.mesh.peers.push(s),`added mesh peer "${a}"`});return{summary:r}}function Nr(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=C(n=>{let r=(n.mesh?.peers||[]).length;if(n.mesh=n.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.peers=(n.mesh.peers||[]).filter(o=>o.url.replace(/\/+$/,"")!==e),n.mesh.peers.length===r)throw new Error(`Peer at ${e} not found.`);return`removed mesh peer ${e}`});return{summary:a}}function Br(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.mesh=n.mesh||{enabled:e,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.enabled=e,`mesh ${e?"enabled":"disabled"}`));return{summary:a}}function zr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=C(n=>{let r=(n.webhooks||[]).length;if(n.webhooks=(n.webhooks||[]).filter(o=>o.id!==e),n.webhooks.length===r)throw new Error(`Webhook "${e}" not found.`);return`removed webhook "${e}"`});return{summary:a}}function qr(t){let e=String(t?.botTokenEnv||"").trim(),a=String(t?.appTokenEnv||"").trim(),n=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. SLACK_BOT_TOKEN).");if(!a)throw new Error("App-level token env-var name is required (e.g. SLACK_APP_TOKEN).");let{summary:r}=C(o=>{if(o.channels=o.channels||{},o.channels.slack=o.channels.slack||{enabled:!1},o.channels.slack.enabled=!0,o.channels.slack.botToken="${"+e+"}",o.channels.slack.appToken="${"+a+"}",n){if(!o.agents?.[n])throw new Error(`Unknown agent "${n}".`);o.channels.slack.agentBinding=n}return"configured slack connector"});return{summary:r,hint:`Add ${e}=xoxb-\u2026 and ${a}=xapp-\u2026 to your .env.`}}function Fr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.slack=n.channels.slack||{enabled:!1},n.channels.slack.enabled=e,`slack ${e?"enabled":"disabled"}`));return{summary:a}}function Ur(t){let e=String(t?.tokenEnv||"").trim(),a=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. DISCORD_BOT_TOKEN).");let{summary:n}=C(r=>{if(r.channels=r.channels||{},r.channels.discord=r.channels.discord||{enabled:!1},r.channels.discord.enabled=!0,r.channels.discord.token="${"+e+"}",a){if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);r.channels.discord.agentBinding=a}return"configured discord connector"});return{summary:n,hint:`Add ${e}=<bot-token> to your .env.`}}function Wr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.discord=n.channels.discord||{enabled:!1},n.channels.discord.enabled=e,`discord ${e?"enabled":"disabled"}`));return{summary:a}}function Gr(t){let e=String(t?.host||"").trim().replace(/\/+$/,""),a=String(t?.tokenEnv||"").trim(),n=parseInt(String(t?.webhookPort||"18810"),10);if(!e||!/^https?:\/\//.test(e))throw new Error("Host must start with http:// or https://");if(!a)throw new Error("Admin token env-var name is required (e.g. GITLAB_TOKEN).");if(!Number.isFinite(n)||n<1||n>65535)throw new Error("Webhook port must be between 1 and 65535.");let{summary:r}=C(o=>(o.channels=o.channels||{},o.channels.gitlab=o.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},o.channels.gitlab.enabled=!0,o.channels.gitlab.host=e,o.channels.gitlab.token="${"+a+"}",o.channels.gitlab.webhookPort=n,"configured gitlab connector"));return{summary:r,hint:`Add ${a}=<personal-access-token> to your .env. Per-project routes + per-agent tokens stay in the Advanced JSON editor.`}}function Xr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.gitlab=n.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},n.channels.gitlab.enabled=e,`gitlab ${e?"enabled":"disabled"}`));return{summary:a}}async function Kr(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-GC3FQKXY.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(i){throw new Error(`Invalid cron: ${i.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let i=0;i<3;i++)s=a(e,s,r),o.push(s.toISOString())}catch(i){throw new Error(`Cron preview failed: ${i.message}`)}return{human:n,next:o,timezone:r}}function Jr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=C(n=>{if(!n.channels?.telegram?.accounts?.[e])throw new Error(`Account "${e}" not found.`);return delete n.channels.telegram.accounts[e],`removed telegram account "${e}"`});return{summary:a}}function Vr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.telegram=n.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},n.channels.telegram.enabled=e,`telegram ${e?"enabled":"disabled"}`));return{summary:a}}function Yr(t){let e=String(t?.id||"").trim(),a=String(t?.schedule||"").trim(),n=String(t?.agent||"").trim(),r=String(t?.prompt||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Cron id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Cron expression is required (e.g. '0 9 * * 1' for Mondays at 9am).");if(!n)throw new Error("Pick an agent to run this schedule.");if(!r)throw new Error("A prompt is required (what should the agent do?).");let{summary:o}=C(s=>{if(s.crons=s.crons||{},s.crons[e])throw new Error(`Cron "${e}" already exists.`);if(!s.agents?.[n])throw new Error(`Unknown agent "${n}".`);return s.crons[e]={schedule:a,agent:n,prompt:r,enabled:!0},`added cron "${e}"`});return{summary:o}}function Qr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=C(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function Zr(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=ge(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Oe(n))try{ur(n,r)}catch{}ba(n,JSON.stringify(a,null,2)+`
4767
- `,"utf-8");try{let s=K().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function Ea(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function eo(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=C(c=>(c.business=c.business||{},c.business.orgChart=c.business.orgChart||{},c.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function to(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=C(n=>{if(!n.business?.orgChart||!(e in n.business.orgChart))throw new Error(`no orgChart entry for "${e}"`);return delete n.business.orgChart[e],`orgChart "${e}" removed`});return{summary:a}}async function ao(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let a=t?.pm?String(t.pm).trim():"",n=t?.client?String(t.client).trim():"",{summary:r}=C(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(l=>l.id===e),i={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...i}:o.business.projects.push(i),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function no(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let a=String(t?.kind||"").trim();if(a&&!["client","internal","own"].includes(a))throw new Error("kind must be client, internal or own");let n=String(t?.respondWithin||"").trim();if(n&&!/^\d+\s*[mhd]$/.test(n))throw new Error('respondWithin must look like "4h", "90m" or "2d"');let r=Array.isArray(t?.standing)?t.standing.map(s=>String(s).trim()).filter(Boolean):String(t?.standing||"").split(",").map(s=>s.trim()).filter(Boolean),{summary:o}=C(s=>{s.business=s.business||{},s.business.clients=s.business.clients||{};let i=!!s.business.clients[e];return s.business.clients[e]={...s.business.clients[e]||{},...t?.name?{name:String(t.name).trim()}:{},...a?{kind:a}:{},...n?{respondWithin:n}:{},standing:r},i?`client "${e}" updated`:`client "${e}" configured`});return{summary:o}}async function ro(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let{summary:a}=C(n=>{if(!n.business?.clients?.[e])throw new Error(`no client override "${e}"`);return delete n.business.clients[e],`client "${e}" reset to defaults`});return{summary:a}}async function oo(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=C(n=>{let r=n.business?.projects||[],o=r.length;if(n.business.projects=r.filter(s=>s.id!==e),n.business.projects.length===o)throw new Error(`no project "${e}"`);return`project "${e}" removed`});return{summary:a}}async function so(t){let e=String(t?.client||"").trim();if(!e)throw new Error("client required");if(!t?.chatId&&!t?.username&&!t?.senderId)throw new Error("one of chatId / username / senderId required");let{summary:a}=C(n=>{n.business=n.business||{},n.business.contactMap=n.business.contactMap||[];let r={client:e};t?.channel&&(r.channel=String(t.channel)),t?.chatId&&(r.chatId=String(t.chatId)),t?.username&&(r.username=String(t.username)),t?.senderId&&(r.senderId=String(t.senderId)),t?.project&&(r.project=String(t.project)),t?.displayName&&(r.displayName=String(t.displayName)),n.business.contactMap.push(r);let o=r.chatId||r.username||r.senderId;return`contact ${r.channel?r.channel+"/":""}${o} \u2192 ${e} added`});return{summary:a}}async function io(t){let a=["channel","chatId","username","senderId"].filter(r=>t?.[r]);if(a.length===0)throw new Error("at least one filter (channel/chatId/username/senderId) required");let{summary:n}=C(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(i=>{for(let l of a)if(i[l]!==t[l])return!0;return!1}),r.business.contactMap.length===s)throw new Error("no matching contact entry");return`${s-r.business.contactMap.length} contact entry/entries removed`});return{summary:n}}async function lo(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=C(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let c=l.boards.findIndex(m=>m.id===e),p={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(p.primaryToolLabel=r),c>=0){let m=l.boards[c];return l.boards[c]={...m,...p,columns:m.columns,labels:m.labels},`board "${e}" updated`}return l.boards.push(p),`board "${e}" added`});return{summary:i}}async function co(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=C(n=>{let r=Array.isArray(n.boards)?n.boards:[],o=r.length;if(n.boards=r.filter(s=>s.id!==e),n.boards.length===o)throw new Error(`board "${e}" not found`);return`board "${e}" removed`});return{summary:a}}async function po(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=C(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(m=>m.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let c={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");c.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");c.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(c.accent=String(t.accent));let p=l.columns.findIndex(m=>m.id===a);return p>=0?(l.columns[p]={...l.columns[p],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function uo(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim();if(!e||!a)throw new Error("boardId and columnId required");let{summary:n}=C(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(l=>l.id===e);if(!s)throw new Error(`board "${e}" not found`);let i=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(l=>l.id!==a),s.columns.length===i)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function mo(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{actionSchema:a}=await import("./types-H5ENIUIT.js");if(!t||typeof t!="object")throw new Error("body required");let n=a.safeParse(t);if(!n.success){let o=n.error.issues[0];throw new Error(`${o.path.join(".")||"<root>"}: ${o.message}`)}let r=new e().save(n.data);return{summary:`action "${r.id}" saved (${r.kind})`,action:r}}async function ho(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),a=String(t?.id||"").trim();if(!a)throw new Error("id required");if(!new e().delete(a))throw new Error(`action "${a}" not found`);return{summary:`action "${a}" removed`}}async function go(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{runAction:a}=await import("./runner-YRBVNYTY.js"),n=String(t?.id||"").trim();if(!n)throw new Error("id required");let r=new e().get(n);if(!r)throw new Error(`action "${n}" not found`);let o=t?.inputs&&typeof t.inputs=="object"?t.inputs:{},s=await a(r,o);return{summary:`action "${n}" ${s.ok?"ok":"failed"} (${s.durationMs}ms)`,result:s}}async function fo(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=C(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function xo(t){let{summary:e}=C(a=>{a.notifications=a.notifications||{};let n=[];if(t&&typeof t=="object"){if("destination"in t)if(!t.destination)delete a.notifications.destination,n.push("destination cleared");else if(t.destination.channel&&t.destination.chatId)a.notifications.destination={channel:String(t.destination.channel),chatId:String(t.destination.chatId),...t.destination.accountId?{accountId:String(t.destination.accountId)}:{}},n.push(`destination=${t.destination.channel}:${t.destination.chatId}`);else throw new Error("destination requires channel + chatId");if("on"in t&&t.on&&typeof t.on=="object"){a.notifications.on=a.notifications.on||{};for(let r of["taskComplete","taskError","taskQueued"])r in t.on&&(a.notifications.on[r]=!!t.on[r]);n.push("on="+JSON.stringify(a.notifications.on))}if("longTaskThreshold"in t){let r=Number(t.longTaskThreshold);if(!Number.isFinite(r)||r<0)throw new Error("longTaskThreshold must be a non-negative number");a.notifications.longTaskThreshold=r,n.push(`threshold=${r}s`)}"local"in t&&t.local&&typeof t.local=="object"&&(a.notifications.local=Dt(a.notifications.local,t.local),n.push("local="+JSON.stringify(a.notifications.local))),"ntfy"in t&&t.ntfy&&typeof t.ntfy=="object"&&(a.channels=a.channels||{},a.channels.ntfy=ia(a.channels.ntfy,t.ntfy),n.push(`ntfy ${a.channels.ntfy.enabled?"on":"off"} (restart the daemon to apply)`))}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function vo(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=Kt(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function bo(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=C(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}Ge();import{resolve as ko}from"path";function Sa(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
4766
+ `)}catch{}return{summary:l}}function Er(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=C(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);let o=r.agents[e];return typeof a.name=="string"&&a.name.trim()&&(o.name=a.name.trim()),typeof a.model=="string"&&(o.model=a.model.trim()||void 0),typeof a.tier=="string"&&["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(a.tier)&&(o.tier=a.tier),typeof a.systemPrompt=="string"&&(o.systemPrompt=a.systemPrompt.trim()||void 0),Array.isArray(a.mentions)?o.mentions=a.mentions.map(s=>String(s).trim()).filter(Boolean):typeof a.triggerWords=="string"&&(o.mentions=Sa(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function Sr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=C(n=>{if(!n.agents||!n.agents[e])throw new Error(`Agent "${e}" not found.`);if(delete n.agents[e],n.channels?.telegram?.accounts)for(let r of Object.keys(n.channels.telegram.accounts))n.channels.telegram.accounts[r]?.agentBinding===e&&(n.channels.telegram.accounts[r].agentBinding="");return`removed agent "${e}"`});return{summary:a}}function Tr(t){let e=String(t?.id||"").trim(),a=String(t?.agentBinding||"").trim(),n=String(t?.botUsername||"").trim(),r=String(t?.botTokenEnv||"").trim();if(!e)throw new Error("Account id is required.");if(!a)throw new Error("Choose an agent to bind this account to.");if(!r)throw new Error("Bot token env-var name is required (e.g. TG_SUPPORT_BOT_TOKEN).");let{summary:o}=C(s=>{if(s.channels=s.channels||{},s.channels.telegram=s.channels.telegram||{enabled:!0,accounts:{},policy:{dm:"pair",group:"mention-required"}},s.channels.telegram.enabled=!0,s.channels.telegram.accounts=s.channels.telegram.accounts||{},s.channels.telegram.accounts[e])throw new Error(`Telegram account "${e}" already exists.`);if(!s.agents?.[a])throw new Error(`Unknown agent "${a}".`);return s.channels.telegram.accounts[e]={token:"${"+r+"}",agentBinding:a},`added telegram account "${e}"`});return{summary:o,hint:`Add ${r}=<bot-token> to your .env file.`}}function Cr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=C(r=>{let o=r.channels?.telegram?.accounts?.[e];if(!o)throw new Error(`Account "${e}" not found.`);if(typeof a.agentBinding=="string"&&a.agentBinding.trim()){if(!r.agents?.[a.agentBinding])throw new Error(`Unknown agent "${a.agentBinding}".`);o.agentBinding=a.agentBinding.trim()}return typeof a.botUsername=="string"&&(o.botUsername=a.botUsername.trim()),typeof a.botTokenEnv=="string"&&a.botTokenEnv.trim()&&(o.token="${"+a.botTokenEnv.trim()+"}"),`updated telegram account "${e}"`});return{summary:n}}async function we(t){let{url:e,headers:a}=rt(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function ne(t,e){let{url:a,headers:n}=rt(),r=await fetch(a+t,{method:"POST",headers:{...n,"Content-Type":"application/json"},body:JSON.stringify(e||{})}),o=await r.text();if(!r.ok)throw new Error(`daemon ${r.status}: ${o.slice(0,200)}`);try{return JSON.parse(o)}catch{return{raw:o}}}async function Ar(t,e){try{let{url:a,headers:n}=rt(),r=await fetch(a+e,{headers:n}),o=await r.text();t.writeHead(r.status,{"Content-Type":r.headers.get("content-type")||"image/svg+xml","Cache-Control":"no-store"}),t.end(o)}catch(a){t.writeHead(502,{"Content-Type":"text/plain; charset=utf-8"}),t.end("daemon unreachable: "+(a?.message||"unknown"))}}function rt(){let t="http://127.0.0.1:18800",e={};try{let a=K();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function ke(t){let a=nt()?.agents?.[t];if(!a)throw new Error(`Unknown agent "${t}".`);if(!a.workspace)throw new Error(`Agent "${t}" has no workspace configured.`);return a.workspace}function at(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Mr(t){let e=at(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=he(ke(e));return{agentId:e,...a}}function Ir(t){let e=at(t,"agent").trim(),a=at(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Te(ke(e),a)}function $r(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=Ce(ke(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function jr(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=Ae(ke(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function Lr(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=Me(ke(e),a);return{summary:`removed skill "${a}"`,...n}}function Rr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a)throw new Error("kind is required");if(!n)throw new Error("label is required");let r={},o=t?.credentials||{};for(let l of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[l];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${l} must be uppercase identifier (got "${c}")`);r[l]=c.trim()}}if(o.auth==="keyring"&&(r.auth="keyring"),typeof o.sessionDir=="string"&&o.sessionDir.trim()&&(r.sessionDir=o.sessionDir.trim()),Object.keys(r).length===0)throw new Error("at least one credential field required");let s={};for(let[l,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[l]=c);let{summary:i}=C(l=>{if(!l.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(l.agents[e].integrations=Array.isArray(l.agents[e].integrations)?l.agents[e].integrations:[],l.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return l.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:i}}function Pr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let{summary:r}=C(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let i=s.integrations||[],l=i.findIndex(c=>c.kind===a&&c.label===n);if(l===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return i.splice(l,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function Dr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let r=t?.patch||{},{summary:o}=C(s=>{let i=s.agents?.[e];if(!i)throw new Error(`Unknown agent "${e}"`);let c=(i.integrations||[]).find(p=>p.kind===a&&p.label===n);if(!c)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(c.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(c.metadata={...c.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var Ea=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function Or(t){let e=String(t?.id||"").trim(),a=String(t?.source||"").trim(),n=String(t?.agentId||"").trim(),r=String(t?.secretEnv||"").trim(),o=String(t?.description||"").trim(),s=String(t?.node||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Webhook id must be lowercase (letters, digits, -, _).");if(!Ea.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:i}=C(l=>{if(s){if(!(l.mesh?.peers||[]).find(m=>m.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(p=>p.id===e))throw new Error(`Webhook "${e}" already exists.`);let c={id:e,source:a,agentId:n,enabled:!0};return r&&(c.secretEnv=r),o&&(c.description=o),s&&(c.node=s),l.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function Hr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=C(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&Ea.includes(a.source)&&(o.source=a.source),typeof a.agentId=="string"&&a.agentId.trim()){if(!r.agents?.[a.agentId])throw new Error(`Unknown agent "${a.agentId}".`);o.agentId=a.agentId.trim()}return typeof a.secretEnv=="string"&&(o.secretEnv=a.secretEnv.trim()||void 0),typeof a.description=="string"&&(o.description=a.description.trim()||void 0),typeof a.enabled=="boolean"&&(o.enabled=a.enabled),`updated webhook "${e}"`});return{summary:n}}function Nr(t){let e=String(t?.url||"").trim().replace(/\/+$/,""),a=String(t?.name||"").trim(),n=String(t?.token||"").trim()||void 0;if(!e||!/^https?:\/\//.test(e))throw new Error("Peer URL must start with http:// or https://");if(!a)throw new Error("Peer name is required.");let{summary:r}=C(o=>{if(o.mesh=o.mesh||{enabled:!0,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},o.mesh.enabled=!0,o.mesh.peers=Array.isArray(o.mesh.peers)?o.mesh.peers:[],o.mesh.peers.find(i=>i.url===e))throw new Error(`Peer at ${e} already registered.`);let s={url:e,name:a};return n&&(s.token=n),o.mesh.peers.push(s),`added mesh peer "${a}"`});return{summary:r}}function Br(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=C(n=>{let r=(n.mesh?.peers||[]).length;if(n.mesh=n.mesh||{enabled:!1,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.peers=(n.mesh.peers||[]).filter(o=>o.url.replace(/\/+$/,"")!==e),n.mesh.peers.length===r)throw new Error(`Peer at ${e} not found.`);return`removed mesh peer ${e}`});return{summary:a}}function zr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.mesh=n.mesh||{enabled:e,peers:[],discovery:"static",healthCheck:{interval:60,timeout:10}},n.mesh.enabled=e,`mesh ${e?"enabled":"disabled"}`));return{summary:a}}function qr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=C(n=>{let r=(n.webhooks||[]).length;if(n.webhooks=(n.webhooks||[]).filter(o=>o.id!==e),n.webhooks.length===r)throw new Error(`Webhook "${e}" not found.`);return`removed webhook "${e}"`});return{summary:a}}function Fr(t){let e=String(t?.botTokenEnv||"").trim(),a=String(t?.appTokenEnv||"").trim(),n=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. SLACK_BOT_TOKEN).");if(!a)throw new Error("App-level token env-var name is required (e.g. SLACK_APP_TOKEN).");let{summary:r}=C(o=>{if(o.channels=o.channels||{},o.channels.slack=o.channels.slack||{enabled:!1},o.channels.slack.enabled=!0,o.channels.slack.botToken="${"+e+"}",o.channels.slack.appToken="${"+a+"}",n){if(!o.agents?.[n])throw new Error(`Unknown agent "${n}".`);o.channels.slack.agentBinding=n}return"configured slack connector"});return{summary:r,hint:`Add ${e}=xoxb-\u2026 and ${a}=xapp-\u2026 to your .env.`}}function Ur(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.slack=n.channels.slack||{enabled:!1},n.channels.slack.enabled=e,`slack ${e?"enabled":"disabled"}`));return{summary:a}}function Wr(t){let e=String(t?.tokenEnv||"").trim(),a=String(t?.agentBinding||"").trim();if(!e)throw new Error("Bot token env-var name is required (e.g. DISCORD_BOT_TOKEN).");let{summary:n}=C(r=>{if(r.channels=r.channels||{},r.channels.discord=r.channels.discord||{enabled:!1},r.channels.discord.enabled=!0,r.channels.discord.token="${"+e+"}",a){if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);r.channels.discord.agentBinding=a}return"configured discord connector"});return{summary:n,hint:`Add ${e}=<bot-token> to your .env.`}}function Gr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.discord=n.channels.discord||{enabled:!1},n.channels.discord.enabled=e,`discord ${e?"enabled":"disabled"}`));return{summary:a}}function Xr(t){let e=String(t?.host||"").trim().replace(/\/+$/,""),a=String(t?.tokenEnv||"").trim(),n=parseInt(String(t?.webhookPort||"18810"),10);if(!e||!/^https?:\/\//.test(e))throw new Error("Host must start with http:// or https://");if(!a)throw new Error("Admin token env-var name is required (e.g. GITLAB_TOKEN).");if(!Number.isFinite(n)||n<1||n>65535)throw new Error("Webhook port must be between 1 and 65535.");let{summary:r}=C(o=>(o.channels=o.channels||{},o.channels.gitlab=o.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},o.channels.gitlab.enabled=!0,o.channels.gitlab.host=e,o.channels.gitlab.token="${"+a+"}",o.channels.gitlab.webhookPort=n,"configured gitlab connector"));return{summary:r,hint:`Add ${a}=<personal-access-token> to your .env. Per-project routes + per-agent tokens stay in the Advanced JSON editor.`}}function Kr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.gitlab=n.channels.gitlab||{enabled:!1,routes:[],agentMappings:[]},n.channels.gitlab.enabled=e,`gitlab ${e?"enabled":"disabled"}`));return{summary:a}}async function Jr(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-7QPG6OTY.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(i){throw new Error(`Invalid cron: ${i.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let i=0;i<3;i++)s=a(e,s,r),o.push(s.toISOString())}catch(i){throw new Error(`Cron preview failed: ${i.message}`)}return{human:n,next:o,timezone:r}}function Vr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=C(n=>{if(!n.channels?.telegram?.accounts?.[e])throw new Error(`Account "${e}" not found.`);return delete n.channels.telegram.accounts[e],`removed telegram account "${e}"`});return{summary:a}}function Yr(t){let e=!!t?.enabled,{summary:a}=C(n=>(n.channels=n.channels||{},n.channels.telegram=n.channels.telegram||{enabled:!1,accounts:{},policy:{dm:"pair",group:"mention-required"}},n.channels.telegram.enabled=e,`telegram ${e?"enabled":"disabled"}`));return{summary:a}}function Qr(t){let e=String(t?.id||"").trim(),a=String(t?.schedule||"").trim(),n=String(t?.agent||"").trim(),r=String(t?.prompt||"").trim();if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Cron id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Cron expression is required (e.g. '0 9 * * 1' for Mondays at 9am).");if(!n)throw new Error("Pick an agent to run this schedule.");if(!r)throw new Error("A prompt is required (what should the agent do?).");let{summary:o}=C(s=>{if(s.crons=s.crons||{},s.crons[e])throw new Error(`Cron "${e}" already exists.`);if(!s.agents?.[n])throw new Error(`Unknown agent "${n}".`);return s.crons[e]={schedule:a,agent:n,prompt:r,enabled:!0},`added cron "${e}"`});return{summary:o}}function Zr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=C(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function eo(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=fe(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(He(n))try{mr(n,r)}catch{}ya(n,JSON.stringify(a,null,2)+`
4767
+ `,"utf-8");try{let s=K().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function Sa(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function to(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=C(c=>(c.business=c.business||{},c.business.orgChart=c.business.orgChart||{},c.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function ao(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=C(n=>{if(!n.business?.orgChart||!(e in n.business.orgChart))throw new Error(`no orgChart entry for "${e}"`);return delete n.business.orgChart[e],`orgChart "${e}" removed`});return{summary:a}}async function no(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let a=t?.pm?String(t.pm).trim():"",n=t?.client?String(t.client).trim():"",{summary:r}=C(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(l=>l.id===e),i={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...i}:o.business.projects.push(i),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function ro(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let a=String(t?.kind||"").trim();if(a&&!["client","internal","own"].includes(a))throw new Error("kind must be client, internal or own");let n=String(t?.respondWithin||"").trim();if(n&&!/^\d+\s*[mhd]$/.test(n))throw new Error('respondWithin must look like "4h", "90m" or "2d"');let r=Array.isArray(t?.standing)?t.standing.map(s=>String(s).trim()).filter(Boolean):String(t?.standing||"").split(",").map(s=>s.trim()).filter(Boolean),{summary:o}=C(s=>{s.business=s.business||{},s.business.clients=s.business.clients||{};let i=!!s.business.clients[e];return s.business.clients[e]={...s.business.clients[e]||{},...t?.name?{name:String(t.name).trim()}:{},...a?{kind:a}:{},...n?{respondWithin:n}:{},standing:r},i?`client "${e}" updated`:`client "${e}" configured`});return{summary:o}}async function oo(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let{summary:a}=C(n=>{if(!n.business?.clients?.[e])throw new Error(`no client override "${e}"`);return delete n.business.clients[e],`client "${e}" reset to defaults`});return{summary:a}}async function so(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=C(n=>{let r=n.business?.projects||[],o=r.length;if(n.business.projects=r.filter(s=>s.id!==e),n.business.projects.length===o)throw new Error(`no project "${e}"`);return`project "${e}" removed`});return{summary:a}}async function io(t){let e=String(t?.client||"").trim();if(!e)throw new Error("client required");if(!t?.chatId&&!t?.username&&!t?.senderId)throw new Error("one of chatId / username / senderId required");let{summary:a}=C(n=>{n.business=n.business||{},n.business.contactMap=n.business.contactMap||[];let r={client:e};t?.channel&&(r.channel=String(t.channel)),t?.chatId&&(r.chatId=String(t.chatId)),t?.username&&(r.username=String(t.username)),t?.senderId&&(r.senderId=String(t.senderId)),t?.project&&(r.project=String(t.project)),t?.displayName&&(r.displayName=String(t.displayName)),n.business.contactMap.push(r);let o=r.chatId||r.username||r.senderId;return`contact ${r.channel?r.channel+"/":""}${o} \u2192 ${e} added`});return{summary:a}}async function lo(t){let a=["channel","chatId","username","senderId"].filter(r=>t?.[r]);if(a.length===0)throw new Error("at least one filter (channel/chatId/username/senderId) required");let{summary:n}=C(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(i=>{for(let l of a)if(i[l]!==t[l])return!0;return!1}),r.business.contactMap.length===s)throw new Error("no matching contact entry");return`${s-r.business.contactMap.length} contact entry/entries removed`});return{summary:n}}async function co(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=C(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let c=l.boards.findIndex(m=>m.id===e),p={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(p.primaryToolLabel=r),c>=0){let m=l.boards[c];return l.boards[c]={...m,...p,columns:m.columns,labels:m.labels},`board "${e}" updated`}return l.boards.push(p),`board "${e}" added`});return{summary:i}}async function po(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=C(n=>{let r=Array.isArray(n.boards)?n.boards:[],o=r.length;if(n.boards=r.filter(s=>s.id!==e),n.boards.length===o)throw new Error(`board "${e}" not found`);return`board "${e}" removed`});return{summary:a}}async function uo(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=C(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(m=>m.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let c={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");c.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");c.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(c.accent=String(t.accent));let p=l.columns.findIndex(m=>m.id===a);return p>=0?(l.columns[p]={...l.columns[p],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function mo(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim();if(!e||!a)throw new Error("boardId and columnId required");let{summary:n}=C(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(l=>l.id===e);if(!s)throw new Error(`board "${e}" not found`);let i=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(l=>l.id!==a),s.columns.length===i)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function ho(t){let{ActionStore:e}=await import("./store-TWQPEM5V.js"),{actionSchema:a}=await import("./types-DO3KLIBS.js");if(!t||typeof t!="object")throw new Error("body required");let n=a.safeParse(t);if(!n.success){let o=n.error.issues[0];throw new Error(`${o.path.join(".")||"<root>"}: ${o.message}`)}let r=new e().save(n.data);return{summary:`action "${r.id}" saved (${r.kind})`,action:r}}async function go(t){let{ActionStore:e}=await import("./store-TWQPEM5V.js"),a=String(t?.id||"").trim();if(!a)throw new Error("id required");if(!new e().delete(a))throw new Error(`action "${a}" not found`);return{summary:`action "${a}" removed`}}async function fo(t){let{ActionStore:e}=await import("./store-TWQPEM5V.js"),{runAction:a}=await import("./runner-56G3N7M4.js"),n=String(t?.id||"").trim();if(!n)throw new Error("id required");let r=new e().get(n);if(!r)throw new Error(`action "${n}" not found`);let o=t?.inputs&&typeof t.inputs=="object"?t.inputs:{},s=await a(r,o);return{summary:`action "${n}" ${s.ok?"ok":"failed"} (${s.durationMs}ms)`,result:s}}async function xo(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=C(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function vo(t){let{summary:e}=C(a=>{a.notifications=a.notifications||{};let n=[];if(t&&typeof t=="object"){if("destination"in t)if(!t.destination)delete a.notifications.destination,n.push("destination cleared");else if(t.destination.channel&&t.destination.chatId)a.notifications.destination={channel:String(t.destination.channel),chatId:String(t.destination.chatId),...t.destination.accountId?{accountId:String(t.destination.accountId)}:{}},n.push(`destination=${t.destination.channel}:${t.destination.chatId}`);else throw new Error("destination requires channel + chatId");if("on"in t&&t.on&&typeof t.on=="object"){a.notifications.on=a.notifications.on||{};for(let r of["taskComplete","taskError","taskQueued"])r in t.on&&(a.notifications.on[r]=!!t.on[r]);n.push("on="+JSON.stringify(a.notifications.on))}if("longTaskThreshold"in t){let r=Number(t.longTaskThreshold);if(!Number.isFinite(r)||r<0)throw new Error("longTaskThreshold must be a non-negative number");a.notifications.longTaskThreshold=r,n.push(`threshold=${r}s`)}"local"in t&&t.local&&typeof t.local=="object"&&(a.notifications.local=Ot(a.notifications.local,t.local),n.push("local="+JSON.stringify(a.notifications.local))),"ntfy"in t&&t.ntfy&&typeof t.ntfy=="object"&&(a.channels=a.channels||{},a.channels.ntfy=la(a.channels.ntfy,t.ntfy),n.push(`ntfy ${a.channels.ntfy.enabled?"on":"off"} (restart the daemon to apply)`))}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function bo(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=Jt(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function yo(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=C(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}Xe();import{resolve as _o}from"path";function Ta(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
4768
4768
 
4769
4769
  <div id="disabled-banner" class="banner warn" style="display:none">
4770
4770
  <b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
@@ -4819,7 +4819,7 @@ ${s||"You are "+a+"."}
4819
4819
  <h2>Recent classifications</h2>
4820
4820
  <p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
4821
4821
  <div id="recent"></div>
4822
- </section>`;return $({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:yo,scripts:`${e}<script>${wo}</script>`})}var yo=`
4822
+ </section>`;return $({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:wo,scripts:`${e}<script>${ko}</script>`})}var wo=`
4823
4823
  main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
4824
4824
  h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
4825
4825
  .grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
@@ -4923,7 +4923,7 @@ details {
4923
4923
  border-radius: 4px; padding: 8px 12px; margin-top: 8px;
4924
4924
  }
4925
4925
  details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
4926
- details[open] summary { margin-bottom: 8px; }`,wo=`
4926
+ details[open] summary { margin-bottom: 8px; }`,ko=`
4927
4927
  const $ = (id) => document.getElementById(id);
4928
4928
  const state = { schema: null, nodes: [], pending: [], recent: [] };
4929
4929
 
@@ -5143,7 +5143,7 @@ $('btn-save-schema').addEventListener('click', async () => {
5143
5143
  $('btn-reload-schema').addEventListener('click', refresh);
5144
5144
 
5145
5145
  refresh();
5146
- `;function Ca(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Sa({peers:a,localToken:n}))}async function Aa(t,e,a){try{let n=t.method==="GET"?void 0:await $o(t),r=_o(),o={"GET /api/admin/graph/state":()=>Eo(r),"POST /api/admin/graph/classifications/approve":()=>So(r,n),"POST /api/admin/graph/classifications/reject":()=>To(r,n),"POST /api/admin/graph/nodes":()=>Co(r,n),"PATCH /api/admin/graph/nodes":()=>Ao(r,n),"DELETE /api/admin/graph/nodes":()=>Mo(r,n),"PUT /api/admin/graph/schema":()=>Io(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){rt(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();rt(e,200,l)}catch(n){rt(e,400,{error:n?.message||"graph op failed"})}}function _o(){let t=K(),e=ko(process.cwd(),t.graph.baseDir);return new St({baseDir:e})}function Eo(t){let e=K(),a=t.loadSchema(),n=t.loadNodes().nodes,r=t.readRecentClassifications(100),o=t.loadIndex().entries,s=new Map;for(let l of r)s.has(l.msgHash)||s.set(l.msgHash,l);let i=[];for(let l of s.values())l.status==="pending"&&!o[l.msgHash]&&i.push(l);return{enabled:e.graph.enabled,schema:a,nodes:n,pending:i,recent:r.slice(0,25),counts:{nodes:n.length,pending:i.length,fingerprints:Object.keys(o).length}}}function So(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Ma(t,a);return Array.isArray(e?.path)&&e.path.length>0&&(n.path=e.path.map(r=>String(r))),e?.proposedAxes&&typeof e.proposedAxes=="object"&&(n.proposedAxes=ot(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function To(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Ma(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Ma(t,e){let n=t.readRecentClassifications(500).find(r=>r.msgHash===e);if(!n)throw new Error(`No classification found for ${e}`);return n}function Co(t,e){let a=Ta(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?Ta(String(e.parentId)):null,o=ot({[a]:e?.axes||{}})[a]||{};if(!a)throw new Error("id is required");if(!n)throw new Error("level is required");let s={id:a,level:n,parentId:r,axes:o,createdAt:new Date().toISOString(),createdBy:"admin-ui"};return t.addNode(s),{node:s}}function Ao(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=ot({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function Mo(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function Io(t,e){if(!e?.schema||typeof e.schema!="object")throw new Error("schema object is required");return t.saveSchema(e.schema),{summary:"Schema saved"}}function ot(t){let e={};for(let[a,n]of Object.entries(t||{})){if(!n||typeof n!="object")continue;let r={};for(let[o,s]of Object.entries(n))typeof s=="string"&&(r[o]=s);e[a]=r}return e}function Ta(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function rt(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function $o(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function Ia(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div class="apv">
5146
+ `;function Aa(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ta({peers:a,localToken:n}))}async function Ma(t,e,a){try{let n=t.method==="GET"?void 0:await jo(t),r=Eo(),o={"GET /api/admin/graph/state":()=>So(r),"POST /api/admin/graph/classifications/approve":()=>To(r,n),"POST /api/admin/graph/classifications/reject":()=>Co(r,n),"POST /api/admin/graph/nodes":()=>Ao(r,n),"PATCH /api/admin/graph/nodes":()=>Mo(r,n),"DELETE /api/admin/graph/nodes":()=>Io(r,n),"PUT /api/admin/graph/schema":()=>$o(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){ot(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();ot(e,200,l)}catch(n){ot(e,400,{error:n?.message||"graph op failed"})}}function Eo(){let t=K(),e=_o(process.cwd(),t.graph.baseDir);return new Tt({baseDir:e})}function So(t){let e=K(),a=t.loadSchema(),n=t.loadNodes().nodes,r=t.readRecentClassifications(100),o=t.loadIndex().entries,s=new Map;for(let l of r)s.has(l.msgHash)||s.set(l.msgHash,l);let i=[];for(let l of s.values())l.status==="pending"&&!o[l.msgHash]&&i.push(l);return{enabled:e.graph.enabled,schema:a,nodes:n,pending:i,recent:r.slice(0,25),counts:{nodes:n.length,pending:i.length,fingerprints:Object.keys(o).length}}}function To(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Ia(t,a);return Array.isArray(e?.path)&&e.path.length>0&&(n.path=e.path.map(r=>String(r))),e?.proposedAxes&&typeof e.proposedAxes=="object"&&(n.proposedAxes=st(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function Co(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Ia(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Ia(t,e){let n=t.readRecentClassifications(500).find(r=>r.msgHash===e);if(!n)throw new Error(`No classification found for ${e}`);return n}function Ao(t,e){let a=Ca(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?Ca(String(e.parentId)):null,o=st({[a]:e?.axes||{}})[a]||{};if(!a)throw new Error("id is required");if(!n)throw new Error("level is required");let s={id:a,level:n,parentId:r,axes:o,createdAt:new Date().toISOString(),createdBy:"admin-ui"};return t.addNode(s),{node:s}}function Mo(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=st({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function Io(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function $o(t,e){if(!e?.schema||typeof e.schema!="object")throw new Error("schema object is required");return t.saveSchema(e.schema),{summary:"Schema saved"}}function st(t){let e={};for(let[a,n]of Object.entries(t||{})){if(!n||typeof n!="object")continue;let r={};for(let[o,s]of Object.entries(n))typeof s=="string"&&(r[o]=s);e[a]=r}return e}function Ca(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function ot(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function jo(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}function $a(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div class="apv">
5147
5147
  <header class="apv__head">
5148
5148
  <div>
5149
5149
  <h1>Approvals</h1>
@@ -5176,7 +5176,7 @@ refresh();
5176
5176
  <div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
5177
5177
  </form>
5178
5178
  </details>
5179
- </div>`;return $({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:jo,scripts:`${e}<script>${Lo}</script>`})}var jo=`
5179
+ </div>`;return $({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Lo,scripts:`${e}<script>${Ro}</script>`})}var Lo=`
5180
5180
  .apv { max-width: 860px; margin: 0 auto; padding: 20px 16px 64px; color: var(--ax-text); }
5181
5181
  .apv__head { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; }
5182
5182
  .apv__head h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
@@ -5225,7 +5225,7 @@ refresh();
5225
5225
  @media (max-width: 560px) {
5226
5226
  .apv__acts .ax-btn { flex: 1 1 0; }
5227
5227
  }
5228
- `,Lo=`
5228
+ `,Ro=`
5229
5229
  (function(){
5230
5230
  var state = { items: [], snoozed: 0, kind: '', showAll: false };
5231
5231
  var LABEL = { card: 'Card', schedule: 'Schedule', memory: 'Memory fact', wiki: 'Wiki lesson' };
@@ -5376,7 +5376,7 @@ $('apv-form').addEventListener('submit', async function(ev){
5376
5376
  load();
5377
5377
  setInterval(function(){ if (document.visibilityState === 'visible' && !document.querySelector('.apv__item:focus-within')) load(); }, 60000);
5378
5378
  })();
5379
- `;var Ro=["yes","no","later"];function re(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function $a(t,e=64*1024){let a=0,n=[];for await(let s of t){if(a+=s.length,a>e)throw new Error("body too large");n.push(s)}let r=Buffer.concat(n).toString("utf-8");if(!r.trim())return{};let o=JSON.parse(r);if(!o||typeof o!="object"||Array.isArray(o))throw new Error("expected a JSON object");return o}function ja(t,e,a){t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(Ia({peers:e,localToken:a}))}async function La(t,e,a,n,r={}){if(!a.startsWith("/api/admin/approvals"))return!1;let o=(t.method||"GET").toUpperCase(),s=r.ctx??{root:process.cwd(),configPath:r.configPath,reload:r.reload};if(o!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return re(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;try{if(o==="GET"&&a==="/api/admin/approvals"){let i=Ot(s,{includeSnoozed:n.searchParams.get("all")==="1"});return re(e,200,{...i,settings:Le(s.configPath)}),!0}if(o==="POST"&&a==="/api/admin/approvals/decide"){let i=await $a(t),l=typeof i.key=="string"?i.key:"",c=i.action;if(!l||!Ro.includes(c))return re(e,400,{error:"send { key, action: yes | no | later }"}),!0;let p=Le(s.configPath),m=await Ht(s,l,c,{note:typeof i.note=="string"?i.note:void 0,force:i.force===!0,laterHours:p.laterHours,by:"operator (dashboard)"});return m.ok?(re(e,200,{ok:!0,message:m.message}),!0):(re(e,409,{error:m.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/settings"){let i=await $a(t),l={},c=m=>{let h=i[m];if(h!==void 0){if(typeof h!="number"||!(h>0))throw new Error(`${m} must be a positive number`);return h}};if(l.defaultExpiryDays=c("defaultExpiryDays"),l.maxExpiryDays=c("maxExpiryDays"),l.laterHours=c("laterHours"),typeof i.notifyAgent=="boolean"&&(l.notifyAgent=i.notifyAgent),typeof i.digestEnabled=="boolean"&&(l.digestEnabled=i.digestEnabled),typeof i.digestTime=="string"&&(l.digestTime=i.digestTime),typeof i.destination=="string"){let m=i.destination.trim();if(!m)l.destination=null;else{let h=na(m);if(!h)throw new Error("digest destination takes channel:chat id, for example telegram:123456");l.destination=h}}let p=await ra(l,{configPath:s.configPath,reload:s.reload});return p.success?(re(e,200,{ok:!0,settings:Le(s.configPath)}),!0):(re(e,400,{error:p.error}),!0)}}catch(i){return re(e,400,{error:String(i?.message??i).slice(0,300)}),!0}return re(e,404,{error:"Not found"}),!0}import{resolve as Oo}from"path";import{existsSync as Ho}from"fs";import No from"better-sqlite3";function Ra(t={}){let e=`<div class="ax-obs">
5379
+ `;var Po=["yes","no","later"];function re(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function ja(t,e=64*1024){let a=0,n=[];for await(let s of t){if(a+=s.length,a>e)throw new Error("body too large");n.push(s)}let r=Buffer.concat(n).toString("utf-8");if(!r.trim())return{};let o=JSON.parse(r);if(!o||typeof o!="object"||Array.isArray(o))throw new Error("expected a JSON object");return o}function La(t,e,a){t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end($a({peers:e,localToken:a}))}async function Ra(t,e,a,n,r={}){if(!a.startsWith("/api/admin/approvals"))return!1;let o=(t.method||"GET").toUpperCase(),s=r.ctx??{root:process.cwd(),configPath:r.configPath,reload:r.reload};if(o!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return re(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;try{if(o==="GET"&&a==="/api/admin/approvals"){let i=Ht(s,{includeSnoozed:n.searchParams.get("all")==="1"});return re(e,200,{...i,settings:Re(s.configPath)}),!0}if(o==="POST"&&a==="/api/admin/approvals/decide"){let i=await ja(t),l=typeof i.key=="string"?i.key:"",c=i.action;if(!l||!Po.includes(c))return re(e,400,{error:"send { key, action: yes | no | later }"}),!0;let p=Re(s.configPath),m=await Nt(s,l,c,{note:typeof i.note=="string"?i.note:void 0,force:i.force===!0,laterHours:p.laterHours,by:"operator (dashboard)"});return m.ok?(re(e,200,{ok:!0,message:m.message}),!0):(re(e,409,{error:m.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/settings"){let i=await ja(t),l={},c=m=>{let h=i[m];if(h!==void 0){if(typeof h!="number"||!(h>0))throw new Error(`${m} must be a positive number`);return h}};if(l.defaultExpiryDays=c("defaultExpiryDays"),l.maxExpiryDays=c("maxExpiryDays"),l.laterHours=c("laterHours"),typeof i.notifyAgent=="boolean"&&(l.notifyAgent=i.notifyAgent),typeof i.digestEnabled=="boolean"&&(l.digestEnabled=i.digestEnabled),typeof i.digestTime=="string"&&(l.digestTime=i.digestTime),typeof i.destination=="string"){let m=i.destination.trim();if(!m)l.destination=null;else{let h=ra(m);if(!h)throw new Error("digest destination takes channel:chat id, for example telegram:123456");l.destination=h}}let p=await oa(l,{configPath:s.configPath,reload:s.reload});return p.success?(re(e,200,{ok:!0,settings:Re(s.configPath)}),!0):(re(e,400,{error:p.error}),!0)}}catch(i){return re(e,400,{error:String(i?.message??i).slice(0,300)}),!0}return re(e,404,{error:"Not found"}),!0}import{resolve as Ho}from"path";import{existsSync as No}from"fs";import Bo from"better-sqlite3";function Pa(t={}){let e=`<div class="ax-obs">
5380
5380
  <header class="ax-obs__head">
5381
5381
  <h1>Health</h1>
5382
5382
  <p class="ax-obs__sub">Platform-health view: what each agent ran, what failed, and how the router decided. <span class="ax-obs__sub-link">Spend lives on the <a href="/admin/cost">Cost</a> page.</span></p>
@@ -5498,7 +5498,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
5498
5498
  </div>
5499
5499
  <div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
5500
5500
  </section>
5501
- </div>`;return $({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Po,scripts:`<script>${Do}</script>`})}var Po=`
5501
+ </div>`;return $({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Do,scripts:`<script>${Oo}</script>`})}var Do=`
5502
5502
  .ax-obs { padding: 16px 24px; }
5503
5503
  .ax-obs__head { margin-bottom: 16px; }
5504
5504
  .ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
@@ -5615,7 +5615,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
5615
5615
  .ax-obs__doctor-title { font-size: 12px; font-weight: 500; }
5616
5616
  .ax-obs__doctor-detail { font-size: 11px; color: var(--ax-muted); margin-top: 2px; font-family: 'IBM Plex Mono', monospace; word-break: break-word; }
5617
5617
  .ax-obs__doctor-fix { font-size: 11px; color: var(--ax-accent, #3a7bd5); margin-top: 2px; }
5618
- `,Do=`
5618
+ `,Oo=`
5619
5619
  (function(){
5620
5620
  var panes = document.querySelectorAll('.ax-obs__pane');
5621
5621
  var tabs = document.querySelectorAll('.ax-obs__tab');
@@ -5999,7 +5999,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
5999
5999
 
6000
6000
  load(current);
6001
6001
  })();
6002
- `;var Oa={opus:{input:15,output:75,cacheRead:1.5,cacheCreate:18.75},sonnet:{input:3,output:15,cacheRead:.3,cacheCreate:3.75},haiku:{input:.25,output:1.25,cacheRead:.025,cacheCreate:.3125},external:{input:0,output:0,cacheRead:0,cacheCreate:0}};function Ha(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function st(t){let e=Oa[Ha(t.model)],a=t.input_tokens/1e6*e.input+t.output_tokens/1e6*e.output+t.cache_read_tokens/1e6*e.cacheRead+t.cache_create_tokens/1e6*e.cacheCreate,n=(t.tier2_input_tokens??0)/1e6*e.input*.5+(t.tier2_output_tokens??0)/1e6*e.output*.5+(t.tier2_cache_read_tokens??0)/1e6*e.cacheRead*.5+(t.tier2_cache_create_tokens??0)/1e6*e.cacheCreate*.5;return a+n}function Bo(){let t=Oo(process.cwd(),".agentx/db.sqlite");if(!Ho(t))return null;try{let e=new No(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Na(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ra({peers:a}))}function zo(t){let e=new URL(t.url||"/","http://_"),a=parseInt(e.searchParams.get("limit")||"50",10),n=Number.isFinite(a)?Math.max(1,Math.min(500,a)):50,r=e.searchParams.get("agent")||void 0;return{limit:n,agent:r&&r.length>0?r:void 0}}function oe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Ba(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=Bo();if(!r)return oe(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=zo(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let c=`
6002
+ `;var Ha={opus:{input:15,output:75,cacheRead:1.5,cacheCreate:18.75},sonnet:{input:3,output:15,cacheRead:.3,cacheCreate:3.75},haiku:{input:.25,output:1.25,cacheRead:.025,cacheCreate:.3125},external:{input:0,output:0,cacheRead:0,cacheCreate:0}};function Na(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function it(t){let e=Ha[Na(t.model)],a=t.input_tokens/1e6*e.input+t.output_tokens/1e6*e.output+t.cache_read_tokens/1e6*e.cacheRead+t.cache_create_tokens/1e6*e.cacheCreate,n=(t.tier2_input_tokens??0)/1e6*e.input*.5+(t.tier2_output_tokens??0)/1e6*e.output*.5+(t.tier2_cache_read_tokens??0)/1e6*e.cacheRead*.5+(t.tier2_cache_create_tokens??0)/1e6*e.cacheCreate*.5;return a+n}function zo(){let t=Ho(process.cwd(),".agentx/db.sqlite");if(!No(t))return null;try{let e=new Bo(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function Ba(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Pa({peers:a}))}function qo(t){let e=new URL(t.url||"/","http://_"),a=parseInt(e.searchParams.get("limit")||"50",10),n=Number.isFinite(a)?Math.max(1,Math.min(500,a)):50,r=e.searchParams.get("agent")||void 0;return{limit:n,agent:r&&r.length>0?r:void 0}}function oe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function za(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=zo();if(!r)return oe(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=qo(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let c=`
6003
6003
  SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
6004
6004
  FROM route_traces
6005
6005
  ${i.length?"WHERE "+i.join(" AND "):""}
@@ -6014,8 +6014,8 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6014
6014
  FROM task_history
6015
6015
  WHERE ${i.join(" AND ")}
6016
6016
  ORDER BY started_at DESC LIMIT @limit
6017
- `,m=r.db.prepare(c).all(l).map(h=>({...h,plain:za(h.error)}));return oe(e,200,{rows:m}),!0}if(n==="summary"||n==="overview")return oe(e,200,qo(r.db)),!0;if(n==="activity")return oe(e,200,Fo(r.db,{agent:s})),!0;if(n==="cost"){let i=new URL(t.url||"/","http://_"),l=Pa(i.searchParams.get("range"));return oe(e,200,Da(r.db,l)),!0}if(n==="cost.csv"){let i=new URL(t.url||"/","http://_"),l=Pa(i.searchParams.get("range")),c=Da(r.db,l),p=Uo(c.days);return e.writeHead(200,{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="agentx-cost-${l||"all"}d-${Date.now()}.csv"`}),e.end(p),!0}return oe(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return oe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function za(t){let e=String(t||"");return e?/timed out|SIGTERM|exit 143|maxExecutionMinutes/i.test(e)?"Agent ran past its time limit":/ECONNREFUSED|fetch failed|getaddrinfo|ENOTFOUND/i.test(e)?"Couldn't reach a service over the network":/401|403|Unauthorized|Forbidden|invalid token|missing scope/i.test(e)?"Authentication or permission denied":/rate limit|429|too many requests/i.test(e)?"Hit a rate limit (too many calls)":/quota|insufficient_quota/i.test(e)?"Provider account out of quota or credits":/tier-?2|tier two|200K|200,000/i.test(e)?"Hit Anthropic tier-2 billing threshold":/JSON|parse|unexpected token/i.test(e)?"Got a response in the wrong shape":/permission denied|EACCES|EPERM/i.test(e)?"File permission denied":/ENOENT|no such file/i.test(e)?"Expected file is missing":/abort|cancel/i.test(e)?"Task was cancelled before it finished":e.split(`
6018
- `)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function qo(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,i=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE status='error' AND started_at >= ?").get(a).n,c=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,p=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),m=y=>p.length?p[Math.min(p.length-1,Math.floor(p.length*y))].duration_ms:0,h=m(.5),_=m(.95),w=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((y,M)=>y+st(M),0),E=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((y,M)=>y+st(M),0),T=t.prepare(`
6017
+ `,m=r.db.prepare(c).all(l).map(h=>({...h,plain:qa(h.error)}));return oe(e,200,{rows:m}),!0}if(n==="summary"||n==="overview")return oe(e,200,Fo(r.db)),!0;if(n==="activity")return oe(e,200,Uo(r.db,{agent:s})),!0;if(n==="cost"){let i=new URL(t.url||"/","http://_"),l=Da(i.searchParams.get("range"));return oe(e,200,Oa(r.db,l)),!0}if(n==="cost.csv"){let i=new URL(t.url||"/","http://_"),l=Da(i.searchParams.get("range")),c=Oa(r.db,l),p=Wo(c.days);return e.writeHead(200,{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="agentx-cost-${l||"all"}d-${Date.now()}.csv"`}),e.end(p),!0}return oe(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return oe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function qa(t){let e=String(t||"");return e?/timed out|SIGTERM|exit 143|maxExecutionMinutes/i.test(e)?"Agent ran past its time limit":/ECONNREFUSED|fetch failed|getaddrinfo|ENOTFOUND/i.test(e)?"Couldn't reach a service over the network":/401|403|Unauthorized|Forbidden|invalid token|missing scope/i.test(e)?"Authentication or permission denied":/rate limit|429|too many requests/i.test(e)?"Hit a rate limit (too many calls)":/quota|insufficient_quota/i.test(e)?"Provider account out of quota or credits":/tier-?2|tier two|200K|200,000/i.test(e)?"Hit Anthropic tier-2 billing threshold":/JSON|parse|unexpected token/i.test(e)?"Got a response in the wrong shape":/permission denied|EACCES|EPERM/i.test(e)?"File permission denied":/ENOENT|no such file/i.test(e)?"Expected file is missing":/abort|cancel/i.test(e)?"Task was cancelled before it finished":e.split(`
6018
+ `)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function Fo(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,i=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE status='error' AND started_at >= ?").get(a).n,c=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,p=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),m=y=>p.length?p[Math.min(p.length-1,Math.floor(p.length*y))].duration_ms:0,h=m(.5),_=m(.95),w=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((y,M)=>y+it(M),0),E=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((y,M)=>y+it(M),0),T=t.prepare(`
6019
6019
  SELECT agent_id,
6020
6020
  COUNT(*) AS tasks,
6021
6021
  SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
@@ -6038,7 +6038,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6038
6038
  FROM task_history
6039
6039
  WHERE status='error' AND started_at >= ?
6040
6040
  ORDER BY started_at DESC LIMIT 5
6041
- `).all(o).map(y=>({...y,plain:za(y.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(c),p50DurationMs:h,p95DurationMs:_,spendToday:w,spendDelta:w-E,idleAgentCount:f.length},perAgent:T,perChannel:d,idleAgents:f,recentErrors:x}}function Fo(t,e){let a=new Date(Date.now()-864e5).toISOString(),n=new Date(Date.now()-7*864e5).toISOString(),r=e.agent?"AND agent_id = @agent":"",o=e.agent?{agent:e.agent}:{},s=t.prepare(`
6041
+ `).all(o).map(y=>({...y,plain:qa(y.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(c),p50DurationMs:h,p95DurationMs:_,spendToday:w,spendDelta:w-E,idleAgentCount:f.length},perAgent:T,perChannel:d,idleAgents:f,recentErrors:x}}function Uo(t,e){let a=new Date(Date.now()-864e5).toISOString(),n=new Date(Date.now()-7*864e5).toISOString(),r=e.agent?"AND agent_id = @agent":"",o=e.agent?{agent:e.agent}:{},s=t.prepare(`
6042
6042
  SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
6043
6043
  COUNT(*) AS tasks,
6044
6044
  SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
@@ -6065,7 +6065,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6065
6065
  WHERE started_at >= @since
6066
6066
  GROUP BY agent_id
6067
6067
  ORDER BY tasks_24h DESC, tasks_7d DESC
6068
- `).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function Pa(t){if(!t)return 30;if(t==="all"||t==="0")return 0;let e=parseInt(t,10);return!Number.isFinite(e)||e<=0?30:Math.min(e,365)}function Da(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
6068
+ `).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function Da(t){if(!t)return 30;if(t==="all"||t==="0")return 0;let e=parseInt(t,10);return!Number.isFinite(e)||e<=0?30:Math.min(e,365)}function Oa(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
6069
6069
  SELECT day, agent_id, model,
6070
6070
  input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
6071
6071
  tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
@@ -6073,20 +6073,20 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6073
6073
  FROM usage_daily
6074
6074
  ${a}
6075
6075
  ORDER BY day
6076
- `).all(),r=new Date().toISOString().slice(0,10),o=new Date(Date.now()-864e5).toISOString().slice(0,10),s=new Date(Date.now()-7*864e5).toISOString().slice(0,10),i=new Date(Date.now()-14*864e5).toISOString().slice(0,10),l=0,c=0,p=0,m=0,h=0,_=0,S=0,w=0,E=0,T={},d={};for(let k of n){let I=st(k),L=Ha(k.model),R=Oa[L],N=(k.tier2_input_tokens||0)/1e6*R.input*.5+(k.tier2_output_tokens||0)/1e6*R.output*.5+(k.tier2_cache_read_tokens||0)/1e6*R.cacheRead*.5+(k.tier2_cache_create_tokens||0)/1e6*R.cacheCreate*.5,Z=(k.input_tokens||0)+(k.tier2_input_tokens||0),B=(k.output_tokens||0)+(k.tier2_output_tokens||0),O=(k.cache_read_tokens||0)+(k.tier2_cache_read_tokens||0),H=(k.cache_create_tokens||0)+(k.tier2_cache_create_tokens||0);m+=I,k.day>=s&&(p+=I,S+=k.tasks||0),k.day>=i&&k.day<s&&(E+=I,w+=k.tasks||0),k.day===r&&(l+=I),k.day===o&&(c+=I),k.day===r&&(h+=N),k.day>=s&&(_+=N);let G=T[k.day]||(T[k.day]={date:k.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});G.tasks+=k.tasks||0,G.input+=Z,G.output+=B,G.cacheRead+=O,G.cacheCreate+=H,G.cost+=I,G.tier2+=N;let z=G.agents[k.agent_id]||(G.agents[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});z.tasks+=k.tasks||0,z.cost+=I,z.tier2+=N,z.input+=Z,z.output+=B,z.cacheRead+=O,z.cacheCreate+=H,k.model&&(z.model=k.model);let X=d[k.agent_id]||(d[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});X.tasks+=k.tasks||0,X.cost+=I,X.tier2+=N,X.input+=Z,X.output+=B,X.cacheRead+=O,X.cacheCreate+=H,k.model&&(X.model=k.model)}let u=Object.values(T).sort((k,I)=>k.date<I.date?-1:1),g=0,f=0,b=0,x=0,y=0,M=0;for(let k of u)g+=k.tasks,f+=k.input,b+=k.output,x+=k.cacheRead,y+=k.cacheCreate,M+=k.cost;let A=Object.entries(d).map(([k,I])=>({agent_id:k,...I,tokens:I.input+I.output+I.cacheRead+I.cacheCreate})).sort((k,I)=>I.cost-k.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:l,spendYesterday:c,spend7d:p,spend30d:m,tier2Today:h,tier2_7d:_,tier2PctToday:l>0?h/l:0,spendRange:M,avgDailyRange:u.length?M/u.length:0,tasksRange:g,tokensRange:f+b+x+y,cacheHitRange:x+f>0?x/(x+f):0,costPerTaskRange:g>0?M/g:0,spendDeltaWoW:E>0?(p-E)/E:0,tasksDeltaWoW:w>0?(S-w)/w:0},days:u,perAgent:A}}function Uo(t){let e="date,tasks,input,output,cache_read,cache_create,cost_usd,top_agent",a=t.map(n=>{let r=Object.entries(n.agents).sort(([,o],[,s])=>s.cost-o.cost)[0];return[n.date,n.tasks,n.input,n.output,n.cacheRead,n.cacheCreate,n.cost.toFixed(6),r?r[0]:""].join(",")});return e+`
6076
+ `).all(),r=new Date().toISOString().slice(0,10),o=new Date(Date.now()-864e5).toISOString().slice(0,10),s=new Date(Date.now()-7*864e5).toISOString().slice(0,10),i=new Date(Date.now()-14*864e5).toISOString().slice(0,10),l=0,c=0,p=0,m=0,h=0,_=0,S=0,w=0,E=0,T={},d={};for(let k of n){let I=it(k),L=Na(k.model),R=Ha[L],N=(k.tier2_input_tokens||0)/1e6*R.input*.5+(k.tier2_output_tokens||0)/1e6*R.output*.5+(k.tier2_cache_read_tokens||0)/1e6*R.cacheRead*.5+(k.tier2_cache_create_tokens||0)/1e6*R.cacheCreate*.5,Z=(k.input_tokens||0)+(k.tier2_input_tokens||0),B=(k.output_tokens||0)+(k.tier2_output_tokens||0),O=(k.cache_read_tokens||0)+(k.tier2_cache_read_tokens||0),H=(k.cache_create_tokens||0)+(k.tier2_cache_create_tokens||0);m+=I,k.day>=s&&(p+=I,S+=k.tasks||0),k.day>=i&&k.day<s&&(E+=I,w+=k.tasks||0),k.day===r&&(l+=I),k.day===o&&(c+=I),k.day===r&&(h+=N),k.day>=s&&(_+=N);let G=T[k.day]||(T[k.day]={date:k.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});G.tasks+=k.tasks||0,G.input+=Z,G.output+=B,G.cacheRead+=O,G.cacheCreate+=H,G.cost+=I,G.tier2+=N;let z=G.agents[k.agent_id]||(G.agents[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});z.tasks+=k.tasks||0,z.cost+=I,z.tier2+=N,z.input+=Z,z.output+=B,z.cacheRead+=O,z.cacheCreate+=H,k.model&&(z.model=k.model);let X=d[k.agent_id]||(d[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});X.tasks+=k.tasks||0,X.cost+=I,X.tier2+=N,X.input+=Z,X.output+=B,X.cacheRead+=O,X.cacheCreate+=H,k.model&&(X.model=k.model)}let u=Object.values(T).sort((k,I)=>k.date<I.date?-1:1),g=0,f=0,b=0,x=0,y=0,M=0;for(let k of u)g+=k.tasks,f+=k.input,b+=k.output,x+=k.cacheRead,y+=k.cacheCreate,M+=k.cost;let A=Object.entries(d).map(([k,I])=>({agent_id:k,...I,tokens:I.input+I.output+I.cacheRead+I.cacheCreate})).sort((k,I)=>I.cost-k.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:l,spendYesterday:c,spend7d:p,spend30d:m,tier2Today:h,tier2_7d:_,tier2PctToday:l>0?h/l:0,spendRange:M,avgDailyRange:u.length?M/u.length:0,tasksRange:g,tokensRange:f+b+x+y,cacheHitRange:x+f>0?x/(x+f):0,costPerTaskRange:g>0?M/g:0,spendDeltaWoW:E>0?(p-E)/E:0,tasksDeltaWoW:w>0?(S-w)/w:0},days:u,perAgent:A}}function Wo(t){let e="date,tasks,input,output,cache_read,cache_create,cost_usd,top_agent",a=t.map(n=>{let r=Object.entries(n.agents).sort(([,o],[,s])=>s.cost-o.cost)[0];return[n.date,n.tasks,n.input,n.output,n.cacheRead,n.cacheCreate,n.cost.toFixed(6),r?r[0]:""].join(",")});return e+`
6077
6077
  `+a.join(`
6078
6078
  `)+`
6079
- `}import{resolve as Wo}from"path";import{existsSync as Go}from"fs";import Xo from"better-sqlite3";function Ko(){let t=Wo(process.cwd(),".agentx/intent/ledger.sqlite");if(!Go(t))return null;try{let e=new Xo(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-qa>6e4&&(qa=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var qa=0;function pe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Jo(t){if(!t)return;let e=String(t).trim().match(/^(\d+)\s*(s|m|h|d|w)?$/i);if(!e)return;let a=parseInt(e[1],10),n=(e[2]||"h").toLowerCase(),r=n==="s"?1e3:n==="m"?6e4:n==="h"?36e5:n==="d"?864e5:n==="w"?7*864e5:0;return Date.now()-a*r}async function Fa(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Ko();if(!r)return pe(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Jo(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",c=parseInt(o.searchParams.get("limit")||"50",10),p=Number.isFinite(c)?Math.max(1,Math.min(500,c)):50;if(n==="stats"){let m=s!==void 0?"WHERE ts >= @since":"",h=s!==void 0?"WHERE decided_at >= @since":"",_=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${m} GROUP BY source ORDER BY n DESC`).all({since:s}),S=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${h}`).get({since:s}).n,w=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${h} GROUP BY outcome ORDER BY n DESC`).all({since:s}),E=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${m}`).get({since:s}).n,T=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${m} GROUP BY source ORDER BY n DESC`).all({since:s}),d=r.db.prepare(`
6079
+ `}import{resolve as Go}from"path";import{existsSync as Xo}from"fs";import Ko from"better-sqlite3";function Jo(){let t=Go(process.cwd(),".agentx/intent/ledger.sqlite");if(!Xo(t))return null;try{let e=new Ko(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-Fa>6e4&&(Fa=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var Fa=0;function ue(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Vo(t){if(!t)return;let e=String(t).trim().match(/^(\d+)\s*(s|m|h|d|w)?$/i);if(!e)return;let a=parseInt(e[1],10),n=(e[2]||"h").toLowerCase(),r=n==="s"?1e3:n==="m"?6e4:n==="h"?36e5:n==="d"?864e5:n==="w"?7*864e5:0;return Date.now()-a*r}async function Ua(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Jo();if(!r)return ue(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Vo(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",c=parseInt(o.searchParams.get("limit")||"50",10),p=Number.isFinite(c)?Math.max(1,Math.min(500,c)):50;if(n==="stats"){let m=s!==void 0?"WHERE ts >= @since":"",h=s!==void 0?"WHERE decided_at >= @since":"",_=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${m} GROUP BY source ORDER BY n DESC`).all({since:s}),S=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${h}`).get({since:s}).n,w=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${h} GROUP BY outcome ORDER BY n DESC`).all({since:s}),E=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${m}`).get({since:s}).n,T=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${m} GROUP BY source ORDER BY n DESC`).all({since:s}),d=r.db.prepare(`
6080
6080
  SELECT COUNT(*) AS n FROM intent_decisions d
6081
6081
  LEFT JOIN intent_resolutions r
6082
6082
  ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
6083
6083
  WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
6084
- `).get().n;return pe(e,200,{since:s??null,eventsBySource:_,totalDecisions:S,decisionsByOutcome:w,totalDivergences:E,divergencesBySource:T,inFlight:d}),!0}if(n==="events"){let m=[],h={limit:p};s!==void 0&&(m.push("ts >= @since"),h.since=s),i&&(m.push("source = @source"),h.source=i),l&&(m.push("project = @project"),h.project=l);let _=`
6084
+ `).get().n;return ue(e,200,{since:s??null,eventsBySource:_,totalDecisions:S,decisionsByOutcome:w,totalDivergences:E,divergencesBySource:T,inFlight:d}),!0}if(n==="events"){let m=[],h={limit:p};s!==void 0&&(m.push("ts >= @since"),h.since=s),i&&(m.push("source = @source"),h.source=i),l&&(m.push("project = @project"),h.project=l);let _=`
6085
6085
  SELECT id, ts, source, source_event_id, project, subject, intent
6086
6086
  FROM intent_events
6087
6087
  ${m.length?"WHERE "+m.join(" AND "):""}
6088
6088
  ORDER BY ts DESC LIMIT @limit
6089
- `;return pe(e,200,{rows:r.db.prepare(_).all(h)}),!0}if(n==="divergences"){let m=[],h={limit:p};s!==void 0&&(m.push("ts >= @since"),h.since=s),i&&(m.push("source = @source"),h.source=i);let _=`
6089
+ `;return ue(e,200,{rows:r.db.prepare(_).all(h)}),!0}if(n==="divergences"){let m=[],h={limit:p};s!==void 0&&(m.push("ts >= @since"),h.since=s),i&&(m.push("source = @source"),h.source=i);let _=`
6090
6090
  SELECT ts, source, decided_by,
6091
6091
  legacy_agent_id, legacy_outcome, legacy_reason,
6092
6092
  ledger_agent_id, ledger_outcome, ledger_reason,
@@ -6094,7 +6094,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6094
6094
  FROM intent_divergences
6095
6095
  ${m.length?"WHERE "+m.join(" AND "):""}
6096
6096
  ORDER BY ts DESC LIMIT @limit
6097
- `;return pe(e,200,{rows:r.db.prepare(_).all(h)}),!0}if(n==="active"){let m=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],h={limit:p};i&&(m.push("e.source = @source"),h.source=i);let _=`
6097
+ `;return ue(e,200,{rows:r.db.prepare(_).all(h)}),!0}if(n==="active"){let m=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],h={limit:p};i&&(m.push("e.source = @source"),h.source=i);let _=`
6098
6098
  SELECT e.id AS event_id, e.ts, e.source, e.project, e.subject, e.intent,
6099
6099
  d.decided_by, d.decided_at, d.agent_id, d.reason
6100
6100
  FROM intent_decisions d
@@ -6103,7 +6103,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6103
6103
  ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
6104
6104
  WHERE ${m.join(" AND ")}
6105
6105
  ORDER BY d.decided_at DESC LIMIT @limit
6106
- `;return pe(e,200,{rows:r.db.prepare(_).all(h)}),!0}return pe(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return pe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Ua(t={}){return $({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
6106
+ `;return ue(e,200,{rows:r.db.prepare(_).all(h)}),!0}return ue(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return ue(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Wa(t={}){return $({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
6107
6107
  <header class="ax-led__head">
6108
6108
  <h1>Intent ledger</h1>
6109
6109
  <p class="ax-led__sub">Read-only view over <code>.agentx/intent/ledger.sqlite</code> \u2014 same source as <code>agentx ledger</code>. Replay and lineage live in the CLI for now.</p>
@@ -6308,7 +6308,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6308
6308
  }
6309
6309
  load();
6310
6310
  })();
6311
- </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Wa(t={}){return $({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
6311
+ </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Ga(t={}){return $({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
6312
6312
  <header class="ax-cost__head">
6313
6313
  <div>
6314
6314
  <h1>Cost</h1>
@@ -6881,7 +6881,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6881
6881
  load();
6882
6882
  setInterval(load, 30000);
6883
6883
  })();
6884
- </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Ga(t={}){let e=`<div class="ax-pj__root">
6884
+ </script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Xa(t={}){let e=`<div class="ax-pj__root">
6885
6885
  <aside class="ax-pj__list">
6886
6886
  <header>
6887
6887
  <h2>Projects</h2>
@@ -6908,7 +6908,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
6908
6908
  </header>
6909
6909
  <div id="pj-detail-body" class="ax-pj__detail-body"></div>
6910
6910
  </section>
6911
- </div>`;return $({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Vo,scripts:`<script>${Yo}</script>`})}var Vo=`
6911
+ </div>`;return $({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Yo,scripts:`<script>${Qo}</script>`})}var Yo=`
6912
6912
  .ax-pj__root {
6913
6913
  display: grid;
6914
6914
  grid-template-columns: 360px 1fr;
@@ -7095,7 +7095,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
7095
7095
  }
7096
7096
  .ax-pj__warn { color: var(--ax-warn, #facc15); border-top: 1px solid var(--ax-border); }
7097
7097
  .ax-pj__hint { font-size: 11px; color: var(--ax-fg-muted, var(--ax-text)); margin-top: 4px; }
7098
- `,Yo=`
7098
+ `,Qo=`
7099
7099
  (function(){
7100
7100
  const $ = (sel) => document.querySelector(sel);
7101
7101
  const esc = (s) => String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({"&":"&amp;","<":"&lt;",">":"&gt;","\\"":"&quot;"}[c]));
@@ -7745,9 +7745,9 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
7745
7745
  load();
7746
7746
  });
7747
7747
  })();
7748
- `;import{resolve as dt,join as ps}from"path";import{existsSync as ct,readdirSync as us,readFileSync as ms}from"fs";import hs from"better-sqlite3";var Ka=String.raw`[\w.-]+(?:/[\w.-]+)+`,Qo=new RegExp(`^(?:chat:)?(${Ka}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),Zo=new RegExp(`^\\[(?:GitLab|GitHub) (${Ka}) `);function Xa(t){if(!t)return null;let e=t.match(Qo);return e?e[1]:null}function it(t){if(!t)return null;let e=t.trimStart().match(Zo);return e?e[1]:null}function He(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Xa(typeof n?.chatId=="string"?n.chatId:null)??Xa(e)??it(a)}function es(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function Ne(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var ts=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,as=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,ns=t=>/^issue/i.test(t)?"issue":"mr";function rs(t){let e=t.subject.match(ts)??t.inputPreview.trimStart().match(as);return e?{kind:ns(e[1]),n:Number(e[2])}:null}function os(t,e=8){let a=[],n=new Set;for(let r of t.matchAll(/(?:^|[\s(,])!(\d{1,6})\b/g)){let o=Number(r[1]);if(!n.has(o)&&(n.add(o),a.push({kind:"mr",n:o}),a.length>=e))break}return a}function Ja(t){if(!es(t.projectId))return[];let e=rs(t);return e?[e]:os(t.inputPreview)}var ss=6e4,is=5*6e4,ls=40,Va=6,Ya=new Map;function Qa(t){let e=new Map,a=[...t].sort((n,r)=>r.startedAt-n.startedAt);for(let n of a){let r=n.channelId==="github"||/\bpull:\d+/.test(n.subject);for(let o of Ja(n)){let s=Ne(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=ls)return[...e.values()]}}return[...e.values()]}async function Za(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=Ne(s.project,s.ref),l=Ya.get(i);l&&n-l.at<(s.github?is:ss)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Va)await Promise.all(o.slice(s,s+Va).map(async i=>{let l=Ne(i.project,i.ref),c=null;try{c=i.github?await cs(i,e,a):await ds(i,e,a)}catch{}Ya.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function en(t,e,a){let n=new AbortController,r=setTimeout(()=>n.abort(),5e3);try{let o=await a(t,{headers:e,signal:n.signal});return o.ok?await o.json():null}finally{clearTimeout(r)}}async function ds(t,e,a){let n=e.gitlab;if(!n?.host||!n.token)return null;let r=`${n.host.replace(/\/+$/,"")}/api/v4/projects/${encodeURIComponent(t.project)}`,o=t.ref.kind==="mr"?`merge_requests/${t.ref.n}`:`issues/${t.ref.n}`,s=await en(`${r}/${o}`,{"PRIVATE-TOKEN":n.token},a);if(!s)return null;let i=s.head_pipeline??s.pipeline;return{kind:t.ref.kind,project:t.project,n:t.ref.n,title:String(s.title??""),state:String(s.state??"opened"),draft:!!(s.draft??s.work_in_progress),url:String(s.web_url??""),pipeline:i&&typeof i.status=="string"?{status:i.status,url:String(i.web_url??"")}:null,mergedAt:s.merged_at?Date.parse(s.merged_at):null}}async function cs(t,e,a){let n=t.ref.kind==="mr"?`pulls/${t.ref.n}`:`issues/${t.ref.n}`,r={Accept:"application/vnd.github+json","User-Agent":"agentx-dashboard"};e.githubToken&&(r.Authorization=`Bearer ${e.githubToken}`);let o=await en(`https://api.github.com/repos/${t.project}/${n}`,r,a);return o?{kind:t.ref.kind,project:t.project,n:t.ref.n,title:String(o.title??""),state:o.merged_at?"merged":o.state==="open"?"opened":String(o.state??"opened"),draft:!!o.draft,url:String(o.html_url??""),pipeline:null,mergedAt:o.merged_at?Date.parse(o.merged_at):null}:null}function pt(){let t=dt(process.cwd(),".agentx/intent/ledger.sqlite");if(!ct(t))return null;try{let e=new hs(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-tn>6e4&&(tn=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var tn=0;function se(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var fe={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"Web API",color:"#3a7bd5"},mcp:{label:"Agent tools (MCP)",color:"#bf8700"},voice:{label:"Voice",color:"#e5534b"},desktop:{label:"Desktop assistant",color:"#8957e5"},opencode:{label:"OpenCode",color:"#57606a"}};function gs(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in fe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in fe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in fe)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in fe)return s}return"workflow"}return t}function rn(t){let e={globex:"#e07a3a",initech:"#3a7bd5",acme:"#10b981",umbrella:"#bc8cff","umbrella-lab":"#bc8cff",hexastack:"#06b6d4",demosite:"#ec775c",internal:"#6b7280",unmapped:"#d29922"};if(e[t])return e[t];let a=["#e07a3a","#3a7bd5","#10b981","#bc8cff","#ec775c","#bf8700","#5865f2","#cf222e"],n=0;for(let r=0;r<t.length;r++)n=n*31+t.charCodeAt(r)|0;return a[Math.abs(n)%a.length]}function fs(t,e){if(!t)return!1;let a=e?.agents?.[t];return a&&typeof a.system=="boolean"?a.system:!!(t==="graph-agent"||t==="intent-classifier"||/-classifier$/.test(t))}function on(t,e,a){return Lt(t,{chatId:String(e?.chatId??e?.message?.chat?.id??""),username:String(e?.sender?.username??e?.message?.from?.username??""),senderId:String(e?.sender?.id??e?.message?.from?.id??"")},a)}function xs(t,e,a){if(!a||typeof a!="object")return null;if(t==="mesh"){if(typeof a.senderAgentId=="string"&&a.senderAgentId.trim()){let r=a.senderAgentId.trim();return{id:r,name:r,avatar:F(r),kind:"a2a"}}let n=a.context&&typeof a.context=="object"?a.context:null;if(n){let r=typeof n.senderUsername=="string"?n.senderUsername:null,o=typeof n.sender=="string"?n.sender:null,s=typeof n.senderId=="string"?n.senderId:null;if(o&&o.startsWith("agent:")){let l=o.slice(6);if(l&&!lt(l))return{id:l,name:l,avatar:F(l),kind:"a2a"}}let i=o||r||s;if(i&&!lt(r||o||"")){let l=r||o||s,c=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":e==="mesh.voice"?"voice":e==="mesh.desktop"?"desktop":"mesh";return{id:l,name:o||r||l,avatar:F(i),kind:c}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,c=i||(s.id!=null?String(s.id):null)||l;if(c&&!lt(i||l||"")){let p=typeof n.channel=="string"?n.channel:"",m=an(p);return{id:c,name:l||i||c,avatar:F(l||i||c),kind:m}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,c=s.name||s.username;return{id:l,name:c,avatar:F(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:F(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:F(i),kind:an(t)}}}if(t==="gitlab"){let n=a.user||a.payload?.user;if(n&&typeof n=="object"&&(n.username||n.name)){let r=n.username||n.name,o=n.name||n.username;return{id:r,name:o,avatar:F(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:F(n.login),kind:"github"}}if(t==="telegram"){let n=a.message?.from||a.from;if(n?.username){let r=n.first_name||n.username;return{id:n.username,name:r,avatar:F(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:F(n.first_name||`tg${n.id}`),kind:"telegram"}}if(t==="whatsapp"){let n=a.from||a.payload?.from;if(n){let r=String(n),o=r.replace(/@.*$/,"");return{id:r,name:o,avatar:F(o),kind:"whatsapp"}}}return null}function an(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function lt(t){if(!t)return!1;let e=t.toLowerCase();return e==="graph-classifier"||e==="graph-agent"||e.startsWith("system:")||e.startsWith("internal:")||e.endsWith("-system")}function F(t){let e=String(t||"?").trim().split(/\s+/).filter(Boolean);return e.length>=2?(e[0][0]+e[1][0]).toUpperCase():String(t||"?").slice(0,2).toUpperCase()}function sn(t,e){if(!e||typeof e!="object")return"";let a=[];if(typeof e.text=="string"&&a.push(e.text),e.message?.text&&a.push(e.message.text),e.message?.caption&&a.push(e.message.caption),e.object_attributes?.note&&a.push(e.object_attributes.note),e.object_attributes?.title){let n=e.object_attributes.title,r=e.object_attributes.description;a.push(r?`${n}
7748
+ `;import{resolve as ct,join as us}from"path";import{existsSync as pt,readdirSync as ms,readFileSync as hs}from"fs";import gs from"better-sqlite3";var Ja=String.raw`[\w.-]+(?:/[\w.-]+)+`,Zo=new RegExp(`^(?:chat:)?(${Ja}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),es=new RegExp(`^\\[(?:GitLab|GitHub) (${Ja}) `);function Ka(t){if(!t)return null;let e=t.match(Zo);return e?e[1]:null}function lt(t){if(!t)return null;let e=t.trimStart().match(es);return e?e[1]:null}function Ne(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Ka(typeof n?.chatId=="string"?n.chatId:null)??Ka(e)??lt(a)}function ts(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function Be(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var as=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,ns=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,rs=t=>/^issue/i.test(t)?"issue":"mr";function os(t){let e=t.subject.match(as)??t.inputPreview.trimStart().match(ns);return e?{kind:rs(e[1]),n:Number(e[2])}:null}function ss(t,e=8){let a=[],n=new Set;for(let r of t.matchAll(/(?:^|[\s(,])!(\d{1,6})\b/g)){let o=Number(r[1]);if(!n.has(o)&&(n.add(o),a.push({kind:"mr",n:o}),a.length>=e))break}return a}function Va(t){if(!ts(t.projectId))return[];let e=os(t);return e?[e]:ss(t.inputPreview)}var is=6e4,ls=5*6e4,ds=40,Ya=6,Qa=new Map;function Za(t){let e=new Map,a=[...t].sort((n,r)=>r.startedAt-n.startedAt);for(let n of a){let r=n.channelId==="github"||/\bpull:\d+/.test(n.subject);for(let o of Va(n)){let s=Be(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=ds)return[...e.values()]}}return[...e.values()]}async function en(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=Be(s.project,s.ref),l=Qa.get(i);l&&n-l.at<(s.github?ls:is)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Ya)await Promise.all(o.slice(s,s+Ya).map(async i=>{let l=Be(i.project,i.ref),c=null;try{c=i.github?await ps(i,e,a):await cs(i,e,a)}catch{}Qa.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function tn(t,e,a){let n=new AbortController,r=setTimeout(()=>n.abort(),5e3);try{let o=await a(t,{headers:e,signal:n.signal});return o.ok?await o.json():null}finally{clearTimeout(r)}}async function cs(t,e,a){let n=e.gitlab;if(!n?.host||!n.token)return null;let r=`${n.host.replace(/\/+$/,"")}/api/v4/projects/${encodeURIComponent(t.project)}`,o=t.ref.kind==="mr"?`merge_requests/${t.ref.n}`:`issues/${t.ref.n}`,s=await tn(`${r}/${o}`,{"PRIVATE-TOKEN":n.token},a);if(!s)return null;let i=s.head_pipeline??s.pipeline;return{kind:t.ref.kind,project:t.project,n:t.ref.n,title:String(s.title??""),state:String(s.state??"opened"),draft:!!(s.draft??s.work_in_progress),url:String(s.web_url??""),pipeline:i&&typeof i.status=="string"?{status:i.status,url:String(i.web_url??"")}:null,mergedAt:s.merged_at?Date.parse(s.merged_at):null}}async function ps(t,e,a){let n=t.ref.kind==="mr"?`pulls/${t.ref.n}`:`issues/${t.ref.n}`,r={Accept:"application/vnd.github+json","User-Agent":"agentx-dashboard"};e.githubToken&&(r.Authorization=`Bearer ${e.githubToken}`);let o=await tn(`https://api.github.com/repos/${t.project}/${n}`,r,a);return o?{kind:t.ref.kind,project:t.project,n:t.ref.n,title:String(o.title??""),state:o.merged_at?"merged":o.state==="open"?"opened":String(o.state??"opened"),draft:!!o.draft,url:String(o.html_url??""),pipeline:null,mergedAt:o.merged_at?Date.parse(o.merged_at):null}:null}function ut(){let t=ct(process.cwd(),".agentx/intent/ledger.sqlite");if(!pt(t))return null;try{let e=new gs(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-an>6e4&&(an=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var an=0;function se(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var xe={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"Web API",color:"#3a7bd5"},mcp:{label:"Agent tools (MCP)",color:"#bf8700"},voice:{label:"Voice",color:"#e5534b"},desktop:{label:"Desktop assistant",color:"#8957e5"},opencode:{label:"OpenCode",color:"#57606a"}};function fs(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in xe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in xe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in xe)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in xe)return s}return"workflow"}return t}function on(t){let e={globex:"#e07a3a",initech:"#3a7bd5",acme:"#10b981",umbrella:"#bc8cff","umbrella-lab":"#bc8cff",hexastack:"#06b6d4",demosite:"#ec775c",internal:"#6b7280",unmapped:"#d29922"};if(e[t])return e[t];let a=["#e07a3a","#3a7bd5","#10b981","#bc8cff","#ec775c","#bf8700","#5865f2","#cf222e"],n=0;for(let r=0;r<t.length;r++)n=n*31+t.charCodeAt(r)|0;return a[Math.abs(n)%a.length]}function xs(t,e){if(!t)return!1;let a=e?.agents?.[t];return a&&typeof a.system=="boolean"?a.system:!!(t==="graph-agent"||t==="intent-classifier"||/-classifier$/.test(t))}function sn(t,e,a){return Rt(t,{chatId:String(e?.chatId??e?.message?.chat?.id??""),username:String(e?.sender?.username??e?.message?.from?.username??""),senderId:String(e?.sender?.id??e?.message?.from?.id??"")},a)}function vs(t,e,a){if(!a||typeof a!="object")return null;if(t==="mesh"){if(typeof a.senderAgentId=="string"&&a.senderAgentId.trim()){let r=a.senderAgentId.trim();return{id:r,name:r,avatar:F(r),kind:"a2a"}}let n=a.context&&typeof a.context=="object"?a.context:null;if(n){let r=typeof n.senderUsername=="string"?n.senderUsername:null,o=typeof n.sender=="string"?n.sender:null,s=typeof n.senderId=="string"?n.senderId:null;if(o&&o.startsWith("agent:")){let l=o.slice(6);if(l&&!dt(l))return{id:l,name:l,avatar:F(l),kind:"a2a"}}let i=o||r||s;if(i&&!dt(r||o||"")){let l=r||o||s,c=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":e==="mesh.voice"?"voice":e==="mesh.desktop"?"desktop":"mesh";return{id:l,name:o||r||l,avatar:F(i),kind:c}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,c=i||(s.id!=null?String(s.id):null)||l;if(c&&!dt(i||l||"")){let p=typeof n.channel=="string"?n.channel:"",m=nn(p);return{id:c,name:l||i||c,avatar:F(l||i||c),kind:m}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,c=s.name||s.username;return{id:l,name:c,avatar:F(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:F(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:F(i),kind:nn(t)}}}if(t==="gitlab"){let n=a.user||a.payload?.user;if(n&&typeof n=="object"&&(n.username||n.name)){let r=n.username||n.name,o=n.name||n.username;return{id:r,name:o,avatar:F(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:F(n.login),kind:"github"}}if(t==="telegram"){let n=a.message?.from||a.from;if(n?.username){let r=n.first_name||n.username;return{id:n.username,name:r,avatar:F(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:F(n.first_name||`tg${n.id}`),kind:"telegram"}}if(t==="whatsapp"){let n=a.from||a.payload?.from;if(n){let r=String(n),o=r.replace(/@.*$/,"");return{id:r,name:o,avatar:F(o),kind:"whatsapp"}}}return null}function nn(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function dt(t){if(!t)return!1;let e=t.toLowerCase();return e==="graph-classifier"||e==="graph-agent"||e.startsWith("system:")||e.startsWith("internal:")||e.endsWith("-system")}function F(t){let e=String(t||"?").trim().split(/\s+/).filter(Boolean);return e.length>=2?(e[0][0]+e[1][0]).toUpperCase():String(t||"?").slice(0,2).toUpperCase()}function ln(t,e){if(!e||typeof e!="object")return"";let a=[];if(typeof e.text=="string"&&a.push(e.text),e.message?.text&&a.push(e.message.text),e.message?.caption&&a.push(e.message.caption),e.object_attributes?.note&&a.push(e.object_attributes.note),e.object_attributes?.title){let n=e.object_attributes.title,r=e.object_attributes.description;a.push(r?`${n}
7749
7749
  ${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
7750
- ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof e.message=="string"&&a.push(e.message),typeof e.prompt=="string"&&a.push(e.prompt),typeof e.input=="string"&&a.push(e.input),e.payload&&typeof e.payload.text=="string"&&a.push(e.payload.text),e.payload&&typeof e.payload.message=="string"&&a.push(e.payload.message);for(let n of a)if(typeof n=="string"&&n.trim().length>0){let r=n.trim();return r.length>220?r.slice(0,217)+"\u2026":r}return""}function vs(t){if(!t)return"(no subject)";let e;return(e=t.match(/^merge_request:(\d+)(?::note:(\d+))?/))?e[2]?`MR #${e[1]} \xB7 note ${e[2]}`:`MR #${e[1]}`:(e=t.match(/^issue:(\d+)(?::note:(\d+))?/))?e[2]?`Issue #${e[1]} \xB7 note ${e[2]}`:`Issue #${e[1]}`:(e=t.match(/^chat:(.+?):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,40)}`:(e=t.match(/^mesh:agent:(.+)$/))?`\u2192 ${e[1]}`:(e=t.match(/^workflow:([^:]+):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,30)}`:t.length>60?t.slice(0,57)+"\u2026":t}function ln(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
7750
+ ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof e.message=="string"&&a.push(e.message),typeof e.prompt=="string"&&a.push(e.prompt),typeof e.input=="string"&&a.push(e.input),e.payload&&typeof e.payload.text=="string"&&a.push(e.payload.text),e.payload&&typeof e.payload.message=="string"&&a.push(e.payload.message);for(let n of a)if(typeof n=="string"&&n.trim().length>0){let r=n.trim();return r.length>220?r.slice(0,217)+"\u2026":r}return""}function bs(t){if(!t)return"(no subject)";let e;return(e=t.match(/^merge_request:(\d+)(?::note:(\d+))?/))?e[2]?`MR #${e[1]} \xB7 note ${e[2]}`:`MR #${e[1]}`:(e=t.match(/^issue:(\d+)(?::note:(\d+))?/))?e[2]?`Issue #${e[1]} \xB7 note ${e[2]}`:`Issue #${e[1]}`:(e=t.match(/^chat:(.+?):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,40)}`:(e=t.match(/^mesh:agent:(.+)$/))?`\u2192 ${e[1]}`:(e=t.match(/^workflow:([^:]+):(.+)$/))?`${e[1]} \xB7 ${e[2].slice(0,30)}`:t.length>60?t.slice(0,57)+"\u2026":t}function dn(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
7751
7751
  SELECT id, ts, source, project, subject, intent, raw_json
7752
7752
  FROM intent_events WHERE ts >= ? ORDER BY ts ASC
7753
7753
  `).all(r),s=new Map,i=new Map;if(o.length>0){let x=o.map(I=>I.id),y=x.map((I,L)=>`@id${L}`).join(","),M=Object.fromEntries(x.map((I,L)=>[`id${L}`,I])),A=t.prepare(`
@@ -7756,11 +7756,11 @@ ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof
7756
7756
  `).all(M);for(let I of A)s.has(I.event_id)||s.set(I.event_id,[]),s.get(I.event_id).push(I);let k=t.prepare(`
7757
7757
  SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
7758
7758
  FROM intent_resolutions WHERE decision_event_id IN (${y})
7759
- `).all(M);for(let I of k)i.set(`${I.decision_event_id}|${I.decision_decided_by}`,I)}let l=new Map,c=new Map,p=new Map,m=new Map,h=[],_=e?.business?.projects??[],S=e?.business?.contactMap??[],w=Je(e?.business??{});for(let x of o){let y=null;try{y=JSON.parse(x.raw_json)}catch{}let M=on(x.source,y,S),A=sn(x.source,y),k=x.project??He(y,x.subject,A),I=null,L=null;M?(I=M.client,L=M.project||`${M.client}/_chat`):k&&(I=Ee(k,_),L=k);let R=gs(x.source,x.intent||"",y),N=fe[R]||{label:R,color:"#6b7280"};p.has(R)||p.set(R,{id:R,label:N.label,color:N.color});let Z="__system",B,O=xs(x.source,x.intent||"",y);if(O){Z=O.id,B=O.kind;let H=M?.displayName||O.name;(!m.has(O.id)||M?.displayName)&&m.set(O.id,{id:O.id,name:H,avatar:F(H),kind:O.kind})}else m.has("__system")||m.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});for(let H of s.get(x.id)??[]){if(H.outcome!=="dispatched"||!H.agent_id)continue;let G=`${x.id}|${H.decided_by}`,z=i.get(G),X=H.decided_at,kt=z?.resolved_at??null,Ue=kt===null,Wn=z?.duration_ms??(Ue?n-X:0),Gn=Ue?"active":z?.status==="error"||z?.status==="fail"?"error":"completed",W,ve;if(I)W=I,ve=L;else{let We=w.get(H.agent_id);We?(W=We,ve=`${We}/_${x.source}`):(W="unmapped",ve=`unmapped/_${x.source}`)}l.has(W)||l.set(W,{id:W,name:W,color:rn(W),projects:[]}),c.has(W)||c.set(W,new Set),c.get(W).add(ve),h.push({id:`${x.id}|${H.decided_by}`,agentId:H.agent_id,clientId:W,projectId:ve,channelId:R,initiatorId:Z,initiatorKind:B,subject:vs(x.subject),intent:x.intent||"",startedAt:X,resolvedAt:kt,duration:Wn,active:Ue,outcome:Gn,tokens:0,inputPreview:A,system:fs(H.agent_id,e)})}}let E=[...l.values()].map(x=>({...x,projects:[...c.get(x.id)||[]].sort()})).sort((x,y)=>x.id.localeCompare(y.id)),T=[],d=new Set;if(e){let x=e.business??{},y=M=>{let A=x.orgChart?.[M]?.role,k=A?x.roles?.[A]?.title:void 0;return typeof k=="string"&&k.trim()?k.trim():void 0};for(let[M,A]of Object.entries(e.agents||{})){let k={id:M,name:A.name||M,tier:A.tier==="claude-code"?"lead":"worker",model:A.model||"",role:A.systemPrompt?A.systemPrompt.split(/[.\n]/)[0].slice(0,60):A.tier||"",title:y(M)};T.push(k),d.add(M)}}for(let x of h)d.has(x.agentId)||(T.push({id:x.agentId,name:x.agentId,tier:"worker",model:"",role:""}),d.add(x.agentId));T.sort((x,y)=>x.id.localeCompare(y.id));let u=[],g=new Set;for(let[x,y]of Object.entries(fe))u.push({id:x,label:y.label,color:y.color}),g.add(x);for(let x of p.values())g.has(x.id)||u.push(x);let f=[...m.values()];f.find(x=>x.id==="__system")||f.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let b=e?.channels?.gitlab?.host;return{now:n,windowH:a,clients:E,agents:T,channels:u,initiators:f,dispatches:h,forges:{gitlab:typeof b=="string"?b:void 0,github:"https://github.com"}}}function ut(t){let e=pt();if(!e)return null;try{return ln(e.db,le,t)}finally{e.close()}}function dn(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,i=0,l={};for(let{nodeId:c,snap:p}of t){l.gitlab??=p.forges?.gitlab,l.github??=p.forges?.github,p.now>s&&(s=p.now),p.windowH>i&&(i=p.windowH);for(let m of p.clients){let h=e.get(m.id);if(!h)e.set(m.id,{...m,projects:[...m.projects]});else{let _=Array.from(new Set([...h.projects,...m.projects])).sort();e.set(m.id,{...h,projects:_})}}for(let m of p.agents)a.has(m.id)||a.set(m.id,m);for(let m of p.channels)n.has(m.id)||n.set(m.id,m);for(let m of p.initiators)r.has(m.id)||r.set(m.id,m);for(let m of p.dispatches){let h=bs(m);if(h.clientId!==m.clientId&&!e.has(h.clientId)&&e.set(h.clientId,{id:h.clientId,name:h.clientId,color:rn(h.clientId),projects:[]}),h.projectId!==m.projectId){let _=e.get(h.clientId);_.projects.includes(h.projectId)||e.set(h.clientId,{..._,projects:[..._.projects,h.projectId].sort()})}o.push({...h,nodeId:c,id:`${c}::${h.id}`})}}return{now:s||Date.now(),windowH:i||6,localNodeId:t[0]?.nodeId,forges:l,clients:[...e.values()].sort((c,p)=>c.id.localeCompare(p.id)),agents:[...a.values()].sort((c,p)=>c.id.localeCompare(p.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((c,p)=>p.startedAt-c.startedAt)}}function bs(t){if(t.clientId!=="unmapped")return t;let e=it(t.inputPreview);if(!e)return t;let a=le?.business?.projects??[];return{...t,projectId:e,clientId:Ee(e,a)}}async function Be(t){let e=le?.channels?.gitlab,a=await Za(Qa(t.dispatches),{gitlab:e?.host&&e?.token?{host:e.host,token:e.token}:void 0,githubToken:process.env.GITHUB_TOKEN||void 0});return{...t,forge:a}}var le=null;function cn(t){le=t}async function pn(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=pt();if(!n)return se(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=un(parseInt(r.searchParams.get("hours")||"6",10));se(e,200,await Be(ln(n.db,le,o)))}catch(r){se(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var ys=5e3;async function mt(t,e,a,n=ut){if(a!=="/api/admin/activity-graph/stream"&&!a.startsWith("/api/admin/activity-graph/stream?"))return!1;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: connected
7759
+ `).all(M);for(let I of k)i.set(`${I.decision_event_id}|${I.decision_decided_by}`,I)}let l=new Map,c=new Map,p=new Map,m=new Map,h=[],_=e?.business?.projects??[],S=e?.business?.contactMap??[],w=Ve(e?.business??{});for(let x of o){let y=null;try{y=JSON.parse(x.raw_json)}catch{}let M=sn(x.source,y,S),A=ln(x.source,y),k=x.project??Ne(y,x.subject,A),I=null,L=null;M?(I=M.client,L=M.project||`${M.client}/_chat`):k&&(I=Se(k,_),L=k);let R=fs(x.source,x.intent||"",y),N=xe[R]||{label:R,color:"#6b7280"};p.has(R)||p.set(R,{id:R,label:N.label,color:N.color});let Z="__system",B,O=vs(x.source,x.intent||"",y);if(O){Z=O.id,B=O.kind;let H=M?.displayName||O.name;(!m.has(O.id)||M?.displayName)&&m.set(O.id,{id:O.id,name:H,avatar:F(H),kind:O.kind})}else m.has("__system")||m.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});for(let H of s.get(x.id)??[]){if(H.outcome!=="dispatched"||!H.agent_id)continue;let G=`${x.id}|${H.decided_by}`,z=i.get(G),X=H.decided_at,_t=z?.resolved_at??null,We=_t===null,Gn=z?.duration_ms??(We?n-X:0),Xn=We?"active":z?.status==="error"||z?.status==="fail"?"error":"completed",W,be;if(I)W=I,be=L;else{let Ge=w.get(H.agent_id);Ge?(W=Ge,be=`${Ge}/_${x.source}`):(W="unmapped",be=`unmapped/_${x.source}`)}l.has(W)||l.set(W,{id:W,name:W,color:on(W),projects:[]}),c.has(W)||c.set(W,new Set),c.get(W).add(be),h.push({id:`${x.id}|${H.decided_by}`,agentId:H.agent_id,clientId:W,projectId:be,channelId:R,initiatorId:Z,initiatorKind:B,subject:bs(x.subject),intent:x.intent||"",startedAt:X,resolvedAt:_t,duration:Gn,active:We,outcome:Xn,tokens:0,inputPreview:A,system:xs(H.agent_id,e)})}}let E=[...l.values()].map(x=>({...x,projects:[...c.get(x.id)||[]].sort()})).sort((x,y)=>x.id.localeCompare(y.id)),T=[],d=new Set;if(e){let x=e.business??{},y=M=>{let A=x.orgChart?.[M]?.role,k=A?x.roles?.[A]?.title:void 0;return typeof k=="string"&&k.trim()?k.trim():void 0};for(let[M,A]of Object.entries(e.agents||{})){let k={id:M,name:A.name||M,tier:A.tier==="claude-code"?"lead":"worker",model:A.model||"",role:A.systemPrompt?A.systemPrompt.split(/[.\n]/)[0].slice(0,60):A.tier||"",title:y(M)};T.push(k),d.add(M)}}for(let x of h)d.has(x.agentId)||(T.push({id:x.agentId,name:x.agentId,tier:"worker",model:"",role:""}),d.add(x.agentId));T.sort((x,y)=>x.id.localeCompare(y.id));let u=[],g=new Set;for(let[x,y]of Object.entries(xe))u.push({id:x,label:y.label,color:y.color}),g.add(x);for(let x of p.values())g.has(x.id)||u.push(x);let f=[...m.values()];f.find(x=>x.id==="__system")||f.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let b=e?.channels?.gitlab?.host;return{now:n,windowH:a,clients:E,agents:T,channels:u,initiators:f,dispatches:h,forges:{gitlab:typeof b=="string"?b:void 0,github:"https://github.com"}}}function mt(t){let e=ut();if(!e)return null;try{return dn(e.db,le,t)}finally{e.close()}}function cn(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,i=0,l={};for(let{nodeId:c,snap:p}of t){l.gitlab??=p.forges?.gitlab,l.github??=p.forges?.github,p.now>s&&(s=p.now),p.windowH>i&&(i=p.windowH);for(let m of p.clients){let h=e.get(m.id);if(!h)e.set(m.id,{...m,projects:[...m.projects]});else{let _=Array.from(new Set([...h.projects,...m.projects])).sort();e.set(m.id,{...h,projects:_})}}for(let m of p.agents)a.has(m.id)||a.set(m.id,m);for(let m of p.channels)n.has(m.id)||n.set(m.id,m);for(let m of p.initiators)r.has(m.id)||r.set(m.id,m);for(let m of p.dispatches){let h=ys(m);if(h.clientId!==m.clientId&&!e.has(h.clientId)&&e.set(h.clientId,{id:h.clientId,name:h.clientId,color:on(h.clientId),projects:[]}),h.projectId!==m.projectId){let _=e.get(h.clientId);_.projects.includes(h.projectId)||e.set(h.clientId,{..._,projects:[..._.projects,h.projectId].sort()})}o.push({...h,nodeId:c,id:`${c}::${h.id}`})}}return{now:s||Date.now(),windowH:i||6,localNodeId:t[0]?.nodeId,forges:l,clients:[...e.values()].sort((c,p)=>c.id.localeCompare(p.id)),agents:[...a.values()].sort((c,p)=>c.id.localeCompare(p.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((c,p)=>p.startedAt-c.startedAt)}}function ys(t){if(t.clientId!=="unmapped")return t;let e=lt(t.inputPreview);if(!e)return t;let a=le?.business?.projects??[];return{...t,projectId:e,clientId:Se(e,a)}}async function ze(t){let e=le?.channels?.gitlab,a=await en(Za(t.dispatches),{gitlab:e?.host&&e?.token?{host:e.host,token:e.token}:void 0,githubToken:process.env.GITHUB_TOKEN||void 0});return{...t,forge:a}}var le=null;function pn(t){le=t}async function un(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=ut();if(!n)return se(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=mn(parseInt(r.searchParams.get("hours")||"6",10));se(e,200,await ze(dn(n.db,le,o)))}catch(r){se(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var ws=5e3;async function ht(t,e,a,n=mt){if(a!=="/api/admin/activity-graph/stream"&&!a.startsWith("/api/admin/activity-graph/stream?"))return!1;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: connected
7760
7760
 
7761
- `);let r=new URL(t.url||"/","http://_"),o=un(parseInt(r.searchParams.get("hours")||"6",10)),s=!1,i=()=>{s=!0};t.on("close",i),t.on("error",i),e.on("close",i),e.on("error",i);let l=setInterval(()=>{if(!s)try{e.write(`: hb
7761
+ `);let r=new URL(t.url||"/","http://_"),o=mn(parseInt(r.searchParams.get("hours")||"6",10)),s=!1,i=()=>{s=!0};t.on("close",i),t.on("error",i),e.on("close",i),e.on("error",i);let l=setInterval(()=>{if(!s)try{e.write(`: hb
7762
7762
 
7763
- `)}catch{i()}},25e3);try{for(;!s;){try{let p=await n(o),m=p&&await Be(p);if(s)break;m?(e.write(`event: snapshot
7763
+ `)}catch{i()}},25e3);try{for(;!s;){try{let p=await n(o),m=p&&await ze(p);if(s)break;m?(e.write(`event: snapshot
7764
7764
  `),e.write(`data: ${JSON.stringify(m)}
7765
7765
 
7766
7766
  `)):e.write(`event: error
@@ -7769,7 +7769,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
7769
7769
  `)}catch(p){e.write(`event: error
7770
7770
  data: ${JSON.stringify({error:p?.message??String(p)})}
7771
7771
 
7772
- `)}let c=Date.now();for(;!s&&Date.now()-c<ys;)await new Promise(p=>setTimeout(p,200))}}finally{clearInterval(l);try{e.end()}catch{}}return!0}function un(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function ws(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=dt(process.cwd(),".agentx/task-history",t,n);if(!ct(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=dt(process.cwd(),".agentx/task-history",t,o);return ct(s)?nn(s,e,a):null}return nn(r,e,a)}function nn(t,e,a){let n=null,r=1/0;for(let o of us(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(ms(ps(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let p=Date.parse(i);if(!Number.isFinite(p))continue;l=p}else continue;let c=Math.abs(l-e);c<r&&c<=a&&(n=s,r=c)}return n}async function mn(t,e,a){let n=a.match(/^\/api\/admin\/activity-graph\/dispatch\/([^/?]+)(?:\?.*)?$/);if(!n)return!1;let r=decodeURIComponent(n[1]),o=r.indexOf("|");if(o<0)return se(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=pt();if(!l)return se(e,503,{error:"ledger not available"}),!0;try{let c=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!c)return se(e,404,{error:"event not found"}),!0;let p=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!p)return se(e,404,{error:"decision not found"}),!0;let m=l.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,i),h=null;try{h=JSON.parse(c.raw_json)}catch{}let _=sn(c.source,h),S=h&&typeof h=="object"&&(h.text||h.message?.text||h.message?.caption||h.object_attributes?.note||h.object_attributes?.description||h.comment?.body||h.issue?.body||(typeof h.message=="string"?h.message:null)||(typeof h.prompt=="string"?h.prompt:null)||null)||_,w=null,E=null;if(p.agent_id){let b=ws(p.agent_id,p.decided_at);if(b){typeof b.responseText=="string"&&(w=b.responseText);let x=b.transcript;Array.isArray(x)&&(E=x.length)}}let T=le?.business?.projects??[],d=le?.business?.contactMap??[],u=Je(le?.business??{}),g={client:"unmapped",project:`unmapped/_${c.source}`,via:"fallback"},f=on(c.source,h,d);if(f)g={client:f.client,project:f.project||`${f.client}/_chat`,via:`contactMap (channel=${f.channel??"*"}${f.username?` username=${f.username}`:""}${f.chatId?` chatId=${f.chatId}`:""})`};else if(c.project||He(h,c.subject,_)){let b=c.project||He(h,c.subject,_);g={client:Ee(b,T),project:b,via:c.project?`project namespace prefix (${b})`:`forge path in chat id / message (${b})`}}else if(p.agent_id){let b=u.get(p.agent_id);b&&(g={client:b,project:`${b}/_${c.source}`,via:`orgChart fallback (agent ${p.agent_id} reports up to a PM whose project belongs to ${b})`})}se(e,200,{id:r,eventId:s,source:c.source,subject:c.subject,intent:c.intent,project:c.project,decidedBy:p.decided_by,agentId:p.agent_id,outcome:p.outcome,reason:p.reason,startedAt:p.decided_at,resolvedAt:m?.resolved_at??null,durationMs:m?.duration_ms??null,input:S,response:w,transcriptLen:E,resolutionStatus:m?.status??null,resultSummary:m?.result_summary??null,attribution:g})}catch(c){se(e,500,{error:c?.message??String(c)})}finally{l.close()}return!0}import{existsSync as Ss,readFileSync as Ts}from"fs";import{resolve as gn}from"path";Ge();function hn(t){let e=t.agentId,a=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",n=`<script>window.AGENT_ID = ${JSON.stringify(e)};</script>`,r=ks.replace(/__AGENT_ID__/g,P(e));return $({title:`AgentX \xB7 ${P(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${P(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:_s,headExtras:'<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">',scripts:`${n}${a}<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script><script>${Es}</script>`})}var ks=`
7772
+ `)}let c=Date.now();for(;!s&&Date.now()-c<ws;)await new Promise(p=>setTimeout(p,200))}}finally{clearInterval(l);try{e.end()}catch{}}return!0}function mn(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function ks(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=ct(process.cwd(),".agentx/task-history",t,n);if(!pt(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=ct(process.cwd(),".agentx/task-history",t,o);return pt(s)?rn(s,e,a):null}return rn(r,e,a)}function rn(t,e,a){let n=null,r=1/0;for(let o of ms(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(hs(us(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let p=Date.parse(i);if(!Number.isFinite(p))continue;l=p}else continue;let c=Math.abs(l-e);c<r&&c<=a&&(n=s,r=c)}return n}async function hn(t,e,a){let n=a.match(/^\/api\/admin\/activity-graph\/dispatch\/([^/?]+)(?:\?.*)?$/);if(!n)return!1;let r=decodeURIComponent(n[1]),o=r.indexOf("|");if(o<0)return se(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=ut();if(!l)return se(e,503,{error:"ledger not available"}),!0;try{let c=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!c)return se(e,404,{error:"event not found"}),!0;let p=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!p)return se(e,404,{error:"decision not found"}),!0;let m=l.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,i),h=null;try{h=JSON.parse(c.raw_json)}catch{}let _=ln(c.source,h),S=h&&typeof h=="object"&&(h.text||h.message?.text||h.message?.caption||h.object_attributes?.note||h.object_attributes?.description||h.comment?.body||h.issue?.body||(typeof h.message=="string"?h.message:null)||(typeof h.prompt=="string"?h.prompt:null)||null)||_,w=null,E=null;if(p.agent_id){let b=ks(p.agent_id,p.decided_at);if(b){typeof b.responseText=="string"&&(w=b.responseText);let x=b.transcript;Array.isArray(x)&&(E=x.length)}}let T=le?.business?.projects??[],d=le?.business?.contactMap??[],u=Ve(le?.business??{}),g={client:"unmapped",project:`unmapped/_${c.source}`,via:"fallback"},f=sn(c.source,h,d);if(f)g={client:f.client,project:f.project||`${f.client}/_chat`,via:`contactMap (channel=${f.channel??"*"}${f.username?` username=${f.username}`:""}${f.chatId?` chatId=${f.chatId}`:""})`};else if(c.project||Ne(h,c.subject,_)){let b=c.project||Ne(h,c.subject,_);g={client:Se(b,T),project:b,via:c.project?`project namespace prefix (${b})`:`forge path in chat id / message (${b})`}}else if(p.agent_id){let b=u.get(p.agent_id);b&&(g={client:b,project:`${b}/_${c.source}`,via:`orgChart fallback (agent ${p.agent_id} reports up to a PM whose project belongs to ${b})`})}se(e,200,{id:r,eventId:s,source:c.source,subject:c.subject,intent:c.intent,project:c.project,decidedBy:p.decided_by,agentId:p.agent_id,outcome:p.outcome,reason:p.reason,startedAt:p.decided_at,resolvedAt:m?.resolved_at??null,durationMs:m?.duration_ms??null,input:S,response:w,transcriptLen:E,resolutionStatus:m?.status??null,resultSummary:m?.result_summary??null,attribution:g})}catch(c){se(e,500,{error:c?.message??String(c)})}finally{l.close()}return!0}import{existsSync as Ts,readFileSync as Cs}from"fs";import{resolve as fn}from"path";Xe();function gn(t){let e=t.agentId,a=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",n=`<script>window.AGENT_ID = ${JSON.stringify(e)};</script>`,r=_s.replace(/__AGENT_ID__/g,P(e));return $({title:`AgentX \xB7 ${P(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${P(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:Es,headExtras:'<link rel="stylesheet" href="https://unpkg.com/easymde/dist/easymde.min.css">',scripts:`${n}${a}<script src="https://unpkg.com/easymde/dist/easymde.min.js"></script><script>${Ss}</script>`})}var _s=`
7773
7773
  <!-- Breadcrumb -->
7774
7774
  <div class="ax-crumb">
7775
7775
  <a href="/admin">Settings</a>
@@ -8358,7 +8358,7 @@ data: ${JSON.stringify({error:p?.message??String(p)})}
8358
8358
  </div>
8359
8359
  </div>
8360
8360
  </div>
8361
- `,_s=`
8361
+ `,Es=`
8362
8362
  /* Agent-specific layout + legacy styles for bits the migration left in
8363
8363
  * place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
8364
8364
  * primitives live in components.css.ts. */
@@ -8477,7 +8477,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
8477
8477
 
8478
8478
  /* Agent-specific button variant used in rail context (no ax-btn wrapper) */
8479
8479
  .ax-btn.lg { padding: 9px 16px; font-size: 13px; }
8480
- `,Es=`
8480
+ `,Ss=`
8481
8481
  const $ = (id) => document.getElementById(id);
8482
8482
  const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
8483
8483
 
@@ -9331,15 +9331,15 @@ document.addEventListener('keydown', (e) => {
9331
9331
  /* ===== Boot ===== */
9332
9332
  initOptsToggles();
9333
9333
  loadAgent();
9334
- `;function fn(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(hn({agentId:a,peers:n,localToken:r}))}async function xn(t,e,a){try{let n=t.method==="GET"?void 0:await Ks(t),r=new URL(t.url||"/","http://localhost"),o=Object.fromEntries(r.searchParams),s=a.match(/^\/api\/admin\/agent\/([a-z0-9][a-z0-9_-]*)(?:\/(.+))?$/);if(!s){ze(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",c=`${t.method} ${l}`,m={"GET ":()=>ke(i),"PATCH ":()=>Cs(i,n),"PATCH capability":()=>Is(i,n),"POST mcp":()=>As(i,n),"DELETE mcp":()=>Ms(i,n),"GET identity":()=>$s(i),"GET identity/file":()=>js(i,String(o.path||"")),"PUT identity/file":()=>Ls(i,n),"GET skills":()=>Rs(i),"POST skills":()=>Ps(i,n),"DELETE skills":()=>Ds(i,n),"GET skills/tree":()=>Os(i,String(o.slug||"")),"GET skills/file":()=>Hs(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>Ns(i,n),"GET skills/deps":()=>Bs(i,String(o.slug||"")),"POST skills/install":()=>zs(i,n,t),"POST skills/deps":()=>qs(i,n,t),"GET channels":()=>Fs(i),"GET activity":()=>Us(i,t),"GET handovers":()=>Ws(i),"POST handovers":()=>Gs(i,n),"DELETE handovers":()=>Xs(n)}[c];if(!m){ze(e,404,{error:`unknown agent sub-endpoint: ${c}`});return}let h=await m();ze(e,200,h)}catch(n){ze(e,400,{error:n?.message||"agent op failed"})}}function vn(){let t=gn(process.cwd(),"agentx.json");return Ss(t)?JSON.parse(Ts(t,"utf-8")):null}function U(t){let e=vn();if(!e)throw new Error("agentx.json not found");let a=e.agents?.[t];if(!a)throw new Error(`Agent "${t}" not found`);return{def:a,cfg:e}}function ke(t){let{def:e,cfg:a}=U(t),n=e.workspace?me(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",intents:Array.isArray(e.intents)?e.intents:[],maxDelegationDepth:e.maxDelegationDepth??5,contextReferences:!!e.contextReferences,contextStrategy:e.contextStrategy||"",mcp:e.mcp&&typeof e.mcp=="object"?e.mcp:{},overview:n,defaultWorker:a.node?.defaultAgent,draftAgent:a.dashboard?.draftAgent}}function Cs(t,e){let a={};for(let r of["name","tier","model","systemPrompt","mentions","access","maxConcurrent","maxExecutionMinutes","permissionMode"])e?.[r]!==void 0&&(a[r]=e[r]);let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);return r.agents[t]={...r.agents[t],...a},`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:ke(t)}}function As(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(i=>String(i)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[i,l]of Object.entries(e.env))typeof l=="string"&&(o[i]=l);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=C(i=>{if(!i.agents?.[t])throw new Error(`Agent "${t}" not found`);return i.agents[t].mcp=i.agents[t].mcp||{},i.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:ke(t)}}function Ms(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);if(!r.agents[t].mcp||!(a in r.agents[t].mcp))throw new Error(`no mcp.${a} on "${t}"`);return delete r.agents[t].mcp[a],Object.keys(r.agents[t].mcp).length===0&&delete r.agents[t].mcp,`agent "${t}" mcp.${a} removed`});return{summary:n,agent:ke(t)}}function Is(t,e){let a={};if(Array.isArray(e?.intents)&&(a.intents=e.intents.map(r=>String(r)).filter(Boolean)),e?.maxDelegationDepth!==void 0){let r=Number(e.maxDelegationDepth);if(!Number.isFinite(r)||r<0||r>50)throw new Error("maxDelegationDepth must be 0..50");a.maxDelegationDepth=r}if(e?.contextReferences!==void 0&&(a.contextReferences=!!e.contextReferences),e?.contextStrategy!==void 0){if(e.contextStrategy&&!["layered","planner"].includes(e.contextStrategy))throw new Error("contextStrategy must be layered|planner|empty");e.contextStrategy?a.contextStrategy=e.contextStrategy:a.contextStrategy=void 0}if(e?.maxExecutionMinutes!==void 0){let r=Number(e.maxExecutionMinutes);if(!Number.isFinite(r)||r<1||r>240)throw new Error("maxExecutionMinutes must be 1..240");a.maxExecutionMinutes=r}if(Object.keys(a).length===0)throw new Error("nothing to update");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,i]of Object.entries(a))i===void 0?delete o[s]:o[s]=i;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:ke(t)}}function $s(t){let{def:e}=U(t);return me(e.workspace)}function js(t,e){if(!e)throw new Error("path query param required");let{def:a}=U(t);return Se(a.workspace,e)}function Ls(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=U(t);return Te(n.workspace,a,String(e?.content??""))}function Rs(t){let{def:e}=U(t),a=me(e.workspace);return{skills:a.skills,workspace:a.workspace}}function Ps(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Ce(n.workspace,a,{title:e?.title,content:e?.content})}function Ds(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Ae(n.workspace,a)}function Os(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t),n=Ut(a.workspace,e),r=Me(a.workspace,e);return{slug:e,tree:n,deps:r}}function Hs(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=U(t);return Wt(n.workspace,e,a)}function Ns(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=U(t);return Gt(r.workspace,a,n,String(e?.content??""))}function Bs(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t);return Me(a.workspace,e)}async function zs(t,e,a){let n=String(e?.package||"").trim();if(!n||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)?$/.test(n))throw new Error("package must be in 'owner/repo' or 'owner/repo/skill' form");let r=bn(e?.worker),{def:o}=U(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
9335
- `);return yn(a,r,s,`install-${n}:${Date.now()}`)}async function qs(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=bn(e?.worker),{def:o}=U(t),s=Me(o.workspace,n);if(!s.manager)throw new Error(`No dependency manifest detected in .claude/skills/${n}. Expected one of: package.json, requirements.txt, Gemfile.`);let i=gn(o.workspace,".claude","skills",n),l=[`Install dependencies for skill "${n}" in agent "${t}".`,`cd to: ${i}`,`Detected manifest: ${s.file}`,`Run: ${s.command}`,"Stream the install output. On success, summarise the packages installed.","On failure, report the exit code and the last 20 lines of output."].join(`
9336
- `);return yn(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function bn(t){if(t&&typeof t=="string")return t;let e=K();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function yn(t,e,a,n){let r=K(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},i=t.headers.authorization;i?s.Authorization=String(i):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let l=await fetch(`${o}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"admin",sender:"admin-ui",chatId:n}})}),c=await l.text(),p;try{p=JSON.parse(c)}catch{p={content:c}}if(!l.ok)throw new Error(p?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:p?.taskId,content:p?.content,duration:p?.duration,error:p?.error}}function Fs(t){let e=vn(),a=[],n=e?.channels?.telegram?.accounts||{};for(let[o,s]of Object.entries(n))s?.agentBinding===t&&a.push({channel:"telegram",account:o,detail:s?.botUsername||o});e?.channels?.slack?.agentBinding===t&&a.push({channel:"slack",detail:"bound"}),e?.channels?.discord?.agentBinding===t&&a.push({channel:"discord",detail:"bound"});let r=e?.channels?.gitlab?.agentMappings||[];for(let o of r)o?.agentId===t&&a.push({channel:"gitlab",detail:(o?.gitlabUsernames||[]).join(", ")||"mapped"});return{bindings:a}}async function Us(t,e){try{let n=(K().dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),r=await fetch(`${n}/agents`);if(!r.ok)throw new Error(`daemon HTTP ${r.status}`);let s=(await r.json()).find(i=>i.id===t);return{activeTasks:s?.activeTasks??0,totalTasks:s?.totalTasks??0,errors:s?.errors??0,lastActive:s?.lastActive??null,runningTasks:s?.runningTasks??[],lastSummary:s?.lastSummary??null}}catch(a){return{error:a?.message,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]}}}function ht(){return new Tt}function Ws(t){let e=ht(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function Gs(t,e){let a=String(e?.channel||"").trim(),n=String(e?.chatId||"").trim(),r=String(e?.toAgent||"").trim();if(!a||!n||!r)throw new Error("channel, chatId, toAgent required");let o=String(e?.fromAgent||t||"").trim()||t,s=e?.accountId?String(e.accountId):void 0,i=e?.summary?String(e.summary):void 0,l=e?.expiresAt?String(e.expiresAt):void 0,c=ht().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:i,expiresAt:l,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:c}}function Xs(t){let e=String(t?.channel||"").trim(),a=String(t?.chatId||"").trim();if(!e||!a)throw new Error("channel and chatId required");let n=t?.accountId?String(t.accountId):void 0;return{summary:ht().remove(e,a,n)?"Released":"No active handover for that chat"}}function ze(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Ks(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var ue={brand:"AgentX",subtitle:"Team AI ops",nodes:"machines",agentsCount:"agents",activeNow:"handling now",errorsCount:"failed",stats:{active:"Handling",total:"Today",errors:"Failed"},idle:"idle",runningNoPreview:"working \xB7 preparing reply",recentActivities:"Recent activities \u2192",noAgentsOnNode:"No agents set up on this machine.",unreachable:"This machine is unreachable.",neverRan:"not used yet",tierLabels:{"claude-code":"Claude Code","codex-cli":"Codex CLI",opencode:"OpenCode",sdk:"SDK",orchestrator:"Orchestrator"},taskModalTitle:"Task activity",taskModalConnecting:"connecting\u2026",taskModalLive:"live",taskModalFinished:"finished",taskModalArchived:"archived",taskModalLoadFailed:"couldn't load",taskModalFinalResponse:"Final reply",historyPanelTitle:"Recent activities",historyEmpty:"No activity yet.",historyLoading:"loading\u2026"};var wn=[{term:"Agent",definition:'An AI worker with its own role, instructions, and channels it responds on. Think of each agent as a job title \u2014 "support", "devops", "sales".'},{term:"Trigger word",alias:"mention",definition:"A word that activates an agent. When the trigger appears in a message (e.g. @support), AgentX routes the message to that agent."},{term:"Channel",definition:"Where messages come from \u2014 Telegram, WhatsApp, Discord, GitLab comments, a scheduled cron, or an HTTP webhook."},{term:"AI engine",alias:"tier",definition:"Which backend answers: Claude Code, Codex CLI, Anthropic Agent SDK, or AgentX's provider-agnostic orchestrator."},{term:"Agent folder",alias:"workspace",definition:"The directory on disk where the agent lives. It holds the agent's personality (CLAUDE.md), its knowledge (wiki), and the tools it can use."},{term:"Team network",alias:"mesh",definition:'When you run AgentX on more than one machine, the machines find each other and share work. Each machine is a "node"; together they are your team network.'},{term:"Status check-in",alias:"heartbeat",definition:"A lightweight ping between machines so each one knows the others are alive and responsive."},{term:"Board",definition:"A Kanban view of tasks (issues, tickets) pulled from GitLab. Drag cards between columns to move work forward \u2014 the labels update upstream automatically."},{term:"Task",definition:"A single conversation or job an agent handles, from trigger message to final reply. Every task is logged and replayable."},{term:"Schedule",alias:"cron",definition:'A recurring job \u2014 e.g. "every Monday at 9am" \u2014 that nudges an agent without a human trigger.'},{term:"Status label",alias:"scopedLabel",definition:"A GitLab label that moves an issue between Kanban columns (e.g. Status::Doing). Labels are mutually exclusive by prefix."}];function gt(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(ue)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
9334
+ `;function xn(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gn({agentId:a,peers:n,localToken:r}))}async function vn(t,e,a){try{let n=t.method==="GET"?void 0:await Js(t),r=new URL(t.url||"/","http://localhost"),o=Object.fromEntries(r.searchParams),s=a.match(/^\/api\/admin\/agent\/([a-z0-9][a-z0-9_-]*)(?:\/(.+))?$/);if(!s){qe(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",c=`${t.method} ${l}`,m={"GET ":()=>_e(i),"PATCH ":()=>As(i,n),"PATCH capability":()=>$s(i,n),"POST mcp":()=>Ms(i,n),"DELETE mcp":()=>Is(i,n),"GET identity":()=>js(i),"GET identity/file":()=>Ls(i,String(o.path||"")),"PUT identity/file":()=>Rs(i,n),"GET skills":()=>Ps(i),"POST skills":()=>Ds(i,n),"DELETE skills":()=>Os(i,n),"GET skills/tree":()=>Hs(i,String(o.slug||"")),"GET skills/file":()=>Ns(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>Bs(i,n),"GET skills/deps":()=>zs(i,String(o.slug||"")),"POST skills/install":()=>qs(i,n,t),"POST skills/deps":()=>Fs(i,n,t),"GET channels":()=>Us(i),"GET activity":()=>Ws(i,t),"GET handovers":()=>Gs(i),"POST handovers":()=>Xs(i,n),"DELETE handovers":()=>Ks(n)}[c];if(!m){qe(e,404,{error:`unknown agent sub-endpoint: ${c}`});return}let h=await m();qe(e,200,h)}catch(n){qe(e,400,{error:n?.message||"agent op failed"})}}function bn(){let t=fn(process.cwd(),"agentx.json");return Ts(t)?JSON.parse(Cs(t,"utf-8")):null}function U(t){let e=bn();if(!e)throw new Error("agentx.json not found");let a=e.agents?.[t];if(!a)throw new Error(`Agent "${t}" not found`);return{def:a,cfg:e}}function _e(t){let{def:e,cfg:a}=U(t),n=e.workspace?he(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",intents:Array.isArray(e.intents)?e.intents:[],maxDelegationDepth:e.maxDelegationDepth??5,contextReferences:!!e.contextReferences,contextStrategy:e.contextStrategy||"",mcp:e.mcp&&typeof e.mcp=="object"?e.mcp:{},overview:n,defaultWorker:a.node?.defaultAgent,draftAgent:a.dashboard?.draftAgent}}function As(t,e){let a={};for(let r of["name","tier","model","systemPrompt","mentions","access","maxConcurrent","maxExecutionMinutes","permissionMode"])e?.[r]!==void 0&&(a[r]=e[r]);let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);return r.agents[t]={...r.agents[t],...a},`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:_e(t)}}function Ms(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(i=>String(i)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[i,l]of Object.entries(e.env))typeof l=="string"&&(o[i]=l);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=C(i=>{if(!i.agents?.[t])throw new Error(`Agent "${t}" not found`);return i.agents[t].mcp=i.agents[t].mcp||{},i.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:_e(t)}}function Is(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);if(!r.agents[t].mcp||!(a in r.agents[t].mcp))throw new Error(`no mcp.${a} on "${t}"`);return delete r.agents[t].mcp[a],Object.keys(r.agents[t].mcp).length===0&&delete r.agents[t].mcp,`agent "${t}" mcp.${a} removed`});return{summary:n,agent:_e(t)}}function $s(t,e){let a={};if(Array.isArray(e?.intents)&&(a.intents=e.intents.map(r=>String(r)).filter(Boolean)),e?.maxDelegationDepth!==void 0){let r=Number(e.maxDelegationDepth);if(!Number.isFinite(r)||r<0||r>50)throw new Error("maxDelegationDepth must be 0..50");a.maxDelegationDepth=r}if(e?.contextReferences!==void 0&&(a.contextReferences=!!e.contextReferences),e?.contextStrategy!==void 0){if(e.contextStrategy&&!["layered","planner"].includes(e.contextStrategy))throw new Error("contextStrategy must be layered|planner|empty");e.contextStrategy?a.contextStrategy=e.contextStrategy:a.contextStrategy=void 0}if(e?.maxExecutionMinutes!==void 0){let r=Number(e.maxExecutionMinutes);if(!Number.isFinite(r)||r<1||r>240)throw new Error("maxExecutionMinutes must be 1..240");a.maxExecutionMinutes=r}if(Object.keys(a).length===0)throw new Error("nothing to update");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,i]of Object.entries(a))i===void 0?delete o[s]:o[s]=i;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:_e(t)}}function js(t){let{def:e}=U(t);return he(e.workspace)}function Ls(t,e){if(!e)throw new Error("path query param required");let{def:a}=U(t);return Te(a.workspace,e)}function Rs(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=U(t);return Ce(n.workspace,a,String(e?.content??""))}function Ps(t){let{def:e}=U(t),a=he(e.workspace);return{skills:a.skills,workspace:a.workspace}}function Ds(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Ae(n.workspace,a,{title:e?.title,content:e?.content})}function Os(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Me(n.workspace,a)}function Hs(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t),n=Wt(a.workspace,e),r=Ie(a.workspace,e);return{slug:e,tree:n,deps:r}}function Ns(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=U(t);return Gt(n.workspace,e,a)}function Bs(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=U(t);return Xt(r.workspace,a,n,String(e?.content??""))}function zs(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t);return Ie(a.workspace,e)}async function qs(t,e,a){let n=String(e?.package||"").trim();if(!n||!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+(?:\/[A-Za-z0-9_.-]+)?$/.test(n))throw new Error("package must be in 'owner/repo' or 'owner/repo/skill' form");let r=yn(e?.worker),{def:o}=U(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
9335
+ `);return wn(a,r,s,`install-${n}:${Date.now()}`)}async function Fs(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=yn(e?.worker),{def:o}=U(t),s=Ie(o.workspace,n);if(!s.manager)throw new Error(`No dependency manifest detected in .claude/skills/${n}. Expected one of: package.json, requirements.txt, Gemfile.`);let i=fn(o.workspace,".claude","skills",n),l=[`Install dependencies for skill "${n}" in agent "${t}".`,`cd to: ${i}`,`Detected manifest: ${s.file}`,`Run: ${s.command}`,"Stream the install output. On success, summarise the packages installed.","On failure, report the exit code and the last 20 lines of output."].join(`
9336
+ `);return wn(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function yn(t){if(t&&typeof t=="string")return t;let e=K();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function wn(t,e,a,n){let r=K(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},i=t.headers.authorization;i?s.Authorization=String(i):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let l=await fetch(`${o}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"admin",sender:"admin-ui",chatId:n}})}),c=await l.text(),p;try{p=JSON.parse(c)}catch{p={content:c}}if(!l.ok)throw new Error(p?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:p?.taskId,content:p?.content,duration:p?.duration,error:p?.error}}function Us(t){let e=bn(),a=[],n=e?.channels?.telegram?.accounts||{};for(let[o,s]of Object.entries(n))s?.agentBinding===t&&a.push({channel:"telegram",account:o,detail:s?.botUsername||o});e?.channels?.slack?.agentBinding===t&&a.push({channel:"slack",detail:"bound"}),e?.channels?.discord?.agentBinding===t&&a.push({channel:"discord",detail:"bound"});let r=e?.channels?.gitlab?.agentMappings||[];for(let o of r)o?.agentId===t&&a.push({channel:"gitlab",detail:(o?.gitlabUsernames||[]).join(", ")||"mapped"});return{bindings:a}}async function Ws(t,e){try{let n=(K().dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),r=await fetch(`${n}/agents`);if(!r.ok)throw new Error(`daemon HTTP ${r.status}`);let s=(await r.json()).find(i=>i.id===t);return{activeTasks:s?.activeTasks??0,totalTasks:s?.totalTasks??0,errors:s?.errors??0,lastActive:s?.lastActive??null,runningTasks:s?.runningTasks??[],lastSummary:s?.lastSummary??null}}catch(a){return{error:a?.message,activeTasks:0,totalTasks:0,errors:0,runningTasks:[]}}}function gt(){return new Ct}function Gs(t){let e=gt(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function Xs(t,e){let a=String(e?.channel||"").trim(),n=String(e?.chatId||"").trim(),r=String(e?.toAgent||"").trim();if(!a||!n||!r)throw new Error("channel, chatId, toAgent required");let o=String(e?.fromAgent||t||"").trim()||t,s=e?.accountId?String(e.accountId):void 0,i=e?.summary?String(e.summary):void 0,l=e?.expiresAt?String(e.expiresAt):void 0,c=gt().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:i,expiresAt:l,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:c}}function Ks(t){let e=String(t?.channel||"").trim(),a=String(t?.chatId||"").trim();if(!e||!a)throw new Error("channel and chatId required");let n=t?.accountId?String(t.accountId):void 0;return{summary:gt().remove(e,a,n)?"Released":"No active handover for that chat"}}function qe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Js(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var me={brand:"AgentX",subtitle:"Team AI ops",nodes:"machines",agentsCount:"agents",activeNow:"handling now",errorsCount:"failed",stats:{active:"Handling",total:"Today",errors:"Failed"},idle:"idle",runningNoPreview:"working \xB7 preparing reply",recentActivities:"Recent activities \u2192",noAgentsOnNode:"No agents set up on this machine.",unreachable:"This machine is unreachable.",neverRan:"not used yet",tierLabels:{"claude-code":"Claude Code","codex-cli":"Codex CLI",opencode:"OpenCode",sdk:"SDK",orchestrator:"Orchestrator"},taskModalTitle:"Task activity",taskModalConnecting:"connecting\u2026",taskModalLive:"live",taskModalFinished:"finished",taskModalArchived:"archived",taskModalLoadFailed:"couldn't load",taskModalFinalResponse:"Final reply",historyPanelTitle:"Recent activities",historyEmpty:"No activity yet.",historyLoading:"loading\u2026"};var kn=[{term:"Agent",definition:'An AI worker with its own role, instructions, and channels it responds on. Think of each agent as a job title \u2014 "support", "devops", "sales".'},{term:"Trigger word",alias:"mention",definition:"A word that activates an agent. When the trigger appears in a message (e.g. @support), AgentX routes the message to that agent."},{term:"Channel",definition:"Where messages come from \u2014 Telegram, WhatsApp, Discord, GitLab comments, a scheduled cron, or an HTTP webhook."},{term:"AI engine",alias:"tier",definition:"Which backend answers: Claude Code, Codex CLI, Anthropic Agent SDK, or AgentX's provider-agnostic orchestrator."},{term:"Agent folder",alias:"workspace",definition:"The directory on disk where the agent lives. It holds the agent's personality (CLAUDE.md), its knowledge (wiki), and the tools it can use."},{term:"Team network",alias:"mesh",definition:'When you run AgentX on more than one machine, the machines find each other and share work. Each machine is a "node"; together they are your team network.'},{term:"Status check-in",alias:"heartbeat",definition:"A lightweight ping between machines so each one knows the others are alive and responsive."},{term:"Board",definition:"A Kanban view of tasks (issues, tickets) pulled from GitLab. Drag cards between columns to move work forward \u2014 the labels update upstream automatically."},{term:"Task",definition:"A single conversation or job an agent handles, from trigger message to final reply. Every task is logged and replayable."},{term:"Schedule",alias:"cron",definition:'A recurring job \u2014 e.g. "every Monday at 9am" \u2014 that nudges an agent without a human trigger.'},{term:"Status label",alias:"scopedLabel",definition:"A GitLab label that moves an issue between Kanban columns (e.g. Status::Doing). Labels are mutually exclusive by prefix."}];function ft(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(me)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
9337
9337
  <span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
9338
9338
  <span id="conn-label">live</span>`,n=`<div class="ax-app-live">
9339
9339
  <section id="statstrip" class="ax-statstrip"></section>
9340
9340
  <main id="grid" class="ax-live__body"></main>
9341
9341
  </div>
9342
- `;return $({title:`${ue.brand} \xB7 ${ue.subtitle}`,activeTab:"live",subtitle:ue.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:Js,scripts:e+`<script>${Vs}</script>`,headExtras:`<script>
9342
+ `;return $({title:`${me.brand} \xB7 ${me.subtitle}`,activeTab:"live",subtitle:me.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:Vs,scripts:e+`<script>${Ys}</script>`,headExtras:`<script>
9343
9343
  // rightExtras for the topbar are injected at runtime \u2014 they reference
9344
9344
  // IDs (#ts, #conn-dot) that the script below addresses directly.
9345
9345
  document.addEventListener('DOMContentLoaded', () => {
@@ -9350,7 +9350,7 @@ loadAgent();
9350
9350
  extras.innerHTML = ${JSON.stringify(a)};
9351
9351
  right.insertBefore(extras, right.firstChild);
9352
9352
  });
9353
- </script>`})}var Js=`
9353
+ </script>`})}var Vs=`
9354
9354
  /* --- Page frame --- */
9355
9355
  .ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
9356
9356
 
@@ -9553,7 +9553,7 @@ loadAgent();
9553
9553
  border-top-color: var(--ax-accent); border-radius: 50%;
9554
9554
  animation: ax-spin 800ms linear infinite; display: inline-block;
9555
9555
  }
9556
- @keyframes ax-spin { to { transform: rotate(360deg); } }`,Vs=`
9556
+ @keyframes ax-spin { to { transform: rotate(360deg); } }`,Ys=`
9557
9557
  'use strict';
9558
9558
 
9559
9559
  const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
@@ -10097,7 +10097,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
10097
10097
  });
10098
10098
  }
10099
10099
 
10100
- `;var kn=`
10100
+ `;var _n=`
10101
10101
  .mx-content{max-width:1180px;margin:0 auto;padding:0 24px 56px}
10102
10102
  .mx-updated{margin:0;color:var(--ax-muted);font-size:11px;font-family:var(--ax-mono)}
10103
10103
  .mx-section{margin-bottom:28px}.mx-section .ax-section-head{margin-bottom:14px}
@@ -10271,7 +10271,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
10271
10271
  .mx-summary{max-width:56vw}
10272
10272
  }
10273
10273
  @media(prefers-reduced-motion:reduce){.mx-drawer{transition:none}}
10274
- `;var _n=`<script>
10274
+ `;var En=`<script>
10275
10275
  window.MX=(function(){
10276
10276
  var ENT={'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'};
10277
10277
  function esc(v){return String(v==null?'':v).replace(/[&<>"']/g,function(c){return ENT[c]})}
@@ -10380,7 +10380,7 @@ window.MX=(function(){
10380
10380
  verdict:verdict,verdictChip:verdictChip,mark:mark,causeLabel:causeLabel,
10381
10381
  setHealth:setHealth,get:get};
10382
10382
  })();
10383
- </script>`;var En=`<script>
10383
+ </script>`;var Sn=`<script>
10384
10384
  window.MXD=(function(){
10385
10385
  function el(id){return document.getElementById(id)}
10386
10386
  function tz(){return -new Date().getTimezoneOffset()}
@@ -10594,7 +10594,7 @@ window.MXD=(function(){
10594
10594
 
10595
10595
  return {openDay:openDay,openJob:openJob,openConversation:openConversation};
10596
10596
  })();
10597
- </script>`;var Sn=`<script>
10597
+ </script>`;var Tn=`<script>
10598
10598
  (function(){
10599
10599
  var LANES=[
10600
10600
  {id:'cron',name:'Scheduled',hint:'cron jobs'},
@@ -10910,7 +10910,7 @@ window.MXD=(function(){
10910
10910
  window.addEventListener('scroll',hideTip,{passive:true});
10911
10911
  load();
10912
10912
  })();
10913
- </script>`;var Tn=`<script>
10913
+ </script>`;var Cn=`<script>
10914
10914
  (function(){
10915
10915
  var showAll=document.getElementById('mx-show-all'),expanded=false;
10916
10916
  var esc=MX.esc;
@@ -11088,7 +11088,7 @@ window.MXD=(function(){
11088
11088
  }
11089
11089
  load();setInterval(load,5000);
11090
11090
  })();
11091
- </script>`;var Cn=`
11091
+ </script>`;var An=`
11092
11092
  .mx-rt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:12px}
11093
11093
  .mx-rt-wrap{border:var(--ax-border-w) solid var(--ax-border);border-radius:var(--ax-radius-lg);background:var(--ax-surface);overflow-x:auto}
11094
11094
  .mx-rt-wrap > .mx-empty{border:0}
@@ -11129,7 +11129,7 @@ window.MXD=(function(){
11129
11129
  .mx-rt-msg td{display:block}.mx-rt-msg td::before{content:none}
11130
11130
  .mx-rt-name{max-width:100%}
11131
11131
  }
11132
- `,An=`<script>
11132
+ `,Mn=`<script>
11133
11133
  (function(){
11134
11134
  var root=document.getElementById('mx-routines');
11135
11135
  var bar=document.getElementById('mx-rt-filter');
@@ -11256,12 +11256,12 @@ window.MXD=(function(){
11256
11256
  syncBar();
11257
11257
  document.addEventListener('mx:snapshot',function(e){render(e.detail||{})});
11258
11258
  })();
11259
- </script>`;var Y={activity:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h3l2-6 4 12 2-6h5"/></svg>',breakage:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v6l-3 3 3 3v6"/><path d="M5 5l14 14"/></svg>',effort:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 20V4M4 20h16"/><circle cx="9" cy="15" r="2"/><circle cx="15" cy="8" r="2"/></svg>',lifetime:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h18"/><path d="M7 8v8M13 8v8M19 8v8"/></svg>',cuts:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><path d="M8 8l12 10M8 16L20 6"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',routines:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h11M4 12h7M4 17h9"/><path d="M17 5l3 3-3 3M16 14l4 4M20 14l-4 4"/></svg>',nodes:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="12" cy="18" r="2"/><path d="M8 6h8M7 8l4 8M17 8l-4 8"/></svg>',agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>'};function Q(t,e,a,n,r=""){return q({icon:t,title:e,lead:a,actionHtml:r}).replace("<h2>",`<h2 id="${n}">`)}var Ys=[{id:"all",label:"All"},{id:"attention",label:"Flagged"},{id:"schedule",label:"Schedules"},{id:"event",label:"Events"}],Qs=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],Zs=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function Mn(t){let e=Ie({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+$e([{kind:"off",num:"-",label:"Nodes online"},{kind:"off",num:"-",label:"Tasks running"},{kind:"off",num:"-",label:"Failed today"},{kind:"off",num:"-",label:"Jobs needing review"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="mx-health">'),a=`<div class="mx-toolbar">
11259
+ </script>`;var Y={activity:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 12h3l2-6 4 12 2-6h5"/></svg>',breakage:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M12 3v6l-3 3 3 3v6"/><path d="M5 5l14 14"/></svg>',effort:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 20V4M4 20h16"/><circle cx="9" cy="15" r="2"/><circle cx="15" cy="8" r="2"/></svg>',lifetime:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M3 12h18"/><path d="M7 8v8M13 8v8M19 8v8"/></svg>',cuts:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><path d="M8 8l12 10M8 16L20 6"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',routines:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 7h11M4 12h7M4 17h9"/><path d="M17 5l3 3-3 3M16 14l4 4M20 14l-4 4"/></svg>',nodes:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="12" cy="18" r="2"/><path d="M8 6h8M7 8l4 8M17 8l-4 8"/></svg>',agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>'};function Q(t,e,a,n,r=""){return q({icon:t,title:e,lead:a,actionHtml:r}).replace("<h2>",`<h2 id="${n}">`)}var Qs=[{id:"all",label:"All"},{id:"attention",label:"Flagged"},{id:"schedule",label:"Schedules"},{id:"event",label:"Events"}],Zs=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],ei=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function In(t){let e=$e({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+je([{kind:"off",num:"-",label:"Nodes online"},{kind:"off",num:"-",label:"Tasks running"},{kind:"off",num:"-",label:"Failed today"},{kind:"off",num:"-",label:"Jobs needing review"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="mx-health">'),a=`<div class="mx-toolbar">
11260
11260
  <div class="mx-tabs" role="tablist" aria-label="Mesh views">
11261
- ${Qs.map((i,l)=>`<button class="mx-tab" type="button" role="tab" id="mx-tab-${i.id}" aria-controls="mx-view-${i.id}" aria-selected="${l===0}" data-view="${i.id}">${i.label}</button>`).join("")}
11261
+ ${Zs.map((i,l)=>`<button class="mx-tab" type="button" role="tab" id="mx-tab-${i.id}" aria-controls="mx-view-${i.id}" aria-selected="${l===0}" data-view="${i.id}">${i.label}</button>`).join("")}
11262
11262
  </div>
11263
11263
  <div class="mx-range" id="mx-range" role="group" aria-label="History window">
11264
- ${Zs.map(i=>`<button type="button" data-days="${i.days}" aria-pressed="${i.days===30}">${i.label}</button>`).join("")}
11264
+ ${ei.map(i=>`<button type="button" data-days="${i.days}" aria-pressed="${i.days===30}">${i.label}</button>`).join("")}
11265
11265
  </div>
11266
11266
  </div>
11267
11267
  <p id="mx-analytics-updated" class="mx-updated" aria-live="polite">Reading node histories...</p>`,n=`<div class="mx-view" id="mx-view-activity" role="tabpanel" aria-labelledby="mx-tab-activity">
@@ -11314,7 +11314,7 @@ window.MXD=(function(){
11314
11314
  <section class="mx-section" aria-labelledby="mx-routines-title">
11315
11315
  ${Q(Y.routines,"Routines","Everything that runs on its own: schedules and cron- or event-triggered workflows, per node. Flags mark routines that keep failing, went quiet, never ran, or sat disabled.","mx-routines-title",'<span class="ax-tab-count" id="mx-rt-count">0 routines</span>')}
11316
11316
  <div class="mx-rt-bar" id="mx-rt-filter" role="group" aria-label="Filter routines">
11317
- ${Ys.map(i=>`<button class="mx-chip" type="button" data-rt-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
11317
+ ${Qs.map(i=>`<button class="mx-chip" type="button" data-rt-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
11318
11318
  </div>
11319
11319
  <div class="mx-rt-wrap" id="mx-routines"><div class="mx-empty">Loading routines...</div></div>
11320
11320
  </section>
@@ -11347,7 +11347,7 @@ window.MXD=(function(){
11347
11347
  <button class="ax-btn ax-btn--ghost" id="mx-close" type="button" aria-label="Close details">Close</button>
11348
11348
  </header>
11349
11349
  <div class="mx-drawer__body" id="mx-drawer-body"></div>
11350
- </aside>`;return $({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:kn+Cn,scripts:_n+ei+En+Sn+An+Tn})}var ei=`<script>
11350
+ </aside>`;return $({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:_n+An,scripts:En+ti+Sn+Tn+Mn+Cn})}var ti=`<script>
11351
11351
  (function(){
11352
11352
  var tabs=Array.prototype.slice.call(document.querySelectorAll('.mx-tab'));
11353
11353
  var range=document.getElementById('mx-range');
@@ -11375,7 +11375,7 @@ window.MXD=(function(){
11375
11375
  var saved=null;try{saved=localStorage.getItem('mx-view')}catch(e){}
11376
11376
  select(tabs.some(function(t){return t.dataset.view===saved})?saved:'activity');
11377
11377
  })();
11378
- </script>`;async function In(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?days=${e.days}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/mesh"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return ti(s,e.days)}function ti(t,e){let a={runs:0,errors:0,hours:0,agents:0,threads:0},n=new Map,r=new Map,o=new Map,s=new Map,i=[],l=[],c=0,p=0,m=0,h=0,_=0,S=0;for(let{node:E,data:T}of t)if(T){a.runs+=T.totals.runs,a.errors+=T.totals.errors,a.hours+=T.totals.hours,a.agents+=T.totals.agents,a.threads+=T.totals.threads;for(let d of T.days){let u=n.get(d.day)||{day:d.day,cron:[0,0],workflow:[0,0],direct:[0,0]};for(let g of["cron","workflow","direct"])u[g][0]+=d[g]?.[0]||0,u[g][1]+=d[g]?.[1]||0;n.set(d.day,u)}for(let d of T.origins){let u=r.get(d.channel)||{channel:d.channel,runs:0,errors:0,hours:0};u.runs+=d.runs,u.errors+=d.errors,u.hours+=d.hours,r.set(d.channel,u)}for(let d of T.causes){let u=o.get(d.cause)||{cause:d.cause,count:0,agents:[],example:""};u.count+=d.count;for(let g of d.agents)u.agents.includes(g)||u.agents.push(g);u.example||(u.example=d.example),o.set(d.cause,u)}for(let d of T.rotations.byReason)s.set(d.reason,(s.get(d.reason)||0)+d.count);c+=T.rotations.total,p+=T.rotations.tokenSum||0,m+=T.rotations.tokenSamples||0,h=Math.max(h,T.rotations.maxTokens),_+=T.retention.traces,S+=T.retention.tracesWithSteps;for(let d of T.jobs)i.push({...d,node:E.name,nodeUrl:E.url});for(let d of T.threads)l.push({...d,node:E.name,nodeUrl:E.url})}let w=t.filter(E=>E.data).map(E=>E.data.since).filter(E=>Number.isFinite(E));return{generatedAt:Date.now(),windowDays:e,since:w.length?Math.min(...w):Date.now()-e*864e5,nodes:t.map(E=>({name:E.node.name,url:E.node.url,ok:!!E.data,error:E.error,runs:E.data?.totals.runs||0})),totals:{...a,hours:Math.round(a.hours*100)/100},days:[...n.values()].sort((E,T)=>E.day.localeCompare(T.day)),origins:[...r.values()].map(E=>({...E,hours:Math.round(E.hours*100)/100})).sort((E,T)=>T.runs-E.runs),causes:[...o.values()].sort((E,T)=>T.count-E.count),jobs:i.sort((E,T)=>T.hours-E.hours),threads:l.sort((E,T)=>T.lastAt-T.firstAt-(E.lastAt-E.firstAt)||T.runs-E.runs),rotations:{total:c,byReason:[...s.entries()].map(([E,T])=>({reason:E,count:T})).sort((E,T)=>T.count-E.count),tokenSum:p,tokenSamples:m,maxTokens:h},retention:{traces:_,tracesWithSteps:S}}}async function $n(t,e,a,n){let r=a.replace(/\/+$/,""),o=e.find(i=>i.url.replace(/\/+$/,"")===r);if(!o){t.writeHead(403,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"node not in dashboard allowlist",target:r}));return}let s={Accept:"application/json"};o.token&&(s.Authorization=`Bearer ${o.token}`);try{let i=await fetch(r+n,{headers:s}),l=await i.text();t.writeHead(i.status,{"Content-Type":"application/json; charset=utf-8"}),t.end(l)}catch(i){t.writeHead(502,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:i?.message||"upstream fetch failed"}))}}async function jn(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?day=${encodeURIComponent(e.day)}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/day"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return ai(s,e.day)}function ai(t,e){let a={runs:0,errors:0,ms:0,inputTokens:0,outputTokens:0},n=new Map,r=new Map,o=[];for(let{node:s,data:i}of t)if(i){a.runs+=i.totals.runs,a.errors+=i.totals.errors,a.ms+=i.totals.ms,a.inputTokens+=i.totals.inputTokens,a.outputTokens+=i.totals.outputTokens;for(let l of i.origins){let c=n.get(l.channel)||{channel:l.channel,runs:0,errors:0,ms:0};c.runs+=l.runs,c.errors+=l.errors,c.ms+=l.ms,n.set(l.channel,c)}for(let l of i.causes)r.set(l.cause,(r.get(l.cause)||0)+l.count);for(let l of i.conversations)o.push({...l,node:s.name,nodeUrl:s.url})}return{day:e,nodes:t.map(s=>({name:s.node.name,url:s.node.url,ok:!!s.data,error:s.error,runs:s.data?.totals.runs||0})),totals:a,origins:[...n.values()].sort((s,i)=>i.runs-s.runs),causes:[...r.entries()].map(([s,i])=>({cause:s,count:i})).sort((s,i)=>i.count-s.count),conversations:o.sort((s,i)=>i.ms-s.ms||i.turns-s.turns)}}function Ln(t={}){let e=`
11378
+ </script>`;async function $n(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?days=${e.days}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/mesh"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return ai(s,e.days)}function ai(t,e){let a={runs:0,errors:0,hours:0,agents:0,threads:0},n=new Map,r=new Map,o=new Map,s=new Map,i=[],l=[],c=0,p=0,m=0,h=0,_=0,S=0;for(let{node:E,data:T}of t)if(T){a.runs+=T.totals.runs,a.errors+=T.totals.errors,a.hours+=T.totals.hours,a.agents+=T.totals.agents,a.threads+=T.totals.threads;for(let d of T.days){let u=n.get(d.day)||{day:d.day,cron:[0,0],workflow:[0,0],direct:[0,0]};for(let g of["cron","workflow","direct"])u[g][0]+=d[g]?.[0]||0,u[g][1]+=d[g]?.[1]||0;n.set(d.day,u)}for(let d of T.origins){let u=r.get(d.channel)||{channel:d.channel,runs:0,errors:0,hours:0};u.runs+=d.runs,u.errors+=d.errors,u.hours+=d.hours,r.set(d.channel,u)}for(let d of T.causes){let u=o.get(d.cause)||{cause:d.cause,count:0,agents:[],example:""};u.count+=d.count;for(let g of d.agents)u.agents.includes(g)||u.agents.push(g);u.example||(u.example=d.example),o.set(d.cause,u)}for(let d of T.rotations.byReason)s.set(d.reason,(s.get(d.reason)||0)+d.count);c+=T.rotations.total,p+=T.rotations.tokenSum||0,m+=T.rotations.tokenSamples||0,h=Math.max(h,T.rotations.maxTokens),_+=T.retention.traces,S+=T.retention.tracesWithSteps;for(let d of T.jobs)i.push({...d,node:E.name,nodeUrl:E.url});for(let d of T.threads)l.push({...d,node:E.name,nodeUrl:E.url})}let w=t.filter(E=>E.data).map(E=>E.data.since).filter(E=>Number.isFinite(E));return{generatedAt:Date.now(),windowDays:e,since:w.length?Math.min(...w):Date.now()-e*864e5,nodes:t.map(E=>({name:E.node.name,url:E.node.url,ok:!!E.data,error:E.error,runs:E.data?.totals.runs||0})),totals:{...a,hours:Math.round(a.hours*100)/100},days:[...n.values()].sort((E,T)=>E.day.localeCompare(T.day)),origins:[...r.values()].map(E=>({...E,hours:Math.round(E.hours*100)/100})).sort((E,T)=>T.runs-E.runs),causes:[...o.values()].sort((E,T)=>T.count-E.count),jobs:i.sort((E,T)=>T.hours-E.hours),threads:l.sort((E,T)=>T.lastAt-T.firstAt-(E.lastAt-E.firstAt)||T.runs-E.runs),rotations:{total:c,byReason:[...s.entries()].map(([E,T])=>({reason:E,count:T})).sort((E,T)=>T.count-E.count),tokenSum:p,tokenSamples:m,maxTokens:h},retention:{traces:_,tracesWithSteps:S}}}async function jn(t,e,a,n){let r=a.replace(/\/+$/,""),o=e.find(i=>i.url.replace(/\/+$/,"")===r);if(!o){t.writeHead(403,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:"node not in dashboard allowlist",target:r}));return}let s={Accept:"application/json"};o.token&&(s.Authorization=`Bearer ${o.token}`);try{let i=await fetch(r+n,{headers:s}),l=await i.text();t.writeHead(i.status,{"Content-Type":"application/json; charset=utf-8"}),t.end(l)}catch(i){t.writeHead(502,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:i?.message||"upstream fetch failed"}))}}async function Ln(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?day=${encodeURIComponent(e.day)}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/day"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return ni(s,e.day)}function ni(t,e){let a={runs:0,errors:0,ms:0,inputTokens:0,outputTokens:0},n=new Map,r=new Map,o=[];for(let{node:s,data:i}of t)if(i){a.runs+=i.totals.runs,a.errors+=i.totals.errors,a.ms+=i.totals.ms,a.inputTokens+=i.totals.inputTokens,a.outputTokens+=i.totals.outputTokens;for(let l of i.origins){let c=n.get(l.channel)||{channel:l.channel,runs:0,errors:0,ms:0};c.runs+=l.runs,c.errors+=l.errors,c.ms+=l.ms,n.set(l.channel,c)}for(let l of i.causes)r.set(l.cause,(r.get(l.cause)||0)+l.count);for(let l of i.conversations)o.push({...l,node:s.name,nodeUrl:s.url})}return{day:e,nodes:t.map(s=>({name:s.node.name,url:s.node.url,ok:!!s.data,error:s.error,runs:s.data?.totals.runs||0})),totals:a,origins:[...n.values()].sort((s,i)=>i.runs-s.runs),causes:[...r.entries()].map(([s,i])=>({cause:s,count:i})).sort((s,i)=>i.count-s.count),conversations:o.sort((s,i)=>i.ms-s.ms||i.turns-s.turns)}}function Rn(t={}){let e=`
11379
11379
  <select id="boardPicker" title="Switch board"></select>
11380
11380
  <div class="search">
11381
11381
  <span class="icon">\u2315</span>
@@ -11476,7 +11476,7 @@ window.MXD=(function(){
11476
11476
  </footer>
11477
11477
  </div>
11478
11478
  </div>
11479
- <script src="/sortable.min.js"></script>`;return $({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:ni,scripts:`<script>${ri}</script>`,headExtras:`<script>
11479
+ <script src="/sortable.min.js"></script>`;return $({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:ri,scripts:`<script>${oi}</script>`,headExtras:`<script>
11480
11480
  // The boards page has its own connection dot + wants body height:100%
11481
11481
  // for the full-viewport kanban layout. Inject the dot into the topbar
11482
11482
  // and override body height at runtime so the shared shell doesn't
@@ -11492,7 +11492,7 @@ window.MXD=(function(){
11492
11492
  right.insertBefore(dot, right.firstChild);
11493
11493
  }
11494
11494
  });
11495
- </script>`})}var ni=`
11495
+ </script>`})}var ri=`
11496
11496
  /* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
11497
11497
  .ax-subheader select, .ax-subheader input, .ax-subheader button {
11498
11498
  background: var(--col); color: var(--text); border: 1px solid var(--border);
@@ -11745,7 +11745,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
11745
11745
  .draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
11746
11746
  .draft-box .draft-row .hint.err { color: var(--red); }
11747
11747
  .draft-box .draft-row .hint.ok { color: var(--green); }
11748
- `,ri=`
11748
+ `,oi=`
11749
11749
  'use strict';
11750
11750
  const state = {
11751
11751
  boards: [], current: null, items: {},
@@ -12798,9 +12798,9 @@ function appendEvents(events) {
12798
12798
  }
12799
12799
 
12800
12800
  loadBoards().catch(e => toast('Init failed: ' + e.message));
12801
- `;function Rn(t={}){let a=`<h1>Plain-English glossary</h1>
12801
+ `;function Pn(t={}){let a=`<h1>Plain-English glossary</h1>
12802
12802
  <p class="lead">What the terms on the dashboard mean. Schema keys (shown in the pill on the right of each term) are what you'd write in <code>agentx.json</code> \u2014 the dashboard just relabels them for readability.</p>
12803
- ${wn.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${P(n.alias)}</span>`:"";return`<article class="term"><h3>${P(n.term)}${r}</h3><p>${P(n.definition)}</p></article>`}).join("")}`;return $({title:`${ue.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:oi})}var oi=`
12803
+ ${kn.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${P(n.alias)}</span>`:"";return`<article class="term"><h3>${P(n.term)}${r}</h3><p>${P(n.definition)}</p></article>`}).join("")}`;return $({title:`${me.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:si})}var si=`
12804
12804
  main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
12805
12805
  h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
12806
12806
  .lead {
@@ -12830,7 +12830,7 @@ article.term .alias {
12830
12830
  }
12831
12831
  article.term p {
12832
12832
  margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
12833
- }`;function Pn(t={}){let e=`<div class="ax-wf__root">
12833
+ }`;function Dn(t={}){let e=`<div class="ax-wf__root">
12834
12834
  <aside class="ax-wf__list">
12835
12835
  <header>
12836
12836
  <h2>Workflows</h2>
@@ -12907,7 +12907,7 @@ article.term p {
12907
12907
  </aside>
12908
12908
  </div>
12909
12909
 
12910
- <div id="wf-toast" class="ax-wf__toast" hidden></div>`;return $({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:si,scripts:`<script>${he({workflowHealth:jt})}${ii}</script>`})}var si=`
12910
+ <div id="wf-toast" class="ax-wf__toast" hidden></div>`;return $({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:ii,scripts:`<script>${ge({workflowHealth:Lt})}${li}</script>`})}var ii=`
12911
12911
  .ax-wf__root {
12912
12912
  display: grid;
12913
12913
  grid-template-columns: 340px 1fr;
@@ -13291,7 +13291,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
13291
13291
  font-size: 12px; z-index: 50;
13292
13292
  }
13293
13293
  .hint { color: var(--ax-muted); font-size: 11px; }
13294
- `,ii=`
13294
+ `,li=`
13295
13295
  (() => {
13296
13296
  const $ = (sel) => document.querySelector(sel)
13297
13297
  const $$ = (sel) => Array.from(document.querySelectorAll(sel))
@@ -14080,7 +14080,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14080
14080
  setInterval(refresh, 15000)
14081
14081
  })
14082
14082
  })();
14083
- `;function Dn(t={}){let e=`<div class="ax-proc__root">
14083
+ `;function On(t={}){let e=`<div class="ax-proc__root">
14084
14084
  <header class="ax-proc__header">
14085
14085
  <h1>Procedures</h1>
14086
14086
  <p class="hint">Reusable building blocks workflows compose. See <a href="/admin/wiki/architecture/three-tier" target="_blank">three-tier model</a> for how this fits with System and Processes.</p>
@@ -14124,7 +14124,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14124
14124
  <p class="hint">AgentX is layered: <strong>System</strong> (agents, channels, mesh) \u2192 <strong>Processes</strong> (workflows that turn intent into work) \u2192 <strong>Procedures</strong> (this page: reusable steps a process composes). Higher tiers depend on lower; never the reverse.</p>
14125
14125
  <p class="hint">Adding a new procedure is a code change (a new <code>action.builtin</code> module under <code>src/actions/builtin/</code> or a new template YAML in <code>src/workflows/templates/</code>) \u2014 not a UI flow. This page is the read-only catalog.</p>
14126
14126
  </section>
14127
- </div>`;return $({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:li,scripts:`<script>${di}</script>`})}var li=`
14127
+ </div>`;return $({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:di,scripts:`<script>${ci}</script>`})}var di=`
14128
14128
  .ax-proc__root { padding: 18px 24px 40px; max-width: 1100px; margin: 0 auto; color: var(--ax-text); }
14129
14129
  .ax-proc__header h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
14130
14130
  .ax-proc__header .hint { color: var(--ax-muted); font-size: 12px; margin: 0 0 18px; }
@@ -14150,7 +14150,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14150
14150
  .ax-proc__req { display: inline-block; padding: 1px 6px; font-size: 10px; font-family: var(--ax-mono); border: 1px solid color-mix(in oklch, var(--ax-warn, #f59e0b) 40%, var(--ax-border)); border-radius: 3px; color: var(--ax-warn, #f59e0b); }
14151
14151
  .ax-proc__link { color: var(--ax-accent, #6366f1); text-decoration: none; font-size: 11px; }
14152
14152
  .ax-proc__link:hover { text-decoration: underline; }
14153
- `,di=`
14153
+ `,ci=`
14154
14154
  (function(){
14155
14155
  function $(sel){ return document.querySelector(sel) }
14156
14156
  function esc(s){ return String(s||"").replace(/[&<>"']/g, function(c){ return ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[c] }) }
@@ -14250,7 +14250,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14250
14250
  if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootAll)
14251
14251
  else bootAll()
14252
14252
  })();
14253
- `;function On(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
14253
+ `;function Hn(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
14254
14254
  data-task-id="${P(t.taskId)}"
14255
14255
  data-agent-id="${P(t.agentId)}"
14256
14256
  data-node-url="${P(t.nodeUrl)}"
@@ -14293,7 +14293,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14293
14293
  <button type="button" id="task-send" class="ax-btn ax-btn--primary">send \u2192</button>
14294
14294
  </div>
14295
14295
  </footer>
14296
- </div>`;return $({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:ci,scripts:`<script>${pi}</script>`})}var ci=`
14296
+ </div>`;return $({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:pi,scripts:`<script>${ui}</script>`})}var pi=`
14297
14297
  /* The shell gives <main> no padding, so page content butted straight against
14298
14298
  the sticky topbar. Breathe. */
14299
14299
  .ax-task-page {
@@ -14435,7 +14435,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14435
14435
  line-height: 1.55; text-wrap: pretty; white-space: pre-wrap; word-break: break-word;
14436
14436
  }
14437
14437
 
14438
- `,pi=`
14438
+ `,ui=`
14439
14439
  (function () {
14440
14440
  var root = document.querySelector('.ax-task-page');
14441
14441
  if (!root) return;
@@ -14820,7 +14820,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14820
14820
  });
14821
14821
 
14822
14822
  })();
14823
- `;function Hn(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
14823
+ `;function Nn(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
14824
14824
  data-agent-id="${P(t.agentId)}"
14825
14825
  data-agent-name="${P(e)}"
14826
14826
  data-node-url="${P(t.nodeUrl)}">
@@ -14849,7 +14849,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14849
14849
  <div class="ax-history__list" id="hist-list">
14850
14850
  <div class="ax-history__empty">loading\u2026</div>
14851
14851
  </div>
14852
- </div>`;return $({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:ui,scripts:`<script>${mi}</script>`})}var ui=`
14852
+ </div>`;return $({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:mi,scripts:`<script>${hi}</script>`})}var mi=`
14853
14853
  /* <main> carries no padding in the shell \u2014 without this the breadcrumb sits
14854
14854
  flush against the sticky topbar. */
14855
14855
  .ax-history {
@@ -14901,7 +14901,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
14901
14901
  -webkit-line-clamp: 2; -webkit-box-orient: vertical;
14902
14902
  }
14903
14903
  .ax-history__foot { margin-top: 6px; font-size: var(--ax-fs-xs); color: var(--ax-muted); font-family: var(--ax-mono); }
14904
- `,mi=`
14904
+ `,hi=`
14905
14905
  (function () {
14906
14906
  var root = document.querySelector('.ax-history');
14907
14907
  if (!root) return;
@@ -15001,25 +15001,25 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
15001
15001
  listEl.innerHTML = '<div class="ax-history__empty" style="color:var(--ax-err)">' + esc(e.message) + '</div>';
15002
15002
  });
15003
15003
  })();
15004
- `;function Bn(t,e,a){let n=t.url||"";if(!n.startsWith("/api/workflows"))return!1;let r=t.method||"GET";if(n==="/api/workflows"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{workflows:a.store.list()}):!0;if(r==="POST"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let s=new URL(n,"http://_").searchParams,i=s.get("convertFromYaml")==="true"||s.get("convertFromYaml")==="1";return xe(t,e,l=>Nn(e,a,l,{mode:"create",convertFromYaml:i}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:gi(t,e,a,n);if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return j(e,501,{error:"dispatcher not enabled"});let s=decodeURIComponent(n.replace(/^\/api\/workflows\/signal\//,"").split("?")[0]);return s?xe(t,e,i=>{let l=i,c=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return j(e,200,{ok:!0,emission:c})}):j(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),i=o[2];if(i==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?xe(t,e,l=>{try{let c=a.layouts.save(s,l);return j(e,200,{layout:c})}catch(c){return j(e,400,{error:"invalid layout",message:c.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?xe(t,e,l=>{let c=Xe.safeParse(l);if(!c.success)return j(e,200,{ok:!1,issues:c.error.issues.map(m=>({path:m.path.join("."),message:m.message}))});let p=Ke(c.data).map(m=>({path:"",message:m}));return j(e,200,{ok:p.length===0,issues:p,workflow:c.data})}):!0;if(!i){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=a.store.get(s);return l?j(e,200,{workflow:l}):j(e,404,{error:"workflow not found"})}if(r==="PUT"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=new URL(n,"http://_").searchParams,c=l.get("convertFromYaml")==="true"||l.get("convertFromYaml")==="1";return xe(t,e,p=>Nn(e,a,p,{mode:"update",id:s,convertFromYaml:c}))}if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=a.store.delete(s);return a.layouts.delete(s),j(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return j(e,404,{error:"unknown workflows endpoint",path:n})}var hi=["mesh"];function Nn(t,e,a,n){let r=Xe.safeParse(a);if(!r.success)return j(t,400,{error:"invalid workflow",issues:r.error.issues.map(l=>({path:l.path.join("."),message:l.message}))});let o=r.data,s=Ke(o);if(s.length>0)return j(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return j(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return j(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let l=a,c=e.store.get(n.id);if(c)for(let p of hi)!(p in l)&&p in c&&(o[p]=c[p])}let i;try{i=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(l){let c=l?.message||String(l),p=l?.yamlPath,m=!!p||/yaml round-trip failed/.test(c);return j(t,m?409:500,{error:m?"couldn't preserve comments while saving back to the YAML file. Re-submit with ?convertFromYaml=true to convert this workflow to JSON (comments will be lost).":c,kind:m?"yaml-authored":"save-failed",...p?{path:p}:{}})}return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),j(t,200,{workflow:i})}function gi(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let l=Math.max(1,Math.min(500,Number(r.get("limit")||50))),c=r.get("workflowId")||void 0,p=r.get("summary")==="1"||r.get("summary")==="true",m=a.runs.list({workflowId:c,limit:l});if(!p)return j(e,200,{runs:m});let h=m.map(_=>({id:_.id,workflowId:_.workflowId,workflowVersion:_.workflowVersion,homeNode:_.homeNode,status:_.status,pending:_.pending,entityRef:_.entityRef,history:(_.history||[]).slice(-5),parentRunId:_.parentRunId,parentNodeId:_.parentNodeId,rootRunId:_.rootRunId,depth:_.depth,createdAt:_.createdAt,updatedAt:_.updatedAt}));return j(e,200,{runs:h})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=decodeURIComponent(s[1]);return xe(t,e,c=>{let p=c?.status;return p!=="paused"&&p!=="running"&&p!=="canceled"?j(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,p)?j(e,200,{ok:!0,runId:l,status:p}):j(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return fi(t,e,a,l);let c=a.runs.get(l);return c?j(e,200,{run:c}):j(e,404,{error:"run not found"})}return j(e,404,{error:"unknown runs endpoint"})}function fi(t,e,a,n){let r=a.runs.get(n);if(!r)return j(e,404,{error:"run not found"}),!0;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`data: ${JSON.stringify(r)}
15004
+ `;function zn(t,e,a){let n=t.url||"";if(!n.startsWith("/api/workflows"))return!1;let r=t.method||"GET";if(n==="/api/workflows"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{workflows:a.store.list()}):!0;if(r==="POST"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let s=new URL(n,"http://_").searchParams,i=s.get("convertFromYaml")==="true"||s.get("convertFromYaml")==="1";return ve(t,e,l=>Bn(e,a,l,{mode:"create",convertFromYaml:i}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:fi(t,e,a,n);if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return j(e,501,{error:"dispatcher not enabled"});let s=decodeURIComponent(n.replace(/^\/api\/workflows\/signal\//,"").split("?")[0]);return s?ve(t,e,i=>{let l=i,c=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return j(e,200,{ok:!0,emission:c})}):j(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),i=o[2];if(i==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?ve(t,e,l=>{try{let c=a.layouts.save(s,l);return j(e,200,{layout:c})}catch(c){return j(e,400,{error:"invalid layout",message:c.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?ve(t,e,l=>{let c=Ke.safeParse(l);if(!c.success)return j(e,200,{ok:!1,issues:c.error.issues.map(m=>({path:m.path.join("."),message:m.message}))});let p=Je(c.data).map(m=>({path:"",message:m}));return j(e,200,{ok:p.length===0,issues:p,workflow:c.data})}):!0;if(!i){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=a.store.get(s);return l?j(e,200,{workflow:l}):j(e,404,{error:"workflow not found"})}if(r==="PUT"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=new URL(n,"http://_").searchParams,c=l.get("convertFromYaml")==="true"||l.get("convertFromYaml")==="1";return ve(t,e,p=>Bn(e,a,p,{mode:"update",id:s,convertFromYaml:c}))}if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=a.store.delete(s);return a.layouts.delete(s),j(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return j(e,404,{error:"unknown workflows endpoint",path:n})}var gi=["mesh"];function Bn(t,e,a,n){let r=Ke.safeParse(a);if(!r.success)return j(t,400,{error:"invalid workflow",issues:r.error.issues.map(l=>({path:l.path.join("."),message:l.message}))});let o=r.data,s=Je(o);if(s.length>0)return j(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return j(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return j(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let l=a,c=e.store.get(n.id);if(c)for(let p of gi)!(p in l)&&p in c&&(o[p]=c[p])}let i;try{i=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(l){let c=l?.message||String(l),p=l?.yamlPath,m=!!p||/yaml round-trip failed/.test(c);return j(t,m?409:500,{error:m?"couldn't preserve comments while saving back to the YAML file. Re-submit with ?convertFromYaml=true to convert this workflow to JSON (comments will be lost).":c,kind:m?"yaml-authored":"save-failed",...p?{path:p}:{}})}return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),j(t,200,{workflow:i})}function fi(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let l=Math.max(1,Math.min(500,Number(r.get("limit")||50))),c=r.get("workflowId")||void 0,p=r.get("summary")==="1"||r.get("summary")==="true",m=a.runs.list({workflowId:c,limit:l});if(!p)return j(e,200,{runs:m});let h=m.map(_=>({id:_.id,workflowId:_.workflowId,workflowVersion:_.workflowVersion,homeNode:_.homeNode,status:_.status,pending:_.pending,entityRef:_.entityRef,history:(_.history||[]).slice(-5),parentRunId:_.parentRunId,parentNodeId:_.parentNodeId,rootRunId:_.rootRunId,depth:_.depth,createdAt:_.createdAt,updatedAt:_.updatedAt}));return j(e,200,{runs:h})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=decodeURIComponent(s[1]);return ve(t,e,c=>{let p=c?.status;return p!=="paused"&&p!=="running"&&p!=="canceled"?j(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,p)?j(e,200,{ok:!0,runId:l,status:p}):j(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return xi(t,e,a,l);let c=a.runs.get(l);return c?j(e,200,{run:c}):j(e,404,{error:"run not found"})}return j(e,404,{error:"unknown runs endpoint"})}function xi(t,e,a,n){let r=a.runs.get(n);if(!r)return j(e,404,{error:"run not found"}),!0;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`data: ${JSON.stringify(r)}
15005
15005
 
15006
15006
  `);let o=!1,s=()=>{o=!0,l?.(),clearInterval(p);try{e.end()}catch{}};t.on("close",s);let i=m=>{if(!o)try{e.write(`data: ${JSON.stringify(m)}
15007
15007
 
15008
- `)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,p=setInterval(()=>{if(o)return;let m=a.runs.get(n);m&&m.updatedAt!==c&&(c=m.updatedAt,i(m))},2e3);return!0}function xe(t,e,a){let n="";return t.setEncoding("utf8"),t.on("data",r=>{n+=r}),t.on("end",()=>{let r;try{r=n?JSON.parse(n):{}}catch(s){j(e,400,{error:"invalid JSON body",message:s.message});return}let o;try{o=a(r)}catch(s){try{j(e,500,{error:"handler threw (sync)",message:s?.message??String(s)})}catch{}return}Promise.resolve(o).catch(s=>{try{j(e,500,{error:"handler threw",message:s?.message??String(s)})}catch{}})}),t.on("error",r=>j(e,400,{error:"body read failed",message:r.message})),!0}function j(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}function Vc(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let _ of a)try{s.set(_.id,Ai(_,t))}catch(S){console.error(` Board "${_.id}" failed to initialize: ${S.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?_e(process.cwd(),t.workflows.dir):void 0,c=new Ct(l?{baseDir:l}:void 0),p=new At(l?{baseDir:l,nodeId:i}:{nodeId:i}),m=new Mt(l?{baseDir:l}:void 0);cn(t),zt({business:t.business?.enabled===!0}),xi(async(_,S)=>{try{await Ei(_,S,{boards:a,sources:s,token:o,config:t,workflowStore:c,workflowRuns:p,workflowLayouts:m})}catch(w){v(S,500,{error:w.message||"internal error"})}}).listen(n,r,()=>{let _=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
15008
+ `)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,p=setInterval(()=>{if(o)return;let m=a.runs.get(n);m&&m.updatedAt!==c&&(c=m.updatedAt,i(m))},2e3);return!0}function ve(t,e,a){let n="";return t.setEncoding("utf8"),t.on("data",r=>{n+=r}),t.on("end",()=>{let r;try{r=n?JSON.parse(n):{}}catch(s){j(e,400,{error:"invalid JSON body",message:s.message});return}let o;try{o=a(r)}catch(s){try{j(e,500,{error:"handler threw (sync)",message:s?.message??String(s)})}catch{}return}Promise.resolve(o).catch(s=>{try{j(e,500,{error:"handler threw",message:s?.message??String(s)})}catch{}})}),t.on("error",r=>j(e,400,{error:"body read failed",message:r.message})),!0}function j(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}function Qc(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let _ of a)try{s.set(_.id,Mi(_,t))}catch(S){console.error(` Board "${_.id}" failed to initialize: ${S.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?Ee(process.cwd(),t.workflows.dir):void 0,c=new At(l?{baseDir:l}:void 0),p=new Mt(l?{baseDir:l,nodeId:i}:{nodeId:i}),m=new It(l?{baseDir:l}:void 0);pn(t),qt({business:t.business?.enabled===!0}),vi(async(_,S)=>{try{await Si(_,S,{boards:a,sources:s,token:o,config:t,workflowStore:c,workflowRuns:p,workflowLayouts:m})}catch(w){v(S,500,{error:w.message||"internal error"})}}).listen(n,r,()=>{let _=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
15009
15009
  Live dashboard: http://${_}:${n}
15010
15010
  `),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
15011
15011
  Kanban dashboard: http://${_}:${n}
15012
- `),console.log(` Boards: ${a.map(S=>S.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}var _i=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/approvals","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki"]);async function Ei(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(Nt(t.headers)==="foreign"&&Bt(o)){v(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&_i.has(r)&&oa("page",r),o==="GET"&&r==="/"){let d=Zt();if(!d.configExists||d.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gt({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ln({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gt({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[d]=await de(a.config);if(!d){v(e,503,{error:"no node available"});return}let u=await new Promise(f=>{let b="";t.on("data",x=>b+=x),t.on("end",()=>f(b)),t.on("error",()=>f(""))}),g=await fetch(d.url+r,{method:"POST",headers:{"Content-Type":"application/json",...d.token?{Authorization:`Bearer ${d.token}`}:{}},body:u||"{}"});e.writeHead(g.status,{"Content-Type":"application/json"}),e.end(await g.text())}catch(d){v(e,502,{error:"could not reach the node",message:String(d?.message||d)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let d=await de(a.config),u=o==="POST"?void 0:n.searchParams.get("node"),g=o==="POST"?await ie(t):void 0,f=g?.node??u,b=f?d.find(M=>M.url===f):d[0];if(!b){v(e,400,{error:"unknown node"});return}let x=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",y=await fetch(b.url+r+x,{method:o,headers:{"Content-Type":"application/json",...b.token?{Authorization:`Bearer ${b.token}`}:{}},...o==="POST"?{body:JSON.stringify({...g,node:void 0})}:{}});v(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(d){v(e,502,{error:"could not reach the node",message:d?.message||String(d)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let d=await ie(t),u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let g=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${g}/api/workflows/editor/chat`,{method:"POST",headers:u,body:JSON.stringify(d??{})}),b=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,b)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[d]=await de(a.config);if(!d){v(e,200,{configured:!1,workflows:[]});return}let u=await fetch(d.url+"/api/n8n/workflows",{headers:d.token?{Authorization:`Bearer ${d.token}`}:{}});v(e,u.status,await u.json().catch(()=>({configured:!1,workflows:[]})))}catch{v(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ga({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ha({peers:D(a.config),view:n.searchParams.get("view")}));return}if(o==="GET"&&r==="/monitor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ca({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let d=new AbortController,u=setTimeout(()=>d.abort(),8e3);try{let g=$t(await de(a.config,d.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let M=await Promise.all(g.map(async A=>{try{let k=await fetch(A.url+"/monitor",{headers:A.token?{Authorization:`Bearer ${A.token}`}:{},signal:d.signal});if(!k.ok)throw new Error(`HTTP ${k.status}`);return{name:A.name,url:A.url,ok:!0,data:await k.json()}}catch(k){return{name:A.name,url:A.url,ok:!1,error:k.message}}}));v(e,200,{nodes:M});return}let f=g.find(M=>M.url===n.searchParams.get("node"));if(!f){v(e,400,{error:"Select a known node"});return}let b=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(b)||o==="POST"&&["register","ended","action","retry","clear"].includes(b))){v(e,405,{error:"Unknown monitor operation"});return}let x=o==="POST"?JSON.stringify(await It(t)):void 0,y=await fetch(f.url+"/monitor/"+b+(b==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):b==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:x,signal:d.signal,headers:{"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}}});v(e,y.status,await y.json())}catch(g){v(e,502,{error:g.message})}finally{clearTimeout(u)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Mn({peers:D(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Rn({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Pn({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Dn({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Qt({}));return}let i=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(i){let d=n.searchParams.get("agent")||"",u=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!d){e.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),e.end("<p>Missing <code>?agent=</code>. Open this task from the Live page.</p>");return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(On({taskId:decodeURIComponent(i[1]),agentId:d,agentName:n.searchParams.get("name")||void 0,channel:n.searchParams.get("channel")||void 0,archived:n.searchParams.get("archived")==="1",ask:n.searchParams.get("ask")||void 0,askAt:n.searchParams.get("at")||void 0,nodeUrl:u,peers:D(a.config)}));return}let l=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(l){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Hn({agentId:decodeURIComponent(l[1]),agentName:n.searchParams.get("name")||void 0,nodeUrl:n.searchParams.get("node")||a.config.dashboard.daemonUrl,peers:D(a.config)}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){ea(t,e);return}if(o==="POST"&&r==="/api/setup"){await ta(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await aa(t,e);return}if(o==="GET"&&r==="/admin"){ya(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){ja(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){Ca(t,e,D(a.config),a.token);return}if(o==="GET"&&(r==="/admin/health"||r==="/admin/observability")){if(r==="/admin/observability"){e.writeHead(302,{Location:"/admin/health"}),e.end();return}Na(t,e,D(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let d=n.searchParams.get("peer")==="fleet"?"fleet":String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(d==="fleet"){if(r==="/api/admin/activity-graph"){await Fi(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await mt(t,e,r,g=>Un(g,a.config));return}let u=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(u){let g=decodeURIComponent(u[1]),f=g.indexOf("::");if(f>0){let b=g.slice(0,f),x=g.slice(f+2),y=a.config.node?.id||a.config.node?.name||"local";if(b===y)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`;else{let M=(a.config.dashboard?.daemons||[]).find(A=>(A.name||A.url)===b);if(M){let A=wt(M.url.replace(/\/+$/,""),a.config);if(A){await zn(t,e,A,`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`);return}}v(e,404,{error:`unknown node "${b}" in fleet dispatch id`});return}}}}else if(d&&d!=="primary"){let u=wt(d,a.config);if(!u){v(e,404,{error:`unknown peer: ${d}`});return}let g=(n.search||"").replace(/[?&]peer=[^&]*/g,b=>b.startsWith("?")?"?":"");await zn(t,e,u,r+(g==="?"?"":g));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Ba(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Ui(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:d}=await import("./doctor-2DMGAWMW.js"),g=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",f=await d({running:g});v(e,200,f)}catch(d){v(e,500,{error:d?.message||String(d)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ua({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Fa(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wa({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ga({peers:D(a.config)}));return}if(o==="GET"&&(r==="/admin/wiki"||r.startsWith("/admin/wiki/"))){if(r==="/admin/wiki"){e.writeHead(302,{Location:"/admin/wiki/"}),e.end();return}await Ii(a)(t,e);return}if(o==="GET"&&r==="/admin/activity-graph"){e.writeHead(302,{Location:"/activity?view=map"}),e.end();return}if(o==="GET"&&r==="/api/admin/activity-graph"&&await pn(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await mt(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await mn(t,e,r))return;let c=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(c){fn(t,e,c[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let d=t.headers.authorization||"",u=d.startsWith("Bearer ")?d.slice(7):"";if(u!==a.token){let g=new ae,f=u?g.verify(u):null;if(!f||!be(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await wa(t,e);return}if(r.startsWith("/api/admin/approvals")){await La(t,e,r,n);return}if(r.startsWith("/api/admin/graph/")){await Aa(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await xn(t,e,r);return}if(r.startsWith("/api/admin/")){await ka(t,e,r);return}if(o==="GET"&&r==="/sortable.min.js"){e.writeHead(200,{"Content-Type":"application/javascript; charset=utf-8","Cache-Control":"public, max-age=86400"}),e.end(fa);return}if(o==="GET"&&r.startsWith("/assets/")){let d=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(d)){v(e,400,{error:"invalid asset name"});return}let u=zi("web/"+d);try{let g=await qi(u),f=d.endsWith(".map")?"application/json; charset=utf-8":d.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",b=n.searchParams.has("v");e.writeHead(200,{"Content-Type":f,"Cache-Control":b?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(g)}catch{v(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let d=await bt(a.config);v(e,200,d)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let d=n.searchParams.get("date")||new Date().toISOString().slice(0,10),u=n.searchParams.get("timezone")||"UTC",g=await bt(a.config,{date:d,timezone:u});v(e,200,g)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let d=(u,g,f,b)=>{let x=parseInt(n.searchParams.get(u)||"",10);return Number.isFinite(x)?Math.max(f,Math.min(b,x)):g};try{let u=await de(a.config);v(e,200,await In(u,{days:d("days",30,0,180),tzOffsetMinutes:d("tzOffset",0,-840,840),limit:d("limit",60,1,200)}))}catch(u){v(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let d=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(d)){v(e,400,{error:"day=YYYY-MM-DD query param required"});return}let u=(g,f,b,x)=>{let y=parseInt(n.searchParams.get(g)||"",10);return Number.isFinite(y)?Math.max(b,Math.min(x,y)):f};try{let g=await de(a.config);v(e,200,await jn(g,{day:d,tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",40,1,200)}))}catch(g){v(e,502,{error:g.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}let u=n.searchParams,g;if(r==="/api/mesh/thread"){let[f,b,x]=[u.get("agent"),u.get("channel"),u.get("chat")];if(!f||!b||!x){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/thread?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(b)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(u.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[f,b]=[u.get("kind"),u.get("key")];if(!f||!b){v(e,400,{error:"kind and key required"});return}g=`/analytics/job?kind=${encodeURIComponent(f)}&key=${encodeURIComponent(b)}&limit=${encodeURIComponent(u.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[f,b,x]=[u.get("agent"),u.get("channel"),u.get("chat")];if(!f||!b||!x){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/conversation?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(b)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(u.get("tzOffset")||"0")}`}else{let f=u.get("task");if(!f){v(e,400,{error:"task required"});return}g=`/analytics/run/${encodeURIComponent(f)}`}try{await $n(e,await de(a.config),d,g)}catch(f){v(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/live/stream"){ji(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task");if(!u||!g||!f){v(e,400,{error:"node, agent, task query params required"});return}await Li(t,e,a,u,g,f);return}if(o==="GET"&&r==="/api/task/history"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task"),b=d.searchParams.get("limit")||"50";if(!u||!g){v(e,400,{error:"node and agent query params required"});return}await Di(e,a,u,g,f,b);return}if(o==="POST"&&r==="/api/task/action"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("task"),f=d.searchParams.get("kind");if(!u||!g||f!=="cancel"&&f!=="followup"){v(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Oi(t,e,a,u,g,f);return}if(o==="POST"&&r==="/api/voice/stop"){let d=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}await yt(t,e,a,d,"/voice/stop");return}if(o==="GET"&&r==="/api/agents"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:d});if(!u.ok)throw new Error(`HTTP ${u.status}`);let g=await u.json();v(e,200,g)}catch(d){v(e,502,{error:d.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:d});if(!u.ok){v(e,u.status,{error:`HTTP ${u.status}`});return}v(e,200,await u.json())}catch(d){v(e,502,{error:d.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let d=await ie(t);try{let u=await Ni(a.config,d);v(e,200,u)}catch(u){v(e,502,{error:u.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let d=p[1];if(!Ri(t,e,[`agent:${d}`]))return;await Pi(t,e,a.config,d);return}if(r.startsWith("/api/")&&a.token){let d=t.headers.authorization||"",u=d.startsWith("Bearer ")?d.slice(7):"";if(u!==a.token){let g=new ae,f=u?g.verify(u):null;if(!f||!be(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){v(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}await yt(t,e,a,d,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let u=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let g=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(y=>({name:y.name,url:y.url,token:y.token}))],f={flag:!1},b=[];t.on("close",()=>{f.flag=!0;for(let y of b)try{y.abort()}catch{}});let x=setInterval(()=>{if(!f.flag)try{e.write(`: ping
15012
+ `),console.log(` Boards: ${a.map(S=>S.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}var Ei=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/approvals","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki"]);async function Si(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(Bt(t.headers)==="foreign"&&zt(o)){v(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&Ei.has(r)&&sa("page",r),o==="GET"&&r==="/"){let d=ea();if(!d.configExists||d.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ft({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Rn({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ft({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[d]=await de(a.config);if(!d){v(e,503,{error:"no node available"});return}let u=await new Promise(f=>{let b="";t.on("data",x=>b+=x),t.on("end",()=>f(b)),t.on("error",()=>f(""))}),g=await fetch(d.url+r,{method:"POST",headers:{"Content-Type":"application/json",...d.token?{Authorization:`Bearer ${d.token}`}:{}},body:u||"{}"});e.writeHead(g.status,{"Content-Type":"application/json"}),e.end(await g.text())}catch(d){v(e,502,{error:"could not reach the node",message:String(d?.message||d)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let d=await de(a.config),u=o==="POST"?void 0:n.searchParams.get("node"),g=o==="POST"?await ie(t):void 0,f=g?.node??u,b=f?d.find(M=>M.url===f):d[0];if(!b){v(e,400,{error:"unknown node"});return}let x=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",y=await fetch(b.url+r+x,{method:o,headers:{"Content-Type":"application/json",...b.token?{Authorization:`Bearer ${b.token}`}:{}},...o==="POST"?{body:JSON.stringify({...g,node:void 0})}:{}});v(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(d){v(e,502,{error:"could not reach the node",message:d?.message||String(d)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let d=await ie(t),u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let g=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${g}/api/workflows/editor/chat`,{method:"POST",headers:u,body:JSON.stringify(d??{})}),b=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,b)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[d]=await de(a.config);if(!d){v(e,200,{configured:!1,workflows:[]});return}let u=await fetch(d.url+"/api/n8n/workflows",{headers:d.token?{Authorization:`Bearer ${d.token}`}:{}});v(e,u.status,await u.json().catch(()=>({configured:!1,workflows:[]})))}catch{v(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fa({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ga({peers:D(a.config),view:n.searchParams.get("view")}));return}if(o==="GET"&&r==="/monitor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(pa({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let d=new AbortController,u=setTimeout(()=>d.abort(),8e3);try{let g=jt(await de(a.config,d.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let M=await Promise.all(g.map(async A=>{try{let k=await fetch(A.url+"/monitor",{headers:A.token?{Authorization:`Bearer ${A.token}`}:{},signal:d.signal});if(!k.ok)throw new Error(`HTTP ${k.status}`);return{name:A.name,url:A.url,ok:!0,data:await k.json()}}catch(k){return{name:A.name,url:A.url,ok:!1,error:k.message}}}));v(e,200,{nodes:M});return}let f=g.find(M=>M.url===n.searchParams.get("node"));if(!f){v(e,400,{error:"Select a known node"});return}let b=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(b)||o==="POST"&&["register","ended","action","retry","clear"].includes(b))){v(e,405,{error:"Unknown monitor operation"});return}let x=o==="POST"?JSON.stringify(await $t(t)):void 0,y=await fetch(f.url+"/monitor/"+b+(b==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):b==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:x,signal:d.signal,headers:{"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}}});v(e,y.status,await y.json())}catch(g){v(e,502,{error:g.message})}finally{clearTimeout(u)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(In({peers:D(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Pn({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Dn({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(On({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Zt({}));return}let i=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(i){let d=n.searchParams.get("agent")||"",u=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!d){e.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),e.end("<p>Missing <code>?agent=</code>. Open this task from the Live page.</p>");return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Hn({taskId:decodeURIComponent(i[1]),agentId:d,agentName:n.searchParams.get("name")||void 0,channel:n.searchParams.get("channel")||void 0,archived:n.searchParams.get("archived")==="1",ask:n.searchParams.get("ask")||void 0,askAt:n.searchParams.get("at")||void 0,nodeUrl:u,peers:D(a.config)}));return}let l=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(l){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Nn({agentId:decodeURIComponent(l[1]),agentName:n.searchParams.get("name")||void 0,nodeUrl:n.searchParams.get("node")||a.config.dashboard.daemonUrl,peers:D(a.config)}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){ta(t,e);return}if(o==="POST"&&r==="/api/setup"){await aa(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await na(t,e);return}if(o==="GET"&&r==="/admin"){wa(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){La(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){Aa(t,e,D(a.config),a.token);return}if(o==="GET"&&(r==="/admin/health"||r==="/admin/observability")){if(r==="/admin/observability"){e.writeHead(302,{Location:"/admin/health"}),e.end();return}Ba(t,e,D(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let d=n.searchParams.get("peer")==="fleet"?"fleet":String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(d==="fleet"){if(r==="/api/admin/activity-graph"){await Ui(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await ht(t,e,r,g=>Wn(g,a.config));return}let u=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(u){let g=decodeURIComponent(u[1]),f=g.indexOf("::");if(f>0){let b=g.slice(0,f),x=g.slice(f+2),y=a.config.node?.id||a.config.node?.name||"local";if(b===y)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`;else{let M=(a.config.dashboard?.daemons||[]).find(A=>(A.name||A.url)===b);if(M){let A=kt(M.url.replace(/\/+$/,""),a.config);if(A){await qn(t,e,A,`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`);return}}v(e,404,{error:`unknown node "${b}" in fleet dispatch id`});return}}}}else if(d&&d!=="primary"){let u=kt(d,a.config);if(!u){v(e,404,{error:`unknown peer: ${d}`});return}let g=(n.search||"").replace(/[?&]peer=[^&]*/g,b=>b.startsWith("?")?"?":"");await qn(t,e,u,r+(g==="?"?"":g));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await za(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Wi(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:d}=await import("./doctor-CXFMV6PT.js"),g=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",f=await d({running:g});v(e,200,f)}catch(d){v(e,500,{error:d?.message||String(d)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wa({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Ua(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ga({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xa({peers:D(a.config)}));return}if(o==="GET"&&(r==="/admin/wiki"||r.startsWith("/admin/wiki/"))){if(r==="/admin/wiki"){e.writeHead(302,{Location:"/admin/wiki/"}),e.end();return}await $i(a)(t,e);return}if(o==="GET"&&r==="/admin/activity-graph"){e.writeHead(302,{Location:"/activity?view=map"}),e.end();return}if(o==="GET"&&r==="/api/admin/activity-graph"&&await un(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await ht(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await hn(t,e,r))return;let c=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(c){xn(t,e,c[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let d=t.headers.authorization||"",u=d.startsWith("Bearer ")?d.slice(7):"";if(u!==a.token){let g=new ae,f=u?g.verify(u):null;if(!f||!ye(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await ka(t,e);return}if(r.startsWith("/api/admin/approvals")){await Ra(t,e,r,n);return}if(r.startsWith("/api/admin/graph/")){await Ma(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await vn(t,e,r);return}if(r.startsWith("/api/admin/")){await _a(t,e,r);return}if(o==="GET"&&r==="/sortable.min.js"){e.writeHead(200,{"Content-Type":"application/javascript; charset=utf-8","Cache-Control":"public, max-age=86400"}),e.end(xa);return}if(o==="GET"&&r.startsWith("/assets/")){let d=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(d)){v(e,400,{error:"invalid asset name"});return}let u=qi("web/"+d);try{let g=await Fi(u),f=d.endsWith(".map")?"application/json; charset=utf-8":d.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",b=n.searchParams.has("v");e.writeHead(200,{"Content-Type":f,"Cache-Control":b?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(g)}catch{v(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let d=await yt(a.config);v(e,200,d)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let d=n.searchParams.get("date")||new Date().toISOString().slice(0,10),u=n.searchParams.get("timezone")||"UTC",g=await yt(a.config,{date:d,timezone:u});v(e,200,g)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let d=(u,g,f,b)=>{let x=parseInt(n.searchParams.get(u)||"",10);return Number.isFinite(x)?Math.max(f,Math.min(b,x)):g};try{let u=await de(a.config);v(e,200,await $n(u,{days:d("days",30,0,180),tzOffsetMinutes:d("tzOffset",0,-840,840),limit:d("limit",60,1,200)}))}catch(u){v(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let d=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(d)){v(e,400,{error:"day=YYYY-MM-DD query param required"});return}let u=(g,f,b,x)=>{let y=parseInt(n.searchParams.get(g)||"",10);return Number.isFinite(y)?Math.max(b,Math.min(x,y)):f};try{let g=await de(a.config);v(e,200,await Ln(g,{day:d,tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",40,1,200)}))}catch(g){v(e,502,{error:g.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}let u=n.searchParams,g;if(r==="/api/mesh/thread"){let[f,b,x]=[u.get("agent"),u.get("channel"),u.get("chat")];if(!f||!b||!x){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/thread?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(b)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(u.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[f,b]=[u.get("kind"),u.get("key")];if(!f||!b){v(e,400,{error:"kind and key required"});return}g=`/analytics/job?kind=${encodeURIComponent(f)}&key=${encodeURIComponent(b)}&limit=${encodeURIComponent(u.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[f,b,x]=[u.get("agent"),u.get("channel"),u.get("chat")];if(!f||!b||!x){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/conversation?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(b)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(u.get("tzOffset")||"0")}`}else{let f=u.get("task");if(!f){v(e,400,{error:"task required"});return}g=`/analytics/run/${encodeURIComponent(f)}`}try{await jn(e,await de(a.config),d,g)}catch(f){v(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/live/stream"){Li(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task");if(!u||!g||!f){v(e,400,{error:"node, agent, task query params required"});return}await Ri(t,e,a,u,g,f);return}if(o==="GET"&&r==="/api/task/history"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task"),b=d.searchParams.get("limit")||"50";if(!u||!g){v(e,400,{error:"node and agent query params required"});return}await Oi(e,a,u,g,f,b);return}if(o==="POST"&&r==="/api/task/action"){let d=new URL(t.url||"/","http://localhost"),u=d.searchParams.get("node"),g=d.searchParams.get("task"),f=d.searchParams.get("kind");if(!u||!g||f!=="cancel"&&f!=="followup"){v(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Hi(t,e,a,u,g,f);return}if(o==="POST"&&r==="/api/voice/stop"){let d=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}await wt(t,e,a,d,"/voice/stop");return}if(o==="GET"&&r==="/api/agents"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:d});if(!u.ok)throw new Error(`HTTP ${u.status}`);let g=await u.json();v(e,200,g)}catch(d){v(e,502,{error:d.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:d});if(!u.ok){v(e,u.status,{error:`HTTP ${u.status}`});return}v(e,200,await u.json())}catch(d){v(e,502,{error:d.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let d=await ie(t);try{let u=await Bi(a.config,d);v(e,200,u)}catch(u){v(e,502,{error:u.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let d=p[1];if(!Pi(t,e,[`agent:${d}`]))return;await Di(t,e,a.config,d);return}if(r.startsWith("/api/")&&a.token){let d=t.headers.authorization||"",u=d.startsWith("Bearer ")?d.slice(7):"";if(u!==a.token){let g=new ae,f=u?g.verify(u):null;if(!f||!ye(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){v(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}await wt(t,e,a,d,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let u=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let g=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(y=>({name:y.name,url:y.url,token:y.token}))],f={flag:!1},b=[];t.on("close",()=>{f.flag=!0;for(let y of b)try{y.abort()}catch{}});let x=setInterval(()=>{if(!f.flag)try{e.write(`: ping
15013
15013
 
15014
15014
  `)}catch{}},15e3);t.on("close",()=>clearInterval(x));for(let y of g)(async()=>{let M={Accept:"text/event-stream"};y.token&&(M.Authorization=`Bearer ${y.token}`);let A=new AbortController;b.push(A);try{let k=await fetch(`${y.url.replace(/\/+$/,"")}/events${u?`?${u}`:""}`,{headers:M,signal:A.signal});if(!k.ok||!k.body)return;let I=k.body.getReader(),L=new TextDecoder,R="";for(;!f.flag;){let{done:N,value:Z}=await I.read();if(N)break;R+=L.decode(Z,{stream:!0});let B;for(;(B=R.indexOf(`
15015
15015
 
15016
15016
  `))>=0;){let O=R.slice(0,B);if(R=R.slice(B+2),f.flag)break;try{e.write(O+`
15017
15017
 
15018
- `)}catch{f.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let d=new URL(t.url||"/","http://localhost"),u=Math.max(1,Math.min(500,Number(d.searchParams.get("limit")||50))),g=d.searchParams.get("workflowId")||void 0,f=d.searchParams.get("summary")==="1"||d.searchParams.get("summary")==="true",b=a.workflowRuns.list({limit:u,workflowId:g}),x=`?limit=${u}${g?`&workflowId=${encodeURIComponent(g)}`:""}${f?"&summary=1":""}`,y=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(L=>({url:L.url,token:L.token}))],M=await Promise.all(y.map(async L=>{let R={};L.token&&(R.Authorization=`Bearer ${L.token}`);try{let N=new AbortController,Z=setTimeout(()=>N.abort(),5e3);try{let B=await fetch(`${L.url.replace(/\/+$/,"")}/api/workflows/runs${x}`,{headers:R,signal:N.signal});if(!B.ok)return[];let O=await B.json();return Array.isArray(O.runs)?O.runs:[]}finally{clearTimeout(Z)}}catch{return[]}})),A=new Map;for(let L of b)A.set(L.id,L);for(let L of M)for(let R of L)A.set(R.id,R);let k=Array.from(A.values()).sort((L,R)=>L.updatedAt<R.updatedAt?1:-1).slice(0,u),I=f?k.map(L=>Ci(L)):k;v(e,200,{runs:I})}catch(d){v(e,502,{error:"runs fetch failed",message:d.message||String(d)})}return}let h=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(h){let d=decodeURIComponent(h[1]),u=a.workflowRuns.get(d);if(u){v(e,200,{run:u});return}let g=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(f=>({url:f.url,token:f.token}))];for(let f of g)try{let b={};f.token&&(b.Authorization=`Bearer ${f.token}`);let x=await fetch(`${f.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(d)}`,{headers:b});if(x.ok){v(e,200,await x.json());return}}catch{}v(e,404,{error:"run not found on any configured peer"});return}if(o==="GET"&&r==="/api/actions/builtin"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=a.config.dashboard.daemonUrl.replace(/\/+$/,""),g=await fetch(`${u}/api/actions/builtin`,{headers:d}),f=await g.json().catch(()=>({error:`HTTP ${g.status}`}));v(e,g.status,f)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}let _=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(_){try{let d=await ie(t).catch(()=>({})),u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let g=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${g}/workflows/${encodeURIComponent(_[1])}/run`,{method:"POST",headers:u,body:JSON.stringify(d??{})}),b=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,b)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(r.startsWith("/api/workflows")&&Bn(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(u,g,f)=>{if(a.token)return!0;let b=Ve(u);if(!b)return!0;let x=new ae().verify(b);if(!x)return v(g,401,{error:"invalid or revoked token"}),!1;for(let y of f)if(!be(x,y))return v(g,403,{error:`token missing scope: ${y}`,scopes:x.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){v(e,200,a.boards.map(d=>({id:d.id,name:d.name,source:d.source,primaryToolLabel:d.primaryToolLabel,labels:d.labels,columns:d.columns,timeRangeDays:d.timeRangeDays})));return}let S=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(S&&o==="GET"){let d=a.sources.get(S[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let u=typeof d.listMembers=="function"?await d.listMembers():[];v(e,200,u)}catch(u){v(e,502,{error:u.message})}return}let w=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(w&&o==="GET"){let d=a.sources.get(w[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let u=typeof d.listMilestones=="function"?await d.listMilestones():[];v(e,200,u)}catch(u){v(e,502,{error:u.message})}return}let E=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),T=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(E&&o==="PATCH"){let[,d,u]=E,g=decodeURIComponent(u),f=a.boards.find(A=>A.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let b=a.sources.get(d);if(!b){v(e,503,{error:`board "${d}" source unavailable`});return}let x=await ie(t),y=f.columns.find(A=>A.id===x.to),M=f.columns.find(A=>A.id===x.from);if(!y){v(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await Ti(b,g,M,y),ft({actor:xt(t),action:"move",boardId:d,itemId:g,payload:{from:x.from,to:x.to}}),v(e,200,{ok:!0})}catch(A){v(e,502,{error:A.message||"transition failed"})}return}if(T){let[,d,u]=T,g=u?decodeURIComponent(u):void 0,f=a.boards.find(x=>x.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let b=a.sources.get(d);if(!b){v(e,503,{error:`board "${d}" source unavailable`});return}if(o==="GET"&&!g){let{columns:x,totals:y}=await Si(f,b,n.searchParams);v(e,200,{columns:x,totals:y});return}if(o==="GET"&&g){try{let x=typeof b.getItem=="function"?await b.getItem(g):null;if(!x){v(e,404,{error:"not found"});return}v(e,200,x)}catch(x){v(e,502,{error:x.message})}return}if(o==="PATCH"&&g){let x=await ie(t);try{let y=typeof b.updateItem=="function"?await b.updateItem(g,x):null;if(!y){v(e,501,{error:"update unsupported"});return}ft({actor:xt(t),action:"update",boardId:d,itemId:g,payload:x}),v(e,200,y)}catch(y){v(e,502,{error:y.message})}return}if(o==="POST"&&!g){let x=await ie(t);if(!x.title){v(e,400,{error:"title required"});return}if(!b.capabilities.create||!b.create){v(e,400,{error:`source ${b.type} does not support create`});return}try{let y=await b.create({title:x.title,description:x.description,labels:x.labels,assigneeUsernames:x.assigneeUsernames,milestoneTitle:x.milestoneTitle,projectHint:x.projectHint});ft({actor:xt(t),action:"create",boardId:d,itemId:y.id,payload:{title:x.title}}),v(e,201,y)}catch(y){v(e,502,{error:y.message})}return}}if(o==="GET"&&/^\/[a-z][a-z-]*\/?$/.test(r)){let d=r.replace(/^\/+|\/+$/g,""),g={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[d];if(g){e.writeHead(302,{Location:g}),e.end();return}}v(e,404,{error:"not found",path:r})}async function Si(t,e,a){if(!e.capabilities.listAll||!e.listAll){let d={};for(let u of t.columns)d[u.id]=[];return{columns:d,totals:Object.fromEntries(t.columns.map(u=>[u.id,0]))}}let n=[];t.primaryToolLabel&&n.push(t.primaryToolLabel);let r=a.get("label")||void 0;r&&n.push(r);let o=a.get("q")||void 0,s=a.get("milestone")||void 0,i=a.get("assignee")||void 0,l=parseInt(a.get("days")||String(t.timeRangeDays),10),c=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),p=t.columns.some(d=>d.kind!=="closed"),m=t.columns.some(d=>d.kind==="closed"),h=p?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],_=m?await e.listAll({sinceDays:c,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],S={};for(let d of t.columns)S[d.id]=[];let w=t.columns.find(d=>d.kind==="closed");for(let d of _)w&&S[w.id].push({...d,stage:w.id});let E=t.columns.filter(d=>d.kind!=="closed");for(let d of h){let u=_t(d,E);if(!u)continue;let g=S[u];g&&g.push({...d,stage:u})}if(i)for(let d of Object.keys(S))S[d]=S[d].filter(u=>u.assignee===i);for(let d of Object.keys(S))S[d].sort((u,g)=>{let f=(u.priority??99)-(g.priority??99);return f!==0?f:(g.updatedAt||"").localeCompare(u.updatedAt||"")});let T=Object.fromEntries(Object.entries(S).map(([d,u])=>[d,u.length]));return{columns:S,totals:T}}async function Ti(t,e,a,n){let r=Et(a,n),o=t;r.closeIssue&&typeof o.setState=="function"?await o.setState(e,"close"):r.reopen&&typeof o.setState=="function"&&await o.setState(e,"reopen"),(r.addLabels?.length||r.removeLabels?.length)&&typeof o.transitionMany=="function"?await o.transitionMany(e,r.addLabels||[],r.removeLabels||[]):r.addLabels?.length&&t.transition&&await t.transition(e,r.addLabels[0],r.removeLabels?.[0])}function Ci(t){return{id:t.id,workflowId:t.workflowId,workflowVersion:t.workflowVersion,homeNode:t.homeNode,status:t.status,pending:t.pending,entityRef:t.entityRef,history:(t.history||[]).slice(-5),parentRunId:t.parentRunId,parentNodeId:t.parentNodeId,rootRunId:t.rootRunId,depth:t.depth,createdAt:t.createdAt,updatedAt:t.updatedAt}}function Ai(t,e){if(t.source.type==="gitlab"){let a=e.channels.gitlab;if(!a?.token)throw new Error("channels.gitlab.token is required for gitlab boards");let n={};for(let r of a.agentMappings)r.gitlabUsernames.length&&(n[r.agentId]=r.gitlabUsernames);return new Ft(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function ft(t){try{let e=_e(process.cwd(),".agentx");qn(e)||bi(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
15019
- `;vi(_e(e,"board-audit.jsonl"),a)}catch{}}function xt(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}async function Mi(t,e,a,n){let r={};e&&(r.Authorization=`Bearer ${e}`);let o={id:t,name:t,url:t,reachable:!1,agents:[]};try{let s=n?`?date=${encodeURIComponent(n.date)}&timezone=${encodeURIComponent(n.timezone)}`:"",[i,l,c,p,m,h,_]=await Promise.all([fetch(t+"/health",{headers:r,signal:a}).catch(()=>null),fetch(t+"/agents",{headers:r,signal:a}).catch(()=>null),fetch(t+"/mesh",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons/runs"+s,{headers:r,signal:a}).catch(()=>null),fetch(t+"/talk",{headers:r,signal:a}).catch(()=>null),fetch(t+"/routines",{headers:r,signal:a}).catch(()=>null)]);if(!l||!l.ok)return o.error=l?`HTTP ${l.status}`:"unreachable",o;let S=await l.json();if(o.agents=S.map(w=>({id:w.id,name:w.name,tier:w.tier,model:w.model,skillCount:Number.isFinite(w.skillCount)?w.skillCount:void 0,active:w.active||0,total:w.total||0,errors:w.errors||0,lastActive:w.lastActive,lastSummary:w.lastSummary,hourlyTasks:Array.isArray(w.hourlyTasks)?w.hourlyTasks:void 0,runningTasks:Array.isArray(w.runningTasks)?w.runningTasks:[]})),i&&i.ok){let w=await i.json();o.uptimeSec=w.uptime,typeof w.inflight?.total=="number"&&(o.inflight=w.inflight.total),w.restart&&typeof w.restart.state=="string"&&(o.restart=w.restart),o.name=w.node?.name||w.node?.id||t,o.id=w.node?.id||t,w.usage&&(o.usage=w.usage)}if(p&&p.ok){let w=await p.json();o.crons=w.map(E=>({id:E.id,enabled:E.enabled===!0,schedule:String(E.schedule||""),timezone:E.timezone,agent:String(E.agent||""),kind:typeof E.command=="string"&&E.command.trim()?"command":"agent",model:E.model,nextRun:E.nextRun,retryPending:E.retryPending===!0,consecutiveErrors:Number(E.consecutiveErrors)||0}))}if(m&&m.ok){let w=await m.json();o.cronRuns=Array.isArray(w.runs)?w.runs:[]}if(_&&_.ok){let w=await _.json().catch(()=>null);w&&Array.isArray(w.routines)&&(o.routines=w.routines.slice(0,Rt.routines))}if(h&&h.ok){let w=await h.json().catch(()=>null);w?.active&&w.kind==="lesson"&&(o.lesson={agentId:w.agentId??null,mode:String(w.mode||"teach"),goal:String(w.goal||""),step:Number(w.step)||0,saying:String(w.saying||""),startedAt:String(w.startedAt||"")})}o.reachable=!0,o._peers=Array.isArray(c&&await $i(c))?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var qe=null;function Ii(t){if(qe)return qe;let e=_e(process.cwd(),".agentx/wiki");return qe=la({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),qe}var vt=new WeakMap;async function $i(t){if(vt.has(t))return vt.get(t);try{let e=t.ok?await t.json():null;return vt.set(t,e),e}catch{return null}}async function Fe(t,e,a){try{let n={};e&&(n.Authorization=`Bearer ${e}`);let r=await fetch(t+"/mesh",{headers:n,signal:a});return r.ok?(await r.json()).filter(s=>s&&s.peerUrl).map(s=>({url:String(s.peerUrl).replace(/\/+$/,""),name:s.peer||s.peerUrl})):[]}catch{return[]}}async function de(t,e){let a=t.dashboard,n=a.daemonUrl.replace(/\/+$/,""),r=new Map;r.set(n,{name:"primary",url:n,token:a.token});for(let s of a.daemons){let i=s.url.replace(/\/+$/,"");r.has(i)||r.set(i,{name:s.name,url:i,token:s.token})}let o=await Fe(n,a.token,e);for(let s of o)r.has(s.url)||r.set(s.url,s);return[...r.values()]}async function bt(t,e){let a=new AbortController,n=setTimeout(()=>a.abort(),3e3);try{let r=await de(t,a.signal),o=await Promise.all(r.map(s=>Mi(s.url,s.token,a.signal,e)));return{ts:new Date().toISOString(),nodes:o}}finally{clearTimeout(n)}}function ji(t,e,a){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let n=!1,r=(i,l)=>{n||e.write(`event: ${i}
15018
+ `)}catch{f.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let d=new URL(t.url||"/","http://localhost"),u=Math.max(1,Math.min(500,Number(d.searchParams.get("limit")||50))),g=d.searchParams.get("workflowId")||void 0,f=d.searchParams.get("summary")==="1"||d.searchParams.get("summary")==="true",b=a.workflowRuns.list({limit:u,workflowId:g}),x=`?limit=${u}${g?`&workflowId=${encodeURIComponent(g)}`:""}${f?"&summary=1":""}`,y=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(L=>({url:L.url,token:L.token}))],M=await Promise.all(y.map(async L=>{let R={};L.token&&(R.Authorization=`Bearer ${L.token}`);try{let N=new AbortController,Z=setTimeout(()=>N.abort(),5e3);try{let B=await fetch(`${L.url.replace(/\/+$/,"")}/api/workflows/runs${x}`,{headers:R,signal:N.signal});if(!B.ok)return[];let O=await B.json();return Array.isArray(O.runs)?O.runs:[]}finally{clearTimeout(Z)}}catch{return[]}})),A=new Map;for(let L of b)A.set(L.id,L);for(let L of M)for(let R of L)A.set(R.id,R);let k=Array.from(A.values()).sort((L,R)=>L.updatedAt<R.updatedAt?1:-1).slice(0,u),I=f?k.map(L=>Ai(L)):k;v(e,200,{runs:I})}catch(d){v(e,502,{error:"runs fetch failed",message:d.message||String(d)})}return}let h=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(h){let d=decodeURIComponent(h[1]),u=a.workflowRuns.get(d);if(u){v(e,200,{run:u});return}let g=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(f=>({url:f.url,token:f.token}))];for(let f of g)try{let b={};f.token&&(b.Authorization=`Bearer ${f.token}`);let x=await fetch(`${f.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(d)}`,{headers:b});if(x.ok){v(e,200,await x.json());return}}catch{}v(e,404,{error:"run not found on any configured peer"});return}if(o==="GET"&&r==="/api/actions/builtin"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let u=a.config.dashboard.daemonUrl.replace(/\/+$/,""),g=await fetch(`${u}/api/actions/builtin`,{headers:d}),f=await g.json().catch(()=>({error:`HTTP ${g.status}`}));v(e,g.status,f)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}let _=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(_){try{let d=await ie(t).catch(()=>({})),u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let g=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${g}/workflows/${encodeURIComponent(_[1])}/run`,{method:"POST",headers:u,body:JSON.stringify(d??{})}),b=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,b)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(r.startsWith("/api/workflows")&&zn(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(u,g,f)=>{if(a.token)return!0;let b=Ye(u);if(!b)return!0;let x=new ae().verify(b);if(!x)return v(g,401,{error:"invalid or revoked token"}),!1;for(let y of f)if(!ye(x,y))return v(g,403,{error:`token missing scope: ${y}`,scopes:x.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){v(e,200,a.boards.map(d=>({id:d.id,name:d.name,source:d.source,primaryToolLabel:d.primaryToolLabel,labels:d.labels,columns:d.columns,timeRangeDays:d.timeRangeDays})));return}let S=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(S&&o==="GET"){let d=a.sources.get(S[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let u=typeof d.listMembers=="function"?await d.listMembers():[];v(e,200,u)}catch(u){v(e,502,{error:u.message})}return}let w=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(w&&o==="GET"){let d=a.sources.get(w[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let u=typeof d.listMilestones=="function"?await d.listMilestones():[];v(e,200,u)}catch(u){v(e,502,{error:u.message})}return}let E=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),T=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(E&&o==="PATCH"){let[,d,u]=E,g=decodeURIComponent(u),f=a.boards.find(A=>A.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let b=a.sources.get(d);if(!b){v(e,503,{error:`board "${d}" source unavailable`});return}let x=await ie(t),y=f.columns.find(A=>A.id===x.to),M=f.columns.find(A=>A.id===x.from);if(!y){v(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await Ci(b,g,M,y),xt({actor:vt(t),action:"move",boardId:d,itemId:g,payload:{from:x.from,to:x.to}}),v(e,200,{ok:!0})}catch(A){v(e,502,{error:A.message||"transition failed"})}return}if(T){let[,d,u]=T,g=u?decodeURIComponent(u):void 0,f=a.boards.find(x=>x.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let b=a.sources.get(d);if(!b){v(e,503,{error:`board "${d}" source unavailable`});return}if(o==="GET"&&!g){let{columns:x,totals:y}=await Ti(f,b,n.searchParams);v(e,200,{columns:x,totals:y});return}if(o==="GET"&&g){try{let x=typeof b.getItem=="function"?await b.getItem(g):null;if(!x){v(e,404,{error:"not found"});return}v(e,200,x)}catch(x){v(e,502,{error:x.message})}return}if(o==="PATCH"&&g){let x=await ie(t);try{let y=typeof b.updateItem=="function"?await b.updateItem(g,x):null;if(!y){v(e,501,{error:"update unsupported"});return}xt({actor:vt(t),action:"update",boardId:d,itemId:g,payload:x}),v(e,200,y)}catch(y){v(e,502,{error:y.message})}return}if(o==="POST"&&!g){let x=await ie(t);if(!x.title){v(e,400,{error:"title required"});return}if(!b.capabilities.create||!b.create){v(e,400,{error:`source ${b.type} does not support create`});return}try{let y=await b.create({title:x.title,description:x.description,labels:x.labels,assigneeUsernames:x.assigneeUsernames,milestoneTitle:x.milestoneTitle,projectHint:x.projectHint});xt({actor:vt(t),action:"create",boardId:d,itemId:y.id,payload:{title:x.title}}),v(e,201,y)}catch(y){v(e,502,{error:y.message})}return}}if(o==="GET"&&/^\/[a-z][a-z-]*\/?$/.test(r)){let d=r.replace(/^\/+|\/+$/g,""),g={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[d];if(g){e.writeHead(302,{Location:g}),e.end();return}}v(e,404,{error:"not found",path:r})}async function Ti(t,e,a){if(!e.capabilities.listAll||!e.listAll){let d={};for(let u of t.columns)d[u.id]=[];return{columns:d,totals:Object.fromEntries(t.columns.map(u=>[u.id,0]))}}let n=[];t.primaryToolLabel&&n.push(t.primaryToolLabel);let r=a.get("label")||void 0;r&&n.push(r);let o=a.get("q")||void 0,s=a.get("milestone")||void 0,i=a.get("assignee")||void 0,l=parseInt(a.get("days")||String(t.timeRangeDays),10),c=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),p=t.columns.some(d=>d.kind!=="closed"),m=t.columns.some(d=>d.kind==="closed"),h=p?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],_=m?await e.listAll({sinceDays:c,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],S={};for(let d of t.columns)S[d.id]=[];let w=t.columns.find(d=>d.kind==="closed");for(let d of _)w&&S[w.id].push({...d,stage:w.id});let E=t.columns.filter(d=>d.kind!=="closed");for(let d of h){let u=Et(d,E);if(!u)continue;let g=S[u];g&&g.push({...d,stage:u})}if(i)for(let d of Object.keys(S))S[d]=S[d].filter(u=>u.assignee===i);for(let d of Object.keys(S))S[d].sort((u,g)=>{let f=(u.priority??99)-(g.priority??99);return f!==0?f:(g.updatedAt||"").localeCompare(u.updatedAt||"")});let T=Object.fromEntries(Object.entries(S).map(([d,u])=>[d,u.length]));return{columns:S,totals:T}}async function Ci(t,e,a,n){let r=St(a,n),o=t;r.closeIssue&&typeof o.setState=="function"?await o.setState(e,"close"):r.reopen&&typeof o.setState=="function"&&await o.setState(e,"reopen"),(r.addLabels?.length||r.removeLabels?.length)&&typeof o.transitionMany=="function"?await o.transitionMany(e,r.addLabels||[],r.removeLabels||[]):r.addLabels?.length&&t.transition&&await t.transition(e,r.addLabels[0],r.removeLabels?.[0])}function Ai(t){return{id:t.id,workflowId:t.workflowId,workflowVersion:t.workflowVersion,homeNode:t.homeNode,status:t.status,pending:t.pending,entityRef:t.entityRef,history:(t.history||[]).slice(-5),parentRunId:t.parentRunId,parentNodeId:t.parentNodeId,rootRunId:t.rootRunId,depth:t.depth,createdAt:t.createdAt,updatedAt:t.updatedAt}}function Mi(t,e){if(t.source.type==="gitlab"){let a=e.channels.gitlab;if(!a?.token)throw new Error("channels.gitlab.token is required for gitlab boards");let n={};for(let r of a.agentMappings)r.gitlabUsernames.length&&(n[r.agentId]=r.gitlabUsernames);return new Ut(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function xt(t){try{let e=Ee(process.cwd(),".agentx");Fn(e)||yi(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
15019
+ `;bi(Ee(e,"board-audit.jsonl"),a)}catch{}}function vt(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}async function Ii(t,e,a,n){let r={};e&&(r.Authorization=`Bearer ${e}`);let o={id:t,name:t,url:t,reachable:!1,agents:[]};try{let s=n?`?date=${encodeURIComponent(n.date)}&timezone=${encodeURIComponent(n.timezone)}`:"",[i,l,c,p,m,h,_]=await Promise.all([fetch(t+"/health",{headers:r,signal:a}).catch(()=>null),fetch(t+"/agents",{headers:r,signal:a}).catch(()=>null),fetch(t+"/mesh",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons/runs"+s,{headers:r,signal:a}).catch(()=>null),fetch(t+"/talk",{headers:r,signal:a}).catch(()=>null),fetch(t+"/routines",{headers:r,signal:a}).catch(()=>null)]);if(!l||!l.ok)return o.error=l?`HTTP ${l.status}`:"unreachable",o;let S=await l.json();if(o.agents=S.map(w=>({id:w.id,name:w.name,tier:w.tier,model:w.model,skillCount:Number.isFinite(w.skillCount)?w.skillCount:void 0,active:w.active||0,total:w.total||0,errors:w.errors||0,lastActive:w.lastActive,lastSummary:w.lastSummary,hourlyTasks:Array.isArray(w.hourlyTasks)?w.hourlyTasks:void 0,runningTasks:Array.isArray(w.runningTasks)?w.runningTasks:[]})),i&&i.ok){let w=await i.json();o.uptimeSec=w.uptime,typeof w.inflight?.total=="number"&&(o.inflight=w.inflight.total),w.restart&&typeof w.restart.state=="string"&&(o.restart=w.restart),o.name=w.node?.name||w.node?.id||t,o.id=w.node?.id||t,w.usage&&(o.usage=w.usage)}if(p&&p.ok){let w=await p.json();o.crons=w.map(E=>({id:E.id,enabled:E.enabled===!0,schedule:String(E.schedule||""),timezone:E.timezone,agent:String(E.agent||""),kind:typeof E.command=="string"&&E.command.trim()?"command":"agent",model:E.model,nextRun:E.nextRun,retryPending:E.retryPending===!0,consecutiveErrors:Number(E.consecutiveErrors)||0}))}if(m&&m.ok){let w=await m.json();o.cronRuns=Array.isArray(w.runs)?w.runs:[]}if(_&&_.ok){let w=await _.json().catch(()=>null);w&&Array.isArray(w.routines)&&(o.routines=w.routines.slice(0,Pt.routines))}if(h&&h.ok){let w=await h.json().catch(()=>null);w?.active&&w.kind==="lesson"&&(o.lesson={agentId:w.agentId??null,mode:String(w.mode||"teach"),goal:String(w.goal||""),step:Number(w.step)||0,saying:String(w.saying||""),startedAt:String(w.startedAt||"")})}o.reachable=!0,o._peers=Array.isArray(c&&await ji(c))?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var Fe=null;function $i(t){if(Fe)return Fe;let e=Ee(process.cwd(),".agentx/wiki");return Fe=da({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),Fe}var bt=new WeakMap;async function ji(t){if(bt.has(t))return bt.get(t);try{let e=t.ok?await t.json():null;return bt.set(t,e),e}catch{return null}}async function Ue(t,e,a){try{let n={};e&&(n.Authorization=`Bearer ${e}`);let r=await fetch(t+"/mesh",{headers:n,signal:a});return r.ok?(await r.json()).filter(s=>s&&s.peerUrl).map(s=>({url:String(s.peerUrl).replace(/\/+$/,""),name:s.peer||s.peerUrl})):[]}catch{return[]}}async function de(t,e){let a=t.dashboard,n=a.daemonUrl.replace(/\/+$/,""),r=ce(a,n),o=new Map;o.set(n,{name:"primary",url:n,token:r});for(let i of a.daemons){let l=i.url.replace(/\/+$/,"");o.has(l)||o.set(l,{name:i.name,url:l,token:ce(a,l)})}let s=await Ue(n,r,e);for(let i of s)o.has(i.url)||o.set(i.url,{...i,token:ce(a,i.url)});return[...o.values()]}async function yt(t,e){let a=new AbortController,n=setTimeout(()=>a.abort(),3e3);try{let r=await de(t,a.signal),o=await Promise.all(r.map(s=>Ii(s.url,s.token,a.signal,e)));return{ts:new Date().toISOString(),nodes:o}}finally{clearTimeout(n)}}function Li(t,e,a){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let n=!1,r=(i,l)=>{n||e.write(`event: ${i}
15020
15020
  data: ${JSON.stringify(l)}
15021
15021
 
15022
- `)},o=async()=>{try{let i=await bt(a);r("snapshot",i)}catch(i){r("error",{message:i.message})}};o();let s=setInterval(o,2e3);t.on("close",()=>{n=!0,clearInterval(s),e.end()})}async function Li(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let S of a.config.dashboard.daemons)i.add(S.url.replace(/\/+$/,""));try{let S=await Fe(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let w of S)i.add(w.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){v(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(S=>S.url.replace(/\/+$/,"")===s)?.token,c={Accept:"text/event-stream"};l&&(c.Authorization=`Bearer ${l}`);let p=new AbortController,m;try{m=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:c,signal:p.signal})}catch(S){v(e,502,{error:S.message||"upstream connect failed"});return}if(!m.ok||!m.body){v(e,m.status||502,{error:`upstream HTTP ${m.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let h=m.body.getReader();(async()=>{try{for(;;){let{value:S,done:w}=await h.read();if(w)break;S&&e.write(S)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{p.abort();try{e.end()}catch{}})}function Ri(t,e,a){let n=Ve(t);if(!n)return v(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new ae().verify(n);if(!r)return v(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!be(r,o))return v(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function Pi(t,e,a,n){let r=a.agents?.[n];if(!r){v(e,404,{error:"unknown agent"});return}if(r.access!=="public"){v(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await ie(t)}catch{v(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){v(e,400,{error:"required: { message: string, context?: {...} }"});return}let i=a.dashboard.daemonUrl.replace(/\/+$/,""),l={"Content-Type":"application/json"};a.dashboard.token&&(l.Authorization=`Bearer ${a.dashboard.token}`);try{let c=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),p=await c.text();e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(p)}catch(c){v(e,502,{error:c.message||"upstream call failed"})}}async function Di(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let m of e.config.dashboard.daemons)i.add(m.url.replace(/\/+$/,""));try{let m=await Fe(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let h of m)i.add(h.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){v(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=s===e.config.dashboard.daemonUrl.replace(/\/+$/,"")?e.config.dashboard.token:e.config.dashboard.daemons.find(m=>m.url.replace(/\/+$/,"")===s)?.token,c={Accept:"application/json"};l&&(c.Authorization=`Bearer ${l}`);let p=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let m=await fetch(`${s}${p}`,{headers:c}),h=await m.text();t.writeHead(m.status,{"Content-Type":m.headers.get("content-type")||"application/json; charset=utf-8"}),t.end(h)}catch(m){v(t,502,{error:m.message||"upstream fetch failed"})}}async function Oi(t,e,a,n,r,o){await yt(t,e,a,n,`/api/tasks/${encodeURIComponent(r)}/${o}`)}async function yt(t,e,a,n,r){let o=n.replace(/\/+$/,""),s=new Set;s.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of a.config.dashboard.daemons)s.add(p.url.replace(/\/+$/,""));try{let p=await Fe(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let m of p)s.add(m.url.replace(/\/+$/,""))}catch{}if(!s.has(o)){v(e,403,{error:"node not in dashboard allowlist",target:o});return}let i=o===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(p=>p.url.replace(/\/+$/,"")===o)?.token,l={"Content-Type":"application/json",Accept:"application/json"};i&&(l.Authorization=`Bearer ${i}`);let c="{}";try{let p=await ie(t);c=p?JSON.stringify(p):"{}"}catch{}try{let p=await fetch(`${o}${r}`,{method:"POST",headers:l,body:c}),m=await p.text();e.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(m)}catch(p){v(e,502,{error:p.message||"upstream fetch failed"})}}var Hi=`
15022
+ `)},o=async()=>{try{let i=await yt(a);r("snapshot",i)}catch(i){r("error",{message:i.message})}};o();let s=setInterval(o,2e3);t.on("close",()=>{n=!0,clearInterval(s),e.end()})}async function Ri(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let S of a.config.dashboard.daemons)i.add(S.url.replace(/\/+$/,""));try{let S=await Ue(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let w of S)i.add(w.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){v(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=ce(a.config.dashboard,s),c={Accept:"text/event-stream"};l&&(c.Authorization=`Bearer ${l}`);let p=new AbortController,m;try{m=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:c,signal:p.signal})}catch(S){v(e,502,{error:S.message||"upstream connect failed"});return}if(!m.ok||!m.body){v(e,m.status||502,{error:`upstream HTTP ${m.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let h=m.body.getReader();(async()=>{try{for(;;){let{value:S,done:w}=await h.read();if(w)break;S&&e.write(S)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{p.abort();try{e.end()}catch{}})}function Pi(t,e,a){let n=Ye(t);if(!n)return v(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new ae().verify(n);if(!r)return v(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!ye(r,o))return v(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function Di(t,e,a,n){let r=a.agents?.[n];if(!r){v(e,404,{error:"unknown agent"});return}if(r.access!=="public"){v(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await ie(t)}catch{v(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){v(e,400,{error:"required: { message: string, context?: {...} }"});return}let i=a.dashboard.daemonUrl.replace(/\/+$/,""),l={"Content-Type":"application/json"};a.dashboard.token&&(l.Authorization=`Bearer ${a.dashboard.token}`);try{let c=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),p=await c.text();e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(p)}catch(c){v(e,502,{error:c.message||"upstream call failed"})}}async function Oi(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let m of e.config.dashboard.daemons)i.add(m.url.replace(/\/+$/,""));try{let m=await Ue(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let h of m)i.add(h.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){v(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=ce(e.config.dashboard,s),c={Accept:"application/json"};l&&(c.Authorization=`Bearer ${l}`);let p=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let m=await fetch(`${s}${p}`,{headers:c}),h=await m.text();t.writeHead(m.status,{"Content-Type":m.headers.get("content-type")||"application/json; charset=utf-8"}),t.end(h)}catch(m){v(t,502,{error:m.message||"upstream fetch failed"})}}async function Hi(t,e,a,n,r,o){await wt(t,e,a,n,`/api/tasks/${encodeURIComponent(r)}/${o}`)}async function wt(t,e,a,n,r){let o=n.replace(/\/+$/,""),s=new Set;s.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of a.config.dashboard.daemons)s.add(p.url.replace(/\/+$/,""));try{let p=await Ue(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let m of p)s.add(m.url.replace(/\/+$/,""))}catch{}if(!s.has(o)){v(e,403,{error:"node not in dashboard allowlist",target:o});return}let i=ce(a.config.dashboard,o),l={"Content-Type":"application/json",Accept:"application/json"};i&&(l.Authorization=`Bearer ${i}`);let c="{}";try{let p=await ie(t);c=p?JSON.stringify(p):"{}"}catch{}try{let p=await fetch(`${o}${r}`,{method:"POST",headers:l,body:c}),m=await p.text();e.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(m)}catch(p){v(e,502,{error:p.message||"upstream fetch failed"})}}var Ni=`
15023
15023
  You are helping draft a new GitLab issue. Follow these conventions strictly.
15024
15024
 
15025
15025
  Title pattern:
@@ -15051,10 +15051,10 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
15051
15051
  Shape:
15052
15052
  { "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
15053
15053
  If you don't have enough information to pick a label confidently, omit it rather than guessing.
15054
- `;async function Ni(t,e){let a=(e?.rough||"").toString().trim();if(!a)throw new Error("rough description required");let n=e?.agent||t.dashboard.draftAgent;if(!n)throw new Error("no draft agent configured (set dashboard.draftAgent or pass agent in body)");let r=e?.context||{},o=["Rough description from the user:",'"""',a,'"""',"",`Board: ${r.boardName||"(unspecified)"}`,r.primaryLabel?`Primary board label (include in labels): ${r.primaryLabel}`:"",r.columnLabel?`Target column label (include in labels): ${r.columnLabel}`:"",r.project?`GitLab project: ${r.project}`:"",r.knownLabels?.length?`Known labels in this project (prefer picking from these when they fit):
15054
+ `;async function Bi(t,e){let a=(e?.rough||"").toString().trim();if(!a)throw new Error("rough description required");let n=e?.agent||t.dashboard.draftAgent;if(!n)throw new Error("no draft agent configured (set dashboard.draftAgent or pass agent in body)");let r=e?.context||{},o=["Rough description from the user:",'"""',a,'"""',"",`Board: ${r.boardName||"(unspecified)"}`,r.primaryLabel?`Primary board label (include in labels): ${r.primaryLabel}`:"",r.columnLabel?`Target column label (include in labels): ${r.columnLabel}`:"",r.project?`GitLab project: ${r.project}`:"",r.knownLabels?.length?`Known labels in this project (prefer picking from these when they fit):
15055
15055
  - ${r.knownLabels.slice(0,60).join(`
15056
15056
  - `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
15057
- `),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",i={"Content-Type":"application/json"};t.dashboard.token&&(i.Authorization=`Bearer ${t.dashboard.token}`);let l=await fetch(s,{method:"POST",headers:i,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:Hi}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let c=await l.json();if(c.error)throw new Error(String(c.error));let p=(c.content||"").toString(),m=Bi(p);if(!m||typeof m.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+p.slice(0,400));let h=Array.isArray(m.labels)?m.labels.filter(_=>typeof _=="string"):[];return r.primaryLabel&&!h.includes(r.primaryLabel)&&h.unshift(r.primaryLabel),r.columnLabel&&!h.includes(r.columnLabel)&&h.unshift(r.columnLabel),{title:m.title.trim(),description:(m.description||"").toString(),labels:h,assigneeUsername:typeof m.assigneeUsername=="string"?m.assigneeUsername:void 0,kind:typeof m.kind=="string"?m.kind:void 0,raw:p}}function Bi(t){if(!t)return null;try{return JSON.parse(t)}catch{}let e=t.match(/```(?:json)?\s*([\s\S]*?)```/);if(e)try{return JSON.parse(e[1])}catch{}let a=t.indexOf("{");if(a===-1)return null;let n=0;for(let r=a;r<t.length;r++){let o=t[r];if(o==="{")n++;else if(o==="}"&&(n--,n===0))try{return JSON.parse(t.slice(a,r+1))}catch{return null}}return null}function zi(t){let e=ki(wi(import.meta.url));return _e(e,t)}async function qi(t){return yi(t)}function v(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function ie(t){return new Promise((e,a)=>{let n=[];t.on("data",r=>n.push(r)),t.on("end",()=>{try{let r=Buffer.concat(n).toString("utf-8");e(r?JSON.parse(r):{})}catch(r){a(r)}}),t.on("error",a)})}function Fn(t){return t.dashboardUrl?t.dashboardUrl.replace(/\/+$/,""):t.url.replace(/\/+$/,"").replace(/:(?:1[89][89]00|18810)$/,":4202")}function D(t,e){let a=e||t,n={id:"primary",name:a.node?.name||"this daemon",dashboardUrl:"",primary:!0},r=(a.dashboard?.daemons||[]).map(s=>({id:s.url.replace(/\/+$/,""),name:s.name,dashboardUrl:Fn(s),tokenScope:s.dashboardToken||s.token?"proxy-ready":void 0})),o=r.length>0?[{id:"fleet",name:"Fleet (all peers)",dashboardUrl:"",tokenScope:"merged across nodes"}]:[];return[n,...r,...o]}async function Fi(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;v(e,200,await Be(await Un(r,a.config)))}async function Un(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=ut(t);r&&n.push({nodeId:a,snap:r});let o=(e.dashboard?.daemons||[]).filter(i=>i.url),s=await Promise.all(o.map(async i=>{let l=wt(i.url.replace(/\/+$/,""),e);if(!l)return null;try{let c=new AbortController,p=setTimeout(()=>c.abort(),8e3);try{let m=await fetch(`${l.url}/api/admin/activity-graph?hours=${t}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...l.token?{Authorization:`Bearer ${l.token}`}:{}},signal:c.signal});return m.ok?{nodeId:i.name||i.url,snap:await m.json()}:null}finally{clearTimeout(p)}}catch{return null}}));for(let i of s)i&&n.push(i);return dn(n)}async function Ui(t,e){let{spawn:a,execSync:n}=await import("child_process"),r,o;try{n("which journalctl",{stdio:"pipe"}),r="journalctl",o=["-u","agentx","--no-pager","-n","200","-f","-o","cat"]}catch{let m=process.env.HOME||"",h=[m&&`${m}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),_=h.find(S=>qn(S));if(!_){e.writeHead(503,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"no log source \u2014 install journalctl, run the daemon under launchd, or run it foreground writing to /tmp/agentx-daemon.log",searched:h}));return}r="tail",o=["-F","-n","200",_]}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: source=${r}
15057
+ `),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",i={"Content-Type":"application/json"};t.dashboard.token&&(i.Authorization=`Bearer ${t.dashboard.token}`);let l=await fetch(s,{method:"POST",headers:i,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:Ni}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let c=await l.json();if(c.error)throw new Error(String(c.error));let p=(c.content||"").toString(),m=zi(p);if(!m||typeof m.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+p.slice(0,400));let h=Array.isArray(m.labels)?m.labels.filter(_=>typeof _=="string"):[];return r.primaryLabel&&!h.includes(r.primaryLabel)&&h.unshift(r.primaryLabel),r.columnLabel&&!h.includes(r.columnLabel)&&h.unshift(r.columnLabel),{title:m.title.trim(),description:(m.description||"").toString(),labels:h,assigneeUsername:typeof m.assigneeUsername=="string"?m.assigneeUsername:void 0,kind:typeof m.kind=="string"?m.kind:void 0,raw:p}}function zi(t){if(!t)return null;try{return JSON.parse(t)}catch{}let e=t.match(/```(?:json)?\s*([\s\S]*?)```/);if(e)try{return JSON.parse(e[1])}catch{}let a=t.indexOf("{");if(a===-1)return null;let n=0;for(let r=a;r<t.length;r++){let o=t[r];if(o==="{")n++;else if(o==="}"&&(n--,n===0))try{return JSON.parse(t.slice(a,r+1))}catch{return null}}return null}function qi(t){let e=_i(ki(import.meta.url));return Ee(e,t)}async function Fi(t){return wi(t)}function v(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function ie(t){return new Promise((e,a)=>{let n=[];t.on("data",r=>n.push(r)),t.on("end",()=>{try{let r=Buffer.concat(n).toString("utf-8");e(r?JSON.parse(r):{})}catch(r){a(r)}}),t.on("error",a)})}function Un(t){return t.dashboardUrl?t.dashboardUrl.replace(/\/+$/,""):t.url.replace(/\/+$/,"").replace(/:(?:1[89][89]00|18810)$/,":4202")}function D(t,e){let a=e||t,n={id:"primary",name:a.node?.name||"this daemon",dashboardUrl:"",primary:!0},r=(a.dashboard?.daemons||[]).map(s=>({id:s.url.replace(/\/+$/,""),name:s.name,dashboardUrl:Un(s),tokenScope:s.dashboardToken||s.token?"proxy-ready":void 0})),o=r.length>0?[{id:"fleet",name:"Fleet (all peers)",dashboardUrl:"",tokenScope:"merged across nodes"}]:[];return[n,...r,...o]}async function Ui(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;v(e,200,await ze(await Wn(r,a.config)))}async function Wn(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=mt(t);r&&n.push({nodeId:a,snap:r});let o=(e.dashboard?.daemons||[]).filter(i=>i.url),s=await Promise.all(o.map(async i=>{let l=kt(i.url.replace(/\/+$/,""),e);if(!l)return null;try{let c=new AbortController,p=setTimeout(()=>c.abort(),8e3);try{let m=await fetch(`${l.url}/api/admin/activity-graph?hours=${t}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...l.token?{Authorization:`Bearer ${l.token}`}:{}},signal:c.signal});return m.ok?{nodeId:i.name||i.url,snap:await m.json()}:null}finally{clearTimeout(p)}}catch{return null}}));for(let i of s)i&&n.push(i);return cn(n)}async function Wi(t,e){let{spawn:a,execSync:n}=await import("child_process"),r,o;try{n("which journalctl",{stdio:"pipe"}),r="journalctl",o=["-u","agentx","--no-pager","-n","200","-f","-o","cat"]}catch{let m=process.env.HOME||"",h=[m&&`${m}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),_=h.find(S=>Fn(S));if(!_){e.writeHead(503,{"Content-Type":"application/json"}),e.end(JSON.stringify({error:"no log source \u2014 install journalctl, run the daemon under launchd, or run it foreground writing to /tmp/agentx-daemon.log",searched:h}));return}r="tail",o=["-F","-n","200",_]}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`: source=${r}
15058
15058
 
15059
15059
  `);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),i="",l=m=>{i+=m.toString("utf8");let h;for(;(h=i.indexOf(`
15060
15060
  `))>=0;){let _=i.slice(0,h).replace(/\r$/,"");i=i.slice(h+1);try{e.write(`event: line
@@ -15062,5 +15062,5 @@ data: ${_.replace(/\n/g," ")}
15062
15062
 
15063
15063
  `)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let c=setInterval(()=>{try{e.write(`: hb
15064
15064
 
15065
- `)}catch{}},15e3),p=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",p),s.on("exit",p),s.on("error",p)}async function zn(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((m,h)=>{let _=[];t.on("data",S=>_.push(S)),t.on("end",()=>m(Buffer.concat(_))),t.on("error",h)}):void 0,l={},c=t.headers["content-type"];c&&(l["Content-Type"]=Array.isArray(c)?c[0]:c);let p=t.headers["x-requested-with"];p&&(l["X-Requested-With"]=Array.isArray(p)?p[0]:p),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let m=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),h=Buffer.from(await m.arrayBuffer());e.writeHead(m.status,{"Content-Type":m.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(h)}catch(m){v(e,502,{error:`proxy to peer failed: ${m?.message||m}`,target:r})}}function wt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Fn(n),token:n.dashboardToken||n.token}:null}export{Vc as startBoardDashboard};
15066
- //# sourceMappingURL=board-dashboard-RUOASCSQ.js.map
15065
+ `)}catch{}},15e3),p=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",p),s.on("exit",p),s.on("error",p)}async function qn(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((m,h)=>{let _=[];t.on("data",S=>_.push(S)),t.on("end",()=>m(Buffer.concat(_))),t.on("error",h)}):void 0,l={},c=t.headers["content-type"];c&&(l["Content-Type"]=Array.isArray(c)?c[0]:c);let p=t.headers["x-requested-with"];p&&(l["X-Requested-With"]=Array.isArray(p)?p[0]:p),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let m=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),h=Buffer.from(await m.arrayBuffer());e.writeHead(m.status,{"Content-Type":m.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(h)}catch(m){v(e,502,{error:`proxy to peer failed: ${m?.message||m}`,target:r})}}function kt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Un(n),token:n.dashboardToken||n.token}:null}export{de as resolveNodeTargets,Qc as startBoardDashboard};
15066
+ //# sourceMappingURL=board-dashboard-XPPBRPQE.js.map