agentix-cli 0.130.0 → 0.132.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.
- package/dist/{App-DWSHIDN6.js → App-VPYWOTTH.js} +2 -2
- package/dist/{ChatApp-CROSI7JM.js → ChatApp-SNED4KJB.js} +2 -2
- package/dist/absorb-eval-WGO4JWTO.js +2 -0
- package/dist/{agent-4AQOFPRD.js → agent-HXQYYLWZ.js} +2 -2
- package/dist/article-sync-4NOPOQU7.js +2 -0
- package/dist/{board-dashboard-54A3XTV5.js → board-dashboard-44JPXA7J.js} +330 -235
- package/dist/board-dashboard-44JPXA7J.js.map +1 -0
- package/dist/{builtin-W6KNX7RS.js → builtin-YD7MC572.js} +2 -2
- package/dist/chunk-2ZDV3DCT.js +52 -0
- package/dist/chunk-2ZDV3DCT.js.map +1 -0
- package/dist/{chunk-QXZLYCEZ.js → chunk-3K35L73A.js} +3 -3
- package/dist/chunk-3K35L73A.js.map +1 -0
- package/dist/chunk-3UOTLMXD.js +4 -0
- package/dist/chunk-3UOTLMXD.js.map +1 -0
- package/dist/{chunk-LJWEJ6UZ.js → chunk-3WYLK3SX.js} +2 -2
- package/dist/chunk-5BI2T3WD.js +3 -0
- package/dist/chunk-5BI2T3WD.js.map +1 -0
- package/dist/{chunk-UBA2QJCY.js → chunk-62NXS7PT.js} +272 -247
- package/dist/chunk-62NXS7PT.js.map +1 -0
- package/dist/chunk-6TURWSMN.js +3 -0
- package/dist/{chunk-VD7IO653.js.map → chunk-6TURWSMN.js.map} +1 -1
- package/dist/{chunk-I4GT27UO.js → chunk-724IBN5Y.js} +2 -2
- package/dist/{chunk-NR7WLMNI.js → chunk-74LPAKQY.js} +2 -2
- package/dist/chunk-7D3RJSN4.js +156 -0
- package/dist/chunk-7D3RJSN4.js.map +1 -0
- package/dist/{chunk-BGG3ZSMW.js → chunk-7LN4VKDU.js} +14 -16
- package/dist/chunk-7LN4VKDU.js.map +1 -0
- package/dist/chunk-7VLLZQ3N.js +2 -0
- package/dist/chunk-7VLLZQ3N.js.map +1 -0
- package/dist/{chunk-LLLBH2HH.js → chunk-A6QJ4VFT.js} +2 -2
- package/dist/{chunk-SCJ5ZXEN.js → chunk-B2QYMUTD.js} +2 -2
- package/dist/{chunk-SCJ5ZXEN.js.map → chunk-B2QYMUTD.js.map} +1 -1
- package/dist/chunk-BIJHMWXK.js +21 -0
- package/dist/chunk-BIJHMWXK.js.map +1 -0
- package/dist/{chunk-4VDA4UM7.js → chunk-BKHIR2YJ.js} +2 -2
- package/dist/{chunk-5VKFIBXY.js → chunk-CM74OUXW.js} +2 -2
- package/dist/chunk-EQ33PFXP.js +55 -0
- package/dist/chunk-EQ33PFXP.js.map +1 -0
- package/dist/chunk-HF5EF335.js +8 -0
- package/dist/chunk-HF5EF335.js.map +1 -0
- package/dist/chunk-IMLAPB7G.js +4 -0
- package/dist/chunk-IMLAPB7G.js.map +1 -0
- package/dist/{chunk-U2EHJZAZ.js → chunk-JNKATLF7.js} +2 -2
- package/dist/{chunk-3PGPN323.js → chunk-JP5OAMWQ.js} +1 -1
- package/dist/chunk-JP5OAMWQ.js.map +1 -0
- package/dist/chunk-JRVJXAVC.js +861 -0
- package/dist/chunk-JRVJXAVC.js.map +1 -0
- package/dist/{chunk-J4I5ZJ2V.js → chunk-KDQI5S7F.js} +2 -2
- package/dist/chunk-KFIJDLQ5.js +3 -0
- package/dist/chunk-KFIJDLQ5.js.map +1 -0
- package/dist/{chunk-MZJY26FW.js → chunk-KKQPV6SO.js} +2 -2
- package/dist/{chunk-WX67I2KN.js → chunk-KQH4LPYC.js} +2 -2
- package/dist/chunk-MCBTVNPX.js +152 -0
- package/dist/chunk-MCBTVNPX.js.map +1 -0
- package/dist/{chunk-YHCPBMRH.js → chunk-MDGYSHO5.js} +2 -2
- package/dist/chunk-MRIVENBY.js +2 -0
- package/dist/{article-sync-TLZTHRZB.js.map → chunk-MRIVENBY.js.map} +1 -1
- package/dist/{chunk-242MPMJX.js → chunk-QNKSRROH.js} +2 -2
- package/dist/{chunk-GLQLCBJS.js → chunk-QSKG754X.js} +6 -3
- package/dist/chunk-QSKG754X.js.map +1 -0
- package/dist/{chunk-HF4OXA5L.js → chunk-RH3J4LCP.js} +3 -3
- package/dist/{chunk-QPYN2UTV.js → chunk-RYGVTAP4.js} +2 -2
- package/dist/chunk-S2RRPTS3.js +54 -0
- package/dist/chunk-S2RRPTS3.js.map +1 -0
- package/dist/{chunk-5KKXJZZ4.js → chunk-UDMI4TYM.js} +2 -2
- package/dist/{chunk-TJDNS5G6.js → chunk-VCQVF44A.js} +2 -2
- package/dist/{chunk-TN5A7PLU.js → chunk-WWNZL7XB.js} +2 -2
- package/dist/{chunk-Q5FEWCS5.js → chunk-XWVBLISN.js} +2 -2
- package/dist/{chunk-AD4QZZVN.js → chunk-YXFTUOZR.js} +2 -2
- package/dist/{chunk-RKB7FQJF.js → chunk-Z7RJ3K3J.js} +2 -2
- package/dist/{chunk-N2YSVZML.js → chunk-ZG4G6BFP.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-KGWYROLX.js → client-TXZF32NO.js} +2 -2
- package/dist/config-ZIXIH23X.js +2 -0
- package/dist/{config-mutate-7BLOYRZF.js → config-mutate-KDBXIN7R.js} +2 -2
- package/dist/config-mutator-HKFGPJMG.js +2 -0
- package/dist/{contributions-DLUQEAGL.js → contributions-FBVULRR4.js} +2 -2
- package/dist/{contributions-DLUQEAGL.js.map → contributions-FBVULRR4.js.map} +1 -1
- package/dist/{doctor-32YP26SJ.js → doctor-NBWYG743.js} +2 -2
- package/dist/enrich-NH3WHKD6.js +16 -0
- package/dist/enrich-NH3WHKD6.js.map +1 -0
- package/dist/{failure-candidates-JNGUVBDG.js → failure-candidates-XZSZP4HT.js} +2 -2
- package/dist/{follow-up-tool-AQ7NYZZR.js → follow-up-tool-E5XKSPKA.js} +2 -2
- package/dist/graph-EXDH7EPZ.js +2 -0
- package/dist/hub-3QTJ7E3O.js +2 -0
- package/dist/index.d.ts +577 -3
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/load-5DNMGHFW.js +2 -0
- package/dist/model-call-BGTDPWZD.js +2 -0
- package/dist/notes-WJJEJ4CJ.js +2 -0
- package/dist/processes-M3N3S7V5.js +2 -0
- package/dist/program-SA5O6IQ3.js +776 -0
- package/dist/program-SA5O6IQ3.js.map +1 -0
- package/dist/{promote-R7FKN5SY.js → promote-4XHYWHLA.js} +2 -2
- package/dist/query-ZGD32CE2.js +2 -0
- package/dist/query-settings-BSDXFS3V.js +3 -0
- package/dist/query-settings-BSDXFS3V.js.map +1 -0
- package/dist/registry-LM35AE2P.js +2 -0
- package/dist/{request-planner-LEUMSI2K.js → request-planner-4BAAOUBH.js} +2 -2
- package/dist/{review-candidates-MOSGA4IS.js → review-candidates-TM53WR7G.js} +2 -2
- package/dist/roster-IRXP32XF.js +2 -0
- package/dist/{rotation-memo-7VLREGS6.js → rotation-memo-2G6N3VF3.js} +2 -2
- package/dist/{routing-FSJ42RZH.js → routing-QLS6UMLM.js} +2 -2
- package/dist/schedule-tool-TTCWBAQ4.js +2 -0
- package/dist/{scheduler-6AQDHQI4.js → scheduler-PVXLF2VJ.js} +2 -2
- package/dist/scheduler-PVXLF2VJ.js.map +1 -0
- package/dist/{seat-O37EQRHE.js → seat-OUUN3F45.js} +2 -2
- package/dist/seat-OUUN3F45.js.map +1 -0
- package/dist/{select-XO2STSQN.js → select-D7UUSODY.js} +2 -2
- package/dist/{set-enabled-ZNEPEFGF.js → set-enabled-FDNS6KW6.js} +2 -2
- package/dist/summaries-BIRSNWGH.js +2 -0
- package/dist/summaries-BIRSNWGH.js.map +1 -0
- package/dist/{tool-PH45YCO5.js → tool-J5FM3OPM.js} +2 -2
- package/dist/{tool-6KMEAY4U.js → tool-SCBQYDI3.js} +2 -2
- package/dist/wiki-IGRRQL6H.js +2 -0
- package/dist/wiki-IGRRQL6H.js.map +1 -0
- package/dist/workspace-env-ROH45HXN.js +2 -0
- package/dist/workspace-env-ROH45HXN.js.map +1 -0
- package/package.json +1 -1
- package/dist/absorb-eval-MNGQ752C.js +0 -2
- package/dist/article-sync-TLZTHRZB.js +0 -2
- package/dist/board-dashboard-54A3XTV5.js.map +0 -1
- package/dist/chunk-3PGPN323.js.map +0 -1
- package/dist/chunk-76Z4VHDX.js +0 -8
- package/dist/chunk-76Z4VHDX.js.map +0 -1
- package/dist/chunk-AERIU4AH.js +0 -892
- package/dist/chunk-AERIU4AH.js.map +0 -1
- package/dist/chunk-BGG3ZSMW.js.map +0 -1
- package/dist/chunk-EO4DEEXL.js +0 -2
- package/dist/chunk-EO4DEEXL.js.map +0 -1
- package/dist/chunk-GLQLCBJS.js.map +0 -1
- package/dist/chunk-I4OQQRY2.js +0 -55
- package/dist/chunk-I4OQQRY2.js.map +0 -1
- package/dist/chunk-JE5EJGGD.js +0 -4
- package/dist/chunk-JE5EJGGD.js.map +0 -1
- package/dist/chunk-QX2B4TJU.js +0 -3
- package/dist/chunk-QX2B4TJU.js.map +0 -1
- package/dist/chunk-QXZLYCEZ.js.map +0 -1
- package/dist/chunk-UBA2QJCY.js.map +0 -1
- package/dist/chunk-UUFJQMHE.js +0 -54
- package/dist/chunk-UUFJQMHE.js.map +0 -1
- package/dist/chunk-VD7IO653.js +0 -3
- package/dist/chunk-W2HEJKJR.js +0 -156
- package/dist/chunk-W2HEJKJR.js.map +0 -1
- package/dist/config-FNTLKUGA.js +0 -2
- package/dist/config-mutator-NCLHYPJ3.js +0 -2
- package/dist/graph-5ZJ7YACP.js +0 -2
- package/dist/hub-Q3I4ALQ2.js +0 -2
- package/dist/load-NK3MIYXP.js +0 -2
- package/dist/notes-TMAGEDUS.js +0 -2
- package/dist/processes-5MP32QZT.js +0 -2
- package/dist/program-FESSM5TY.js +0 -766
- package/dist/program-FESSM5TY.js.map +0 -1
- package/dist/query-YTKTNXCQ.js +0 -2
- package/dist/registry-7L4RUATA.js +0 -2
- package/dist/schedule-tool-4T2VZIDW.js +0 -2
- package/dist/wiki-4HD4FZ4W.js +0 -2
- /package/dist/{App-DWSHIDN6.js.map → App-VPYWOTTH.js.map} +0 -0
- /package/dist/{ChatApp-CROSI7JM.js.map → ChatApp-SNED4KJB.js.map} +0 -0
- /package/dist/{absorb-eval-MNGQ752C.js.map → absorb-eval-WGO4JWTO.js.map} +0 -0
- /package/dist/{agent-4AQOFPRD.js.map → agent-HXQYYLWZ.js.map} +0 -0
- /package/dist/{builtin-W6KNX7RS.js.map → article-sync-4NOPOQU7.js.map} +0 -0
- /package/dist/{client-KGWYROLX.js.map → builtin-YD7MC572.js.map} +0 -0
- /package/dist/{chunk-LJWEJ6UZ.js.map → chunk-3WYLK3SX.js.map} +0 -0
- /package/dist/{chunk-I4GT27UO.js.map → chunk-724IBN5Y.js.map} +0 -0
- /package/dist/{chunk-NR7WLMNI.js.map → chunk-74LPAKQY.js.map} +0 -0
- /package/dist/{chunk-LLLBH2HH.js.map → chunk-A6QJ4VFT.js.map} +0 -0
- /package/dist/{chunk-4VDA4UM7.js.map → chunk-BKHIR2YJ.js.map} +0 -0
- /package/dist/{chunk-5VKFIBXY.js.map → chunk-CM74OUXW.js.map} +0 -0
- /package/dist/{chunk-U2EHJZAZ.js.map → chunk-JNKATLF7.js.map} +0 -0
- /package/dist/{chunk-J4I5ZJ2V.js.map → chunk-KDQI5S7F.js.map} +0 -0
- /package/dist/{chunk-MZJY26FW.js.map → chunk-KKQPV6SO.js.map} +0 -0
- /package/dist/{chunk-WX67I2KN.js.map → chunk-KQH4LPYC.js.map} +0 -0
- /package/dist/{chunk-YHCPBMRH.js.map → chunk-MDGYSHO5.js.map} +0 -0
- /package/dist/{chunk-242MPMJX.js.map → chunk-QNKSRROH.js.map} +0 -0
- /package/dist/{chunk-HF4OXA5L.js.map → chunk-RH3J4LCP.js.map} +0 -0
- /package/dist/{chunk-QPYN2UTV.js.map → chunk-RYGVTAP4.js.map} +0 -0
- /package/dist/{chunk-5KKXJZZ4.js.map → chunk-UDMI4TYM.js.map} +0 -0
- /package/dist/{chunk-TJDNS5G6.js.map → chunk-VCQVF44A.js.map} +0 -0
- /package/dist/{chunk-TN5A7PLU.js.map → chunk-WWNZL7XB.js.map} +0 -0
- /package/dist/{chunk-Q5FEWCS5.js.map → chunk-XWVBLISN.js.map} +0 -0
- /package/dist/{chunk-AD4QZZVN.js.map → chunk-YXFTUOZR.js.map} +0 -0
- /package/dist/{chunk-RKB7FQJF.js.map → chunk-Z7RJ3K3J.js.map} +0 -0
- /package/dist/{chunk-N2YSVZML.js.map → chunk-ZG4G6BFP.js.map} +0 -0
- /package/dist/{config-FNTLKUGA.js.map → client-TXZF32NO.js.map} +0 -0
- /package/dist/{config-mutate-7BLOYRZF.js.map → config-ZIXIH23X.js.map} +0 -0
- /package/dist/{config-mutator-NCLHYPJ3.js.map → config-mutate-KDBXIN7R.js.map} +0 -0
- /package/dist/{doctor-32YP26SJ.js.map → config-mutator-HKFGPJMG.js.map} +0 -0
- /package/dist/{failure-candidates-JNGUVBDG.js.map → doctor-NBWYG743.js.map} +0 -0
- /package/dist/{graph-5ZJ7YACP.js.map → failure-candidates-XZSZP4HT.js.map} +0 -0
- /package/dist/{follow-up-tool-AQ7NYZZR.js.map → follow-up-tool-E5XKSPKA.js.map} +0 -0
- /package/dist/{hub-Q3I4ALQ2.js.map → graph-EXDH7EPZ.js.map} +0 -0
- /package/dist/{load-NK3MIYXP.js.map → hub-3QTJ7E3O.js.map} +0 -0
- /package/dist/{notes-TMAGEDUS.js.map → load-5DNMGHFW.js.map} +0 -0
- /package/dist/{processes-5MP32QZT.js.map → model-call-BGTDPWZD.js.map} +0 -0
- /package/dist/{promote-R7FKN5SY.js.map → notes-WJJEJ4CJ.js.map} +0 -0
- /package/dist/{query-YTKTNXCQ.js.map → processes-M3N3S7V5.js.map} +0 -0
- /package/dist/{registry-7L4RUATA.js.map → promote-4XHYWHLA.js.map} +0 -0
- /package/dist/{routing-FSJ42RZH.js.map → query-ZGD32CE2.js.map} +0 -0
- /package/dist/{schedule-tool-4T2VZIDW.js.map → registry-LM35AE2P.js.map} +0 -0
- /package/dist/{request-planner-LEUMSI2K.js.map → request-planner-4BAAOUBH.js.map} +0 -0
- /package/dist/{review-candidates-MOSGA4IS.js.map → review-candidates-TM53WR7G.js.map} +0 -0
- /package/dist/{scheduler-6AQDHQI4.js.map → roster-IRXP32XF.js.map} +0 -0
- /package/dist/{rotation-memo-7VLREGS6.js.map → rotation-memo-2G6N3VF3.js.map} +0 -0
- /package/dist/{seat-O37EQRHE.js.map → routing-QLS6UMLM.js.map} +0 -0
- /package/dist/{wiki-4HD4FZ4W.js.map → schedule-tool-TTCWBAQ4.js.map} +0 -0
- /package/dist/{select-XO2STSQN.js.map → select-D7UUSODY.js.map} +0 -0
- /package/dist/{set-enabled-ZNEPEFGF.js.map → set-enabled-FDNS6KW6.js.map} +0 -0
- /package/dist/{tool-PH45YCO5.js.map → tool-J5FM3OPM.js.map} +0 -0
- /package/dist/{tool-6KMEAY4U.js.map → tool-SCBQYDI3.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{B as Ot,C as ro,D as oo,E as so,a as zr,b as qr,c as Fr,d as Ur,e as Ae,f as Wr,g as Gr,h as jt,j as Xr,p as Kr,q as Jr,r as Vr,s as Yr,t as Qr,x as Zr,y as eo}from"./chunk-
|
|
1
|
+
import{B as Ot,C as ro,D as oo,E as so,a as zr,b as qr,c as Fr,d as Ur,e as Ae,f as Wr,g as Gr,h as jt,j as Xr,p as Kr,q as Jr,r as Vr,s as Yr,t as Qr,x as Zr,y as eo}from"./chunk-JRVJXAVC.js";import"./chunk-MCBTVNPX.js";import{a as to}from"./chunk-5NTWGUSJ.js";import{a as ao,b as no}from"./chunk-KBJNJGBP.js";import"./chunk-KFIJDLQ5.js";import"./chunk-5BI2T3WD.js";import{a as C}from"./chunk-KKQPV6SO.js";import{a as Or}from"./chunk-LNY6N73E.js";import{a as Br}from"./chunk-BKHIR2YJ.js";import{a as ze,b as q,c as I,h as pe,i as Pt,j as oe,k as K,l as $t,m as Nr,n as Dr,o as Hr}from"./chunk-B2QYMUTD.js";import{$a as Pr,A as ur,B as St,Ba as Tr,C as mr,Ca as Ar,D as Et,Da as Cr,E as Tt,F as At,G as fr,H as gr,K as xr,L as br,La as Ir,M as vr,Na as Te,Sa as Mr,T as U,U as yr,Ua as Be,V as wr,Va as Ct,Wa as It,Xa as Mt,Ya as Lt,Za as Lr,_a as Rr,a as er,ab as Rt,c as bt,cb as $r,d as _a,e as tr,fb as jr,i as vt,l as Ze,n as ar,z as _t,za as Er}from"./chunk-3K35L73A.js";import"./chunk-GTJIKXDB.js";import{h as Qn,i as Zn}from"./chunk-UDMI4TYM.js";import{p as nr,t as rr}from"./chunk-S2GAEH2F.js";import{a as H,b as kr,c as _r,g as Sr}from"./chunk-7LN4VKDU.js";import{a as hr}from"./chunk-IMLAPB7G.js";import{a as ir,b as yt,d as lr,e as cr,f as wt}from"./chunk-WCXXXAHV.js";import{g as kt}from"./chunk-LQE73AZR.js";import{b as dr,c as pr}from"./chunk-2D3RYIDU.js";import"./chunk-MRIVENBY.js";import"./chunk-AKLZ4YO2.js";import"./chunk-3WYLK3SX.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import{b as G,c as Ee,d as or,e as Sa}from"./chunk-EMGB23H5.js";import{b as sr}from"./chunk-JWDJMFU6.js";import{E as Vn,F as ht,G as gt,H as xt,I as de,J as Yn,a as Fn,f as Un,g as wa,h as ka,l as Wn,m as Gn,n as Xn,y as Jn}from"./chunk-RH3J4LCP.js";import"./chunk-QSKG754X.js";import"./chunk-MEFPXHQJ.js";import"./chunk-Y4CYQV7G.js";import"./chunk-SHEUCITK.js";import"./chunk-QNKSRROH.js";import"./chunk-AFRHKA7B.js";import"./chunk-MDGYSHO5.js";import{a as Kn}from"./chunk-KDQI5S7F.js";import"./chunk-3UOTLMXD.js";import"./chunk-KA2UIZXG.js";import"./chunk-GQ76J72O.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-SZDACK6O.js";import"./chunk-VCQVF44A.js";import"./chunk-74LPAKQY.js";import"./chunk-JP5OAMWQ.js";import"./chunk-4VVHGR7H.js";import{g as qn}from"./chunk-ZG4G6BFP.js";import"./chunk-WPNRDEHW.js";import"./chunk-ILEC3IAV.js";import"./chunk-724IBN5Y.js";import"./chunk-72SZI2UW.js";import"./chunk-FCPTN6NF.js";import"./chunk-MCI3DIWW.js";import"./chunk-6TURWSMN.js";import"./chunk-QD6IICK7.js";import"./chunk-QOYAX2FT.js";import"./chunk-2PJKGZWP.js";import"./chunk-7I7IEX4S.js";import{B as td,I as Nn,L as va,O as Dn,Q as mt,R as Hn,T as Bn,V as zn,Z as ya,a as Mn,b as Ln,c as Qc,oa as X,u as dt,v as Zc,w as xa,wa as ft,x as ba}from"./chunk-S2RRPTS3.js";import{a as Rn,b as pt,c as ga,d as Pn,h as $n}from"./chunk-BRK6M6LA.js";import{d as jn,e as ed,f as ut,n as On}from"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";function Ea(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 io(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:Ea(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}var se={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>",Nt=(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 lo(t={}){return I({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>
|
|
@@ -85,7 +85,7 @@ ${Nt(se.file,"Session briefings","brief-count")}
|
|
|
85
85
|
</div>
|
|
86
86
|
</details>
|
|
87
87
|
</section>
|
|
88
|
-
</div>`,css:
|
|
88
|
+
</div>`,css:ad,scripts:`<script>${q({decayOf:Ea,rankByDecay:io})}const ICON = ${JSON.stringify(se)};${nd}</script>`})}var ad=`
|
|
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
|
-
}`,
|
|
364
|
+
}`,nd=String.raw`
|
|
365
365
|
(function(){
|
|
366
366
|
const $=id=>document.getElementById(id), esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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,7 +776,7 @@ 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
|
|
779
|
+
})();`;function Ta(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),d=r[r.length-1];d&&l.startedAt-d.to<=e?(d.to=Math.max(d.to,c),d.runs++):r.push({from:l.startedAt,to:c,runs:1})}for(;r.length>a;){let l=0,c=1/0;for(let d=1;d<r.length;d++){let p=r[d].from-r[d-1].to;p<c&&(c=p,l=d)}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 Aa(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 co(t,e=[],a){let{bands:n,gaps:r}=Ta(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(b=>l.startedAt>=b.from&&l.startedAt<=b.to);if(c===-1)continue;let d=n[c],p=d.to-d.from||1,m=(l.startedAt-d.from)/p*100,g=Math.min(Math.max((l.durationMs||0)/p*100,1.2),100-m),_=s.get(l.laneKey)??{key:l.laneKey,label:l.laneLabel,sub:l.laneSub,tracks:1,runs:[]};_.runs.push({...l,band:c,track:0,left:m,width:g,marks:o.get(l.id)??[]}),s.set(l.laneKey,_)}let i=[...s.values()];for(let l of i)l.tracks=Math.max(...n.map((c,d)=>Aa(l.runs.filter(p=>p.band===d))),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 rd}from"crypto";import{readFileSync as od,statSync as sd}from"fs";import{resolve as id,dirname as ld}from"path";import{fileURLToPath as cd}from"url";var po=new Map;function Dt(t){let e=po.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=ld(cd(import.meta.url)),r=id(n,"web",t),o=sd(r),s=o.size<8e6?rd("sha1").update(od(r)).digest("hex").slice(0,10):`${o.size}-${Math.floor(o.mtimeMs)}`;a=`/assets/${t}?v=${s}`}catch{}return po.set(t,a),a}var ie={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"/>'},Ht=(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>",dd=[["agent","Agent",ie.bot],["client","Client",ie.user],["project","Project",ie.folder],["channel","Channel",ie.route],["person","Person",ie.user],["node","Node",ie.mesh]],uo={timeline:"Every run on the mesh, from task traces. The axis breaks over silence — 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 mo(t={}){let e=t.view==="map"?"map":"timeline",a=e==="map";return I({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>
|
|
@@ -799,7 +799,7 @@ 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
|
-
${
|
|
802
|
+
${dd.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${Ht(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>
|
|
@@ -819,7 +819,7 @@ refresh();
|
|
|
819
819
|
<div id="ax-fleet-root" data-hours="24" data-src="${Dt("activity-graph.global.js")}"></div>
|
|
820
820
|
</div>
|
|
821
821
|
|
|
822
|
-
</div>`,css:
|
|
822
|
+
</div>`,css:pd,scripts:`<script>${q({computeBands:Ta,packTracks:Aa,buildTimeline:co})}const ICON = ${JSON.stringify(ie)};const SUB = ${JSON.stringify(uo)};${ud}</script>`})}var pd=`
|
|
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
|
-
`,
|
|
908
|
+
`,ud=String.raw`
|
|
909
909
|
const $=id=>document.getElementById(id);
|
|
910
910
|
const esc=s=>String(s==null?'':s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[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>';
|
|
@@ -1024,7 +1024,7 @@ history.replaceState(null,'',u);
|
|
|
1024
1024
|
if(v==='map')ensureMap();else if(!loaded){loaded=true;load();}}
|
|
1025
1025
|
$('view').addEventListener('click',e=>{const b=e.target.closest('button[data-value]');if(!b||b.dataset.value===view)return;show(b.dataset.value);});
|
|
1026
1026
|
show(view);
|
|
1027
|
-
`;function fo(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return I({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
1027
|
+
`;function fo(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return I({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:md,scripts:`<script src="${Dt("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var md=`
|
|
1028
1028
|
/* Preload the fonts the redesign's CSS references. Placed in the shell so
|
|
1029
1029
|
* they start fetching while the React bundle is still parsing. */
|
|
1030
1030
|
@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");
|
|
@@ -1045,11 +1045,11 @@ body { margin: 0; overflow: hidden; }
|
|
|
1045
1045
|
font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
|
|
1046
1046
|
text-align: center;
|
|
1047
1047
|
}
|
|
1048
|
-
`;import{createServer as
|
|
1049
|
-
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...
|
|
1050
|
-
WHERE l.kind = 'run' AND r.person = ? AND l.ref IN (${d.map(()=>"?").join(",")})`).all(e,...d.map(
|
|
1048
|
+
`;import{createServer as Sh}from"http";import{appendFileSync as Eh,existsSync as Fc,mkdirSync as Th}from"fs";import{readFile as Ah}from"fs/promises";import{fileURLToPath as Ch}from"url";import{dirname as Ih,resolve as it}from"path";Dn();function qe(t,e){if(!t)return"absent";let a=or(t),n=e.list().find(r=>r.hash===a);return n&&(n.revokedAt||n.expiresAt&&Date.parse(n.expiresAt)<Date.now())?"revoked":"invalid"}var Ie=class{constructor(e=r=>console.log(r),a=Date.now,n=6e4){this.log=e;this.now=a;this.everyMs=n}last=new Map;record(e,a){let n=Object.entries(a).map(([i,l])=>`${i}=${l}`).join(" "),r=`${e} ${a.cookie??""} ${a.bearer??""}`,o=this.now(),s=this.last.get(r);s!==void 0&&o-s<this.everyMs||(this.last.size>500&&this.prune(o),this.last.set(r,o),this.log(`[app] unauthenticated ${e} ${n}`))}prune(e){for(let[a,n]of this.last)e-n>=this.everyMs&&this.last.delete(a);this.last.size>500&&this.last.clear()}};function Bt(t,e,a){let n={cookie:e};return a&&(n.bearer=a),n.mode=ho(t.headers["sec-fetch-mode"]),n.site=ho(t.headers["sec-fetch-site"]),n}function ho(t){let e=Array.isArray(t)?t[0]:t;return e&&/^[a-z-]{1,20}$/.test(e)?e:"-"}import{deflateSync as gd}from"zlib";var fd=[[[441,393],[600,393],[614,396],[625,401],[634,410],[1028,940],[846,940],[833,937],[823,931],[818,925],[440,414],[435,406],[436,398]],[[893,393],[1079,393],[861,653],[771,535]],[[413,439],[510,574],[282,874],[100,874]],[[451,709],[610,709],[615,712],[698,824],[599,939],[447,719],[446,713]]],ye={x:100,y:393,width:979,height:547},Ca="#1a1a18",Ia="#ffffff",go=Math.hypot(ye.width,ye.height)/2/ye.width,zt={full:.74,safe:.37/go,android:.29/go,mac:.6};function Ma(t,e){let a=t*e/ye.width,n=t/2-(ye.x+ye.width/2)*a,r=t/2-(ye.y+ye.height/2)*a;return fd.map(o=>o.map(([s,i])=>[s*a+n,i*a+r]))}function hd(t,e){let a=n=>String(Math.round(n*100)/100);return Ma(t,e).map(n=>"M"+n.map(([r,o])=>`${a(r)},${a(o)}`).join("L")+"Z").join("")}function xo(t=64,e=zt.full){return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${t} ${t}"><rect width="${t}" height="${t}" rx="${t*.18}" fill="${Ia}"/><path fill="${Ca}" d="${hd(t,e)}"/></svg>`}var xd=Eo(Ca),bo=Eo(Ia),vo=new Map;function Fe(t){let e=vo.get(t);return e||(e=So({size:t,width:zt.safe,background:"square"}),vo.set(t,e)),e}var bd=xo();function _o(t){return t==="/favicon.svg"?{type:"image/svg+xml",body:bd}:t==="/favicon.ico"?{type:"image/png",body:wo(32)}:t==="/apple-touch-icon.png"?{type:"image/png",body:wo(180)}:null}var yo=new Map;function wo(t){let e=yo.get(t);return e||(e=So({size:t,width:zt.full,background:"square"}),yo.set(t,e)),e}function So(t){let{size:e}=t,a=t.background==="mac"?ko(e,[vd(e)]):null,n=ko(e,Ma(e,t.width)),r=1+e*4,o=Buffer.alloc(r*e);for(let s=0;s<e;s++)for(let i=0;i<e;i++){let l=s*e+i,c=n[l],d=s*r+1+i*4;for(let p=0;p<3;p++)o[d+p]=Math.round(bo[p]+(xd[p]-bo[p])*c);o[d+3]=Math.round(255*(a?a[l]:1))}return yd(e,o)}function vd(t){let e=t/1024,a=100*e,n=924*e,r=185*e,o=[],s=[[n-r,a+r,-90],[n-r,n-r,0],[a+r,n-r,90],[a+r,a+r,180]];for(let[i,l,c]of s)for(let d=0;d<=12;d++){let p=(c+90*d/12)*Math.PI/180;o.push([i+r*Math.cos(p),l+r*Math.sin(p)])}return o}var La=8;function ko(t,e){let a=new Float32Array(t*t),n=[];for(let o of e)for(let s=0;s<o.length;s++){let[i,l]=o[s],[c,d]=o[(s+1)%o.length];l!==d&&n.push([i,l,c,d])}let r=[];for(let o=0;o<t;o++)for(let s=0;s<La;s++){let i=o+(s+.5)/La;r.length=0;for(let[l,c,d,p]of n)(i>=c&&i<p||i>=p&&i<c)&&r.push(l+(i-c)*(d-l)/(p-c));r.sort((l,c)=>l-c);for(let l=0;l+1<r.length;l+=2){let c=Math.max(0,r[l]),d=Math.min(t,r[l+1]);for(let p=Math.floor(c);p<d;p++){let m=Math.min(p+1,d)-Math.max(p,c);m>0&&(a[o*t+p]+=m/La)}}}for(let o=0;o<a.length;o++)a[o]>1&&(a[o]=1);return a}function Eo(t){let e=parseInt(t.slice(1),16);return[e>>16&255,e>>8&255,e&255]}function yd(t,e){let a=Buffer.alloc(13);return a.writeUInt32BE(t,0),a.writeUInt32BE(t,4),a[8]=8,a[9]=6,Buffer.concat([Buffer.from([137,80,78,71,13,10,26,10]),Ra("IHDR",a),Ra("IDAT",gd(e)),Ra("IEND",Buffer.alloc(0))])}function Ra(t,e){let a=Buffer.alloc(4);a.writeUInt32BE(e.length);let n=Buffer.concat([Buffer.from(t,"ascii"),e]),r=Buffer.alloc(4);return r.writeUInt32BE(kd(n)),Buffer.concat([a,n,r])}var wd=Array.from({length:256},(t,e)=>{let a=e;for(let n=0;n<8;n++)a=a&1?3988292384^a>>>1:a>>>1;return a>>>0});function kd(t){let e=4294967295;for(let a of t)e=wd[(e^a)&255]^e>>>8;return(e^4294967295)>>>0}ft();td();var qt=7,_d=["waiting_owner","needs_attention"],Sd={gitlab:"GitLab",github:"GitHub",telegram:"Telegram",whatsapp:"WhatsApp",slack:"Slack",discord:"Discord",voice:"Voice",app:"Phone app",dashboard:"Dashboard",webrtc:"Call"};function Ue(t,e){let a=t.toLowerCase().split("@")[0],n=Sd[a]??t,r=/^(.+):(issue|merge_request|pull):(\d+)$/.exec(e);if(r){let o=r[2]==="issue"?"issue":r[2]==="pull"?"pull request":"merge request";return`${n} ${o} #${r[3]} in ${r[1]}`}return n}function To(t,e,a){let n=t.toLowerCase().split("@")[0],r=/^(.+):(issue|merge_request|pull):(\d+)$/.exec(e);if(!r)return null;let[,o,s,i]=r;return n==="gitlab"?`${(a.gitlab||"https://gitlab.com").replace(/\/+$/,"")}/${o}/-/${s==="issue"?"issues":"merge_requests"}/${i}`:n==="github"?`${(a.github||"https://github.com").replace(/\/+$/,"")}/${o}/${s==="issue"?"issues":"pull"}/${i}`:null}function Ao(t,e,a={}){let n=a.now??Date.now(),s=(t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'requests'").get()?t.prepare("PRAGMA table_info(requests)").all():[]).some(b=>b.name==="person"),i=b=>({id:b.id,state:b.state,agentId:b.agent_id,text:b.text,channel:b.channel,chatId:b.chat_id,createdAt:b.created_at,updatedAt:b.updated_at,closedAt:b.closed_at??null,question:b.question??null,attentionReason:b.attention_reason??null,evidence:b.evidence??null,where:{label:Ue(b.channel,b.chat_id),url:a.linkFor?.(b.channel,b.chat_id)??null}}),l=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${xa.map(()=>"?").join(",")}) ORDER BY created_at, rowid`).all(e,...xa).map(i):[],c=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${ba.map(()=>"?").join(",")}) AND COALESCE(closed_at, updated_at) >= ?
|
|
1049
|
+
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...ba,n-qt*864e5).map(i):[],d=[];try{d=jt(t,e,50).filter(b=>b.startedAt>=n-qt*864e5)}catch{}let p=new Map;if(s&&d.length){let b=t.prepare(`SELECT l.ref, r.id, r.state, r.evidence FROM request_links l JOIN requests r ON r.id = l.request_id
|
|
1050
|
+
WHERE l.kind = 'run' AND r.person = ? AND l.ref IN (${d.map(()=>"?").join(",")})`).all(e,...d.map(S=>S.taskId));for(let S of b)p.set(S.ref,{id:S.id,state:S.state,evidence:S.evidence??null})}let m=d.map(b=>({...b,where:b.channel?{label:Ue(b.channel,b.chatId??""),url:a.linkFor?.(b.channel,b.chatId??"")??null}:null,request:p.get(b.taskId)??null})),g=new Set(m.map(b=>b.request?.id).filter(Boolean)),_=[...l.filter(b=>!_d.includes(b.state)),...c].filter(b=>!g.has(b.id));return{open:l,recent:c,runs:m,other:_}}ya();ed();var Co={waiting:0,yours:0,ahead:null};function Io(t,e,a={}){let n=jn(t),r=new Map,o=[],s=new Map;for(let i of n){let l=`${i.agentId}\0${i.channel}\0${i.chatId}`,c=s.get(l)??0;s.set(l,c+1);let d=r.get(i.agentId)??{waiting:0,yours:0,ahead:null};d.waiting++,i.person===e&&(d.yours++,d.ahead===null&&(d.ahead=c),o.push({agentId:i.agentId,channel:i.channel,chatId:i.chatId,queuedAt:i.queuedAt,messagePreview:i.messagePreview,where:{label:Ue(i.channel,i.chatId),url:a.linkFor?.(i.channel,i.chatId)??null},ahead:c})),r.set(i.agentId,d)}return{byAgent:r,mine:o}}var Ed=4e3;function Mo(t,e,a){return e.agents?.length?[...e.agents]:t.prepare(`SELECT agent_id, MAX(started_at) AS last FROM task_traces
|
|
1051
1051
|
WHERE person = ? AND started_at >= ? AND (channel IS NULL OR channel != 'a2a')
|
|
1052
|
-
GROUP BY agent_id ORDER BY last DESC LIMIT 12`).all(e.id,a-qt*864e5).map(r=>r.agent_id)}function Lo(t,e,a,n){let r=new Set(n.people.filter(l=>l.role==="owner").map(l=>l.id));r.add(mt);let o=l=>l===e?"you":l&&r.has(l)?"owner":"other",s=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status = 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1"),i=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status != 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1");return a.map(l=>{let c=n.queue?.get(l)??Co,d=s.get(l),p=d??i.get(l);if(!p)return{agentId:l,state:"free",by:null,at:null,text:null,fullText:null,where:null,queue:c};let m=o(p.person??null),
|
|
1052
|
+
GROUP BY agent_id ORDER BY last DESC LIMIT 12`).all(e.id,a-qt*864e5).map(r=>r.agent_id)}function Lo(t,e,a,n){let r=new Set(n.people.filter(l=>l.role==="owner").map(l=>l.id));r.add(mt);let o=l=>l===e?"you":l&&r.has(l)?"owner":"other",s=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status = 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1"),i=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status != 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1");return a.map(l=>{let c=n.queue?.get(l)??Co,d=s.get(l),p=d??i.get(l);if(!p)return{agentId:l,state:"free",by:null,at:null,text:null,fullText:null,where:null,queue:c};let m=o(p.person??null),g=p.status==="error"||p.status==="timeout",_=d?"working":g&&m==="you"?"blocked":"free",b=m==="you"&&p.channel!=="a2a",S=b&&p.channel;return{agentId:l,state:_,by:m,at:d?p.started_at:p.finished_at??p.started_at,text:d||b?p.message_preview??null:null,fullText:b&&d&&String(p.original_message??p.message_preview??"").slice(0,Ed)||null,where:S?{label:Ue(p.channel,p.chat_id??""),url:n.linkFor?.(p.channel,p.chat_id??"")??null}:null,queue:c}})}function Ro(t){return t>=200&&t<300?"retry":t===401?"lock":"keep"}function Po(t,e){return!t||e-t>=3e4||t>e}function Ft(t,e){let a="23456789ABCDEFGHJKMNPQRSTUVWXYZ",n=String(t||"").toUpperCase(),r=Math.max(0,Math.min(Number(e)||0,n.length)),o="",s=0;for(let l=0;l<n.length&&o.length<8;l++)a.indexOf(n.charAt(l))<0||(o+=n.charAt(l),l<r&&s++);let i=o.length>4?o.slice(0,4)+"-"+o.slice(4):o;return{value:i,caret:Math.min(s>4?s+1:s,i.length)}}function $o(t){let e=String(t||"").trim(),a=/^https?:[/][/][^/#?]+[/]app[/]pair[/]?#(.*)$/i.exec(e);if(a){let r=a[1].split("&");for(let o=0;o<r.length;o++){if(r[o].indexOf("token=")!==0)continue;let s="";try{s=decodeURIComponent(r[o].slice(6))}catch{return{kind:"none"}}return/^agx_live_[0-9a-f]{64}$/.test(s)?{kind:"token",token:s}:{kind:"none"}}return{kind:"none"}}let n=e.toUpperCase();return/^[A-Z0-9]{4}-?[A-Z0-9]{4}$/.test(n)?{kind:"code",code:n.slice(0,4)+"-"+n.slice(-4)}:{kind:"none"}}function Ut(t,e,a,n){return t?e?{text:"Can't reach the server. "+(n?"Showing what was last loaded. ":"")+"Trying again every "+a+" seconds.",retry:!0}:{text:"Offline. Showing what was last loaded; live state needs a connection.",retry:!1}:null}function Wt(t){return String(t??"").replace(/```[\w-]*|`/g,"").replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/^[ \t]*(?:#{1,6}|>+|[-*+]|\d+[.)])[ \t]+(?:\[[ xX]\][ \t]+)?/gm,"").replace(/\*\*|~~/g,"").replace(/(^|[\s(])\*(\S(?:[^*\n]*\S)?)\*(?=[\s).,;:!?]|$)/gm,"$1$2").replace(/\s+/g," ").trim()}function jo(t){let e=t.by==="you"?"you":t.by==="owner"?"the owner":t.by?"someone else":null;if(t.state==="working"){let a=t.queue||{waiting:0,yours:0,ahead:null},n=a.ahead||0,r;return a.yours>0?r=(a.yours===1?"Your message is in line":a.yours+" messages of yours are in line")+(n===0?a.yours===1?": it runs when this ends.":": the first runs when this ends.":", "+n+(n===1?" message":" messages")+" ahead of "+(a.yours===1?"it.":"the first.")):a.waiting>0?r=a.waiting+(a.waiting===1?" message waits":" messages wait")+" in line. A new one from you waits behind "+(a.waiting===1?"it.":"them."):r=t.by==="you"?"Busy. A new message waits in line until this ends.":"A message you send now waits in line until this ends.",t.by==="you"?{label:"Working",tone:"work",what:t.text,by:e,hint:r}:{label:"Working",tone:"work",what:t.text||"Busy with someone else's task",by:e,hint:r}}return t.state==="blocked"?{label:"Blocked",tone:"stuck",what:t.text?"Stopped on: "+t.text:null,by:e,hint:"It stopped before finishing. It needs a person."}:{label:"Free",tone:"free",what:t.by==="you"&&t.text?"Finished: "+t.text:null,by:t.by==="you"?e:null,hint:"Free. Ready for your next message."}}function Oo(t){let e=t.request?t.request.state:"";return e==="waiting_owner"?{label:"Waiting on the owner",tone:"wait"}:e==="waiting_other"?{label:"Waiting on another agent",tone:"wait"}:e==="needs_attention"?{label:"Stuck",tone:"stuck"}:t.status==="queued"?{label:"In line",tone:"wait"}:t.status==="in-flight"?{label:"Running",tone:"work"}:t.status==="ok"?{label:"Finished",tone:"done"}:t.status==="error"||t.status==="timeout"?{label:"Stopped",tone:"stuck"}:t.status==="canceled"||t.status==="cancelled"?{label:"Stopped",tone:"off"}:{label:String(t.status||"").replace(/[_-]/g," "),tone:"off"}}function No(t){return t==="in_progress"?{label:"In progress",tone:"work"}:t==="waiting_owner"?{label:"Waiting on the owner",tone:"wait"}:t==="waiting_other"?{label:"Waiting on another agent",tone:"wait"}:t==="needs_attention"?{label:"Stuck",tone:"stuck"}:t==="done"?{label:"Finished",tone:"done"}:t==="declined"?{label:"Declined",tone:"off"}:t==="dropped"?{label:"Dropped",tone:"off"}:{label:String(t||"").replace(/_/g," "),tone:"off"}}function Do(t,e){if(!t.length&&!e)return"Nothing sent yet.";let a=t.slice(0,4).map(function(n){return n.state==="working"?n.agentId+(n.by==="you"?" is working on your task.":" is busy with someone else's task."):n.state==="blocked"?n.agentId+" stopped on your task.":n.agentId+" is free."});return t.length>4&&a.push(t.length-4+" more below."),a.join(" ")||"Nothing running now."}function Ho(t,e){if(!t)return[];let a={};return t.forEach(function(n){a[n.agentId]=n.state}),e.filter(function(n){return n.state==="free"&&a[n.agentId]==="working"}).map(function(n){return n.agentId})}var Bo=`
|
|
1053
1053
|
(function () {
|
|
1054
1054
|
var POLL_S = 30, RETRY_S = 20, GIVE_UP_MS = 15000;
|
|
1055
1055
|
var who = document.getElementById('who');
|
|
@@ -1380,7 +1380,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
1380
1380
|
.pulse { display: inline-block; width: 12px; height: 12px; margin-right: 10px; border-radius: 50%; border: 3px solid var(--ax-amber-ink); box-sizing: border-box; animation: breathe 2.4s ease-in-out infinite; }
|
|
1381
1381
|
@keyframes breathe { 50% { opacity: 0.35; } }
|
|
1382
1382
|
@media (prefers-reduced-motion: reduce) { .pulse { animation: none; } }
|
|
1383
|
-
`;var
|
|
1383
|
+
`;var Td="<script>(function(){var t;try{t=localStorage.getItem('ax-theme')}catch(e){}if(t!=='light'&&t!=='dark'){t=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'}document.documentElement.setAttribute('data-theme',t)})()</script>";function Pa(t,e={}){return`<meta charset="utf-8">
|
|
1384
1384
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
1385
1385
|
<meta name="theme-color" content="#2979FF">
|
|
1386
1386
|
<meta name="referrer" content="no-referrer">
|
|
@@ -1390,7 +1390,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
1390
1390
|
<link rel="icon" type="image/png" href="/member/icon-192.png">
|
|
1391
1391
|
<link rel="apple-touch-icon" href="/member/icon-192.png">
|
|
1392
1392
|
<title>${t}</title>
|
|
1393
|
-
${
|
|
1393
|
+
${Td}
|
|
1394
1394
|
<style>${ze}${Gt}</style>`}function Fo(){return JSON.stringify({id:"/member",name:"My work \xB7 AgentX",short_name:"My work",description:"What you asked the agents for, and where it stands.",start_url:"/member",scope:"/member",display:"standalone",background_color:"#FFFFFF",theme_color:"#2979FF",icons:[{src:"/member/icon-192.png",sizes:"192x192",type:"image/png",purpose:"any"},{src:"/member/icon-512.png",sizes:"512x512",type:"image/png",purpose:"any"},{src:"/member/icon-512.png",sizes:"512x512",type:"image/png",purpose:"maskable"}]})}var Uo=`
|
|
1395
1395
|
var CACHE = 'agentx-member-v1';
|
|
1396
1396
|
var STATIC = ['/member/manifest.webmanifest', '/member/icon-192.png', '/member/icon-512.png'];
|
|
@@ -1421,14 +1421,14 @@ self.addEventListener('fetch', function (e) {
|
|
|
1421
1421
|
e.respondWith(caches.match(url.pathname).then(function (hit) { return hit || fetch(req); }));
|
|
1422
1422
|
}
|
|
1423
1423
|
});
|
|
1424
|
-
`;function
|
|
1424
|
+
`;function $a(t,e="",a="My work"){return`<header class="bar">
|
|
1425
1425
|
<img class="mark" src="/member/icon-192.png" alt="" width="36" height="36">
|
|
1426
1426
|
<div class="grow"><h1>${a}</h1><p id="who" class="who">${t}</p></div>${e}
|
|
1427
|
-
</header>`}var
|
|
1427
|
+
</header>`}var ja=Pa,Oa=$a;function Wo(t){return`<ol class="steps" role="list" aria-label="Steps">${["Type the code","The owner says yes","Your work opens"].map((a,n)=>n<t?`<li class="done"><span class="sr">Done: </span>${a}</li>`:n===t?`<li class="now" aria-current="step">${a}</li>`:`<li>${a}</li>`).join("")}</ol>`}function Go(){return`<!doctype html>
|
|
1428
1428
|
<html lang="en">
|
|
1429
|
-
<head>${
|
|
1429
|
+
<head>${ja("My work \xB7 AgentX")}<style>${Xt}</style></head>
|
|
1430
1430
|
<body>
|
|
1431
|
-
${
|
|
1431
|
+
${Oa("Connecting\u2026",`
|
|
1432
1432
|
<button type="button" id="theme" class="icon-btn" aria-label="Switch theme">\u25D0</button>`)}
|
|
1433
1433
|
<p id="offline" class="strip" role="status" hidden><span id="offline-text"></span><button type="button" id="retry" hidden>Try now</button></p>
|
|
1434
1434
|
<aside id="install" class="install" aria-label="Keep this window" hidden>To keep this window on your desktop: in Edge or Chrome open the browser menu, then <b>Apps</b>, then <b>Install this site as an app</b>.</aside>
|
|
@@ -1439,13 +1439,13 @@ ${ja("Connecting\u2026",`
|
|
|
1439
1439
|
<section aria-labelledby="h-sent"><h2 id="h-sent" tabindex="-1">What you sent <span class="n">(last 7 days)</span></h2><ul id="sent" class="rows" role="list"></ul></section>
|
|
1440
1440
|
<p id="updated" class="foot"></p>
|
|
1441
1441
|
</main>
|
|
1442
|
-
<script>${q({workState:
|
|
1442
|
+
<script>${q({workState:Ad,ageText:Na,connectionNote:Ut,plainPreview:Wt,agentLine:jo,sentState:Oo,requestState:No,summaryLine:Do,freedAgents:Ho})}${Bo}</script>
|
|
1443
1443
|
</body>
|
|
1444
1444
|
</html>`}function Xo(){return`<!doctype html>
|
|
1445
1445
|
<html lang="en">
|
|
1446
|
-
<head>${
|
|
1446
|
+
<head>${ja("Pair this machine \xB7 AgentX")}<style>${zo}</style></head>
|
|
1447
1447
|
<body>
|
|
1448
|
-
${
|
|
1448
|
+
${Oa("This machine is not paired yet")}
|
|
1449
1449
|
<main class="narrow">
|
|
1450
1450
|
${Wo(0)}
|
|
1451
1451
|
<div class="card">
|
|
@@ -1464,13 +1464,13 @@ ${ja("This machine is not paired yet")}
|
|
|
1464
1464
|
<p class="help">No code? Ask the person who invited you for one. A code works once, for 10 minutes.</p>
|
|
1465
1465
|
</div>
|
|
1466
1466
|
</main>
|
|
1467
|
-
<script>${q({formatPairInput:Ft})}${
|
|
1467
|
+
<script>${q({formatPairInput:Ft})}${Cd}</script>
|
|
1468
1468
|
</body>
|
|
1469
1469
|
</html>`}function Ko(){return`<!doctype html>
|
|
1470
1470
|
<html lang="en">
|
|
1471
|
-
<head>${
|
|
1471
|
+
<head>${ja("Waiting for the owner \xB7 AgentX")}<style>${qo}</style></head>
|
|
1472
1472
|
<body>
|
|
1473
|
-
${
|
|
1473
|
+
${Oa("This machine is paired")}
|
|
1474
1474
|
<main class="narrow">
|
|
1475
1475
|
${Wo(1)}
|
|
1476
1476
|
<div class="card">
|
|
@@ -1479,9 +1479,9 @@ ${ja("This machine is paired")}
|
|
|
1479
1479
|
<p class="help">If they say no, this page asks for a new code.</p>
|
|
1480
1480
|
</div>
|
|
1481
1481
|
</main>
|
|
1482
|
-
<script>${
|
|
1482
|
+
<script>${Id}</script>
|
|
1483
1483
|
</body>
|
|
1484
|
-
</html>`}function
|
|
1484
|
+
</html>`}function Ad(t){let e=String(t||"");return e==="in_progress"?{label:"In progress",tone:"ok"}:e==="waiting_owner"?{label:"Waiting on the owner",tone:"warn"}:e==="waiting_other"?{label:"Waiting on another agent",tone:"warn"}:e==="needs_attention"?{label:"Stuck: needs attention",tone:"bad"}:e==="done"?{label:"Done",tone:"ok"}:e==="declined"?{label:"Declined",tone:"bad"}:e==="dropped"?{label:"Dropped",tone:"muted"}:{label:e.replace(/_/g," "),tone:"muted"}}function Na(t,e){let a=Math.max(0,Number(e)-Number(t)),n=Math.floor(a/6e4);if(n<1)return"just now";if(n<60)return n+" min ago";let r=Math.floor(n/60);return r<24?r+" h "+n%60+" min ago":Math.floor(r/24)+" d "+r%24+" h ago"}var Cd=`
|
|
1485
1485
|
(function () {
|
|
1486
1486
|
var form = document.getElementById('pair-form');
|
|
1487
1487
|
var machine = document.getElementById('machine');
|
|
@@ -1525,7 +1525,7 @@ ${ja("This machine is paired")}
|
|
|
1525
1525
|
}).catch(function () { busy = false; btn.disabled = false; say('No connection. Check the private network and try again.', true); });
|
|
1526
1526
|
});
|
|
1527
1527
|
})();
|
|
1528
|
-
`,
|
|
1528
|
+
`,Id=`
|
|
1529
1529
|
(function () {
|
|
1530
1530
|
var msg = document.getElementById('msg');
|
|
1531
1531
|
function check() {
|
|
@@ -1536,15 +1536,15 @@ ${ja("This machine is paired")}
|
|
|
1536
1536
|
}
|
|
1537
1537
|
setInterval(check, 5000);
|
|
1538
1538
|
})();
|
|
1539
|
-
`;function Jo(t){let e=t.request?t.request.state:"";return e==="waiting_owner"||e==="waiting_other"?{label:"Waiting on us",tone:"wait"}:e==="needs_attention"?{label:"Needs a look from us",tone:"stuck"}:t.status==="in-flight"?{label:"Being worked on",tone:"work"}:t.status==="ok"?{label:"Finished",tone:"done"}:t.status==="error"||t.status==="timeout"?{label:"Stopped, we will look at it",tone:"stuck"}:t.status==="canceled"||t.status==="cancelled"?{label:"Stopped",tone:"off"}:{label:String(t.status||"").replace(/[_-]/g," "),tone:"off"}}function Vo(t){return t==="in_progress"?{label:"Being worked on",tone:"work"}:t==="waiting_owner"||t==="waiting_other"?{label:"Waiting on us",tone:"wait"}:t==="needs_attention"?{label:"Needs a look from us",tone:"stuck"}:t==="done"?{label:"Finished",tone:"done"}:t==="declined"?{label:"Not taken on",tone:"off"}:t==="dropped"?{label:"Set aside",tone:"off"}:{label:String(t||"").replace(/_/g," "),tone:"off"}}function Yo(t){if(!t.length)return"Nothing asked for yet.";let e=0,a=0,n=0,r=0;for(let s=0;s<t.length;s++)t[s]==="work"?e++:t[s]==="wait"?a++:t[s]==="stuck"?n++:t[s]==="done"&&r++;let o=[];return e&&o.push(e===1?"1 request is being worked on for you.":e+" requests are being worked on for you."),a&&o.push(a===1?"1 is waiting on us.":a+" are waiting on us."),n&&o.push(n===1?"1 needs a look from us.":n+" need a look from us."),o.length?o.join(" "):r?"Nothing in progress right now. "+(r===1?"1 request finished":r+" requests finished")+" this week.":"Nothing in progress right now."}var
|
|
1539
|
+
`;function Jo(t){let e=t.request?t.request.state:"";return e==="waiting_owner"||e==="waiting_other"?{label:"Waiting on us",tone:"wait"}:e==="needs_attention"?{label:"Needs a look from us",tone:"stuck"}:t.status==="in-flight"?{label:"Being worked on",tone:"work"}:t.status==="ok"?{label:"Finished",tone:"done"}:t.status==="error"||t.status==="timeout"?{label:"Stopped, we will look at it",tone:"stuck"}:t.status==="canceled"||t.status==="cancelled"?{label:"Stopped",tone:"off"}:{label:String(t.status||"").replace(/[_-]/g," "),tone:"off"}}function Vo(t){return t==="in_progress"?{label:"Being worked on",tone:"work"}:t==="waiting_owner"||t==="waiting_other"?{label:"Waiting on us",tone:"wait"}:t==="needs_attention"?{label:"Needs a look from us",tone:"stuck"}:t==="done"?{label:"Finished",tone:"done"}:t==="declined"?{label:"Not taken on",tone:"off"}:t==="dropped"?{label:"Set aside",tone:"off"}:{label:String(t||"").replace(/_/g," "),tone:"off"}}function Yo(t){if(!t.length)return"Nothing asked for yet.";let e=0,a=0,n=0,r=0;for(let s=0;s<t.length;s++)t[s]==="work"?e++:t[s]==="wait"?a++:t[s]==="stuck"?n++:t[s]==="done"&&r++;let o=[];return e&&o.push(e===1?"1 request is being worked on for you.":e+" requests are being worked on for you."),a&&o.push(a===1?"1 is waiting on us.":a+" are waiting on us."),n&&o.push(n===1?"1 needs a look from us.":n+" need a look from us."),o.length?o.join(" "):r?"Nothing in progress right now. "+(r===1?"1 request finished":r+" requests finished")+" this week.":"Nothing in progress right now."}var Da="/member/client.webmanifest",et="Your project";function Qo(){return JSON.stringify({id:"/member?client",name:`${et} \xB7 AgentX`,short_name:et,description:"What you asked for, and where it stands.",start_url:"/member",scope:"/member",display:"standalone",background_color:"#2979FF",theme_color:"#2979FF",icons:[{src:"/member/icon-192.png",sizes:"192x192",type:"image/png",purpose:"any"},{src:"/member/icon-512.png",sizes:"512x512",type:"image/png",purpose:"any"},{src:"/member/icon-512.png",sizes:"512x512",type:"image/png",purpose:"maskable"}]})}var Md=`
|
|
1540
1540
|
.about { margin-top: 32px; padding: 16px 20px; border: var(--ax-border-w) solid var(--ax-border); border-radius: var(--ax-radius-lg); background: var(--ax-surface); font-size: 15px; color: var(--ax-text-2); }
|
|
1541
1541
|
.wrap .about h2 { margin: 0 0 6px; }
|
|
1542
1542
|
.about p + p { margin-top: 6px; }
|
|
1543
1543
|
`;function Zo(){return`<!doctype html>
|
|
1544
1544
|
<html lang="en">
|
|
1545
|
-
<head>${
|
|
1545
|
+
<head>${Pa(`${et} \xB7 AgentX`,{manifest:Da,appTitle:et})}<style>${ze}${Gt}${Xt}${Md}</style></head>
|
|
1546
1546
|
<body>
|
|
1547
|
-
${
|
|
1547
|
+
${$a("Connecting\u2026",`
|
|
1548
1548
|
<button type="button" id="theme" class="icon-btn" aria-label="Switch theme">\u25D0</button>`,et)}
|
|
1549
1549
|
<p id="offline" class="strip" role="status" hidden><span id="offline-text"></span><button type="button" id="retry" hidden>Try now</button></p>
|
|
1550
1550
|
<aside id="install" class="install" aria-label="Keep this window" hidden>To keep this window on your desktop: in Edge or Chrome open the browser menu, then <b>Apps</b>, then <b>Install this site as an app</b>.</aside>
|
|
@@ -1557,9 +1557,9 @@ ${Pa("Connecting\u2026",`
|
|
|
1557
1557
|
</section>
|
|
1558
1558
|
<p id="updated" class="foot"></p>
|
|
1559
1559
|
</main>
|
|
1560
|
-
<script>${q({ageText:
|
|
1560
|
+
<script>${q({ageText:Na,connectionNote:Ut,plainPreview:Wt,clientSentState:Jo,clientRequestState:Vo,clientSummary:Yo})}${Ld}</script>
|
|
1561
1561
|
</body>
|
|
1562
|
-
</html>`}var
|
|
1562
|
+
</html>`}var Ld=`
|
|
1563
1563
|
(function () {
|
|
1564
1564
|
var POLL_S = 30, RETRY_S = 20, GIVE_UP_MS = 15000;
|
|
1565
1565
|
var who = document.getElementById('who');
|
|
@@ -1666,10 +1666,10 @@ ${Pa("Connecting\u2026",`
|
|
|
1666
1666
|
showConn();
|
|
1667
1667
|
load();
|
|
1668
1668
|
})();
|
|
1669
|
-
`;var Kt="agentx_member",Ld=90*86400,Rd=new At,ns=t=>t.replace(/^\[app\]/,"[member]"),Pd=new Ie(t=>console.log(ns(t))),es=new WeakMap;function $d(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return Pd;let e=es.get(t.log);return e||es.set(t.log,e=new Ie(a=>t.log(ns(a)))),e}var ts=null;function tt(t,e=X){try{return ts=e().people}catch{return ts??t}}async function rs(t,e,a,n,r){if(a!=="/member"&&!a.startsWith("/member/")&&!a.startsWith("/api/member/"))return!1;let o=r.tokens??new G(r.root),s=r.members??new ht(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new kt(r.root),limiter:r.pairLimiter??Rd,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return fe(e,200,"application/manifest+json",Fo());if(a===Na)return fe(e,200,"application/manifest+json",Qo());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),fe(e,200,"text/javascript; charset=utf-8",Uo);if(a==="/member/icon-192.png")return fe(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/member/icon-512.png")return fe(e,200,"image/png",Fe(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let p=await Jr(t,i);return p.status===200&&e.setHeader("Set-Cookie",as(p.token)),p.status===429&&e.setHeader("Retry-After",String(p.retryAfter)),we(e,p.status,p.body)}let l=Yr(Od(t),i,Kr(t));if(!l.ok){if(l.status===401){let p=Da(t);return $d(r).record(a.slice(0,120),Bt(t,qe(Ha(t,Kt),o),p?qe(p,o):null)),a==="/member"?fe(e,401,"text/html; charset=utf-8",Xo()):we(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?fe(e,202,"text/html; charset=utf-8",Ko()):we(e,403,{error:l.error,waiting:!0})}let c=r.people().find(p=>p.id===l.personId),d=c?.role==="client";if(n==="GET"&&a==="/member"){let p=Ha(t,Kt);return p&&!Da(t)&&e.setHeader("Set-Cookie",as(p)),fe(e,200,"text/html; charset=utf-8",d?Zo():Go())}if(n==="GET"&&a==="/api/member/me")return we(e,200,{person:l.personId,name:c?.name??l.personId,role:c?.role??"member",device:l.device.name,since:l.device.approvedAt??l.device.createdAt,node:r.nodeName??null});if(n==="GET"&&a==="/api/member/work"){let p=r.db?.()??null;if(!p)return we(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),h=Ao(p,l.personId,{now:m,linkFor:r.linkFor}),S=(b,x)=>{let u=x instanceof Error?x.message:String(x);/no such table/i.test(u)||r.log?.(`[member] ${b} failed: ${u}`)},v={byAgent:new Map,mine:[]};try{v=Io(p,l.personId,{linkFor:r.linkFor})}catch(b){S("the line",b)}let E=[];if(d)return we(e,200,{...jd(h),agents:E});try{let b=Mo(p,c??{id:l.personId},m);E=Lo(p,l.personId,b,{people:r.people(),linkFor:r.linkFor,queue:v.byAgent})}catch(b){S("agent cards",b)}return we(e,200,{...h,agents:E,queued:v.mine})}return we(e,404,{error:"not found"})}function jd(t){let e=a=>a.map(({agentId:n,...r})=>r);return{...t,open:e(t.open),recent:e(t.recent),runs:e(t.runs),other:e(t.other)}}function as(t){return`${Kt}=${t}; Path=/; Max-Age=${Ld}; HttpOnly; Secure; SameSite=Lax`}function Od(t){return Da(t)??Ha(t,Kt)}function Da(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Ha(t,e){for(let a of(t.headers.cookie||"").split(";")){let n=a.indexOf("=");if(n>0&&a.slice(0,n).trim()===e)return a.slice(n+1).trim()||null}return null}function fe(t,e,a,n,r="no-store"){return t.writeHead(e,{"Content-Type":a,"Cache-Control":r}),t.end(n),!0}function we(t,e,a){return fe(t,e,"application/json",JSON.stringify(a))}Yc();var os='/*! 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 Vt,readFileSync as ms,writeFileSync as fs,rmSync as Cx,mkdirSync as qd,copyFileSync as Fd,readdirSync as Ud}from"fs";import{resolve as Ge}from"path";Qc();function is(t){let e=dt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:dt.parse({});return{enabled:a.enabled,secretEnv:a.secretEnv,secretSet:!!process.env[a.secretEnv],batchSeconds:a.batchSeconds,allowAutoAck:a.allowAutoAck,rules:a.rules,...e.success?{}:{error:e.error.issues[0]?.message??"invalid whatsappTriage section"}}}function Jt(t){return C(e=>{let a=e.whatsappTriage&&typeof e.whatsappTriage=="object"?e.whatsappTriage:{};a.rules=Array.isArray(a.rules)?a.rules:[];let n=t(a,e),r=dt.safeParse(a);if(!r.success){let o=r.error.issues[0];throw new Error(`${o?.path.join(".")||"whatsappTriage"}: ${o?.message??"invalid"}`)}return e.whatsappTriage=a,n})}var ss=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function ls(t){return Jt(e=>(typeof t?.enabled=="boolean"&&(e.enabled=t.enabled),typeof t?.allowAutoAck=="boolean"&&(e.allowAutoAck=t.allowAutoAck),t?.batchSeconds!==void 0&&(e.batchSeconds=Number(t.batchSeconds)),`WhatsApp triage ${e.enabled?"on":"off"}`))}function cs(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Jt((n,r)=>{if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);if(n.rules.some(i=>i.id===e))throw new Error(`Watch rule "${e}" already exists.`);let o={id:e,agent:a,chats:ss(t?.chats),senders:ss(t?.senders)},s=String(t?.prompt??"").trim();return s&&(o.prompt=s),t?.quietStart&&t?.quietEnd&&(o.quietHours={start:String(t.quietStart),end:String(t.quietEnd)}),t?.autoAck===!0&&(o.autoAck=!0),n.rules.push(o),`added watch rule "${e}" \u2192 ${a}`})}function ds(t){let e=String(t?.id??"");return Jt(a=>{let n=a.rules.find(r=>r.id===e);if(!n)throw new Error(`Watch rule "${e}" not found.`);return typeof t?.patch?.enabled=="boolean"&&(n.enabled=t.patch.enabled),typeof t?.patch?.autoAck=="boolean"&&(n.autoAck=t.patch.autoAck),`updated watch rule "${e}"`})}function ps(t){let e=String(t?.id??"");return Jt(a=>{if(!a.rules.some(n=>n.id===e))throw new Error(`Watch rule "${e}" not found.`);return a.rules=a.rules.filter(n=>n.id!==e),`removed watch rule "${e}"`})}ft();var pe={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 us(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=de({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.`})+Pt([{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">')+'<div class="ax-wit" id="ax-voice-missing" style="display:none"><span class="ax-wit__icon">!</span><div></div></div>';return I({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Dd()+Nr,css:Bd,scripts:`${e}<script>${Dr}
|
|
1669
|
+
`;var Kt="agentx_member",Rd=90*86400,Pd=new At,ns=t=>t.replace(/^\[app\]/,"[member]"),$d=new Ie(t=>console.log(ns(t))),es=new WeakMap;function jd(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return $d;let e=es.get(t.log);return e||es.set(t.log,e=new Ie(a=>t.log(ns(a)))),e}var ts=null;function tt(t,e=X){try{return ts=e().people}catch{return ts??t}}async function rs(t,e,a,n,r){if(a!=="/member"&&!a.startsWith("/member/")&&!a.startsWith("/api/member/"))return!1;let o=r.tokens??new G(r.root),s=r.members??new ht(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new kt(r.root),limiter:r.pairLimiter??Pd,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return fe(e,200,"application/manifest+json",Fo());if(a===Da)return fe(e,200,"application/manifest+json",Qo());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),fe(e,200,"text/javascript; charset=utf-8",Uo);if(a==="/member/icon-192.png")return fe(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/member/icon-512.png")return fe(e,200,"image/png",Fe(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let p=await Jr(t,i);return p.status===200&&e.setHeader("Set-Cookie",as(p.token)),p.status===429&&e.setHeader("Retry-After",String(p.retryAfter)),we(e,p.status,p.body)}let l=Yr(Nd(t),i,Kr(t));if(!l.ok){if(l.status===401){let p=Ha(t);return jd(r).record(a.slice(0,120),Bt(t,qe(Ba(t,Kt),o),p?qe(p,o):null)),a==="/member"?fe(e,401,"text/html; charset=utf-8",Xo()):we(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?fe(e,202,"text/html; charset=utf-8",Ko()):we(e,403,{error:l.error,waiting:!0})}let c=r.people().find(p=>p.id===l.personId),d=c?.role==="client";if(n==="GET"&&a==="/member"){let p=Ba(t,Kt);return p&&!Ha(t)&&e.setHeader("Set-Cookie",as(p)),fe(e,200,"text/html; charset=utf-8",d?Zo():Go())}if(n==="GET"&&a==="/api/member/me")return we(e,200,{person:l.personId,name:c?.name??l.personId,role:c?.role??"member",device:l.device.name,since:l.device.approvedAt??l.device.createdAt,node:r.nodeName??null});if(n==="GET"&&a==="/api/member/work"){let p=r.db?.()??null;if(!p)return we(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),g=Ao(p,l.personId,{now:m,linkFor:r.linkFor}),_=(T,h)=>{let u=h instanceof Error?h.message:String(h);/no such table/i.test(u)||r.log?.(`[member] ${T} failed: ${u}`)},b={byAgent:new Map,mine:[]};try{b=Io(p,l.personId,{linkFor:r.linkFor})}catch(T){_("the line",T)}let S=[];if(d)return we(e,200,{...Od(g),agents:S});try{let T=Mo(p,c??{id:l.personId},m);S=Lo(p,l.personId,T,{people:r.people(),linkFor:r.linkFor,queue:b.byAgent})}catch(T){_("agent cards",T)}return we(e,200,{...g,agents:S,queued:b.mine})}return we(e,404,{error:"not found"})}function Od(t){let e=a=>a.map(({agentId:n,...r})=>r);return{...t,open:e(t.open),recent:e(t.recent),runs:e(t.runs),other:e(t.other)}}function as(t){return`${Kt}=${t}; Path=/; Max-Age=${Rd}; HttpOnly; Secure; SameSite=Lax`}function Nd(t){return Ha(t)??Ba(t,Kt)}function Ha(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Ba(t,e){for(let a of(t.headers.cookie||"").split(";")){let n=a.indexOf("=");if(n>0&&a.slice(0,n).trim()===e)return a.slice(n+1).trim()||null}return null}function fe(t,e,a,n,r="no-store"){return t.writeHead(e,{"Content-Type":a,"Cache-Control":r}),t.end(n),!0}function we(t,e,a){return fe(t,e,"application/json",JSON.stringify(a))}Qc();var os='/*! 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 Vt,readFileSync as ms,writeFileSync as fs,rmSync as Mx,mkdirSync as Fd,copyFileSync as Ud,readdirSync as Wd}from"fs";import{resolve as Ge}from"path";Zc();function is(t){let e=dt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:dt.parse({});return{enabled:a.enabled,secretEnv:a.secretEnv,secretSet:!!process.env[a.secretEnv],batchSeconds:a.batchSeconds,allowAutoAck:a.allowAutoAck,rules:a.rules,...e.success?{}:{error:e.error.issues[0]?.message??"invalid whatsappTriage section"}}}function Jt(t){return C(e=>{let a=e.whatsappTriage&&typeof e.whatsappTriage=="object"?e.whatsappTriage:{};a.rules=Array.isArray(a.rules)?a.rules:[];let n=t(a,e),r=dt.safeParse(a);if(!r.success){let o=r.error.issues[0];throw new Error(`${o?.path.join(".")||"whatsappTriage"}: ${o?.message??"invalid"}`)}return e.whatsappTriage=a,n})}var ss=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function ls(t){return Jt(e=>(typeof t?.enabled=="boolean"&&(e.enabled=t.enabled),typeof t?.allowAutoAck=="boolean"&&(e.allowAutoAck=t.allowAutoAck),t?.batchSeconds!==void 0&&(e.batchSeconds=Number(t.batchSeconds)),`WhatsApp triage ${e.enabled?"on":"off"}`))}function cs(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Jt((n,r)=>{if(!r.agents?.[a])throw new Error(`Unknown agent "${a}".`);if(n.rules.some(i=>i.id===e))throw new Error(`Watch rule "${e}" already exists.`);let o={id:e,agent:a,chats:ss(t?.chats),senders:ss(t?.senders)},s=String(t?.prompt??"").trim();return s&&(o.prompt=s),t?.quietStart&&t?.quietEnd&&(o.quietHours={start:String(t.quietStart),end:String(t.quietEnd)}),t?.autoAck===!0&&(o.autoAck=!0),n.rules.push(o),`added watch rule "${e}" \u2192 ${a}`})}function ds(t){let e=String(t?.id??"");return Jt(a=>{let n=a.rules.find(r=>r.id===e);if(!n)throw new Error(`Watch rule "${e}" not found.`);return typeof t?.patch?.enabled=="boolean"&&(n.enabled=t.patch.enabled),typeof t?.patch?.autoAck=="boolean"&&(n.autoAck=t.patch.autoAck),`updated watch rule "${e}"`})}function ps(t){let e=String(t?.id??"");return Jt(a=>{if(!a.rules.some(n=>n.id===e))throw new Error(`Watch rule "${e}" not found.`);return a.rules=a.rules.filter(n=>n.id!==e),`removed watch rule "${e}"`})}ft();var ue={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 us(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=pe({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.`})+Pt([{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">')+'<div class="ax-wit" id="ax-voice-missing" style="display:none"><span class="ax-wit__icon">!</span><div></div></div>';return I({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Hd()+Nr,css:zd,scripts:`${e}<script>${Dr}
|
|
1670
1670
|
${Hr}
|
|
1671
|
-
${
|
|
1672
|
-
${
|
|
1671
|
+
${Dd}
|
|
1672
|
+
${qd}</script>`})}var Dd=`
|
|
1673
1673
|
(function(){
|
|
1674
1674
|
function fmt(n) { return n == null ? '\u2014' : String(n); }
|
|
1675
1675
|
async function voiceMissing() {
|
|
@@ -1763,8 +1763,8 @@ ${zd}</script>`})}var Nd=`
|
|
|
1763
1763
|
refresh();
|
|
1764
1764
|
// Refresh again after the main admin script has had a chance to mutate config.
|
|
1765
1765
|
document.addEventListener('ax-config-saved', refresh);
|
|
1766
|
-
})();`;function
|
|
1767
|
-
`:"";return
|
|
1766
|
+
})();`;function Hd(){let t=_r().business?`<button data-tab="business">Business</button>
|
|
1767
|
+
`:"";return Bd.replace("__BUSINESS_TABS__",t)}var Bd=`
|
|
1768
1768
|
<div id="peer-banner" class="peer-banner">
|
|
1769
1769
|
<span class="label">Managing</span>
|
|
1770
1770
|
<span class="name" id="peer-banner-name">\u2014</span>
|
|
@@ -1909,9 +1909,19 @@ ${zd}</script>`})}var Nd=`
|
|
|
1909
1909
|
<div id="global-msg" class="msg"></div>
|
|
1910
1910
|
|
|
1911
1911
|
<section id="tab-agents" class="tab active">
|
|
1912
|
-
${K({icon:
|
|
1912
|
+
${K({icon:ue.agents,title:"Your agents",lead:"Each agent is a role with its own trigger words and workspace. Delete removes the config only \u2014 the folder on disk stays."})}
|
|
1913
1913
|
${oe({persistKey:"agents",bodyHtml:`<b>What's an agent, exactly?</b> Think of it as a specialised teammate. A sales agent handles pricing questions, a support agent answers tickets, a reports agent sends a weekly summary. You decide what they do and what to say to wake them up (their "trigger words", like <code>@support</code>).`})}
|
|
1914
1914
|
<div id="agent-list" class="ax-stack"></div>
|
|
1915
|
+
<details class="add-form" style="margin-top:14px" id="wiki-curator-section">
|
|
1916
|
+
<summary class="primary">\u{1F4AC} Wiki page curator</summary>
|
|
1917
|
+
<div style="margin-top:10px">
|
|
1918
|
+
<p style="font-size:11px;color:var(--ax-muted);margin:0 0 10px">A chat bubble on every wiki page. Type an instruction and an agent researches it and edits the open page; every change can be undone. Mirrors <code>agentx wiki curator</code>.</p>
|
|
1919
|
+
<label class="toggle-switch"><input type="checkbox" id="wc-enabled" /> <span>Show the bubble on wiki pages</span></label>
|
|
1920
|
+
<label style="margin-top:10px">Agent that answers <span class="hint">(default: the agent that owns the page)</span></label>
|
|
1921
|
+
<select id="wc-agent"></select>
|
|
1922
|
+
<div class="actions"><button class="primary" onclick="saveWikiCurator()">Save</button><div id="wc-msg" class="msg"></div></div>
|
|
1923
|
+
</div>
|
|
1924
|
+
</details>
|
|
1915
1925
|
<div class="add-form">
|
|
1916
1926
|
<h3>Add a new agent</h3>
|
|
1917
1927
|
<div class="rowf">
|
|
@@ -1932,7 +1942,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
1932
1942
|
</section>
|
|
1933
1943
|
|
|
1934
1944
|
<section id="tab-channels" class="tab">
|
|
1935
|
-
${K({icon:
|
|
1945
|
+
${K({icon:ue.channels,title:"Where your agents show up",lead:"Connect a chat app, and your agents can answer from there. Set up once \u2014 they'll keep working in the background."})}
|
|
1936
1946
|
${oe({persistKey:"channels",bodyHtml:"<b>How does this work?</b> Connect Telegram with a bot token or pair WhatsApp with a QR code. For webhook sources (GitHub, GitLab), use the URL shown in setup. Slack and Discord adapters are not supported in this build."})}
|
|
1937
1947
|
|
|
1938
1948
|
<details class="add-form" style="margin-top:14px;margin-bottom:18px" id="notif-section">
|
|
@@ -2039,7 +2049,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2039
2049
|
</section>
|
|
2040
2050
|
|
|
2041
2051
|
<section id="tab-crons" class="tab">
|
|
2042
|
-
${K({icon:
|
|
2052
|
+
${K({icon:ue.schedules,title:"Schedules",lead:"Make an agent do something on a timer \u2014 no one has to ask. Daily summaries, weekly reports, hourly health checks."})}
|
|
2043
2053
|
${oe({persistKey:"crons",bodyHtml:"<b>What's a good schedule?</b> Anything recurring. A <i>Reports agent</i> sending Monday-morning numbers, a <i>Health agent</i> pinging you at 3am if a server's down, a <i>Standup agent</i> reminding the team. Pick a time below."})}
|
|
2044
2054
|
<div id="cron-list" class="ax-stack" style="margin-bottom:22px"></div>
|
|
2045
2055
|
|
|
@@ -2161,7 +2171,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2161
2171
|
</section>
|
|
2162
2172
|
|
|
2163
2173
|
<section id="tab-webhooks" class="tab">
|
|
2164
|
-
${K({icon:
|
|
2174
|
+
${K({icon:ue.webhooks,title:"Webhooks",lead:"A URL you give to another service. When something happens there \u2014 a PR is merged, an error fires \u2014 they POST to that URL, and we forward it to your agent as a readable message."})}
|
|
2165
2175
|
${oe({persistKey:"webhooks",bodyHtml:`<b>Not sure you need this?</b> If a service you use has a "webhooks" setting (GitHub, Stripe, Sentry, Typeform\u2026), you probably do. It's how those services tell AgentX when something's worth looking at.`})}
|
|
2166
2176
|
<div id="webhook-list" class="ax-stack"></div>
|
|
2167
2177
|
<div class="add-form">
|
|
@@ -2203,7 +2213,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2203
2213
|
</section>
|
|
2204
2214
|
|
|
2205
2215
|
<section id="tab-mesh" class="tab">
|
|
2206
|
-
${K({icon:
|
|
2216
|
+
${K({icon:ue.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."})}
|
|
2207
2217
|
<div id="mesh-hero" class="ax-mesh-hero"></div>
|
|
2208
2218
|
${oe({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."})}
|
|
2209
2219
|
${$t({label:"Connected peers"})}
|
|
@@ -2233,7 +2243,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2233
2243
|
</section>
|
|
2234
2244
|
|
|
2235
2245
|
<section id="tab-business" class="tab">
|
|
2236
|
-
${K({icon:
|
|
2246
|
+
${K({icon:ue.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."})}
|
|
2237
2247
|
${oe({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.'})}
|
|
2238
2248
|
|
|
2239
2249
|
<div class="ax-stack" style="margin-top:14px">
|
|
@@ -2321,7 +2331,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2321
2331
|
</section>
|
|
2322
2332
|
|
|
2323
2333
|
<section id="tab-boards-cfg" class="tab">
|
|
2324
|
-
${K({icon:
|
|
2334
|
+
${K({icon:ue.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."})}
|
|
2325
2335
|
${oe({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.'})}
|
|
2326
2336
|
|
|
2327
2337
|
<div class="ax-stack" style="margin-top:14px">
|
|
@@ -2346,7 +2356,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2346
2356
|
</section>
|
|
2347
2357
|
|
|
2348
2358
|
<section id="tab-actions" class="tab">
|
|
2349
|
-
${K({icon:
|
|
2359
|
+
${K({icon:ue.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."})}
|
|
2350
2360
|
${oe({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."})}
|
|
2351
2361
|
|
|
2352
2362
|
<div class="ax-stack" style="margin-top:14px">
|
|
@@ -2402,7 +2412,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2402
2412
|
</section>
|
|
2403
2413
|
|
|
2404
2414
|
<section id="tab-tokens" class="tab">
|
|
2405
|
-
${K({icon:
|
|
2415
|
+
${K({icon:ue.tokens,title:"Access tokens",lead:"Passwords, but for software. Anything that wants to talk to AgentX from outside (a Slack bridge, another AgentX machine, a script) uses one."})}
|
|
2406
2416
|
${oe({persistKey:"tokens",bodyHtml:"<b>Tokens get scopes.</b> A scope is what the token is allowed to do. Give the narrowest one that works \u2014 a Slack bridge only needs to send messages, it doesn't need to edit settings. You can't recover a token after you close this page, so copy it immediately."})}
|
|
2407
2417
|
<div id="token-list" class="ax-stack"></div>
|
|
2408
2418
|
<div class="add-form">
|
|
@@ -2422,7 +2432,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2422
2432
|
</section>
|
|
2423
2433
|
|
|
2424
2434
|
<section id="tab-advanced" class="tab">
|
|
2425
|
-
${K({icon:
|
|
2435
|
+
${K({icon:ue.advanced,title:"Raw configuration",lead:"Everything on the other tabs writes to this file. Edit here for bulk changes, diffs, or fields we haven't put in the UI yet. Saving creates a timestamped backup."})}
|
|
2426
2436
|
${oe({persistKey:"advanced",bodyHtml:`<b>Safe to look, careful editing.</b> We've pretty-printed and annotated each section so you can read it. Click any <span class="mono" style="color:var(--ax-muted)">\u25B8</span> to fold. Switch to <b>Edit</b> to change values \u2014 invalid JSON is refused before saving.`})}
|
|
2427
2437
|
|
|
2428
2438
|
<div class="ax-jv-toolbar">
|
|
@@ -2449,7 +2459,7 @@ ${zd}</script>`})}var Nd=`
|
|
|
2449
2459
|
<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>
|
|
2450
2460
|
</section>
|
|
2451
2461
|
</main>
|
|
2452
|
-
`,
|
|
2462
|
+
`,zd=`
|
|
2453
2463
|
|
|
2454
2464
|
/* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
|
|
2455
2465
|
nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
|
|
@@ -2657,7 +2667,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
|
|
|
2657
2667
|
.peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
|
|
2658
2668
|
padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
|
|
2659
2669
|
.peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
|
|
2660
|
-
`,
|
|
2670
|
+
`,qd=`
|
|
2661
2671
|
const $ = (id) => document.getElementById(id);
|
|
2662
2672
|
let state = null;
|
|
2663
2673
|
|
|
@@ -2712,6 +2722,7 @@ async function refresh() {
|
|
|
2712
2722
|
wireBoardsCfgHandlers();
|
|
2713
2723
|
renderNotifications();
|
|
2714
2724
|
renderWikiNotes();
|
|
2725
|
+
renderWikiCurator();
|
|
2715
2726
|
renderScreen();
|
|
2716
2727
|
renderActions();
|
|
2717
2728
|
wireActionsHandlers();
|
|
@@ -3323,6 +3334,28 @@ function wireBoardsCfgHandlers() {
|
|
|
3323
3334
|
});
|
|
3324
3335
|
}
|
|
3325
3336
|
|
|
3337
|
+
// ---------------- Wiki page curator (#818) ----------------
|
|
3338
|
+
|
|
3339
|
+
function renderWikiCurator() {
|
|
3340
|
+
const c = state.wikiCurator || { enabled: true, agent: '' };
|
|
3341
|
+
if ($('wc-enabled')) $('wc-enabled').checked = c.enabled !== false;
|
|
3342
|
+
const sel = $('wc-agent');
|
|
3343
|
+
if (!sel) return;
|
|
3344
|
+
const opts = ['<option value="">The page owner</option>'].concat((state.agents || []).map(function (a) {
|
|
3345
|
+
return '<option value="' + escapeHtml(a.id) + '">' + escapeHtml(a.name ? a.name + ' (' + a.id + ')' : a.id) + '</option>';
|
|
3346
|
+
}));
|
|
3347
|
+
sel.innerHTML = opts.join('');
|
|
3348
|
+
sel.value = c.agent || '';
|
|
3349
|
+
}
|
|
3350
|
+
|
|
3351
|
+
window.saveWikiCurator = async function() {
|
|
3352
|
+
try {
|
|
3353
|
+
await req('POST', '/api/admin/wiki/curator', { enabled: $('wc-enabled').checked, agent: $('wc-agent').value });
|
|
3354
|
+
showMsg($('wc-msg'), 'ok', 'Saved');
|
|
3355
|
+
await refresh();
|
|
3356
|
+
} catch (e) { showMsg($('wc-msg'), 'err', e.message); }
|
|
3357
|
+
};
|
|
3358
|
+
|
|
3326
3359
|
// ---------------- Notifications + Webhook triggers ----------------
|
|
3327
3360
|
|
|
3328
3361
|
// ---------------- Wiki notes inbox (#825) ----------------
|
|
@@ -5349,6 +5382,11 @@ const JV_HINTS = {
|
|
|
5349
5382
|
'crons[].schedule': 'standard five-field cron',
|
|
5350
5383
|
'mesh.peers[].url': 'full URL including port',
|
|
5351
5384
|
'tokens[].scopes': 'permissions this token grants',
|
|
5385
|
+
'signals.enabled': 'allow stopping a running task with a resume plan',
|
|
5386
|
+
'signals.windDownSeconds': 'time a stopped agent gets to write its resume plan',
|
|
5387
|
+
'signals.allowAgents': 'agents that may stop or resume any task ("*" for all)',
|
|
5388
|
+
'signals.allowPeers': 'mesh nodes whose stop and resume signals are accepted',
|
|
5389
|
+
'signals.maxPerRoot': 'loop brake: most signals one request may carry per day',
|
|
5352
5390
|
};
|
|
5353
5391
|
|
|
5354
5392
|
let __jvMode = 'tree';
|
|
@@ -5598,11 +5636,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
|
|
|
5598
5636
|
})();
|
|
5599
5637
|
|
|
5600
5638
|
refresh();
|
|
5601
|
-
`;function hs(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(us({peers:a,localToken:n}))}async function gs(t,e){let a=qa();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function xs(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await rp(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Wd(t),r={"GET /api/admin/state":()=>Xd(),"POST /api/admin/agents":()=>Zd(n),"PATCH /api/admin/agents":()=>ep(n),"DELETE /api/admin/agents":()=>tp(n),"POST /api/admin/agents/access":()=>Kd(n),"POST /api/admin/channels/telegram":()=>ap(n),"DELETE /api/admin/channels/telegram":()=>Tp(n),"POST /api/admin/channels/telegram/toggle":()=>Ap(n),"POST /api/admin/crons":()=>Cp(n),"DELETE /api/admin/crons":()=>Ip(n),"POST /api/admin/config/raw":()=>Mp(n),"GET /api/admin/tokens":()=>Jd(),"POST /api/admin/tokens":()=>Vd(n),"DELETE /api/admin/tokens":()=>Yd(n),"POST /api/admin/agents/test":()=>Qd(n),"POST /api/admin/agents/integrations":()=>dp(n),"DELETE /api/admin/agents/integrations":()=>pp(n),"PATCH /api/admin/agents/integrations":()=>up(n),"PATCH /api/admin/channels/telegram":()=>np(n),"POST /api/admin/channels/slack":()=>vp(n),"POST /api/admin/channels/slack/toggle":()=>yp(n),"POST /api/admin/channels/discord":()=>wp(n),"POST /api/admin/channels/discord/toggle":()=>kp(n),"POST /api/admin/channels/gitlab":()=>_p(n),"POST /api/admin/channels/gitlab/toggle":()=>Sp(n),"POST /api/admin/channels/request-status":()=>eo(n),"GET /api/admin/channels/whatsapp/state":()=>We("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>We("/webrtc/history"),"POST /api/admin/actions":()=>Fp(n),"DELETE /api/admin/actions":()=>Up(n),"POST /api/admin/actions/run":()=>Wp(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":()=>he("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Ep(n),"POST /api/admin/webhooks":()=>mp(n),"PATCH /api/admin/webhooks":()=>fp(n),"DELETE /api/admin/webhooks":()=>bp(n),"POST /api/admin/whatsapp-triage":()=>ls(n),"POST /api/admin/whatsapp-triage/rules":()=>cs(n),"PATCH /api/admin/whatsapp-triage/rules":()=>ds(n),"DELETE /api/admin/whatsapp-triage/rules":()=>ps(n),"POST /api/admin/mesh/peers":()=>hp(n),"DELETE /api/admin/mesh/peers":()=>gp(n),"POST /api/admin/mesh/toggle":()=>xp(n),"GET /api/admin/files":()=>op(t),"GET /api/admin/files/read":()=>sp(t),"PUT /api/admin/files":()=>ip(n),"POST /api/admin/files/skill":()=>lp(n),"DELETE /api/admin/files/skill":()=>cp(n),"POST /api/admin/business/orgchart":()=>Lp(n),"DELETE /api/admin/business/orgchart":()=>Rp(n),"POST /api/admin/business/project":()=>Pp(n),"DELETE /api/admin/business/project":()=>Op(n),"POST /api/admin/business/client":()=>$p(n),"DELETE /api/admin/business/client":()=>jp(n),"POST /api/admin/business/contact":()=>Np(n),"DELETE /api/admin/business/contact":()=>Dp(n),"POST /api/admin/boards":()=>Hp(n),"DELETE /api/admin/boards":()=>Bp(n),"POST /api/admin/boards/columns":()=>zp(n),"DELETE /api/admin/boards/columns":()=>qp(n),"POST /api/admin/notifications":()=>Xp(n),"POST /api/admin/screen":()=>Jp(n),"POST /api/admin/wiki-notes":()=>Kp(n),"GET /api/admin/wiki-notes/list":()=>We("/wiki/notes?status=all&limit=20"),"POST /api/admin/webhooks/triggers":()=>Vp(n),"POST /api/admin/mesh/health":()=>Gp(n),"GET /api/admin/projects":()=>We("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>he("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>he("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>he("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>he("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>he("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>he("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>he("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>he("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Ba(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();Ba(e,200,i)}catch(n){Ba(e,400,{error:n.message||"admin op failed"})}}function Ba(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Wd(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 Gd(t){let e=Ge(process.cwd(),t);if(!Vt(e))return[];let a=[];for(let n of Ud(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(ms(Ge(e,n.name),"utf-8")))}catch{}return a}function qa(){let t=Ge(process.cwd(),"agentx.json");return Vt(t)?JSON.parse(ms(t,"utf-8")):null}function Xd(){let t=qa();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([x,u])=>({id:x,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",wikiAbsorb:u.wiki?.absorb?.enabled!==!1,integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(f=>{let w=f.credentials||{},y={};for(let[T,g]of Object.entries(w))typeof g=="string"&&/^[A-Z][A-Z0-9_]*$/.test(g)?y[T]=process.env[g]?"set":"unset":typeof g=="string"&&(y[T]="literal");return{kind:f.kind,label:f.label,enabled:f.enabled!==!1,credentials:w,credStatus:y,metadata:f.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([x,u])=>({id:x,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(([x,u])=>({id:x,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(x=>({id:x.id,source:x.source,agentId:x.agentId,secretEnv:x.secretEnv||"",description:x.description||"",enabled:x.enabled!==!1,triggers:x.triggers&&typeof x.triggers=="object"?x.triggers:{},defaultWorkflow:x.defaultWorkflow||""})):[],d={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(x=>({url:x.url,name:x.name,hasToken:!!x.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},p=t.dashboard?.daemonUrl||"http://localhost:18800",m=t.business||{},h={enabled:!!m.enabled,timezone:m.timezone||"UTC",orgChart:m.orgChart||{},projects:Array.isArray(m.projects)?m.projects:[],contactMap:Array.isArray(m.contactMap)?m.contactMap:[],clients:m.clients&&typeof m.clients=="object"?m.clients:{}},S=t.notifications||{},v={longTaskThreshold:S.longTaskThreshold??30,destination:S.destination||null,on:{taskComplete:S.on?.taskComplete!==!1,taskError:S.on?.taskError!==!1,taskQueued:!!S.on?.taskQueued},local:nr(S.local),ntfy:ro(t.channels?.ntfy)},E=[];try{E=Gd(".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,f)=>u.id.localeCompare(f.id))}catch{}let b=(Array.isArray(t.boards)?t.boards:[]).map(x=>({id:x.id,name:x.name,source:x.source||{type:"gitlab",projects:[]},primaryToolLabel:x.primaryToolLabel||"",timeRangeDays:x.timeRangeDays??30,closedWindowDays:x.closedWindowDays??30,columns:Array.isArray(x.columns)?x.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,requestStatus:Zr(t),whatsappTriage:is(t),crons:l,webhooks:c,mesh:d,daemonUrl:p,nodeName:t.node?.name,business:h,boards:b,notifications:v,screen:$r(t.screen),wikiNotes:ao(t.wikiNotes),actions:E}}function Kd(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 Jd(){return new G().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 Vd(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 G().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function Yd(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new G().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function Qd(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 d=X();r=d.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=d.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 Zd(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=vs(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(d=>{if(d.agents=d.agents||{},d.agents[e])throw new Error(`Agent "${e}" already exists.`);let p={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(p.model=o),s&&(p.systemPrompt=s.slice(0,400)),d.agents[e]=p,`added agent "${e}"`}),c=Ge(i,"CLAUDE.md");if(!Vt(c))try{qd(i,{recursive:!0}),fs(c,`# ${a}
|
|
5639
|
+
`;function hs(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(us({peers:a,localToken:n}))}async function gs(t,e){let a=Fa();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function xs(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await op(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Gd(t),r={"GET /api/admin/state":()=>Kd(),"POST /api/admin/agents":()=>ep(n),"PATCH /api/admin/agents":()=>tp(n),"DELETE /api/admin/agents":()=>ap(n),"POST /api/admin/agents/access":()=>Jd(n),"POST /api/admin/channels/telegram":()=>np(n),"DELETE /api/admin/channels/telegram":()=>Ap(n),"POST /api/admin/channels/telegram/toggle":()=>Cp(n),"POST /api/admin/crons":()=>Ip(n),"DELETE /api/admin/crons":()=>Mp(n),"POST /api/admin/config/raw":()=>Lp(n),"GET /api/admin/tokens":()=>Vd(),"POST /api/admin/tokens":()=>Yd(n),"DELETE /api/admin/tokens":()=>Qd(n),"POST /api/admin/agents/test":()=>Zd(n),"POST /api/admin/agents/integrations":()=>pp(n),"DELETE /api/admin/agents/integrations":()=>up(n),"PATCH /api/admin/agents/integrations":()=>mp(n),"PATCH /api/admin/channels/telegram":()=>rp(n),"POST /api/admin/channels/slack":()=>yp(n),"POST /api/admin/channels/slack/toggle":()=>wp(n),"POST /api/admin/channels/discord":()=>kp(n),"POST /api/admin/channels/discord/toggle":()=>_p(n),"POST /api/admin/channels/gitlab":()=>Sp(n),"POST /api/admin/channels/gitlab/toggle":()=>Ep(n),"POST /api/admin/channels/request-status":()=>eo(n),"GET /api/admin/channels/whatsapp/state":()=>We("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>We("/webrtc/history"),"POST /api/admin/actions":()=>Up(n),"DELETE /api/admin/actions":()=>Wp(n),"POST /api/admin/actions/run":()=>Gp(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":()=>he("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Tp(n),"POST /api/admin/webhooks":()=>fp(n),"PATCH /api/admin/webhooks":()=>hp(n),"DELETE /api/admin/webhooks":()=>vp(n),"POST /api/admin/whatsapp-triage":()=>ls(n),"POST /api/admin/whatsapp-triage/rules":()=>cs(n),"PATCH /api/admin/whatsapp-triage/rules":()=>ds(n),"DELETE /api/admin/whatsapp-triage/rules":()=>ps(n),"POST /api/admin/mesh/peers":()=>gp(n),"DELETE /api/admin/mesh/peers":()=>xp(n),"POST /api/admin/mesh/toggle":()=>bp(n),"GET /api/admin/files":()=>sp(t),"GET /api/admin/files/read":()=>ip(t),"PUT /api/admin/files":()=>lp(n),"POST /api/admin/files/skill":()=>cp(n),"DELETE /api/admin/files/skill":()=>dp(n),"POST /api/admin/business/orgchart":()=>Rp(n),"DELETE /api/admin/business/orgchart":()=>Pp(n),"POST /api/admin/business/project":()=>$p(n),"DELETE /api/admin/business/project":()=>Np(n),"POST /api/admin/business/client":()=>jp(n),"DELETE /api/admin/business/client":()=>Op(n),"POST /api/admin/business/contact":()=>Dp(n),"DELETE /api/admin/business/contact":()=>Hp(n),"POST /api/admin/boards":()=>Bp(n),"DELETE /api/admin/boards":()=>zp(n),"POST /api/admin/boards/columns":()=>qp(n),"DELETE /api/admin/boards/columns":()=>Fp(n),"POST /api/admin/notifications":()=>Jp(n),"POST /api/admin/wiki/curator":()=>Kp(n),"POST /api/admin/screen":()=>Yp(n),"POST /api/admin/wiki-notes":()=>Vp(n),"GET /api/admin/wiki-notes/list":()=>We("/wiki/notes?status=all&limit=20"),"POST /api/admin/webhooks/triggers":()=>Qp(n),"POST /api/admin/mesh/health":()=>Xp(n),"GET /api/admin/projects":()=>We("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>he("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>he("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>he("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>he("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>he("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>he("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>he("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>he("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){za(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();za(e,200,i)}catch(n){za(e,400,{error:n.message||"admin op failed"})}}function za(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Gd(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 Xd(t){let e=Ge(process.cwd(),t);if(!Vt(e))return[];let a=[];for(let n of Wd(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(ms(Ge(e,n.name),"utf-8")))}catch{}return a}function Fa(){let t=Ge(process.cwd(),"agentx.json");return Vt(t)?JSON.parse(ms(t,"utf-8")):null}function Kd(){let t=Fa();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([h,u])=>({id:h,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",wikiAbsorb:u.wiki?.absorb?.enabled!==!1,integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(f=>{let y=f.credentials||{},v={};for(let[E,x]of Object.entries(y))typeof x=="string"&&/^[A-Z][A-Z0-9_]*$/.test(x)?v[E]=process.env[x]?"set":"unset":typeof x=="string"&&(v[E]="literal");return{kind:f.kind,label:f.label,enabled:f.enabled!==!1,credentials:y,credStatus:v,metadata:f.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([h,u])=>({id:h,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(([h,u])=>({id:h,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(h=>({id:h.id,source:h.source,agentId:h.agentId,secretEnv:h.secretEnv||"",description:h.description||"",enabled:h.enabled!==!1,triggers:h.triggers&&typeof h.triggers=="object"?h.triggers:{},defaultWorkflow:h.defaultWorkflow||""})):[],d={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(h=>({url:h.url,name:h.name,hasToken:!!h.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},p=t.dashboard?.daemonUrl||"http://localhost:18800",m=t.business||{},g={enabled:!!m.enabled,timezone:m.timezone||"UTC",orgChart:m.orgChart||{},projects:Array.isArray(m.projects)?m.projects:[],contactMap:Array.isArray(m.contactMap)?m.contactMap:[],clients:m.clients&&typeof m.clients=="object"?m.clients:{}},_=t.notifications||{},b={longTaskThreshold:_.longTaskThreshold??30,destination:_.destination||null,on:{taskComplete:_.on?.taskComplete!==!1,taskError:_.on?.taskError!==!1,taskQueued:!!_.on?.taskQueued},local:nr(_.local),ntfy:ro(t.channels?.ntfy)},S=[];try{S=Xd(".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,f)=>u.id.localeCompare(f.id))}catch{}let T=(Array.isArray(t.boards)?t.boards:[]).map(h=>({id:h.id,name:h.name,source:h.source||{type:"gitlab",projects:[]},primaryToolLabel:h.primaryToolLabel||"",timeRangeDays:h.timeRangeDays??30,closedWindowDays:h.closedWindowDays??30,columns:Array.isArray(h.columns)?h.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,requestStatus:Zr(t),whatsappTriage:is(t),crons:l,webhooks:c,mesh:d,daemonUrl:p,nodeName:t.node?.name,business:g,boards:T,notifications:b,screen:$r(t.screen),wikiNotes:ao(t.wikiNotes),actions:S,wikiCurator:ys(t)}}function Jd(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 Vd(){return new G().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 Yd(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 G().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function Qd(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new G().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function Zd(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 d=X();r=d.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=d.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 ep(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=vs(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(d=>{if(d.agents=d.agents||{},d.agents[e])throw new Error(`Agent "${e}" already exists.`);let p={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(p.model=o),s&&(p.systemPrompt=s.slice(0,400)),d.agents[e]=p,`added agent "${e}"`}),c=Ge(i,"CLAUDE.md");if(!Vt(c))try{Fd(i,{recursive:!0}),fs(c,`# ${a}
|
|
5602
5640
|
|
|
5603
5641
|
${s||"You are "+a+"."}
|
|
5604
|
-
`)}catch{}return{summary:l}}function ep(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=vs(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),typeof a.wikiAbsorb=="boolean"&&Ot(o,a.wikiAbsorb),`updated agent "${e}"`});return{summary:n}}function tp(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 ap(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 np(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}=Fa(),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 he(t,e){let{url:a,headers:n}=Fa(),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 rp(t,e){try{let{url:a,headers:n}=Fa(),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 Fa(){let t="http://127.0.0.1:18800",e={};try{let a=X();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function at(t){let a=qa()?.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 za(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function op(t){let e=za(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=Be(at(e));return{agentId:e,...a}}function sp(t){let e=za(t,"agent").trim(),a=za(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Ct(at(e),a)}function ip(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=It(at(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function lp(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=Mt(at(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function cp(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=Lt(at(e),a);return{summary:`removed skill "${a}"`,...n}}function dp(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 pp(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 up(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(d=>d.kind===a&&d.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 bs=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function mp(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(!bs.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(p=>p.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(d=>d.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 fp(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"&&bs.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 hp(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 gp(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 xp(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 bp(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 vp(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 yp(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 wp(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 kp(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 _p(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 Sp(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 Ep(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-6AQDHQI4.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 Tp(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 Ap(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 Cp(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 Ip(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 Mp(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(Vt(n))try{Fd(n,r)}catch{}fs(n,JSON.stringify(a,null,2)+`
|
|
5605
|
-
`,"utf-8");try{let s=X().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 vs(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function Lp(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 Rp(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 Pp(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 $p(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 jp(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 Op(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 Np(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 Dp(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 Hp(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(p=>p.id===e),d={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(d.primaryToolLabel=r),c>=0){let p=l.boards[c];return l.boards[c]={...p,...d,columns:p.columns,labels:p.labels},`board "${e}" updated`}return l.boards.push(d),`board "${e}" added`});return{summary:i}}async function Bp(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 zp(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(p=>p.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 d=l.columns.findIndex(p=>p.id===a);return d>=0?(l.columns[d]={...l.columns[d],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function qp(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 Fp(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 Up(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 Wp(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 Gp(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 Xp(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=rr(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=oo(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 Kp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let e={};"enabled"in t&&(e.enabled=!!t.enabled),"inbox"in t&&(e.inbox=String(t.inbox??"")),"crons"in t&&(e.crons=Array.isArray(t.crons)?t.crons.map(String):String(t.crons??"").split(",")),"absorbAgent"in t&&(e.absorbAgent=String(t.absorbAgent??"")),"maxNotesPerRun"in t&&(e.maxNotesPerRun=Number(t.maxNotesPerRun)),"maxDeferrals"in t&&(e.maxDeferrals=Number(t.maxDeferrals));let{summary:a}=C(n=>no(n,e));return{summary:a}}async function Jp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=jr(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Vp(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}}ft();import{resolve as Zp}from"path";function ys(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
5642
|
+
`)}catch{}return{summary:l}}function tp(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=vs(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),typeof a.wikiAbsorb=="boolean"&&Ot(o,a.wikiAbsorb),`updated agent "${e}"`});return{summary:n}}function ap(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 np(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 rp(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}=Ua(),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 he(t,e){let{url:a,headers:n}=Ua(),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 op(t,e){try{let{url:a,headers:n}=Ua(),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 Ua(){let t="http://127.0.0.1:18800",e={};try{let a=X();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function at(t){let a=Fa()?.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 qa(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function sp(t){let e=qa(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=Be(at(e));return{agentId:e,...a}}function ip(t){let e=qa(t,"agent").trim(),a=qa(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Ct(at(e),a)}function lp(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=It(at(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function cp(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=Mt(at(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function dp(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=Lt(at(e),a);return{summary:`removed skill "${a}"`,...n}}function pp(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 up(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 mp(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(d=>d.kind===a&&d.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 bs=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function fp(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(!bs.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(p=>p.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(d=>d.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 hp(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"&&bs.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 gp(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 xp(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 bp(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 vp(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 yp(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 wp(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 kp(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 _p(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 Sp(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 Ep(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 Tp(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-PVXLF2VJ.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 Ap(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 Cp(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 Ip(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 Mp(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 Lp(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(Vt(n))try{Ud(n,r)}catch{}fs(n,JSON.stringify(a,null,2)+`
|
|
5643
|
+
`,"utf-8");try{let s=X().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 vs(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function Rp(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 Pp(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 $p(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 jp(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 Op(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 Np(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 Dp(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 Hp(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 Bp(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(p=>p.id===e),d={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(d.primaryToolLabel=r),c>=0){let p=l.boards[c];return l.boards[c]={...p,...d,columns:p.columns,labels:p.labels},`board "${e}" updated`}return l.boards.push(d),`board "${e}" added`});return{summary:i}}async function zp(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 qp(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(p=>p.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 d=l.columns.findIndex(p=>p.id===a);return d>=0?(l.columns[d]={...l.columns[d],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Fp(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 Up(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 Wp(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 Gp(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 Xp(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}}function ys(t){let e=t?.wiki?.curator||{};return{enabled:e.enabled!==!1,agent:typeof e.agent=="string"?e.agent:""}}function Kp(t){let{summary:e}=C(a=>{if(a.wiki=a.wiki||{},a.wiki.curator=a.wiki.curator||{},t&&"enabled"in t&&(a.wiki.curator.enabled=!!t.enabled),t&&"agent"in t){let r=String(t.agent||"").trim();if(!r)delete a.wiki.curator.agent;else if(a.agents?.[r])a.wiki.curator.agent=r;else throw new Error(`no agent "${r}"`)}let n=ys(a);return`wiki.curator ${n.enabled?"on":"off"}, answered by ${n.agent||"the page owner"}`});return{summary:e}}async function Jp(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=rr(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=oo(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 Vp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let e={};"enabled"in t&&(e.enabled=!!t.enabled),"inbox"in t&&(e.inbox=String(t.inbox??"")),"crons"in t&&(e.crons=Array.isArray(t.crons)?t.crons.map(String):String(t.crons??"").split(",")),"absorbAgent"in t&&(e.absorbAgent=String(t.absorbAgent??"")),"maxNotesPerRun"in t&&(e.maxNotesPerRun=Number(t.maxNotesPerRun)),"maxDeferrals"in t&&(e.maxDeferrals=Number(t.maxDeferrals));let{summary:a}=C(n=>no(n,e));return{summary:a}}async function Yp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=jr(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Qp(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}}ft();import{resolve as tu}from"path";function ws(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
5606
5644
|
|
|
5607
5645
|
<div id="disabled-banner" class="banner warn" style="display:none">
|
|
5608
5646
|
<b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
|
|
@@ -5657,7 +5695,7 @@ ${s||"You are "+a+"."}
|
|
|
5657
5695
|
<h2>Recent classifications</h2>
|
|
5658
5696
|
<p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
|
|
5659
5697
|
<div id="recent"></div>
|
|
5660
|
-
</section>`;return I({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
5698
|
+
</section>`;return I({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Zp,scripts:`${e}<script>${eu}</script>`})}var Zp=`
|
|
5661
5699
|
main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
|
|
5662
5700
|
h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
|
|
5663
5701
|
.grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
|
|
@@ -5761,7 +5799,7 @@ details {
|
|
|
5761
5799
|
border-radius: 4px; padding: 8px 12px; margin-top: 8px;
|
|
5762
5800
|
}
|
|
5763
5801
|
details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
|
|
5764
|
-
details[open] summary { margin-bottom: 8px; }`,
|
|
5802
|
+
details[open] summary { margin-bottom: 8px; }`,eu=`
|
|
5765
5803
|
const $ = (id) => document.getElementById(id);
|
|
5766
5804
|
const state = { schema: null, nodes: [], pending: [], recent: [] };
|
|
5767
5805
|
|
|
@@ -5981,7 +6019,7 @@ $('btn-save-schema').addEventListener('click', async () => {
|
|
|
5981
6019
|
$('btn-reload-schema').addEventListener('click', refresh);
|
|
5982
6020
|
|
|
5983
6021
|
refresh();
|
|
5984
|
-
`;function
|
|
6022
|
+
`;function _s(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ws({peers:a,localToken:n}))}async function Ss(t,e,a){try{let n=t.method==="GET"?void 0:await du(t),r=au(),o={"GET /api/admin/graph/state":()=>nu(r),"POST /api/admin/graph/classifications/approve":()=>ru(r,n),"POST /api/admin/graph/classifications/reject":()=>ou(r,n),"POST /api/admin/graph/nodes":()=>su(r,n),"PATCH /api/admin/graph/nodes":()=>iu(r,n),"DELETE /api/admin/graph/nodes":()=>lu(r,n),"PUT /api/admin/graph/schema":()=>cu(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){Wa(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();Wa(e,200,l)}catch(n){Wa(e,400,{error:n?.message||"graph op failed"})}}function au(){let t=X(),e=tu(process.cwd(),t.graph.baseDir);return new qn({baseDir:e})}function nu(t){let e=X(),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 ru(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Es(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=Ga(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function ou(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Es(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Es(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 su(t,e){let a=ks(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?ks(String(e.parentId)):null,o=Ga({[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 iu(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=Ga({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function lu(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function cu(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 Ga(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 ks(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function Wa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function du(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 Ts=`
|
|
5985
6023
|
<section class="apv__req" id="req-section" aria-labelledby="req-h">
|
|
5986
6024
|
<h2 id="req-h">Open requests <span id="req-n"></span></h2>
|
|
5987
6025
|
<p class="apv__lead">What you asked agents for that is not finished, oldest first. Reply, hand it to an agent, close it as done, or drop it. Nothing leaves this list by getting old.</p>
|
|
@@ -6003,7 +6041,7 @@ refresh();
|
|
|
6003
6041
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
6004
6042
|
</form>
|
|
6005
6043
|
</details>
|
|
6006
|
-
</section>`,
|
|
6044
|
+
</section>`,As=`
|
|
6007
6045
|
.apv__req { margin-top: 32px; border-top: 1px solid var(--ax-border); padding-top: 16px; }
|
|
6008
6046
|
.apv__req h2 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
|
|
6009
6047
|
.apv__req h2 span { color: var(--ax-muted); font-family: var(--ax-mono); font-size: 12px; font-weight: 400; }
|
|
@@ -6031,7 +6069,7 @@ refresh();
|
|
|
6031
6069
|
.apv__plan .is-done { color: var(--ax-ok, inherit); }
|
|
6032
6070
|
.apv__plan .is-blocked { color: var(--ax-err); }
|
|
6033
6071
|
.apv__plan small { display: block; color: var(--ax-muted); }
|
|
6034
|
-
`,
|
|
6072
|
+
`,Cs=`
|
|
6035
6073
|
(function(){
|
|
6036
6074
|
var STATE = { in_progress: 'In progress', waiting_owner: 'Waiting on you', waiting_other: 'Waiting on another agent', needs_attention: 'Needs attention' };
|
|
6037
6075
|
function $(id){ return document.getElementById(id); }
|
|
@@ -6196,7 +6234,7 @@ function busy(){
|
|
|
6196
6234
|
}
|
|
6197
6235
|
setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) load(); }, 60000);
|
|
6198
6236
|
})();
|
|
6199
|
-
`;function
|
|
6237
|
+
`;function Is(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div class="apv">
|
|
6200
6238
|
<header class="apv__head">
|
|
6201
6239
|
<div>
|
|
6202
6240
|
<h1>Approvals</h1>
|
|
@@ -6218,7 +6256,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) l
|
|
|
6218
6256
|
<ol id="apv-list" class="apv__list" aria-label="Waiting for you"></ol>
|
|
6219
6257
|
<p id="apv-snoozed" class="apv__foot"></p>
|
|
6220
6258
|
|
|
6221
|
-
${
|
|
6259
|
+
${Ts}
|
|
6222
6260
|
|
|
6223
6261
|
<details class="apv__settings" id="apv-settings">
|
|
6224
6262
|
<summary>Settings: expiry, later, daily digest</summary>
|
|
@@ -6233,7 +6271,7 @@ ${Es}
|
|
|
6233
6271
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
6234
6272
|
</form>
|
|
6235
6273
|
</details>
|
|
6236
|
-
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
6274
|
+
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:pu+As,scripts:`${e}<script>${uu}</script><script>${Cs}</script>`})}var pu=`
|
|
6237
6275
|
.apv { max-width: 860px; margin: 0 auto; padding: 20px 16px 64px; color: var(--ax-text); }
|
|
6238
6276
|
.apv__head { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; }
|
|
6239
6277
|
.apv__head h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
@@ -6290,7 +6328,7 @@ ${Es}
|
|
|
6290
6328
|
@media (max-width: 560px) {
|
|
6291
6329
|
.apv__acts .ax-btn { flex: 1 1 0; }
|
|
6292
6330
|
}
|
|
6293
|
-
`,
|
|
6331
|
+
`,uu=`
|
|
6294
6332
|
(function(){
|
|
6295
6333
|
var state = { items: [], snoozed: 0, kind: '', showAll: false, popup: false };
|
|
6296
6334
|
var LABEL = { card: 'Card', schedule: 'Schedule', memory: 'Memory fact', wiki: 'Wiki lesson', whatsapp: 'WhatsApp reply', request: 'Request' };
|
|
@@ -6514,7 +6552,7 @@ $('apv-form').addEventListener('submit', async function(ev){
|
|
|
6514
6552
|
load();
|
|
6515
6553
|
setInterval(function(){ if (document.visibilityState === 'visible' && !document.querySelector('.apv__item:focus-within, .apv__item[data-touched]')) load(); }, 60000);
|
|
6516
6554
|
})();
|
|
6517
|
-
`;import{existsSync as
|
|
6555
|
+
`;import{existsSync as mu,readFileSync as fu}from"fs";var Me="/api/admin/approvals/requests";function Ms(t){let e=Kn(t);if(!mu(e))return[];try{let a=JSON.parse(fu(e,"utf-8"))?.agents??{};return Object.entries(a).map(([n,r])=>({id:n,name:typeof r?.name=="string"&&r.name?r.name:n}))}catch{return[]}}var Yt=t=>typeof t=="string"?t.split(",").map(e=>e.trim()).filter(Boolean):void 0;async function Ls(t,e,a,n){try{return await hu(t,e,a,n)}catch(r){return{status:400,body:{error:String(r?.message??r).slice(0,300)}}}}async function hu(t,e,a,n){if(t==="GET"&&e===Me){let o=St(n);return{status:200,body:{items:o?o.listOpen().map(s=>gr(s,o,mr(n))):[],agents:Ms(n.configPath),settings:_t(n.configPath)}}}let r=e===`${Me}/reply`?"reply":e===`${Me}/handoff`?"handoff":null;if(t==="POST"&&r){let o=typeof a.id=="string"?a.id:"",s=r==="reply"?a.text:a.note,i=typeof s=="string"?s.trim():"";if(!o||r==="reply"&&!i)return{status:400,body:{error:r==="reply"?"send { id, text }":"send { id, agentId, note? }"}};let l=St(n),c=l?.get(o);if(!l||!c||c.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let d=r==="reply"?c.agentId:typeof a.agentId=="string"?a.agentId:"",p=Ms(n.configPath).find(g=>g.id===d);if(r==="handoff"&&!p)return{status:400,body:{error:`"${d}" is not an agent on this node`}};if(!_t(n.configPath).enabled)return{status:409,body:{error:"Requests are off, so nothing would tell the agent. Turn them on in the settings below."}};if(!l.handOff(o,d,i,n.now??Date.now()))return{status:409,body:{error:`${o} is already closed`}};let m=p?.name??d;return{status:200,body:{ok:!0,message:r==="reply"?`Reply sent: ${m} will go on with ${o}`:`${m} has ${o} now and will be told within a minute`}}}if(t==="POST"&&e===`${Me}/close`){let o=typeof a.id=="string"?a.id:"",s=a.action;if(!o||s!=="done"&&s!=="drop")return{status:400,body:{error:"send { id, action: done | drop }"}};let i=St(n),l=i?.get(o);if(!i||!l||l.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let c=s==="done"?typeof a.evidence=="string"&&a.evidence.trim()?a.evidence:"closed by the owner (dashboard)":typeof a.reason=="string"&&a.reason.trim()?a.reason:"dropped by the owner (dashboard)";return i.close(o,s==="done"?"done":"dropped",c,n.now??Date.now())?{status:200,body:{ok:!0,message:s==="done"?`${o} closed as done`:`${o} dropped`}}:{status:409,body:{error:`${o} is already closed`}}}if(t==="POST"&&e===`${Me}/settings`){let o={},s=c=>{let d=a[c];if(d!==void 0){if(typeof d!="number"||!(d>0))throw new Error(`${c} must be a positive number`);return d}};typeof a.enabled=="boolean"&&(o.enabled=a.enabled),o.from=Yt(a.from),o.channels=Yt(a.channels),o.staleAfterHours=s("staleAfterHours"),o.retentionDays=s("retentionDays");let i={};if(typeof a.plansEnabled=="boolean"&&(i.enabled=a.plansEnabled),i.stallMinutes=s("stallMinutes"),a.maxNudges!==void 0){if(typeof a.maxNudges!="number"||!Number.isInteger(a.maxNudges)||a.maxNudges<0)throw new Error("maxNudges must be a whole number, 0 or more");i.maxNudges=a.maxNudges}i.approveKinds=Yt(a.approveKinds),i.disabledAgents=Yt(a.plansOffFor),Object.values(i).some(c=>c!==void 0)&&(o.plans=i);let l=await ur(o,{configPath:n.configPath,reload:n.reload});return l.success?{status:200,body:{ok:!0,settings:_t(n.configPath)}}:{status:400,body:{error:l.error}}}return{status:404,body:{error:"Not found"}}}var gu=["yes","no","later"];function te(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Qt(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 xu(t){let e=t.choice;return{...typeof e=="number"||typeof e=="string"&&e.trim()?{choice:typeof e=="string"?e.trim():e}:{},...typeof t.text=="string"&&t.text.trim()?{text:t.text}:{}}}function Rs(t,e,a){t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(Is({peers:e,localToken:a}))}async function Ps(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 te(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;try{if(a.startsWith(Me)){let i=await Ls(o,a,o==="POST"?await Qt(t):{},s);return te(e,i.status,i.body),!0}if(o==="GET"&&a==="/api/admin/approvals"){let i=Et(s,{includeSnoozed:n.searchParams.get("all")==="1"});return te(e,200,{...i,settings:Ae(s.configPath)}),!0}if(o==="POST"&&a==="/api/admin/approvals/decide"){let i=await Qt(t),l=typeof i.key=="string"?i.key:"",c=i.action;if(!l||!gu.includes(c))return te(e,400,{error:"send { key, action: yes | no | later }"}),!0;let d=Ae(s.configPath),p=await Tt(s,l,c,{note:typeof i.note=="string"?i.note:void 0,force:i.force===!0,laterHours:d.laterHours,by:"operator (dashboard)",...xu(i)});return p.ok?(te(e,200,{ok:!0,message:p.message}),!0):(te(e,409,{error:p.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/popup"){let i=await Qt(t),l=xr(s,typeof i.key=="string"?i.key:"",!!Ae(s.configPath).popup?.enabled);return l.ok?(te(e,200,{ok:!0,message:l.message}),!0):(te(e,409,{error:l.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/settings"){let i=await Qt(t),l={},c=p=>{let m=i[p];if(m!==void 0){if(typeof m!="number"||!(m>0))throw new Error(`${p} must be a positive number`);return m}};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 p=i.destination.trim();if(!p)l.destination=null;else{let m=Wr(p);if(!m)throw new Error("digest destination takes channel:chat id, for example telegram:123456");l.destination=m}}let d=await Gr(l,{configPath:s.configPath,reload:s.reload});return d.success?(te(e,200,{ok:!0,settings:Ae(s.configPath)}),!0):(te(e,400,{error:d.error}),!0)}}catch(i){return te(e,400,{error:String(i?.message??i).slice(0,300)}),!0}return te(e,404,{error:"Not found"}),!0}ya();function $s(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=pe({kicker:"Operations",title:"People",lead:"Everyone who talks to your agents: you, your teammates, your clients and guests. Open a person to see the machines they paired and what they asked for."})+`
|
|
6518
6556
|
<div class="pp">
|
|
6519
6557
|
<div id="pp-msg" class="pp-msg" role="status" aria-live="polite"></div>
|
|
6520
6558
|
<section id="pp-none" class="pp-none" hidden aria-labelledby="pp-none-title">
|
|
@@ -6527,7 +6565,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6527
6565
|
</ol>
|
|
6528
6566
|
</section>
|
|
6529
6567
|
<ol id="pp-list" class="pp-list" aria-label="People"><li class="pp-empty">Loading\u2026</li></ol>
|
|
6530
|
-
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:
|
|
6568
|
+
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:bu,scripts:`${e}<script>${vu}</script>`})}var bu=`
|
|
6531
6569
|
.pp { max-width: 1040px; margin: 0 auto; padding: 0 24px 64px; }
|
|
6532
6570
|
.pp-msg { min-height: 1.4em; margin: 4px 0 8px; font-size: var(--ax-fs-sm); }
|
|
6533
6571
|
.pp-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -6568,7 +6606,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6568
6606
|
.pp-text { overflow-wrap: anywhere; }
|
|
6569
6607
|
.pp-meta { margin-top: 2px; display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: var(--ax-fs-xs); color: var(--ax-text-2); }
|
|
6570
6608
|
@media (prefers-reduced-motion: reduce) { .pp-caret { transition: none; } }
|
|
6571
|
-
`,
|
|
6609
|
+
`,vu=`
|
|
6572
6610
|
(function () {
|
|
6573
6611
|
var list = document.getElementById('pp-list');
|
|
6574
6612
|
var msg = document.getElementById('pp-msg');
|
|
@@ -6706,7 +6744,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6706
6744
|
load();
|
|
6707
6745
|
setInterval(load, 30000);
|
|
6708
6746
|
})();
|
|
6709
|
-
`;var
|
|
6747
|
+
`;var Xa="/api/admin/people";function yu(t,e){let a=Vr(t,e);return a?{...e,answer:a}:e}function wu(t){return t.state!=="pending"||!t.answer?t.state:t.answer==="yes"?"active":"removed"}function ge(t,e,a){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a))}function ku(t,e){let a=(o,s)=>e.filter(i=>i.personId===o&&wu(i)===s).length,n=o=>({id:o.id,name:o.name,role:o.role,identities:o.identities,agents:o.agents??[],machines:{active:a(o.id,"active"),pending:a(o.id,"pending")}}),r=t.map(n);return t.some(o=>o.role==="owner")||r.unshift({...n({id:mt,name:"Owner of this machine",role:"owner",identities:[]}),builtIn:!0}),r}var _u=(t,e)=>e.createdAt.localeCompare(t.createdAt);async function js(t,e,a,n){if(a!=="/people"&&a!==Xa&&!a.startsWith(`${Xa}/`))return!1;let r=(t.method||"GET").toUpperCase();if(a==="/people")return r!=="GET"?(ge(e,405,{error:"GET only"}),!0):(e.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end($s({peers:n.peers,localToken:n.localToken})),!0);if(r!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return ge(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;let o=c=>n.members.devices(c).map(d=>yu(n.root,d)),s=()=>ku(n.people(),o());if(r==="GET"&&a===Xa){let c=s();return ge(e,200,{people:c,paired:c.reduce((d,p)=>d+p.machines.active+p.machines.pending,0)}),!0}let i=a.match(/^\/api\/admin\/people\/([a-z0-9][a-z0-9_-]{0,39})$/);if(r==="GET"&&i){let c=s().find(g=>g.id===i[1]);if(!c)return ge(e,404,{error:`no person "${i[1]}"`}),!0;let d=n.db(),p=[],m=[];try{d&&(p=Xr(d,c.id))}catch{}try{d&&(m=jt(d,c.id,20))}catch{}return ge(e,200,{person:c,devices:o(c.id).sort(_u),requests:p,runs:m,database:!!d}),!0}let l=a.match(/^\/api\/admin\/people\/([a-z0-9][a-z0-9_-]{0,39})\/devices\/([A-Za-z0-9_-]{1,80})\/end$/);if(r==="POST"&&l){let[,c,d]=l,p=n.members.byToken(d);if(!p||p.personId!==c)return ge(e,404,{error:"no such machine for this person"}),!0;if(p.state==="removed")return ge(e,409,{error:"this machine's access has already ended"}),!0;let m=Qr({tokens:n.tokens??new G,members:n.members,now:n.now},d,"removed by the owner (dashboard)");return ge(e,200,{ok:!0,device:m}),!0}return ge(e,404,{error:"not found"}),!0}import{resolve as Cu}from"path";import{existsSync as Iu}from"fs";import Mu from"better-sqlite3";var Os=new WeakSet;function Su(t,e,a={}){if(Os.has(t))return;Os.add(t);let n=a.thresholdMs??200,r=a.now??(()=>performance.now()),o=t.prepare.bind(t);t.prepare=s=>{let i=o(s);for(let l of["all","get","run"]){let c=i[l].bind(i);i[l]=(...d)=>{let p=r();try{return c(...d)}finally{let m=r()-p;m>=n&&e({sql:s,ms:m})}}}return i}}function Eu(t,e=160){let a=t.replace(/\s+/g," ").trim();return a.length>e?`${a.slice(0,e-1)}\u2026`:a}function ke(t,e){Su(t,({sql:a,ms:n})=>console.error(`[${e}] slow query, ${Math.round(n)} ms: ${Eu(a)}`))}function Ns(t={}){let e=`<div class="ax-obs">
|
|
6710
6748
|
<header class="ax-obs__head">
|
|
6711
6749
|
<h1>Health</h1>
|
|
6712
6750
|
<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>
|
|
@@ -6828,7 +6866,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6828
6866
|
</div>
|
|
6829
6867
|
<div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
|
|
6830
6868
|
</section>
|
|
6831
|
-
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
6869
|
+
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Tu,scripts:`<script>${Au}</script>`})}var Tu=`
|
|
6832
6870
|
.ax-obs { padding: 16px 24px; }
|
|
6833
6871
|
.ax-obs__head { margin-bottom: 16px; }
|
|
6834
6872
|
.ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
|
|
@@ -6945,7 +6983,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6945
6983
|
.ax-obs__doctor-title { font-size: 12px; font-weight: 500; }
|
|
6946
6984
|
.ax-obs__doctor-detail { font-size: 11px; color: var(--ax-muted); margin-top: 2px; font-family: 'IBM Plex Mono', monospace; word-break: break-word; }
|
|
6947
6985
|
.ax-obs__doctor-fix { font-size: 11px; color: var(--ax-accent, #3a7bd5); margin-top: 2px; }
|
|
6948
|
-
`,
|
|
6986
|
+
`,Au=`
|
|
6949
6987
|
(function(){
|
|
6950
6988
|
var panes = document.querySelectorAll('.ax-obs__pane');
|
|
6951
6989
|
var tabs = document.querySelectorAll('.ax-obs__tab');
|
|
@@ -7329,7 +7367,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7329
7367
|
|
|
7330
7368
|
load(current);
|
|
7331
7369
|
})();
|
|
7332
|
-
`;var
|
|
7370
|
+
`;var Bs={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 zs(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function Ka(t){let e=Bs[zs(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 Lu(){let t=Cu(process.cwd(),".agentx/db.sqlite");if(!Iu(t))return null;try{let e=new Mu(t,{readonly:!0,fileMustExist:!0});return ke(e,"health"),{db:e,close:()=>e.close()}}catch{return null}}function qs(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ns({peers:a}))}function Ru(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 xe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Fs(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=Lu();if(!r)return xe(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=Ru(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let c=`
|
|
7333
7371
|
SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
|
|
7334
7372
|
FROM route_traces
|
|
7335
7373
|
${i.length?"WHERE "+i.join(" AND "):""}
|
|
@@ -7344,8 +7382,8 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7344
7382
|
FROM task_history
|
|
7345
7383
|
WHERE ${i.join(" AND ")}
|
|
7346
7384
|
ORDER BY started_at DESC LIMIT @limit
|
|
7347
|
-
`,p=r.db.prepare(c).all(l).map(m=>({...m,plain:
|
|
7348
|
-
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function
|
|
7385
|
+
`,p=r.db.prepare(c).all(l).map(m=>({...m,plain:Us(m.error)}));return xe(e,200,{rows:p}),!0}if(n==="summary"||n==="overview")return xe(e,200,Pu(r.db)),!0;if(n==="activity")return xe(e,200,$u(r.db,{agent:s})),!0;if(n==="cost"){let i=new URL(t.url||"/","http://_"),l=Ds(i.searchParams.get("range"));return xe(e,200,Hs(r.db,l)),!0}if(n==="cost.csv"){let i=new URL(t.url||"/","http://_"),l=Ds(i.searchParams.get("range")),c=Hs(r.db,l),d=ju(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(d),!0}return xe(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return xe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Us(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(`
|
|
7386
|
+
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function Pu(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,d=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),p=x=>d.length?d[Math.min(d.length-1,Math.floor(d.length*x))].duration_ms:0,m=p(.5),g=p(.95),b=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((x,A)=>x+Ka(A),0),S=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((x,A)=>x+Ka(A),0),T=t.prepare(`
|
|
7349
7387
|
SELECT agent_id,
|
|
7350
7388
|
COUNT(*) AS tasks,
|
|
7351
7389
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
|
|
@@ -7355,7 +7393,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7355
7393
|
WHERE started_at >= ?
|
|
7356
7394
|
GROUP BY agent_id
|
|
7357
7395
|
ORDER BY tasks DESC LIMIT 10
|
|
7358
|
-
`).all(a),
|
|
7396
|
+
`).all(a),h=t.prepare(`
|
|
7359
7397
|
SELECT COALESCE(channel, 'unknown') AS channel,
|
|
7360
7398
|
COUNT(*) AS tasks,
|
|
7361
7399
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
|
|
@@ -7363,12 +7401,12 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7363
7401
|
WHERE started_at >= ?
|
|
7364
7402
|
GROUP BY channel
|
|
7365
7403
|
ORDER BY tasks DESC
|
|
7366
|
-
`).all(a),u=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(
|
|
7404
|
+
`).all(a),u=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(x=>x.agent_id),f=new Set(t.prepare("SELECT DISTINCT agent_id FROM task_history WHERE started_at >= ?").all(o).map(x=>x.agent_id)),y=u.filter(x=>!f.has(x)),E=t.prepare(`
|
|
7367
7405
|
SELECT started_at, agent_id, channel, message_preview, error
|
|
7368
7406
|
FROM task_history
|
|
7369
7407
|
WHERE status='error' AND started_at >= ?
|
|
7370
7408
|
ORDER BY started_at DESC LIMIT 5
|
|
7371
|
-
`).all(o).map(
|
|
7409
|
+
`).all(o).map(x=>({...x,plain:Us(x.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(c),p50DurationMs:m,p95DurationMs:g,spendToday:b,spendDelta:b-S,idleAgentCount:y.length},perAgent:T,perChannel:h,idleAgents:y,recentErrors:E}}function $u(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(`
|
|
7372
7410
|
SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
|
|
7373
7411
|
COUNT(*) AS tasks,
|
|
7374
7412
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
|
|
@@ -7395,7 +7433,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7395
7433
|
WHERE started_at >= @since
|
|
7396
7434
|
GROUP BY agent_id
|
|
7397
7435
|
ORDER BY tasks_24h DESC, tasks_7d DESC
|
|
7398
|
-
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function
|
|
7436
|
+
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function Ds(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 Hs(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
|
|
7399
7437
|
SELECT day, agent_id, model,
|
|
7400
7438
|
input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
|
|
7401
7439
|
tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
|
|
@@ -7403,20 +7441,20 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7403
7441
|
FROM usage_daily
|
|
7404
7442
|
${a}
|
|
7405
7443
|
ORDER BY day
|
|
7406
|
-
`).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,d=0,p=0,m=0,
|
|
7444
|
+
`).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,d=0,p=0,m=0,g=0,_=0,b=0,S=0,T={},h={};for(let k of n){let L=Ka(k),j=zs(k.model),$=Bs[j],O=(k.tier2_input_tokens||0)/1e6*$.input*.5+(k.tier2_output_tokens||0)/1e6*$.output*.5+(k.tier2_cache_read_tokens||0)/1e6*$.cacheRead*.5+(k.tier2_cache_create_tokens||0)/1e6*$.cacheCreate*.5,W=(k.input_tokens||0)+(k.tier2_input_tokens||0),ce=(k.output_tokens||0)+(k.tier2_output_tokens||0),Q=(k.cache_read_tokens||0)+(k.tier2_cache_read_tokens||0),re=(k.cache_create_tokens||0)+(k.tier2_cache_create_tokens||0);p+=L,k.day>=s&&(d+=L,_+=k.tasks||0),k.day>=i&&k.day<s&&(S+=L,b+=k.tasks||0),k.day===r&&(l+=L),k.day===o&&(c+=L),k.day===r&&(m+=O),k.day>=s&&(g+=O);let Z=T[k.day]||(T[k.day]={date:k.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});Z.tasks+=k.tasks||0,Z.input+=W,Z.output+=ce,Z.cacheRead+=Q,Z.cacheCreate+=re,Z.cost+=L,Z.tier2+=O;let F=Z.agents[k.agent_id]||(Z.agents[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});F.tasks+=k.tasks||0,F.cost+=L,F.tier2+=O,F.input+=W,F.output+=ce,F.cacheRead+=Q,F.cacheCreate+=re,k.model&&(F.model=k.model);let N=h[k.agent_id]||(h[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});N.tasks+=k.tasks||0,N.cost+=L,N.tier2+=O,N.input+=W,N.output+=ce,N.cacheRead+=Q,N.cacheCreate+=re,k.model&&(N.model=k.model)}let u=Object.values(T).sort((k,L)=>k.date<L.date?-1:1),f=0,y=0,v=0,E=0,x=0,A=0;for(let k of u)f+=k.tasks,y+=k.input,v+=k.output,E+=k.cacheRead,x+=k.cacheCreate,A+=k.cost;let R=Object.entries(h).map(([k,L])=>({agent_id:k,...L,tokens:L.input+L.output+L.cacheRead+L.cacheCreate})).sort((k,L)=>L.cost-k.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:l,spendYesterday:c,spend7d:d,spend30d:p,tier2Today:m,tier2_7d:g,tier2PctToday:l>0?m/l:0,spendRange:A,avgDailyRange:u.length?A/u.length:0,tasksRange:f,tokensRange:y+v+E+x,cacheHitRange:E+y>0?E/(E+y):0,costPerTaskRange:f>0?A/f:0,spendDeltaWoW:S>0?(d-S)/S:0,tasksDeltaWoW:b>0?(_-b)/b:0},days:u,perAgent:R}}function ju(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+`
|
|
7407
7445
|
`+a.join(`
|
|
7408
7446
|
`)+`
|
|
7409
|
-
`}import{resolve as
|
|
7447
|
+
`}import{resolve as Ou}from"path";import{existsSync as Nu}from"fs";import Du from"better-sqlite3";function Hu(){let t=Ou(process.cwd(),".agentx/intent/ledger.sqlite");if(!Nu(t))return null;try{let e=new Du(t,{readonly:!0,fileMustExist:!0});return ke(e,"ledger-panel"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-Ws>6e4&&(Ws=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var Ws=0;function Le(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Bu(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 Gs(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Hu();if(!r)return Le(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Bu(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",c=parseInt(o.searchParams.get("limit")||"50",10),d=Number.isFinite(c)?Math.max(1,Math.min(500,c)):50;if(n==="stats"){let p=s!==void 0?"WHERE ts >= @since":"",m=s!==void 0?"WHERE decided_at >= @since":"",g=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${p} GROUP BY source ORDER BY n DESC`).all({since:s}),_=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${m}`).get({since:s}).n,b=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${m} GROUP BY outcome ORDER BY n DESC`).all({since:s}),S=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${p}`).get({since:s}).n,T=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${p} GROUP BY source ORDER BY n DESC`).all({since:s}),h=r.db.prepare(`
|
|
7410
7448
|
SELECT COUNT(*) AS n FROM intent_decisions d
|
|
7411
7449
|
LEFT JOIN intent_resolutions r
|
|
7412
7450
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7413
7451
|
WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
|
|
7414
|
-
`).get().n;return Le(e,200,{since:s??null,eventsBySource:
|
|
7452
|
+
`).get().n;return Le(e,200,{since:s??null,eventsBySource:g,totalDecisions:_,decisionsByOutcome:b,totalDivergences:S,divergencesBySource:T,inFlight:h}),!0}if(n==="events"){let p=[],m={limit:d};s!==void 0&&(p.push("ts >= @since"),m.since=s),i&&(p.push("source = @source"),m.source=i),l&&(p.push("project = @project"),m.project=l);let g=`
|
|
7415
7453
|
SELECT id, ts, source, source_event_id, project, subject, intent
|
|
7416
7454
|
FROM intent_events
|
|
7417
7455
|
${p.length?"WHERE "+p.join(" AND "):""}
|
|
7418
7456
|
ORDER BY ts DESC LIMIT @limit
|
|
7419
|
-
`;return Le(e,200,{rows:r.db.prepare(
|
|
7457
|
+
`;return Le(e,200,{rows:r.db.prepare(g).all(m)}),!0}if(n==="divergences"){let p=[],m={limit:d};s!==void 0&&(p.push("ts >= @since"),m.since=s),i&&(p.push("source = @source"),m.source=i);let g=`
|
|
7420
7458
|
SELECT ts, source, decided_by,
|
|
7421
7459
|
legacy_agent_id, legacy_outcome, legacy_reason,
|
|
7422
7460
|
ledger_agent_id, ledger_outcome, ledger_reason,
|
|
@@ -7424,7 +7462,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7424
7462
|
FROM intent_divergences
|
|
7425
7463
|
${p.length?"WHERE "+p.join(" AND "):""}
|
|
7426
7464
|
ORDER BY ts DESC LIMIT @limit
|
|
7427
|
-
`;return Le(e,200,{rows:r.db.prepare(
|
|
7465
|
+
`;return Le(e,200,{rows:r.db.prepare(g).all(m)}),!0}if(n==="active"){let p=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],m={limit:d};i&&(p.push("e.source = @source"),m.source=i);let g=`
|
|
7428
7466
|
SELECT e.id AS event_id, e.ts, e.source, e.project, e.subject, e.intent,
|
|
7429
7467
|
d.decided_by, d.decided_at, d.agent_id, d.reason
|
|
7430
7468
|
FROM intent_decisions d
|
|
@@ -7433,7 +7471,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7433
7471
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7434
7472
|
WHERE ${p.join(" AND ")}
|
|
7435
7473
|
ORDER BY d.decided_at DESC LIMIT @limit
|
|
7436
|
-
`;return Le(e,200,{rows:r.db.prepare(
|
|
7474
|
+
`;return Le(e,200,{rows:r.db.prepare(g).all(m)}),!0}return Le(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Le(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Xs(t={}){return I({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
|
|
7437
7475
|
<header class="ax-led__head">
|
|
7438
7476
|
<h1>Intent ledger</h1>
|
|
7439
7477
|
<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>
|
|
@@ -7638,7 +7676,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7638
7676
|
}
|
|
7639
7677
|
load();
|
|
7640
7678
|
})();
|
|
7641
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
7679
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Ks(t={}){return I({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
|
|
7642
7680
|
<header class="ax-cost__head">
|
|
7643
7681
|
<div>
|
|
7644
7682
|
<h1>Cost</h1>
|
|
@@ -8211,7 +8249,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8211
8249
|
load();
|
|
8212
8250
|
setInterval(load, 30000);
|
|
8213
8251
|
})();
|
|
8214
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
8252
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Js(t={}){let e=`<div class="ax-pj__root">
|
|
8215
8253
|
<aside class="ax-pj__list">
|
|
8216
8254
|
<header>
|
|
8217
8255
|
<h2>Projects</h2>
|
|
@@ -8238,7 +8276,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8238
8276
|
</header>
|
|
8239
8277
|
<div id="pj-detail-body" class="ax-pj__detail-body"></div>
|
|
8240
8278
|
</section>
|
|
8241
|
-
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
8279
|
+
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:zu,scripts:`<script>${qu}</script>`})}var zu=`
|
|
8242
8280
|
.ax-pj__root {
|
|
8243
8281
|
display: grid;
|
|
8244
8282
|
grid-template-columns: 360px 1fr;
|
|
@@ -8425,7 +8463,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8425
8463
|
}
|
|
8426
8464
|
.ax-pj__warn { color: var(--ax-warn, #facc15); border-top: 1px solid var(--ax-border); }
|
|
8427
8465
|
.ax-pj__hint { font-size: 11px; color: var(--ax-fg-muted, var(--ax-text)); margin-top: 4px; }
|
|
8428
|
-
`,
|
|
8466
|
+
`,qu=`
|
|
8429
8467
|
(function(){
|
|
8430
8468
|
const $ = (sel) => document.querySelector(sel);
|
|
8431
8469
|
const esc = (s) => String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({"&":"&","<":"<",">":">","\\"":"""}[c]));
|
|
@@ -9075,20 +9113,20 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
9075
9113
|
load();
|
|
9076
9114
|
});
|
|
9077
9115
|
})();
|
|
9078
|
-
`;import{resolve as Qa,join as am}from"path";import{existsSync as Za,readdirSync as nm,readFileSync as rm}from"fs";import om from"better-sqlite3";var Vs=String.raw`[\w.-]+(?:/[\w.-]+)+`,zu=new RegExp(`^(?:chat:)?(${Vs}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),qu=new RegExp(`^\\[(?:GitLab|GitHub) (${Vs}) `);function Js(t){if(!t)return null;let e=t.match(zu);return e?e[1]:null}function Ka(t){if(!t)return null;let e=t.trimStart().match(qu);return e?e[1]:null}function Zt(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Js(typeof n?.chatId=="string"?n.chatId:null)??Js(e)??Ka(a)}function Fu(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function ea(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Uu=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Wu=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Gu=t=>/^issue/i.test(t)?"issue":"mr";function Xu(t){let e=t.subject.match(Uu)??t.inputPreview.trimStart().match(Wu);return e?{kind:Gu(e[1]),n:Number(e[2])}:null}function Ku(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 Ys(t){if(!Fu(t.projectId))return[];let e=Xu(t);return e?[e]:Ku(t.inputPreview)}var Ju=6e4,Vu=5*6e4,Yu=40,Qs=6,Zs=new Map;function ei(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 Ys(n)){let s=ea(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Yu)return[...e.values()]}}return[...e.values()]}async function ti(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=ea(s.project,s.ref),l=Zs.get(i);l&&n-l.at<(s.github?Vu:Ju)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Qs)await Promise.all(o.slice(s,s+Qs).map(async i=>{let l=ea(i.project,i.ref),c=null;try{c=i.github?await Zu(i,e,a):await Qu(i,e,a)}catch{}Zs.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function ai(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 Qu(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 ai(`${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 Zu(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 ai(`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}$n();var Ja=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function ni(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=pt(e);n&&(a.root={kind:n.kind,channel:n.channel},n.sender&&(a.root.sender=n.sender),n.agentId&&(a.root.agentId=n.agentId));let r=e.delegation;if(r&&typeof r=="object"){let o=r,s=Ja(o.from,80);if(s){a.callback={from:s,status:Ja(o.status,20)??"done"};let i=Ja(o.peer,80);i&&(a.callback.peer=i)}}return a}$n();va();var ri={kind:"agentx",id:"agentx",name:"AgentX"},Va={kind:"person",id:"unknown",name:"Unknown"},em=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),oi=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),Re=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function tm(t,e,a){let n=t==="workflow"?a?.event?.payload:a,r=n?.issueEvent||n?.webhookEvent,o=n?.sender??r?.sender??n?.message?.from??n?.user??r?.user,s=Re(o?.id)??(e==="whatsapp"?Re(n?.from):void 0),i=Re(o?.username)??Re(o?.login);return s||i?{id:s,username:i,name:Re(o?.name)}:null}function si(t){let e=s=>({kind:"person",id:`person:${s}`,name:Hn(t.people,s)}),a=(s,i)=>i||em.has(s)?ri:{kind:"external",id:`ext:${s}`,name:t.channelLabel(s)},n=t.raw&&typeof t.raw=="object"?t.raw:{};if(t.source==="mesh"){let s=n.context&&typeof n.context=="object"?n.context:void 0,i=Re(n.person)??zn(t.people,s)?.id;if(i)return e(i);let l=pt(s),c=l?.channel??t.channel;if(Pn(s)==="human")return oi(s?.senderUsername)?a(c,!1):Va;let d=!!Re(n.senderAgentId)||ha(l?l.sender:s?.sender);return c==="desktop"&&!d?Va:a(c,d)}let r=tm(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Bn(t.people,t.channel,r);return o?e(o.id):ha(r.name)?ri:Rn.has(t.channel)&&!oi(r.username)?Va:a(t.channel,!1)}function en(){let t=Qa(process.cwd(),".agentx/intent/ledger.sqlite");if(!Za(t))return null;try{let e=new om(t,{readonly:!0,fileMustExist:!0});return ke(e,"activity-graph"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-ii>6e4&&(ii=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var ii=0;function be(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var Pe={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"},app:{label:"Phone app",color:"#0f9d8a"},opencode:{label:"OpenCode",color:"#57606a"}};function sm(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in Pe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in Pe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in Pe)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 Pe)return s}return"workflow"}return t}function di(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 im(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 pi(t,e,a){return tr(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 lm(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:J(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&&!Ya(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!Ya(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:dm(e,n)}}}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&&!Ya(i||l||"")){let d=typeof n.channel=="string"?n.channel:"",p=li(d);return{id:c,name:l||i||c,avatar:J(l||i||c),kind:p}}}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:J(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:J(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:J(i),kind:li(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:J(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:J(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:J(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:J(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:J(o),kind:"whatsapp"}}}return null}var cm={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function dm(t,e){let a=cm[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function li(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Ya(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 J(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 ui(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}
|
|
9116
|
+
`;import{resolve as Za,join as rm}from"path";import{existsSync as en,readdirSync as om,readFileSync as sm}from"fs";import im from"better-sqlite3";var Ys=String.raw`[\w.-]+(?:/[\w.-]+)+`,Fu=new RegExp(`^(?:chat:)?(${Ys}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),Uu=new RegExp(`^\\[(?:GitLab|GitHub) (${Ys}) `);function Vs(t){if(!t)return null;let e=t.match(Fu);return e?e[1]:null}function Ja(t){if(!t)return null;let e=t.trimStart().match(Uu);return e?e[1]:null}function Zt(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Vs(typeof n?.chatId=="string"?n.chatId:null)??Vs(e)??Ja(a)}function Wu(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function ea(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Gu=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Xu=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Ku=t=>/^issue/i.test(t)?"issue":"mr";function Ju(t){let e=t.subject.match(Gu)??t.inputPreview.trimStart().match(Xu);return e?{kind:Ku(e[1]),n:Number(e[2])}:null}function Vu(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 Qs(t){if(!Wu(t.projectId))return[];let e=Ju(t);return e?[e]:Vu(t.inputPreview)}var Yu=6e4,Qu=5*6e4,Zu=40,Zs=6,ei=new Map;function ti(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 Qs(n)){let s=ea(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Zu)return[...e.values()]}}return[...e.values()]}async function ai(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=ea(s.project,s.ref),l=ei.get(i);l&&n-l.at<(s.github?Qu:Yu)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Zs)await Promise.all(o.slice(s,s+Zs).map(async i=>{let l=ea(i.project,i.ref),c=null;try{c=i.github?await tm(i,e,a):await em(i,e,a)}catch{}ei.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function ni(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 em(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 ni(`${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 tm(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 ni(`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}$n();var Va=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function ri(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=pt(e);n&&(a.root={kind:n.kind,channel:n.channel},n.sender&&(a.root.sender=n.sender),n.agentId&&(a.root.agentId=n.agentId));let r=e.delegation;if(r&&typeof r=="object"){let o=r,s=Va(o.from,80);if(s){a.callback={from:s,status:Va(o.status,20)??"done"};let i=Va(o.peer,80);i&&(a.callback.peer=i)}}return a}$n();ya();var oi={kind:"agentx",id:"agentx",name:"AgentX"},Ya={kind:"person",id:"unknown",name:"Unknown"},am=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),si=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),Re=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function nm(t,e,a){let n=t==="workflow"?a?.event?.payload:a,r=n?.issueEvent||n?.webhookEvent,o=n?.sender??r?.sender??n?.message?.from??n?.user??r?.user,s=Re(o?.id)??(e==="whatsapp"?Re(n?.from):void 0),i=Re(o?.username)??Re(o?.login);return s||i?{id:s,username:i,name:Re(o?.name)}:null}function ii(t){let e=s=>({kind:"person",id:`person:${s}`,name:Hn(t.people,s)}),a=(s,i)=>i||am.has(s)?oi:{kind:"external",id:`ext:${s}`,name:t.channelLabel(s)},n=t.raw&&typeof t.raw=="object"?t.raw:{};if(t.source==="mesh"){let s=n.context&&typeof n.context=="object"?n.context:void 0,i=Re(n.person)??zn(t.people,s)?.id;if(i)return e(i);let l=pt(s),c=l?.channel??t.channel;if(Pn(s)==="human")return si(s?.senderUsername)?a(c,!1):Ya;let d=!!Re(n.senderAgentId)||ga(l?l.sender:s?.sender);return c==="desktop"&&!d?Ya:a(c,d)}let r=nm(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Bn(t.people,t.channel,r);return o?e(o.id):ga(r.name)?oi:Rn.has(t.channel)&&!si(r.username)?Ya:a(t.channel,!1)}function tn(){let t=Za(process.cwd(),".agentx/intent/ledger.sqlite");if(!en(t))return null;try{let e=new im(t,{readonly:!0,fileMustExist:!0});return ke(e,"activity-graph"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-li>6e4&&(li=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var li=0;function be(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var Pe={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"},app:{label:"Phone app",color:"#0f9d8a"},opencode:{label:"OpenCode",color:"#57606a"}};function lm(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in Pe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in Pe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in Pe)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 Pe)return s}return"workflow"}return t}function pi(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 cm(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 ui(t,e,a){return tr(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 dm(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:J(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&&!Qa(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!Qa(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:um(e,n)}}}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&&!Qa(i||l||"")){let d=typeof n.channel=="string"?n.channel:"",p=ci(d);return{id:c,name:l||i||c,avatar:J(l||i||c),kind:p}}}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:J(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:J(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:J(i),kind:ci(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:J(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:J(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:J(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:J(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:J(o),kind:"whatsapp"}}}return null}var pm={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function um(t,e){let a=pm[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function ci(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Qa(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 J(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 mi(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}
|
|
9079
9117
|
${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
|
|
9080
|
-
${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
|
|
9118
|
+
${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 mm(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 fi(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
|
|
9081
9119
|
SELECT id, ts, source, project, subject, intent, raw_json
|
|
9082
9120
|
FROM intent_events WHERE ts >= ? ORDER BY ts ASC
|
|
9083
|
-
`).all(r),s=new Map,i=new Map;if(o.length>0){let
|
|
9121
|
+
`).all(r),s=new Map,i=new Map;if(o.length>0){let x=o.map(j=>j.id),A=x.map((j,$)=>`@id${$}`).join(","),R=Object.fromEntries(x.map((j,$)=>[`id${$}`,j])),k=t.prepare(`
|
|
9084
9122
|
SELECT event_id, decided_at, decided_by, agent_id, outcome, reason
|
|
9085
9123
|
FROM intent_decisions WHERE event_id IN (${A}) ORDER BY decided_at ASC
|
|
9086
|
-
`).all(R);for(let j of
|
|
9124
|
+
`).all(R);for(let j of k)s.has(j.event_id)||s.set(j.event_id,[]),s.get(j.event_id).push(j);let L=t.prepare(`
|
|
9087
9125
|
SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
|
|
9088
9126
|
FROM intent_resolutions WHERE decision_event_id IN (${A})
|
|
9089
|
-
`).all(R);for(let j of L)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,c=new Map,d=new Map,p=new Map,m=[],
|
|
9127
|
+
`).all(R);for(let j of L)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,c=new Map,d=new Map,p=new Map,m=[],g=e?.business?.projects??[],_=e?.business?.contactMap??[],b=_a(e?.business??{}),S=e?.people??[];for(let x of o){let A=null;try{A=JSON.parse(x.raw_json)}catch{}let R=ui(x.source,A,_),k=mi(x.source,A),L=ri(A),j=x.project??Zt(A,x.subject,k),$=null,O=null;R?($=R.client,O=R.project||`${R.client}/_chat`):j&&($=bt(j,g),O=j);let W=lm(x.source,x.intent||"",A),ce=Pe[W]||{label:W,color:"#6b7280"};d.has(W)||d.set(W,{id:W,label:ce.label,color:ce.color});let Q=ii({source:x.source,channel:W,raw:A,people:S,channelLabel:N=>Pe[N]?.label??N}),re="__system",Z,F=dm(x.source,x.intent||"",A);if(F){re=F.id,Z=F.kind;let N=R?.displayName||F.name;(!p.has(F.id)||R?.displayName)&&p.set(F.id,{id:F.id,name:N,avatar:J(N),kind:F.kind})}else p.has("__system")||p.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});for(let N of s.get(x.id)??[]){if(N.outcome!=="dispatched"||!N.agent_id)continue;let Jc=`${x.id}|${N.decided_by}`,ct=i.get(Jc),Cn=N.decided_at,In=ct?.resolved_at??null,fa=In===null,Vc=ct?.duration_ms??(fa?n-Cn:0),Yc=fa?"active":ct?.status==="error"||ct?.status==="fail"?"error":"completed",ee,Qe;if($)ee=$,Qe=O;else{let ha=b.get(N.agent_id);ha?(ee=ha,Qe=`${ha}/_${x.source}`):(ee="unmapped",Qe=`unmapped/_${x.source}`)}l.has(ee)||l.set(ee,{id:ee,name:ee,color:pi(ee),projects:[]}),c.has(ee)||c.set(ee,new Set),c.get(ee).add(Qe),m.push({id:`${x.id}|${N.decided_by}`,agentId:N.agent_id,clientId:ee,projectId:Qe,channelId:W,initiatorId:re,initiatorKind:Z,subject:mm(x.subject),intent:x.intent||"",startedAt:Cn,resolvedAt:In,duration:Vc,active:fa,outcome:Yc,tokens:0,inputPreview:k,system:cm(N.agent_id,e),...L,starter:Q})}}let T=[...l.values()].map(x=>({...x,projects:[...c.get(x.id)||[]].sort()})).sort((x,A)=>x.id.localeCompare(A.id)),h=[],u=new Set;if(e){let x=e.business??{},A=R=>{let k=x.orgChart?.[R]?.role,L=k?x.roles?.[k]?.title:void 0;return typeof L=="string"&&L.trim()?L.trim():void 0};for(let[R,k]of Object.entries(e.agents||{})){let L={id:R,name:k.name||R,tier:k.tier==="claude-code"?"lead":"worker",model:k.model||"",role:k.systemPrompt?k.systemPrompt.split(/[.\n]/)[0].slice(0,60):k.tier||"",title:A(R)};h.push(L),u.add(R)}}for(let x of m)u.has(x.agentId)||(h.push({id:x.agentId,name:x.agentId,tier:"worker",model:"",role:""}),u.add(x.agentId));h.sort((x,A)=>x.id.localeCompare(A.id));let f=[],y=new Set;for(let[x,A]of Object.entries(Pe))f.push({id:x,label:A.label,color:A.color}),y.add(x);for(let x of d.values())y.has(x.id)||f.push(x);let v=[...p.values()];v.find(x=>x.id==="__system")||v.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let E=e?.channels?.gitlab?.host;return{now:n,windowH:a,clients:T,agents:h,channels:f,initiators:v,dispatches:m,forges:{gitlab:typeof E=="string"?E:void 0,github:"https://github.com"}}}function an(t){let e=tn();if(!e)return null;try{return fi(e.db,gi(),t)}finally{e.close()}}function hi(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:d}of t){l.gitlab??=d.forges?.gitlab,l.github??=d.forges?.github,d.now>s&&(s=d.now),d.windowH>i&&(i=d.windowH);for(let p of d.clients){let m=e.get(p.id);if(!m)e.set(p.id,{...p,projects:[...p.projects]});else{let g=Array.from(new Set([...m.projects,...p.projects])).sort();e.set(p.id,{...m,projects:g})}}for(let p of d.agents)a.has(p.id)||a.set(p.id,p);for(let p of d.channels)n.has(p.id)||n.set(p.id,p);for(let p of d.initiators)r.has(p.id)||r.set(p.id,p);for(let p of d.dispatches){let m=fm(p);if(m.clientId!==p.clientId&&!e.has(m.clientId)&&e.set(m.clientId,{id:m.clientId,name:m.clientId,color:pi(m.clientId),projects:[]}),m.projectId!==p.projectId){let g=e.get(m.clientId);g.projects.includes(m.projectId)||e.set(m.clientId,{...g,projects:[...g.projects,m.projectId].sort()})}o.push({...m,nodeId:c,id:`${c}::${m.id}`})}}return{now:s||Date.now(),windowH:i||6,localNodeId:t[0]?.nodeId,forges:l,clients:[...e.values()].sort((c,d)=>c.id.localeCompare(d.id)),agents:[...a.values()].sort((c,d)=>c.id.localeCompare(d.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((c,d)=>d.startedAt-c.startedAt)}}function fm(t){if(t.clientId!=="unmapped")return t;let e=Ja(t.inputPreview);if(!e)return t;let a=ve?.business?.projects??[];return{...t,projectId:e,clientId:bt(e,a)}}async function ta(t){let e=ve?.channels?.gitlab,a=await ai(ti(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 ve=null;function gi(){return ve&&{...ve,people:tt(ve.people)}}function xi(t){ve=t}async function bi(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=tn();if(!n)return be(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=vi(parseInt(r.searchParams.get("hours")||"6",10));be(e,200,await ta(fi(n.db,gi(),o)))}catch(r){be(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var hm=5e3;async function nn(t,e,a,n=an){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
|
|
9090
9128
|
|
|
9091
|
-
`);let r=new URL(t.url||"/","http://_"),o=
|
|
9129
|
+
`);let r=new URL(t.url||"/","http://_"),o=vi(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
|
|
9092
9130
|
|
|
9093
9131
|
`)}catch{i()}},25e3);try{for(;!s;){try{let d=await n(o),p=d&&await ta(d);if(s)break;p?(e.write(`event: snapshot
|
|
9094
9132
|
`),e.write(`data: ${JSON.stringify(p)}
|
|
@@ -9099,7 +9137,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
|
|
|
9099
9137
|
`)}catch(d){e.write(`event: error
|
|
9100
9138
|
data: ${JSON.stringify({error:d?.message??String(d)})}
|
|
9101
9139
|
|
|
9102
|
-
`)}let c=Date.now();for(;!s&&Date.now()-c<
|
|
9140
|
+
`)}let c=Date.now();for(;!s&&Date.now()-c<hm;)await new Promise(d=>setTimeout(d,200))}}finally{clearInterval(l);try{e.end()}catch{}}return!0}function vi(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function gm(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=Za(process.cwd(),".agentx/task-history",t,n);if(!en(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=Za(process.cwd(),".agentx/task-history",t,o);return en(s)?di(s,e,a):null}return di(r,e,a)}function di(t,e,a){let n=null,r=1/0;for(let o of om(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(sm(rm(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let d=Date.parse(i);if(!Number.isFinite(d))continue;l=d}else continue;let c=Math.abs(l-e);c<r&&c<=a&&(n=s,r=c)}return n}async function yi(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 be(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=tn();if(!l)return be(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 be(e,404,{error:"event not found"}),!0;let d=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(!d)return be(e,404,{error:"decision not found"}),!0;let p=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),m=null;try{m=JSON.parse(c.raw_json)}catch{}let g=mi(c.source,m),_=m&&typeof m=="object"&&(m.text||m.message?.text||m.message?.caption||m.object_attributes?.note||m.object_attributes?.description||m.comment?.body||m.issue?.body||(typeof m.message=="string"?m.message:null)||(typeof m.prompt=="string"?m.prompt:null)||null)||g,b=null,S=null;if(d.agent_id){let v=gm(d.agent_id,d.decided_at);if(v){typeof v.responseText=="string"&&(b=v.responseText);let E=v.transcript;Array.isArray(E)&&(S=E.length)}}let T=ve?.business?.projects??[],h=ve?.business?.contactMap??[],u=_a(ve?.business??{}),f={client:"unmapped",project:`unmapped/_${c.source}`,via:"fallback"},y=ui(c.source,m,h);if(y)f={client:y.client,project:y.project||`${y.client}/_chat`,via:`contactMap (channel=${y.channel??"*"}${y.username?` username=${y.username}`:""}${y.chatId?` chatId=${y.chatId}`:""})`};else if(c.project||Zt(m,c.subject,g)){let v=c.project||Zt(m,c.subject,g);f={client:bt(v,T),project:v,via:c.project?`project namespace prefix (${v})`:`forge path in chat id / message (${v})`}}else if(d.agent_id){let v=u.get(d.agent_id);v&&(f={client:v,project:`${v}/_${c.source}`,via:`orgChart fallback (agent ${d.agent_id} reports up to a PM whose project belongs to ${v})`})}be(e,200,{id:r,eventId:s,source:c.source,subject:c.subject,intent:c.intent,project:c.project,decidedBy:d.decided_by,agentId:d.agent_id,outcome:d.outcome,reason:d.reason,startedAt:d.decided_at,resolvedAt:p?.resolved_at??null,durationMs:p?.duration_ms??null,input:_,response:b,transcriptLen:S,resolutionStatus:p?.status??null,resultSummary:p?.result_summary??null,attribution:f})}catch(c){be(e,500,{error:c?.message??String(c)})}finally{l.close()}return!0}import{existsSync as ym,readFileSync as wm}from"fs";import{resolve as ki}from"path";ft();function wi(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=xm.replace(/__AGENT_ID__/g,H(e));return I({title:`AgentX \xB7 ${H(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${H(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:bm,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>${vm}</script>`})}var xm=`
|
|
9103
9141
|
<!-- Breadcrumb -->
|
|
9104
9142
|
<div class="ax-crumb">
|
|
9105
9143
|
<a href="/admin">Settings</a>
|
|
@@ -9697,7 +9735,7 @@ data: ${JSON.stringify({error:d?.message??String(d)})}
|
|
|
9697
9735
|
</div>
|
|
9698
9736
|
</div>
|
|
9699
9737
|
</div>
|
|
9700
|
-
`,
|
|
9738
|
+
`,bm=`
|
|
9701
9739
|
/* Agent-specific layout + legacy styles for bits the migration left in
|
|
9702
9740
|
* place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
|
|
9703
9741
|
* primitives live in components.css.ts. */
|
|
@@ -9816,7 +9854,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
|
|
|
9816
9854
|
|
|
9817
9855
|
/* Agent-specific button variant used in rail context (no ax-btn wrapper) */
|
|
9818
9856
|
.ax-btn.lg { padding: 9px 16px; font-size: 13px; }
|
|
9819
|
-
`,
|
|
9857
|
+
`,vm=`
|
|
9820
9858
|
const $ = (id) => document.getElementById(id);
|
|
9821
9859
|
const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
|
|
9822
9860
|
|
|
@@ -10675,15 +10713,15 @@ document.addEventListener('keydown', (e) => {
|
|
|
10675
10713
|
/* ===== Boot ===== */
|
|
10676
10714
|
initOptsToggles();
|
|
10677
10715
|
loadAgent();
|
|
10678
|
-
`;function
|
|
10679
|
-
`);return
|
|
10680
|
-
`);return
|
|
10716
|
+
`;function _i(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(wi({agentId:a,peers:n,localToken:r}))}async function Si(t,e,a){try{let n=t.method==="GET"?void 0:await Fm(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){aa(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",c=`${t.method} ${l}`,p={"GET ":()=>nt(i),"PATCH ":()=>km(i,n),"PATCH capability":()=>Em(i,n),"POST mcp":()=>_m(i,n),"DELETE mcp":()=>Sm(i,n),"GET identity":()=>Tm(i),"GET identity/file":()=>Am(i,String(o.path||"")),"PUT identity/file":()=>Cm(i,n),"GET skills":()=>Im(i),"POST skills":()=>Mm(i,n),"DELETE skills":()=>Lm(i,n),"GET skills/tree":()=>Rm(i,String(o.slug||"")),"GET skills/file":()=>Pm(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>$m(i,n),"GET skills/deps":()=>jm(i,String(o.slug||"")),"POST skills/install":()=>Om(i,n,t),"POST skills/deps":()=>Nm(i,n,t),"GET channels":()=>Dm(i),"GET activity":()=>Hm(i,t),"GET handovers":()=>Bm(i),"POST handovers":()=>zm(i,n),"DELETE handovers":()=>qm(n)}[c];if(!p){aa(e,404,{error:`unknown agent sub-endpoint: ${c}`});return}let m=await p();aa(e,200,m)}catch(n){aa(e,400,{error:n?.message||"agent op failed"})}}function Ei(){let t=ki(process.cwd(),"agentx.json");return ym(t)?JSON.parse(wm(t,"utf-8")):null}function V(t){let e=Ei();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 nt(t){let{def:e,cfg:a}=V(t),n=e.workspace?Be(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",wikiAbsorb:e.wiki?.absorb?.enabled!==!1,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 km(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},typeof e?.wikiAbsorb=="boolean"&&(Ot(r.agents[t],e.wikiAbsorb),a.wikiAbsorb=e.wikiAbsorb),`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:nt(t)}}function _m(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:nt(t)}}function Sm(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:nt(t)}}function Em(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:nt(t)}}function Tm(t){let{def:e}=V(t);return Be(e.workspace)}function Am(t,e){if(!e)throw new Error("path query param required");let{def:a}=V(t);return Ct(a.workspace,e)}function Cm(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=V(t);return It(n.workspace,a,String(e?.content??""))}function Im(t){let{def:e}=V(t),a=Be(e.workspace);return{skills:a.skills,workspace:a.workspace}}function Mm(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return Mt(n.workspace,a,{title:e?.title,content:e?.content})}function Lm(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return Lt(n.workspace,a)}function Rm(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t),n=Lr(a.workspace,e),r=Rt(a.workspace,e);return{slug:e,tree:n,deps:r}}function Pm(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=V(t);return Rr(n.workspace,e,a)}function $m(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=V(t);return Pr(r.workspace,a,n,String(e?.content??""))}function jm(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t);return Rt(a.workspace,e)}async function Om(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=Ti(e?.worker),{def:o}=V(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(`
|
|
10717
|
+
`);return Ai(a,r,s,`install-${n}:${Date.now()}`)}async function Nm(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=Ti(e?.worker),{def:o}=V(t),s=Rt(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=ki(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(`
|
|
10718
|
+
`);return Ai(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function Ti(t){if(t&&typeof t=="string")return t;let e=X();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function Ai(t,e,a,n){let r=X(),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(),d;try{d=JSON.parse(c)}catch{d={content:c}}if(!l.ok)throw new Error(d?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:d?.taskId,content:d?.content,duration:d?.duration,error:d?.error}}function Dm(t){let e=Ei(),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 Hm(t,e){try{let n=(X().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 rn(){return new Fn}function Bm(t){let e=rn(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function zm(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=rn().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 qm(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:rn().remove(e,a,n)?"Released":"No active handover for that chat"}}function aa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Fm(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 $e={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 Ci=[{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 on(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify($e)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
|
|
10681
10719
|
<span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
|
|
10682
10720
|
<span id="conn-label">live</span>`,n=`<div class="ax-app-live">
|
|
10683
10721
|
<section id="statstrip" class="ax-statstrip"></section>
|
|
10684
10722
|
<main id="grid" class="ax-live__body"></main>
|
|
10685
10723
|
</div>
|
|
10686
|
-
`;return I({title:`${$e.brand} \xB7 ${$e.subtitle}`,activeTab:"live",subtitle:$e.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:
|
|
10724
|
+
`;return I({title:`${$e.brand} \xB7 ${$e.subtitle}`,activeTab:"live",subtitle:$e.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:Um,scripts:e+`<script>${Wm}</script>`,headExtras:`<script>
|
|
10687
10725
|
// rightExtras for the topbar are injected at runtime \u2014 they reference
|
|
10688
10726
|
// IDs (#ts, #conn-dot) that the script below addresses directly.
|
|
10689
10727
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -10694,7 +10732,7 @@ loadAgent();
|
|
|
10694
10732
|
extras.innerHTML = ${JSON.stringify(a)};
|
|
10695
10733
|
right.insertBefore(extras, right.firstChild);
|
|
10696
10734
|
});
|
|
10697
|
-
</script>`})}var
|
|
10735
|
+
</script>`})}var Um=`
|
|
10698
10736
|
/* --- Page frame --- */
|
|
10699
10737
|
.ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
|
|
10700
10738
|
|
|
@@ -10717,6 +10755,14 @@ loadAgent();
|
|
|
10717
10755
|
.ax-node__session { display: inline-flex; gap: 6px; align-items: center; padding: 2px 8px; border: 1px solid var(--ax-line, currentColor); border-radius: 999px; color: var(--ax-text-2, inherit); }
|
|
10718
10756
|
.ax-node__session.is-bound { color: var(--ax-text, inherit); border-color: var(--ax-accent, currentColor); }
|
|
10719
10757
|
.ax-node__session.is-waiting { border-style: dashed; }
|
|
10758
|
+
.ax-node__stopped { padding: 10px 16px 0; font-size: 12px; color: var(--ax-muted); }
|
|
10759
|
+
.ax-node__stopped ul { list-style: none; margin: 6px 0 0; padding: 0; display: grid; gap: 6px; }
|
|
10760
|
+
.ax-node__stopped-item { border: 1px solid var(--ax-border); border-radius: 6px; padding: 6px 10px; color: var(--ax-text-2, inherit); }
|
|
10761
|
+
.ax-node__stopped-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; }
|
|
10762
|
+
.ax-node__stopped-head .ax-task-action { margin-left: auto; }
|
|
10763
|
+
.ax-node__stopped-ask { margin-top: 2px; overflow-wrap: anywhere; }
|
|
10764
|
+
.ax-node__stopped summary { cursor: pointer; margin-top: 4px; }
|
|
10765
|
+
.ax-node__stopped-plan { white-space: pre-wrap; overflow-wrap: anywhere; font-family: var(--ax-mono); font-size: 11px; margin: 4px 0 0; max-height: 240px; overflow: auto; }
|
|
10720
10766
|
.ax-node__tag {
|
|
10721
10767
|
font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px;
|
|
10722
10768
|
padding: 2px 7px; border-radius: 3px; border: 1px solid var(--ax-border-2);
|
|
@@ -10901,7 +10947,7 @@ loadAgent();
|
|
|
10901
10947
|
border-top-color: var(--ax-accent); border-radius: 50%;
|
|
10902
10948
|
animation: ax-spin 800ms linear infinite; display: inline-block;
|
|
10903
10949
|
}
|
|
10904
|
-
@keyframes ax-spin { to { transform: rotate(360deg); } }`,
|
|
10950
|
+
@keyframes ax-spin { to { transform: rotate(360deg); } }`,Wm=`
|
|
10905
10951
|
'use strict';
|
|
10906
10952
|
|
|
10907
10953
|
const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
|
|
@@ -11062,7 +11108,7 @@ function renderNode(node) {
|
|
|
11062
11108
|
sec.innerHTML = '<header>' +
|
|
11063
11109
|
'<span class="ax-node__name">' + escapeHtml(node.name) + '</span>' +
|
|
11064
11110
|
'<span class="ax-node__url">' + escapeHtml(node.url) + '</span>' +
|
|
11065
|
-
tag + (node.stale ? '' : restartHtml(node)) + '</header>' + sessionsHtml(node) + '<div class="ax-grid--agents"></div>';
|
|
11111
|
+
tag + (node.stale ? '' : restartHtml(node)) + '</header>' + sessionsHtml(node) + stoppedHtml(node) + '<div class="ax-grid--agents"></div>';
|
|
11066
11112
|
const g = sec.querySelector('.ax-grid--agents');
|
|
11067
11113
|
if (!node.reachable || node.agents.length === 0) {
|
|
11068
11114
|
const empty = document.createElement('div');
|
|
@@ -11092,6 +11138,44 @@ function sessionsHtml(node) {
|
|
|
11092
11138
|
return '<div class="ax-node__sessions" aria-label="Claude Code sessions"><span>Claude Code sessions</span>' + chips + '</div>';
|
|
11093
11139
|
}
|
|
11094
11140
|
|
|
11141
|
+
// #857 \u2014 tasks a stop signal paused on this node, each with the resume plan
|
|
11142
|
+
// it left (folded) and a Resume button. Hidden when there are none.
|
|
11143
|
+
function stoppedHtml(node) {
|
|
11144
|
+
const rows = node.stoppedTasks || [];
|
|
11145
|
+
if (!rows.length) return '';
|
|
11146
|
+
const url = escapeHtml(node.url);
|
|
11147
|
+
const items = rows.map(t => {
|
|
11148
|
+
const by = t.plan ? (t.plan.author === 'agent' ? 'plan by the agent' : 'plan by AgentX (' + (t.plan.note || 'no answer') + ')') : 'writing its plan\u2026';
|
|
11149
|
+
const resume = t.state === 'stopped' && t.resumable
|
|
11150
|
+
? '<button type="button" class="ax-task-action" data-action="signal-resume" data-stopped-id="' + escapeHtml(t.id) + '" data-node-url="' + url + '" title="Resume this task from its plan, in the same chat">\u25B6 resume</button>'
|
|
11151
|
+
: '';
|
|
11152
|
+
return '<li class="ax-node__stopped-item">' +
|
|
11153
|
+
'<div class="ax-node__stopped-head"><b>' + escapeHtml(t.agentId) + '</b> \xB7 ' + escapeHtml(t.channel) +
|
|
11154
|
+
' \xB7 stopped by ' + escapeHtml(t.stoppedBy) + ' \xB7 ' + escapeHtml(fmtAgo(t.stoppedAt)) +
|
|
11155
|
+
(t.reason ? ' \xB7 ' + escapeHtml(t.reason) : '') + resume + '</div>' +
|
|
11156
|
+
'<div class="ax-node__stopped-ask">' + escapeHtml(t.request) + '</div>' +
|
|
11157
|
+
(t.plan ? '<details><summary>' + escapeHtml(by) + '</summary><pre class="ax-node__stopped-plan">' + escapeHtml(t.plan.text) + '</pre></details>'
|
|
11158
|
+
: '<div class="ax-node__stopped-ask">' + escapeHtml(by) + '</div>') +
|
|
11159
|
+
'</li>';
|
|
11160
|
+
}).join('');
|
|
11161
|
+
return '<div class="ax-node__stopped" aria-label="Stopped tasks"><span>Stopped tasks \xB7 ' + rows.length + '</span><ul>' + items + '</ul></div>';
|
|
11162
|
+
}
|
|
11163
|
+
|
|
11164
|
+
function signalPost(el, path, nodeUrl, body, done) {
|
|
11165
|
+
el.disabled = true;
|
|
11166
|
+
fetch(path + '?node=' + encodeURIComponent(nodeUrl), {
|
|
11167
|
+
method: 'POST',
|
|
11168
|
+
headers: { 'Content-Type': 'application/json', 'X-Requested-With': 'agentx-board' },
|
|
11169
|
+
body: JSON.stringify(body),
|
|
11170
|
+
})
|
|
11171
|
+
.then(async function (r) {
|
|
11172
|
+
const res = await r.json().catch(function () { return {}; });
|
|
11173
|
+
if (!r.ok) throw new Error(res.error || ('HTTP ' + r.status));
|
|
11174
|
+
el.textContent = done;
|
|
11175
|
+
})
|
|
11176
|
+
.catch(function (err) { el.disabled = false; alert('Failed: ' + (err && err.message || err)); });
|
|
11177
|
+
}
|
|
11178
|
+
|
|
11095
11179
|
// "Restart when idle": the node restarts itself once no task is running.
|
|
11096
11180
|
// Only nodes that report restart state (GET /health) offer it.
|
|
11097
11181
|
function restartHtml(node) {
|
|
@@ -11180,6 +11264,7 @@ function renderAgent(a, node) {
|
|
|
11180
11264
|
const actions = t.id
|
|
11181
11265
|
? '<div class="ax-agent__task-actions">' +
|
|
11182
11266
|
'<button type="button" class="ax-task-action ax-task-action--update" data-action="followup" data-task-id="' + escapeHtml(t.id) + '" data-node-url="' + escapeHtml(nodeUrl) + '" title="Add a message to this chat \u2014 the current turn keeps running, your message dispatches as the next turn">\u270E update</button>' +
|
|
11267
|
+
'<button type="button" class="ax-task-action ax-task-action--pause" data-action="signal-stop" data-task-id="' + escapeHtml(t.id) + '" data-node-url="' + escapeHtml(nodeUrl) + '" title="Stop this task and keep a resume plan, so it can be resumed later">\u275A\u275A pause</button>' +
|
|
11183
11268
|
'<button type="button" class="ax-task-action ax-task-action--stop" data-action="cancel" data-task-id="' + escapeHtml(t.id) + '" data-node-url="' + escapeHtml(nodeUrl) + '" title="Stop this running task">\u2715 stop</button>' +
|
|
11184
11269
|
'</div>'
|
|
11185
11270
|
: '';
|
|
@@ -11393,6 +11478,16 @@ document.getElementById('grid').addEventListener('click', (e) => {
|
|
|
11393
11478
|
nodeRestart(actionEl, action === 'node-restart-cancel');
|
|
11394
11479
|
return;
|
|
11395
11480
|
}
|
|
11481
|
+
if (action === 'signal-stop') {
|
|
11482
|
+
const reason = prompt('Pause this task? The agent writes a resume plan, and you can resume it later.\\nReason (optional):', '');
|
|
11483
|
+
if (reason === null) return;
|
|
11484
|
+
signalPost(actionEl, '/api/signals/stop', nodeUrl, { taskId: taskId, reason: reason || undefined }, 'pausing\u2026');
|
|
11485
|
+
return;
|
|
11486
|
+
}
|
|
11487
|
+
if (action === 'signal-resume') {
|
|
11488
|
+
signalPost(actionEl, '/api/signals/resume', nodeUrl, { id: actionEl.dataset.stoppedId }, 'resumed');
|
|
11489
|
+
return;
|
|
11490
|
+
}
|
|
11396
11491
|
if (action === 'voice-stop') {
|
|
11397
11492
|
actionEl.disabled = true;
|
|
11398
11493
|
fetch('/api/voice/stop?node=' + encodeURIComponent(nodeUrl), { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' })
|
|
@@ -11472,7 +11567,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11472
11567
|
});
|
|
11473
11568
|
}
|
|
11474
11569
|
|
|
11475
|
-
`;var
|
|
11570
|
+
`;var Ii=`
|
|
11476
11571
|
.mx-content{max-width:1180px;margin:0 auto;padding:0 24px 56px}
|
|
11477
11572
|
.mx-updated{margin:0;color:var(--ax-muted);font-size:11px;font-family:var(--ax-mono)}
|
|
11478
11573
|
.mx-section{margin-bottom:28px}.mx-section .ax-section-head{margin-bottom:14px}
|
|
@@ -11646,7 +11741,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11646
11741
|
.mx-summary{max-width:56vw}
|
|
11647
11742
|
}
|
|
11648
11743
|
@media(prefers-reduced-motion:reduce){.mx-drawer{transition:none}}
|
|
11649
|
-
`;var
|
|
11744
|
+
`;var Mi=`<script>
|
|
11650
11745
|
window.MX=(function(){
|
|
11651
11746
|
var ENT={'&':'&','<':'<','>':'>','"':'"',"'":'''};
|
|
11652
11747
|
function esc(v){return String(v==null?'':v).replace(/[&<>"']/g,function(c){return ENT[c]})}
|
|
@@ -11755,7 +11850,7 @@ window.MX=(function(){
|
|
|
11755
11850
|
verdict:verdict,verdictChip:verdictChip,mark:mark,causeLabel:causeLabel,
|
|
11756
11851
|
setHealth:setHealth,get:get};
|
|
11757
11852
|
})();
|
|
11758
|
-
</script>`;var
|
|
11853
|
+
</script>`;var Li=`<script>
|
|
11759
11854
|
window.MXD=(function(){
|
|
11760
11855
|
function el(id){return document.getElementById(id)}
|
|
11761
11856
|
function tz(){return -new Date().getTimezoneOffset()}
|
|
@@ -11969,7 +12064,7 @@ window.MXD=(function(){
|
|
|
11969
12064
|
|
|
11970
12065
|
return {openDay:openDay,openJob:openJob,openConversation:openConversation};
|
|
11971
12066
|
})();
|
|
11972
|
-
</script>`;var
|
|
12067
|
+
</script>`;var Ri=`<script>
|
|
11973
12068
|
(function(){
|
|
11974
12069
|
var LANES=[
|
|
11975
12070
|
{id:'cron',name:'Scheduled',hint:'cron jobs'},
|
|
@@ -12285,7 +12380,7 @@ window.MXD=(function(){
|
|
|
12285
12380
|
window.addEventListener('scroll',hideTip,{passive:true});
|
|
12286
12381
|
load();
|
|
12287
12382
|
})();
|
|
12288
|
-
</script>`;var
|
|
12383
|
+
</script>`;var Pi=`<script>
|
|
12289
12384
|
(function(){
|
|
12290
12385
|
var showAll=document.getElementById('mx-show-all'),expanded=false;
|
|
12291
12386
|
var esc=MX.esc;
|
|
@@ -12463,7 +12558,7 @@ window.MXD=(function(){
|
|
|
12463
12558
|
}
|
|
12464
12559
|
load();setInterval(load,5000);
|
|
12465
12560
|
})();
|
|
12466
|
-
</script>`;var
|
|
12561
|
+
</script>`;var $i=`
|
|
12467
12562
|
.mx-rt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:12px}
|
|
12468
12563
|
.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}
|
|
12469
12564
|
.mx-rt-wrap > .mx-empty{border:0}
|
|
@@ -12504,7 +12599,7 @@ window.MXD=(function(){
|
|
|
12504
12599
|
.mx-rt-msg td{display:block}.mx-rt-msg td::before{content:none}
|
|
12505
12600
|
.mx-rt-name{max-width:100%}
|
|
12506
12601
|
}
|
|
12507
|
-
|
|
12602
|
+
`,ji=`<script>
|
|
12508
12603
|
(function(){
|
|
12509
12604
|
var root=document.getElementById('mx-routines');
|
|
12510
12605
|
var bar=document.getElementById('mx-rt-filter');
|
|
@@ -12631,7 +12726,7 @@ window.MXD=(function(){
|
|
|
12631
12726
|
syncBar();
|
|
12632
12727
|
document.addEventListener('mx:snapshot',function(e){render(e.detail||{})});
|
|
12633
12728
|
})();
|
|
12634
|
-
</script>`;var
|
|
12729
|
+
</script>`;var Oi=[{id:"all",label:"All"},{id:"peers",label:"Other machines"},{id:"announce",label:"Announcements"},{id:"problems",label:"Problems"}],Ni=`<script>
|
|
12635
12730
|
(function(){
|
|
12636
12731
|
var root=document.getElementById('mx-feed');
|
|
12637
12732
|
if(!root)return;
|
|
@@ -12706,12 +12801,12 @@ window.MXD=(function(){
|
|
|
12706
12801
|
}
|
|
12707
12802
|
load();setInterval(load,5000);
|
|
12708
12803
|
})();
|
|
12709
|
-
</script>`;var ae={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>',feed:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1.5"/></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 ne(t,e,a,n,r=""){return K({icon:t,title:e,lead:a,actionHtml:r}).replace("<h2>",`<h2 id="${n}">`)}var
|
|
12804
|
+
</script>`;var ae={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>',feed:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M4 11a9 9 0 0 1 9 9"/><path d="M4 4a16 16 0 0 1 16 16"/><circle cx="5" cy="19" r="1.5"/></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 ne(t,e,a,n,r=""){return K({icon:t,title:e,lead:a,actionHtml:r}).replace("<h2>",`<h2 id="${n}">`)}var Gm=[{id:"all",label:"All"},{id:"attention",label:"Flagged"},{id:"schedule",label:"Schedules"},{id:"event",label:"Events"}],Xm=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],Km=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function Di(t){let e=pe({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+Pt([{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">
|
|
12710
12805
|
<div class="mx-tabs" role="tablist" aria-label="Mesh views">
|
|
12711
|
-
${
|
|
12806
|
+
${Xm.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("")}
|
|
12712
12807
|
</div>
|
|
12713
12808
|
<div class="mx-range" id="mx-range" role="group" aria-label="History window">
|
|
12714
|
-
${
|
|
12809
|
+
${Km.map(i=>`<button type="button" data-days="${i.days}" aria-pressed="${i.days===30}">${i.label}</button>`).join("")}
|
|
12715
12810
|
</div>
|
|
12716
12811
|
</div>
|
|
12717
12812
|
<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">
|
|
@@ -12764,7 +12859,7 @@ window.MXD=(function(){
|
|
|
12764
12859
|
<section class="mx-section" aria-labelledby="mx-routines-title">
|
|
12765
12860
|
${ne(ae.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>')}
|
|
12766
12861
|
<div class="mx-rt-bar" id="mx-rt-filter" role="group" aria-label="Filter routines">
|
|
12767
|
-
${
|
|
12862
|
+
${Gm.map(i=>`<button class="mx-chip" type="button" data-rt-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12768
12863
|
</div>
|
|
12769
12864
|
<div class="mx-rt-wrap" id="mx-routines"><div class="mx-empty">Loading routines...</div></div>
|
|
12770
12865
|
</section>
|
|
@@ -12772,7 +12867,7 @@ window.MXD=(function(){
|
|
|
12772
12867
|
<section class="mx-section" aria-labelledby="mx-feed-title">
|
|
12773
12868
|
${ne(ae.feed,"Mesh feed","The newest events from this machine and every machine it follows. Unreachable machines and announcements show here too. Select an event for its details.","mx-feed-title",'<div class="mx-section-actions"><span class="ax-tab-count" id="mx-feed-count">0 events</span><button class="ax-btn ax-btn--ghost" id="mx-feed-more" type="button" hidden>Show all</button></div>')}
|
|
12774
12869
|
<div class="mx-rt-bar" role="group" aria-label="Filter the mesh feed">
|
|
12775
|
-
${
|
|
12870
|
+
${Oi.map(i=>`<button class="mx-chip" type="button" data-feed-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12776
12871
|
</div>
|
|
12777
12872
|
<div class="ax-stack" id="mx-feed" aria-live="polite"><div class="mx-empty">Loading the mesh feed...</div></div>
|
|
12778
12873
|
</section>
|
|
@@ -12805,7 +12900,7 @@ window.MXD=(function(){
|
|
|
12805
12900
|
<button class="ax-btn ax-btn--ghost" id="mx-close" type="button" aria-label="Close details">Close</button>
|
|
12806
12901
|
</header>
|
|
12807
12902
|
<div class="mx-drawer__body" id="mx-drawer-body"></div>
|
|
12808
|
-
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:
|
|
12903
|
+
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:Ii+$i,scripts:Mi+Jm+Li+Ri+ji+Pi+Ni})}var Jm=`<script>
|
|
12809
12904
|
(function(){
|
|
12810
12905
|
var tabs=Array.prototype.slice.call(document.querySelectorAll('.mx-tab'));
|
|
12811
12906
|
var range=document.getElementById('mx-range');
|
|
@@ -12833,10 +12928,10 @@ window.MXD=(function(){
|
|
|
12833
12928
|
var saved=null;try{saved=localStorage.getItem('mx-view')}catch(e){}
|
|
12834
12929
|
select(tabs.some(function(t){return t.dataset.view===saved})?saved:'activity');
|
|
12835
12930
|
})();
|
|
12836
|
-
</script>`;function
|
|
12931
|
+
</script>`;function Hi(t){let e=pe({kicker:"Operations",title:"Guest meshes",lead:"Other organisations let into part of this mesh. Each grant names one agent of yours, what it may touch for them, how much freedom it has and until when. Nothing is shared until you open it."})+`
|
|
12837
12932
|
<div id="gm-msg" class="gm-msg" role="status" aria-live="polite"></div>
|
|
12838
12933
|
<ol id="gm-list" class="gm-list" aria-label="Grants"><li class="gm-empty">Loading\u2026</li></ol>
|
|
12839
|
-
<p class="gm-note">Open a grant from a terminal: <code>agentx mesh guests invite --name "\u2026" --guest "\u2026" --agent <id></code>. The guest joins with the code; its join arrives as a card in Approvals.</p>`;return I({title:"AgentX \xB7 Guest meshes",activeTab:"mesh",subtitle:"Guest meshes",peers:t.peers,body:e,css:
|
|
12934
|
+
<p class="gm-note">Open a grant from a terminal: <code>agentx mesh guests invite --name "\u2026" --guest "\u2026" --agent <id></code>. The guest joins with the code; its join arrives as a card in Approvals.</p>`;return I({title:"AgentX \xB7 Guest meshes",activeTab:"mesh",subtitle:"Guest meshes",peers:t.peers,body:e,css:Vm,scripts:`<script>${Ym}</script>`})}var Vm=`
|
|
12840
12935
|
.gm-list { list-style: none; margin: 16px 0; padding: 0; display: grid; gap: 12px; }
|
|
12841
12936
|
.gm-empty { color: var(--ax-text-2); }
|
|
12842
12937
|
.gm-item { padding: 14px 16px; border: var(--ax-border-w) solid var(--ax-border); border-radius: var(--ax-radius); background: var(--ax-surface); }
|
|
@@ -12854,7 +12949,7 @@ window.MXD=(function(){
|
|
|
12854
12949
|
.gm-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
12855
12950
|
.gm-msg.is-bad { color: var(--ax-red-ink); }
|
|
12856
12951
|
.gm-note { color: var(--ax-text-2); font-size: var(--ax-fs-sm); }
|
|
12857
|
-
`,
|
|
12952
|
+
`,Ym=`
|
|
12858
12953
|
(function () {
|
|
12859
12954
|
var list = document.getElementById('gm-list');
|
|
12860
12955
|
var msg = document.getElementById('gm-msg');
|
|
@@ -12901,7 +12996,7 @@ window.MXD=(function(){
|
|
|
12901
12996
|
load();
|
|
12902
12997
|
setInterval(load, 30000);
|
|
12903
12998
|
})();
|
|
12904
|
-
`;async function
|
|
12999
|
+
`;async function Bi(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 Qm(s,e.days)}function Qm(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,d=0,p=0,m=0,g=0,_=0;for(let{node:S,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 h of T.days){let u=n.get(h.day)||{day:h.day,cron:[0,0],workflow:[0,0],direct:[0,0]};for(let f of["cron","workflow","direct"])u[f][0]+=h[f]?.[0]||0,u[f][1]+=h[f]?.[1]||0;n.set(h.day,u)}for(let h of T.origins){let u=r.get(h.channel)||{channel:h.channel,runs:0,errors:0,hours:0};u.runs+=h.runs,u.errors+=h.errors,u.hours+=h.hours,r.set(h.channel,u)}for(let h of T.causes){let u=o.get(h.cause)||{cause:h.cause,count:0,agents:[],example:""};u.count+=h.count;for(let f of h.agents)u.agents.includes(f)||u.agents.push(f);u.example||(u.example=h.example),o.set(h.cause,u)}for(let h of T.rotations.byReason)s.set(h.reason,(s.get(h.reason)||0)+h.count);c+=T.rotations.total,d+=T.rotations.tokenSum||0,p+=T.rotations.tokenSamples||0,m=Math.max(m,T.rotations.maxTokens),g+=T.retention.traces,_+=T.retention.tracesWithSteps;for(let h of T.jobs)i.push({...h,node:S.name,nodeUrl:S.url});for(let h of T.threads)l.push({...h,node:S.name,nodeUrl:S.url})}let b=t.filter(S=>S.data).map(S=>S.data.since).filter(S=>Number.isFinite(S));return{generatedAt:Date.now(),windowDays:e,since:b.length?Math.min(...b):Date.now()-e*864e5,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,hours:Math.round(a.hours*100)/100},days:[...n.values()].sort((S,T)=>S.day.localeCompare(T.day)),origins:[...r.values()].map(S=>({...S,hours:Math.round(S.hours*100)/100})).sort((S,T)=>T.runs-S.runs),causes:[...o.values()].sort((S,T)=>T.count-S.count),jobs:i.sort((S,T)=>T.hours-S.hours),threads:l.sort((S,T)=>T.lastAt-T.firstAt-(S.lastAt-S.firstAt)||T.runs-S.runs),rotations:{total:c,byReason:[...s.entries()].map(([S,T])=>({reason:S,count:T})).sort((S,T)=>T.count-S.count),tokenSum:d,tokenSamples:p,maxTokens:m},retention:{traces:g,tracesWithSteps:_}}}async function zi(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 qi(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 Zm(s,e.day)}function Zm(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 Fi(t={}){let e=`
|
|
12905
13000
|
<select id="boardPicker" title="Switch board"></select>
|
|
12906
13001
|
<div class="search">
|
|
12907
13002
|
<span class="icon">\u2315</span>
|
|
@@ -13002,7 +13097,7 @@ window.MXD=(function(){
|
|
|
13002
13097
|
</footer>
|
|
13003
13098
|
</div>
|
|
13004
13099
|
</div>
|
|
13005
|
-
<script src="/sortable.min.js"></script>`;return I({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:
|
|
13100
|
+
<script src="/sortable.min.js"></script>`;return I({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:ef,scripts:`<script>${tf}</script>`,headExtras:`<script>
|
|
13006
13101
|
// The boards page has its own connection dot + wants body height:100%
|
|
13007
13102
|
// for the full-viewport kanban layout. Inject the dot into the topbar
|
|
13008
13103
|
// and override body height at runtime so the shared shell doesn't
|
|
@@ -13018,7 +13113,7 @@ window.MXD=(function(){
|
|
|
13018
13113
|
right.insertBefore(dot, right.firstChild);
|
|
13019
13114
|
}
|
|
13020
13115
|
});
|
|
13021
|
-
</script>`})}var
|
|
13116
|
+
</script>`})}var ef=`
|
|
13022
13117
|
/* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
|
|
13023
13118
|
.ax-subheader select, .ax-subheader input, .ax-subheader button {
|
|
13024
13119
|
background: var(--col); color: var(--text); border: 1px solid var(--border);
|
|
@@ -13271,7 +13366,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
|
|
|
13271
13366
|
.draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
|
|
13272
13367
|
.draft-box .draft-row .hint.err { color: var(--red); }
|
|
13273
13368
|
.draft-box .draft-row .hint.ok { color: var(--green); }
|
|
13274
|
-
`,
|
|
13369
|
+
`,tf=`
|
|
13275
13370
|
'use strict';
|
|
13276
13371
|
const state = {
|
|
13277
13372
|
boards: [], current: null, items: {},
|
|
@@ -14324,9 +14419,9 @@ function appendEvents(events) {
|
|
|
14324
14419
|
}
|
|
14325
14420
|
|
|
14326
14421
|
loadBoards().catch(e => toast('Init failed: ' + e.message));
|
|
14327
|
-
`;function
|
|
14422
|
+
`;function Ui(t={}){let a=`<h1>Plain-English glossary</h1>
|
|
14328
14423
|
<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>
|
|
14329
|
-
${
|
|
14424
|
+
${Ci.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${H(n.alias)}</span>`:"";return`<article class="term"><h3>${H(n.term)}${r}</h3><p>${H(n.definition)}</p></article>`}).join("")}`;return I({title:`${$e.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:af})}var af=`
|
|
14330
14425
|
main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
|
|
14331
14426
|
h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
|
|
14332
14427
|
.lead {
|
|
@@ -14356,7 +14451,7 @@ article.term .alias {
|
|
|
14356
14451
|
}
|
|
14357
14452
|
article.term p {
|
|
14358
14453
|
margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
|
|
14359
|
-
}`;function
|
|
14454
|
+
}`;function Wi(t={}){let e=`<div class="ax-wf__root">
|
|
14360
14455
|
<aside class="ax-wf__list">
|
|
14361
14456
|
<header>
|
|
14362
14457
|
<h2>Workflows</h2>
|
|
@@ -14441,7 +14536,7 @@ article.term p {
|
|
|
14441
14536
|
</aside>
|
|
14442
14537
|
</div>
|
|
14443
14538
|
|
|
14444
|
-
<div id="wf-toast" class="ax-wf__toast" hidden></div>`;return I({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
14539
|
+
<div id="wf-toast" class="ax-wf__toast" hidden></div>`;return I({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:nf,scripts:`<script>${q({workflowHealth:er})}${rf}</script>`})}var nf=`
|
|
14445
14540
|
.ax-wf__root {
|
|
14446
14541
|
display: grid;
|
|
14447
14542
|
grid-template-columns: 340px 1fr;
|
|
@@ -14847,7 +14942,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14847
14942
|
font-size: 12px; z-index: 50;
|
|
14848
14943
|
}
|
|
14849
14944
|
.hint { color: var(--ax-muted); font-size: 11px; }
|
|
14850
|
-
`,
|
|
14945
|
+
`,rf=`
|
|
14851
14946
|
(() => {
|
|
14852
14947
|
const $ = (sel) => document.querySelector(sel)
|
|
14853
14948
|
const $$ = (sel) => Array.from(document.querySelectorAll(sel))
|
|
@@ -15672,7 +15767,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15672
15767
|
setInterval(refresh, 15000)
|
|
15673
15768
|
})
|
|
15674
15769
|
})();
|
|
15675
|
-
`;function
|
|
15770
|
+
`;function Gi(t={}){let e=`<div class="ax-proc__root">
|
|
15676
15771
|
<header class="ax-proc__header">
|
|
15677
15772
|
<h1>Procedures</h1>
|
|
15678
15773
|
<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>
|
|
@@ -15716,7 +15811,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15716
15811
|
<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>
|
|
15717
15812
|
<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>
|
|
15718
15813
|
</section>
|
|
15719
|
-
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
15814
|
+
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:of,scripts:`<script>${sf}</script>`})}var of=`
|
|
15720
15815
|
.ax-proc__root { padding: 18px 24px 40px; max-width: 1100px; margin: 0 auto; color: var(--ax-text); }
|
|
15721
15816
|
.ax-proc__header h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
15722
15817
|
.ax-proc__header .hint { color: var(--ax-muted); font-size: 12px; margin: 0 0 18px; }
|
|
@@ -15742,7 +15837,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15742
15837
|
.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); }
|
|
15743
15838
|
.ax-proc__link { color: var(--ax-accent, #6366f1); text-decoration: none; font-size: 11px; }
|
|
15744
15839
|
.ax-proc__link:hover { text-decoration: underline; }
|
|
15745
|
-
`,
|
|
15840
|
+
`,sf=`
|
|
15746
15841
|
(function(){
|
|
15747
15842
|
function $(sel){ return document.querySelector(sel) }
|
|
15748
15843
|
function esc(s){ return String(s||"").replace(/[&<>"']/g, function(c){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c] }) }
|
|
@@ -15842,7 +15937,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15842
15937
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootAll)
|
|
15843
15938
|
else bootAll()
|
|
15844
15939
|
})();
|
|
15845
|
-
`;function
|
|
15940
|
+
`;function Xi(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
|
|
15846
15941
|
data-task-id="${H(t.taskId)}"
|
|
15847
15942
|
data-agent-id="${H(t.agentId)}"
|
|
15848
15943
|
data-node-url="${H(t.nodeUrl)}"
|
|
@@ -15885,7 +15980,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15885
15980
|
<button type="button" id="task-send" class="ax-btn ax-btn--primary">send \u2192</button>
|
|
15886
15981
|
</div>
|
|
15887
15982
|
</footer>
|
|
15888
|
-
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
15983
|
+
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:lf,scripts:`<script>${cf}</script>`})}var lf=`
|
|
15889
15984
|
/* The shell gives <main> no padding, so page content butted straight against
|
|
15890
15985
|
the sticky topbar. Breathe. */
|
|
15891
15986
|
.ax-task-page {
|
|
@@ -16027,7 +16122,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16027
16122
|
line-height: 1.55; text-wrap: pretty; white-space: pre-wrap; word-break: break-word;
|
|
16028
16123
|
}
|
|
16029
16124
|
|
|
16030
|
-
`,
|
|
16125
|
+
`,cf=`
|
|
16031
16126
|
(function () {
|
|
16032
16127
|
var root = document.querySelector('.ax-task-page');
|
|
16033
16128
|
if (!root) return;
|
|
@@ -16412,7 +16507,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16412
16507
|
});
|
|
16413
16508
|
|
|
16414
16509
|
})();
|
|
16415
|
-
`;function
|
|
16510
|
+
`;function Ki(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
|
|
16416
16511
|
data-agent-id="${H(t.agentId)}"
|
|
16417
16512
|
data-agent-name="${H(e)}"
|
|
16418
16513
|
data-node-url="${H(t.nodeUrl)}">
|
|
@@ -16441,7 +16536,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16441
16536
|
<div class="ax-history__list" id="hist-list">
|
|
16442
16537
|
<div class="ax-history__empty">loading\u2026</div>
|
|
16443
16538
|
</div>
|
|
16444
|
-
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
16539
|
+
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:df,scripts:`<script>${pf}</script>`})}var df=`
|
|
16445
16540
|
/* <main> carries no padding in the shell \u2014 without this the breadcrumb sits
|
|
16446
16541
|
flush against the sticky topbar. */
|
|
16447
16542
|
.ax-history {
|
|
@@ -16493,7 +16588,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16493
16588
|
-webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
|
16494
16589
|
}
|
|
16495
16590
|
.ax-history__foot { margin-top: 6px; font-size: var(--ax-fs-xs); color: var(--ax-muted); font-family: var(--ax-mono); }
|
|
16496
|
-
`,
|
|
16591
|
+
`,pf=`
|
|
16497
16592
|
(function () {
|
|
16498
16593
|
var root = document.querySelector('.ax-history');
|
|
16499
16594
|
if (!root) return;
|
|
@@ -16593,11 +16688,11 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16593
16688
|
listEl.innerHTML = '<div class="ax-history__empty" style="color:var(--ax-err)">' + esc(e.message) + '</div>';
|
|
16594
16689
|
});
|
|
16595
16690
|
})();
|
|
16596
|
-
`;function
|
|
16691
|
+
`;function Vi(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"])?P(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=>Ji(e,a,l,{mode:"create",convertFromYaml:i}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:mf(t,e,a,n);if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return P(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return P(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 P(e,200,{ok:!0,emission:c})}):P(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"])?P(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 P(e,200,{layout:c})}catch(c){return P(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=wa.safeParse(l);if(!c.success)return P(e,200,{ok:!1,issues:c.error.issues.map(p=>({path:p.path.join("."),message:p.message}))});let d=ka(c.data).map(p=>({path:"",message:p}));return P(e,200,{ok:d.length===0,issues:d,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?P(e,200,{workflow:l}):P(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,d=>Ji(e,a,d,{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),P(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return P(e,404,{error:"unknown workflows endpoint",path:n})}var uf=["mesh"];function Ji(t,e,a,n){let r=wa.safeParse(a);if(!r.success)return P(t,400,{error:"invalid workflow",issues:r.error.issues.map(l=>({path:l.path.join("."),message:l.message}))});let o=r.data,s=ka(o);if(s.length>0)return P(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return P(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return P(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 d of uf)!(d in l)&&d in c&&(o[d]=c[d])}let i;try{i=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(l){let c=l?.message||String(l),d=l?.yamlPath,p=!!d||/yaml round-trip failed/.test(c);return P(t,p?409:500,{error:p?"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:p?"yaml-authored":"save-failed",...d?{path:d}:{}})}return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),P(t,200,{workflow:i})}function mf(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,d=r.get("summary")==="1"||r.get("summary")==="true",p=a.runs.list({workflowId:c,limit:l});if(!d)return P(e,200,{runs:p});let m=p.map(g=>({id:g.id,workflowId:g.workflowId,workflowVersion:g.workflowVersion,homeNode:g.homeNode,status:g.status,pending:g.pending,entityRef:g.entityRef,history:(g.history||[]).slice(-5),parentRunId:g.parentRunId,parentNodeId:g.parentNodeId,rootRunId:g.rootRunId,depth:g.depth,createdAt:g.createdAt,updatedAt:g.updatedAt}));return P(e,200,{runs:m})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return P(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 d=c?.status;return d!=="paused"&&d!=="running"&&d!=="canceled"?P(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,d)?P(e,200,{ok:!0,runId:l,status:d}):P(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return ff(t,e,a,l);let c=a.runs.get(l);return c?P(e,200,{run:c}):P(e,404,{error:"run not found"})}return P(e,404,{error:"unknown runs endpoint"})}function ff(t,e,a,n){let r=a.runs.get(n);if(!r)return P(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)}
|
|
16597
16692
|
|
|
16598
16693
|
`);let o=!1,s=()=>{o=!0,l?.(),clearInterval(d);try{e.end()}catch{}};t.on("close",s);let i=p=>{if(!o)try{e.write(`data: ${JSON.stringify(p)}
|
|
16599
16694
|
|
|
16600
|
-
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,d=setInterval(()=>{if(o)return;let p=a.runs.get(n);p&&p.updatedAt!==c&&(c=p.updatedAt,i(p))},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){P(e,400,{error:"invalid JSON body",message:s.message});return}let o;try{o=a(r)}catch(s){try{P(e,500,{error:"handler threw (sync)",message:s?.message??String(s)})}catch{}return}Promise.resolve(o).catch(s=>{try{P(e,500,{error:"handler threw",message:s?.message??String(s)})}catch{}})}),t.on("error",r=>P(e,400,{error:"body read failed",message:r.message})),!0}function P(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}import{readFileSync as
|
|
16695
|
+
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,d=setInterval(()=>{if(o)return;let p=a.runs.get(n);p&&p.updatedAt!==c&&(c=p.updatedAt,i(p))},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){P(e,400,{error:"invalid JSON body",message:s.message});return}let o;try{o=a(r)}catch(s){try{P(e,500,{error:"handler threw (sync)",message:s?.message??String(s)})}catch{}return}Promise.resolve(o).catch(s=>{try{P(e,500,{error:"handler threw",message:s?.message??String(s)})}catch{}})}),t.on("error",r=>P(e,400,{error:"body read failed",message:r.message})),!0}function P(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}import{readFileSync as sh}from"fs";import{createRequire as ih}from"module";On();var Qi=50,hf=280;async function Zi(t,e,a,n,r,o){if(a!=="/api/app/announcements")return!1;if(n==="GET"){let s=o.prefs(),i=[],l=null;try{i=gf(await o.recent(Qi))}catch(c){l=String(c?.message||"unreachable").slice(0,200)}return Yi(e,200,{items:i,error:l,notify:s?s.on(r.id,"announce"):!1,notifyAvailable:!!s})}return Yi(e,404,{error:"not found"})}function el(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=process.env.MESH_TOKEN||U(t.dashboard,e),n=t.channels.push;return{async recent(r){let o=await fetch(`${e}/events/recent?kind=announce&limit=${r}`,{headers:a?{Authorization:`Bearer ${a}`}:{},signal:AbortSignal.timeout(5e3)});if(!o.ok)throw new Error(`the daemon answered ${o.status}`);return(await o.json()).events??[]},prefs:()=>{if(!n.enabled)return null;if(n.relayTo)return wt();let r=ut();return r?new sr(r):null}}}function gf(t){let e=[];for(let a of Array.isArray(t)?t:[]){let n=a;!n||n.kind!=="announce"||typeof n.id!="string"||typeof n.at!="string"||e.push({id:n.id.slice(0,64),text:sn(typeof n.summary=="string"?n.summary:"",hf),by:typeof n.agentId=="string"?sn(n.agentId,100):null,node:sn(typeof n.node=="string"?n.node:"",100),at:n.at.slice(0,40)})}return e.sort((a,n)=>(Date.parse(n.at)||0)-(Date.parse(a.at)||0)),e.slice(0,Qi)}function sn(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}function Yi(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var xf="operator",bf=50,tl=4,al=500;function vf(t){let e={channel:"app",chatId:t.chatId,sender:xf,...t.spoken?{via:"voice"}:{}};return t.node==="local"?{path:"/task",body:{agent:t.agent,message:t.message,stream:!0,context:e}}:{path:"/mesh/task",body:{peer:t.node,agent:t.agent,message:t.message,stream:!0,context:e}}}async function nl(t,e,a,n){let{path:r,body:o}=vf(e),s="",i=!1,l=[],c=new Map,d=(p,m,g)=>{let _=p!=="done",b=i?{text:xt(m,_),artifacts:[]}:gt(m,de.perMessage,_),{cleanText:S,ui:T}=p==="done"?vt(b.text):{cleanText:b.text,ui:void 0},h=i?void 0:ln(T);return{status:p,text:S,tools:l,files:b.artifacts,...h?{ui:h}:{},...g?{error:g}:{}}};try{let p=await fetch(t.url.replace(/\/+$/,"")+r,{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream",...t.token?{Authorization:`Bearer ${t.token}`}:{},...t.operatorKey?{"X-AgentX-Operator":t.operatorKey}:{}},body:JSON.stringify(o),signal:a});if(!p.ok||!p.body){let m=await p.json().then(g=>g?.error).catch(()=>"");return d("error",s,m||`AgentX answered HTTP ${p.status}.`)}for await(let m of wf(p.body)){n(m.event,m.data);let g=m.data??{};if(m.event==="start")i=g.rich===!1;else if(m.event==="text"&&typeof g.text=="string")s+=g.text;else if(m.event==="tool"&&g.status==="start"&&l.length<bf){let _={name:String(g.name||"tool").slice(0,80),...g.arg?{arg:String(g.arg).slice(0,80)}:{}};l.push(_),g.id&&c.set(String(g.id),_)}else if(m.event==="tool"&&g.status==="result"&&g.error===!0&&c.has(String(g.id)))c.get(String(g.id)).error=!0;else{if(m.event==="done")return d("done",typeof g.content=="string"&&g.content?g.content:s);if(m.event==="error")return d("error",s,yf(g.error))}}return a.aborted?d("stopped",s):d("error",s,"The connection to the agent closed before it answered.")}catch(p){return a.aborted?d("stopped",s):d("error",s,`Could not reach AgentX: ${p?.message||p}`)}}function yf(t){let e=String(t||"The agent could not answer.");return Un(e)?"The agent is busy with other work. Send the message again when it is free.":e.slice(0,500)}function ln(t){if(!t)return;let e=s=>/^https?:\/\//i.test(s)&&s.length<=2048,a={},n=(t.buttons??[]).filter(s=>e(s.url)).slice(0,8).map(s=>({label:s.label.slice(0,80),url:s.url}));n.length&&(a.buttons=n),t.poll&&(a.poll={question:t.poll.question.slice(0,300),options:t.poll.options.slice(0,10).map(s=>s.slice(0,100)),multiple:t.poll.multiple===!0}),t.media&&e(t.media.url)&&(a.media={type:t.media.type,url:t.media.url,...t.media.caption?{caption:t.media.caption.slice(0,300)}:{}});let r=(t.quickReplies??[]).slice(0,tl).map(s=>s.slice(0,al));r.length&&(a.quickReplies=r);let o=(t.replies??[]).slice(0,tl).map(s=>({label:s.label.slice(0,80),reply:s.reply.slice(0,al)}));return o.length&&(a.replies=o),Object.keys(a).length?a:void 0}async function*wf(t){let e=t.getReader(),a=new TextDecoder,n="";try{for(;;){let{done:r,value:o}=await e.read();if(r)break;n+=a.decode(o,{stream:!0}).replace(/\r\n/g,`
|
|
16601
16696
|
`);let s;for(;(s=n.indexOf(`
|
|
16602
16697
|
|
|
16603
16698
|
`))!==-1;){let i=n.slice(0,s);n=n.slice(s+2);let l="message",c=[];for(let d of i.split(`
|
|
@@ -16607,17 +16702,17 @@ data: ${JSON.stringify(s)}
|
|
|
16607
16702
|
|
|
16608
16703
|
`)},r=setInterval(()=>{a()&&e.write(`: ping
|
|
16609
16704
|
|
|
16610
|
-
`)},15e3);r.unref?.(),this.listeners.set(n,e),this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=null),e.on("close",()=>{clearInterval(r),this.listeners.delete(n),!this.done&&!this.listeners.size&&!this.ac.signal.aborted&&!this.orphanTimer&&(this.orphanTimer=setTimeout(()=>{this.orphaned=!0,this.ac.abort()},this.orphanLimitMs),this.orphanTimer.unref?.())})}finish(){this.done=!0,this.orphanTimer&&clearTimeout(this.orphanTimer);for(let e of this.listeners.values())e.writableEnded||e.end();this.listeners.clear()}};function
|
|
16611
|
-
`)){let n=
|
|
16612
|
-
`).map(
|
|
16705
|
+
`)},15e3);r.unref?.(),this.listeners.set(n,e),this.orphanTimer&&(clearTimeout(this.orphanTimer),this.orphanTimer=null),e.on("close",()=>{clearInterval(r),this.listeners.delete(n),!this.done&&!this.listeners.size&&!this.ac.signal.aborted&&!this.orphanTimer&&(this.orphanTimer=setTimeout(()=>{this.orphaned=!0,this.ac.abort()},this.orphanLimitMs),this.orphanTimer.unref?.())})}finish(){this.done=!0,this.orphanTimer&&clearTimeout(this.orphanTimer);for(let e of this.listeners.values())e.writableEnded||e.end();this.listeners.clear()}};function ol(t,e,a,n=12){let r=[],o=new Set,s=e.filter(i=>i.deviceId===t).sort((i,l)=>i.startedAt-l.startedAt);for(let i of s){if(r.length>=n)break;o.add(i.id);let l=kf(i.text);r.push({id:i.id,title:i.title,agent:i.agent,agentName:i.agentName||i.agent,...i.color?{color:i.color}:{},state:l?"answering":"thinking",preview:l||i.title.slice(0,120),updatedAt:i.startedAt})}for(let i of a){if(r.length>=n)break;o.has(i.id)||(o.add(i.id),r.push({id:i.id,title:i.title,agent:i.agent,agentName:i.agentName||i.agent,...i.color?{color:i.color}:{},state:"done",status:i.status,preview:cn(i.answer)||(i.status==="done"?"Answered.":i.status==="stopped"?"Stopped.":"The agent could not answer."),updatedAt:i.at}))}return r}function cn(t,e=120){for(let a of t.split(`
|
|
16706
|
+
`)){let n=sl(a);if(n)return dn(n,e)}return""}function kf(t,e=120){let a=t.split(`
|
|
16707
|
+
`).map(sl).filter(Boolean);return a.length?dn(a[a.length-1],e):""}function sl(t){return t.replace(/^\s*(?:[#>]+|[-*+]\s|\d+\.\s)\s*/,"").replace(/[*_`]+/g,"").replace(/\s+/g," ").trim()}function dn(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}var ra=class{constructor(e=15e3){this.windowMs=e}seen=new Map;poll(e,a=Date.now()){this.seen.set(e,a)}away(e){this.seen.delete(e)}open(e,a=Date.now()){let n=this.seen.get(e);return n!==void 0&&a-n<=this.windowMs}};function oa(t){return t.enabled&&!t.attached&&!t.appOpen&&t.status!=="stopped"}var rl=140;function sa(t,e,a,n,r){let o=a==="error"?`Could not answer: ${cn(r||"",rl-18)||"something went wrong."}`:cn(n,rl)||"Answered.";return{deviceId:t,title:dn(e.agentName||e.agent,80),body:o,url:`/app#chat=${e.id}`}}var ll=8e3,Sf=/^[A-Za-z0-9_.:-]{1,64}$/,je=new Map,pn=new Map,fn=new ra;function cl(){return fn}async function dl(t,e,a,n,r,o){if(a!=="/api/app/agents"&&a!=="/api/app/chat"&&a!=="/api/app/chat/stop"&&a!=="/api/app/chat/attach"&&a!=="/api/app/chat/active"&&a!=="/api/app/chat/away"&&a!=="/api/app/conversations"&&!a.startsWith("/api/app/conversations/"))return!1;let s=o.presence??fn;if(n==="GET"&&a==="/api/app/agents")return B(e,200,{nodes:await pl(o)});let i=o.store();if(!i)return B(e,503,{error:"The database on this computer is unavailable, so chats can't be saved."});if(n==="GET"&&a==="/api/app/chat/active")return s.poll(r.id),B(e,200,{conversations:ol(r.id,Af(),i.unread(r.id,12))});if(n==="POST"&&a==="/api/app/chat/away")return s.away(r.id),B(e,200,{ok:!0});if(n==="GET"&&a==="/api/app/conversations")return B(e,200,{conversations:i.list(r.id)});let l=n==="GET"?/^\/api\/app\/conversations\/([^/]+)$/.exec(a):null;if(l){let d=i.get(r.id,decodeURIComponent(l[1]));if(!d)return B(e,404,{error:"no such conversation"});new URL(t.url||a,"http://x").searchParams.get("peek")!=="1"&&i.markRead(r.id,d.id);let p=je.get(d.id);return B(e,200,{...d,running:!!p,...p?{partial:{text:p.text,tools:p.tools,...p.plain?{plain:!0}:{}}}:{}})}if(n==="GET"&&a==="/api/app/chat/attach"){let d=i.get(r.id,new URL(t.url||a,"http://x").searchParams.get("conversationId")||""),p=d&&je.get(d.id);if(!d||!p)return B(e,404,{error:"nothing is running in this conversation"});i.markRead(r.id,d.id),ul(e);let{id:m,title:g,node:_,nodeName:b,agent:S,agentName:T}=d;return e.write(un("conversation",{id:m,title:g,node:_,nodeName:b,agent:S,agentName:T})),e.write(un("resume",{text:p.text,tools:p.tools,...p.plain?{plain:!0}:{}})),p.attach(e),!0}if(n!=="POST"||a!=="/api/app/chat"&&a!=="/api/app/chat/stop")return B(e,404,{error:"not found"});let c;try{c=await yt(t,64*1024)}catch(d){return B(e,400,{error:d.message})}if(a==="/api/app/chat/stop"){let d=i.get(r.id,String(c.conversationId??""));if(!d)return B(e,404,{error:"no such conversation"});let p=je.get(d.id);return p?(p.ac.abort(),mn(d,o,r.name),B(e,200,{stopped:!0})):await mn(d,o,r.name)?B(e,200,{stopped:!0}):B(e,404,{error:"nothing is running in this conversation"})}return await Tf(e,c,r,i,o),!0}function Ef(t,e,a){let n=Ke(e.url),r=new Set,o=[];for(let s of t){let i=Ke(s.url),l=a.find(p=>Ke(p.peerUrl)===i);l&&r.add(l.peer);let c=i===n,d=s.agents.length?s.agents:l?.skills??[];o.push({target:c?"local":l?l.peer:null,name:s.reachable?s.name:(c?e.name:l?.peer)||s.name,online:c?s.reachable:l?l.healthy:!1,agents:d.map(p=>{let m=Array.isArray(p.runningTasks)?p.runningTasks.length:0;return{id:p.id,name:p.name||p.id,busy:m>0||(p.active??0)>0,running:m,...p.color?{color:p.color}:{}}})})}for(let s of a)r.has(s.peer)||o.push({target:s.peer,name:s.peer,online:s.healthy,agents:(s.skills??[]).map(i=>({id:i.id,name:i.name||i.id,busy:!1,running:0}))});return o}async function pl(t){let[e,a]=await Promise.all([t.snapshot().catch(()=>({nodes:[]})),t.meshPeers().catch(()=>[])]);return Ef(e.nodes,t.daemon,a)}async function Tf(t,e,a,n,r){let o=typeof e.message=="string"?e.message.trim():"";if(!o||o.length>ll){B(t,400,{error:`message must be 1\u2013${ll} characters`});return}let s;if(e.conversationId!=null){if(s=n.get(a.id,String(e.conversationId)),!s){B(t,404,{error:"no such conversation"});return}}else{let _=typeof e.node=="string"?e.node:"",b=typeof e.agent=="string"?e.agent:"";if(!Sf.test(b)){B(t,400,{error:"pick an agent"});return}let S=(await pl(r)).find(h=>h.target===_);if(!S){B(t,400,{error:`unknown node "${_}"`});return}if(!S.online){B(t,409,{error:`${S.name} is offline`});return}let T=S.agents.find(h=>h.id===b);if(!T){B(t,400,{error:`no agent "${b}" on ${S.name}`});return}s=n.create(a.id,{node:_,nodeName:S.name,agent:b,agentName:T.name,...T.color?{color:T.color}:{}},o)}if(je.has(s.id)){B(t,409,{error:"The agent is still answering in this conversation."});return}let i=new na(r.orphanLimitMs??18e5);je.set(s.id,i);let{id:l,title:c,node:d,nodeName:p,agent:m,agentName:g}=s;pn.set(l,{id:l,deviceId:a.id,title:c,agent:m,...g?{agentName:g}:{},...s.color?{color:s.color}:{}}),n.append(a.id,s.id,{role:"user",content:o,at:Date.now()}),ul(t),t.write(un("conversation",{id:l,title:c,node:d,nodeName:p,agent:m,agentName:g})),i.attach(t);try{let _=e.spoken===!0,b=await nl(r.daemon,{node:d,agent:m,message:o,chatId:`app:${l}`,spoken:_},i.ac.signal,(u,f)=>i.broadcast(u,f));i.orphaned&&(b.error=`Stopped: the phone was away for more than ${Math.round((r.orphanLimitMs??18e5)/6e4)} minutes.`,mn(s,r,a.name));let S=n.appendWithFiles(a.id,l,{role:"assistant",content:b.text,status:b.status,at:Date.now(),...b.error?{error:b.error}:{},...b.ui?{ui:b.ui}:{},...b.tools.length?{tools:b.tools}:{}},b.files)??[];i.broadcast("final",{status:b.status,content:b.text,...b.error?{error:b.error}:{},...b.ui?{ui:b.ui}:{},...S.length?{files:S}:{}});let T=i.watched();T&&n.markRead(a.id,l);let h={status:b.status,attached:T,appOpen:(r.presence??fn).open(a.id),enabled:!!r.finishAlerts?.(a.id)};r.notifyFinish&&oa(h)&&r.notifyFinish(sa(a.id,s,b.status,b.text,b.error)).catch(()=>{})}finally{je.delete(l),pn.delete(l),i.finish()}}function Af(){let t=[];for(let[e,a]of pn){let n=je.get(e);n&&t.push({...a,text:n.text,startedAt:n.startedAt})}return t}function ul(t){t.writeHead(200,{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-store","X-Accel-Buffering":"no"})}function un(t,e){return`event: ${t}
|
|
16613
16708
|
data: ${JSON.stringify(e)}
|
|
16614
16709
|
|
|
16615
|
-
`}async function un(t,e,a){try{let n=Ke(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(c=>c.peer===t.node);if(!l)return 0;n=Ke(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Ke(l.url)===n)?.agents.find(l=>l.id===t.agent)?.runningTasks?.filter(l=>l.chatId===`app:${t.id}`)??[],i=0;for(let l of s)(await e.nodePost(n,`/api/tasks/${encodeURIComponent(l.id)}/cancel`,{reason:`cancelled by operator (phone: ${a})`})).status<300&&i++;return i}catch{return 0}}function Ke(t){return t.replace(/\/+$/,"")}function B(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{Readable as Tf}from"stream";var Af=/^\/api\/app\/files\/([^/]+)$/,Cf=15e3;async function ml(t,e,a,n,r,o){let s=Af.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return Oe(e,405,{error:"GET only"});let i=o.store();if(!i)return Oe(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let c=i.getFile(r.id,l);if(!c)return Oe(e,404,{error:"no such file"});let d=await If(c.node,o);if(!d)return Oe(e,502,{error:`${c.node} is not linked to this computer's mesh any more.`});let p=new AbortController;e.on("close",()=>p.abort());let m=setTimeout(()=>p.abort(),Cf),h;try{let x=new URLSearchParams({agent:c.agent,file:c.path});h=await fetch(`${d.url}${br}?${x}`,{method:n,headers:{...d.token?{Authorization:`Bearer ${d.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:p.signal})}catch{return Oe(e,502,{error:"The computer that made this file did not answer."})}finally{clearTimeout(m)}if(h.status!==200&&h.status!==206){let x=await h.json().then(f=>f?.error).catch(()=>""),u=[403,404,413,415,416].includes(h.status)?h.status:502;return Oe(e,u,{error:x||`The computer that made this file answered HTTP ${h.status}.`})}let S=Number(h.headers.get("content-length")||0);if(S>ce.bytes)return p.abort(),Oe(e,413,{error:"the file is too large"});let v=h.headers.get("content-range");if(e.writeHead(h.status,{...vr(c.mime,c.name,c.kind),...h.headers.get("content-length")?{"Content-Length":String(S)}:{},...h.status===206&&v?{"Content-Range":v}:{}}),n==="HEAD"||!h.body)return e.end(),!0;let E=0,b=Tf.fromWeb(h.body);return b.on("data",x=>{E+=x.length,E>ce.bytes&&(b.destroy(),e.destroy())}),b.on("error",()=>e.destroy()),b.pipe(e),!0}async function If(t,e){if(t==="local")return{url:ul(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=ul(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function ul(t){return t.replace(/\/+$/,"")}function Oe(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),t.end(JSON.stringify(a)),!0}var hl=8e3;async function gl(t,e,a,n,r,o){if(a!=="/api/app/voice/transcribe"&&a!=="/api/app/voice/speak")return!1;if(n!=="POST")return Y(e,405,{error:"POST"});if(a==="/api/app/voice/transcribe"){let h=String(t.headers["content-type"]||"");if(!Cr(h))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let S=Ar(t.headers["x-audio-duration-ms"]);if(S)return t.resume(),Y(e,S.status,{error:S.error});let v=await Te(t,Tr.bytes);if(!v)return Y(e,413,{error:Ir()});if(!v.length)return Y(e,400,{error:"The recording is empty."});let E={"Content-Type":h,"X-Audio-Duration-Ms":String(t.headers["x-audio-duration-ms"]).trim()};return fl(e,o.daemon,"/voice/transcribe",v,E,18e4)}let s,i=await Te(t,64*1024);if(!i)return Y(e,413,{error:"request too large"});try{s=JSON.parse(i.toString("utf8")||"{}")}catch{return Y(e,400,{error:"expected JSON"})}let l=o.store();if(!l)return Y(e,503,{error:"The database on this computer is unavailable."});let c=l.get(r.id,String(s?.conversationId??""));if(!c)return Y(e,404,{error:"no such conversation"});let d=typeof s?.text=="string"?s.text.slice(0,hl):"";if(!d.trim())return Y(e,400,{error:"text is required"});if(!Lf(c.messages,d))return Y(e,404,{error:"no such answer in this conversation"});let p=s?.announce===!0?`${c.agentName||c.agent}: ${d}`:d,m={agent:c.agent,text:p,...c.node!=="local"?{peer:c.node}:{}};return fl(e,o.daemon,"/voice/speak",Buffer.from(JSON.stringify(m)),{"Content-Type":"application/json"},9e4)}async function fl(t,e,a,n,r,o){try{let s=await fetch(e.url.replace(/\/+$/,"")+a,{method:"POST",headers:{...r,...e.token?{Authorization:`Bearer ${e.token}`}:{}},body:new Uint8Array(n),signal:AbortSignal.timeout(o)}),i=s.headers.get("content-type")||"",l=Buffer.from(await s.arrayBuffer());return s.ok&&i.startsWith("audio/")?(t.writeHead(200,{"Content-Type":i,"Content-Length":l.length,"Cache-Control":"no-store"}),t.end(l),!0):s.status===404&&Array.isArray(Mf(l)?.endpoints)?Y(t,503,{error:"AgentX on this computer is too old for voice. Update it."}):(t.writeHead(s.status,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(i.includes("json")?l:JSON.stringify({error:`AgentX answered HTTP ${s.status}.`})),!0)}catch(s){return Y(t,502,{error:s?.name==="TimeoutError"?"AgentX took too long to answer.":"Could not reach AgentX on this computer."})}}function Y(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}function Mf(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function Lf(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===hl&&a.content.startsWith(e)))}var Rf=new Set(["ring","offer","answer","ice","hangup"]),Je=/^[A-Za-z0-9_-]{4,64}$/,Pf=128*1024,$f=24,jf=2*1024*1024,Ne=new Map;async function bl(t,e,a,n,r){if(!a.startsWith("/api/app/camera/"))return!1;let o=r.daemon.url.replace(/\/+$/,""),s=r.daemon.token?{Authorization:`Bearer ${r.daemon.token}`}:{};if(a==="/api/app/camera/config"){if(n!=="GET")return M(e,405,{error:"GET"});try{let l=await fetch(`${o}/webrtc/config`,{headers:s,signal:AbortSignal.timeout(1e4)});if(l.status===404)return M(e,503,{error:"Calls are off on this computer. Set channels.webrtc.enabled to true in agentx.json."});if(!l.ok)return M(e,502,{error:`AgentX answered HTTP ${l.status}.`});let c=await l.json(),d=Ze(r.nodeName),p=(Array.isArray(c.peers)?c.peers:[]).filter(h=>Ze(String(h?.name??""))!==d),m=(Array.isArray(c.agents)?c.agents:[]).filter(h=>h&&typeof h.id=="string").map(h=>({id:h.id,name:typeof h.name=="string"&&h.name?h.name:h.id}));return M(e,200,{node:r.nodeName,iceServers:c.iceServers??[],peers:p,agents:m,camera:c.camera??null})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/signal"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,Pf);if(!l)return M(e,413,{error:"signal too large"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=Nf(c,r.nodeName);if(typeof d=="string")return M(e,400,{error:d});let p=vl(d.to);if(p&&d.kind==="ring"){let m=await De(o,s,"POST","/webrtc/camera/watch",{callId:d.callId,agentId:p});return M(e,m.status,m.status<300?{ok:!0,watch:m.body.watch}:{error:m.body.error})}try{let m=await fetch(`${o}/webrtc/signal/out`,{method:"POST",headers:{"Content-Type":"application/json",...s},body:JSON.stringify(d),signal:AbortSignal.timeout(15e3)}),h=await m.json().catch(()=>({}));return M(e,m.ok?200:502,m.ok?{ok:!0}:{error:h?.error||`AgentX answered HTTP ${m.status}.`})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/events"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";return Je.test(l)?Df(t,e,`${o}/webrtc/events?callId=${encodeURIComponent(l)}&as=${encodeURIComponent(r.nodeName)}`,s):M(e,400,{error:"callId is required"})}if(a==="/api/app/camera/look"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,4096);if(!l)return M(e,413,{error:"note too long"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=String(c?.callId??"");if(!Je.test(d))return M(e,400,{error:"callId is required"});let p=typeof c?.note=="string"?c.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/look`,{note:p},18e4);return M(e,m.status,m.status<300?{reply:m.body.reply,frame:m.body.frame}:{error:m.body.error})}if(a==="/api/app/camera/stream"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await xl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Je.test(c))return M(e,400,{error:"callId is required"});let d=Number(l.seconds??0);if(!Number.isFinite(d)||d<0)return M(e,400,{error:"seconds must be 0 or more"});let p=typeof l.note=="string"?l.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(c)}/stream`,{seconds:d,note:p});return M(e,m.status,m.status<300?{watch:m.body.watch}:{error:m.body.error})}if(a==="/api/app/camera/speak"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await xl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Je.test(c))return M(e,400,{error:"callId is required"});let d=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(c)}`);if(d.status>=300)return M(e,d.status,{error:d.body.error});let p=(Array.isArray(d.body.watch?.replies)?d.body.watch.replies:[]).find(v=>v&&v.at===l.at);if(!p||typeof p.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(d.body.watch.agentId??""),h=JSON.stringify([c,p.at,m,p.text]),S=Ne.get(h);return S?(Ne.delete(h),Ne.set(h,S),yl(e,S.type,S.bytes)):Of(e,o,s,{agent:m,text:p.text},(v,E)=>{if(!(E.length>jf))for(Ne.set(h,{type:v,bytes:E});Ne.size>$f;)Ne.delete(Ne.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await De(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let c=(Array.isArray(l.body.calls)?l.body.calls:[]).map(d=>({id:d.id,agentId:d.agentId,reason:d.reason,createdAt:d.createdAt}));return M(e,200,{asks:c,ringSeconds:l.body.ringSeconds??null})}let i=/^\/api\/app\/camera\/asks\/([A-Za-z0-9_-]{4,64})\/(answer|decline)$/.exec(a);if(i){if(n!=="POST")return M(e,405,{error:"POST"});let l=await De(o,s,"POST",`/calls/${i[1]}/${i[2]}`,{});return M(e,l.status,l.status<300?{call:l.body.call}:{error:l.body.error})}if(a==="/api/app/camera/watch"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";if(!Je.test(l))return M(e,400,{error:"callId is required"});let c=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,c.status,c.status<300?{watch:c.body.watch}:{error:c.body.error})}return M(e,404,{error:"not found"})}function vl(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function De(t,e,a,n,r,o=15e3){try{let s=await fetch(`${t}${n}`,{method:a,headers:{"Content-Type":"application/json",...e},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(o)}),i=await s.json().catch(()=>({}));return s.status===404&&typeof i?.error=="string"&&/channels\.webrtc\.enabled/.test(i.error)?{status:503,body:i}:{status:s.ok?s.status:s.status>=500?502:s.status,body:s.ok?i:{error:i?.error||`AgentX answered HTTP ${s.status}.`}}}catch{return{status:502,body:{error:"Could not reach AgentX on this computer."}}}}async function xl(t,e){let a=await Te(t,e);if(!a)return null;try{let n=JSON.parse(a.toString("utf8")||"{}");return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}async function Of(t,e,a,n,r){try{let o=await fetch(`${e}/voice/speak`,{method:"POST",headers:{"Content-Type":"application/json",...a},body:JSON.stringify(n),signal:AbortSignal.timeout(9e4)}),s=o.headers.get("content-type")||"";if(o.ok&&s.startsWith("audio/")){let l=Buffer.from(await o.arrayBuffer());return r(s,l),yl(t,s,l)}let i=await o.json().catch(()=>({}));return o.ok||typeof i?.text=="string"?M(t,200,{text:typeof i?.text=="string"?i.text:n.text}):M(t,200,{text:n.text,error:i?.error||`AgentX answered HTTP ${o.status}.`})}catch{return M(t,200,{text:n.text,error:"Could not reach AgentX on this computer."})}}function yl(t,e,a){return t.writeHead(200,{"Content-Type":e,"Content-Length":String(a.length),"Cache-Control":"no-store"}),t.end(a),!0}function Nf(t,e){let a=String(t?.kind??"");if(!Rf.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!Je.test(n))return"callId must be 4 to 64 letters, digits, - or _";let r=typeof t?.to=="string"?t.to.trim():"";if(!r||r.length>100)return"to must name a machine or an agent";if(r.startsWith("bot:")&&!vl(r))return"to must be bot:<agent id> for an agent";if(Ze(r)===Ze(e))return"pick another machine; this phone signals from this one";let o={kind:a,callId:n,from:e,to:r};if(a==="offer"||a==="answer"){if(typeof t.sdp!="string"||!t.sdp)return"sdp is required";o.sdp=t.sdp}if(a==="ice"){let s=t.candidate;if(!s||typeof s.candidate!="string")return"candidate is required";o.candidate={candidate:s.candidate,sdpMid:typeof s.sdpMid=="string"?s.sdpMid:null,sdpMLineIndex:typeof s.sdpMLineIndex=="number"?s.sdpMLineIndex:null,usernameFragment:typeof s.usernameFragment=="string"?s.usernameFragment:null}}return a==="ring"&&(o.reason="camera"),o}async function Df(t,e,a,n){let r=new AbortController;t.on("close",()=>r.abort());let o;try{o=await fetch(a,{headers:{Accept:"text/event-stream",...n},signal:r.signal})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}if(!o.ok||!o.body)return o.status===404?M(e,503,{error:"Calls are off on this computer."}):M(e,502,{error:`AgentX answered HTTP ${o.status}.`});e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"});let s=o.body.getReader();try{for(;;){let{done:i,value:l}=await s.read();if(i)break;e.write(l)}}catch{}finally{r.abort(),e.end()}return!0}function M(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{mkdirSync as Hf,readFileSync as Bf,renameSync as zf,writeFileSync as qf}from"fs";import{dirname as Ff,isAbsolute as Uf,resolve as Wf}from"path";import{randomBytes as Gf}from"crypto";var wl=60,kl=500,Xf=200,El=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,Kf=/^[A-Za-z0-9_-]{8,64}$/,Jf=/^[A-Za-z0-9._-]{1,64}$/;function Tl(t,e){return Uf(e)?e:Wf(t,e)}function _l(t){return`${t}_${Gf(6).toString("hex")}`}function Sl(){return{places:[],rules:[],seen:[]}}function Al(t,e){let a=typeof t.name=="string"?t.name.trim():"";if(!a)return{ok:!1,error:"Give the place a name."};if([...a].length>wl)return{ok:!1,error:`Keep the name under ${wl} characters.`};let n=Number(t.lat),r=Number(t.lng);if(t.lat===void 0||t.lat===""||!Number.isFinite(n)||n<-90||n>90)return{ok:!1,error:"Latitude must be a number from -90 to 90."};if(t.lng===void 0||t.lng===""||!Number.isFinite(r)||r<-180||r>180)return{ok:!1,error:"Longitude must be a number from -180 to 180."};let o=t.radius===void 0||t.radius===""?e.defaultRadiusMeters:Math.round(Number(t.radius));if(!Number.isFinite(o)||o<e.minRadiusMeters||o>e.maxRadiusMeters)return{ok:!1,error:`The radius must be from ${e.minRadiusMeters} to ${e.maxRadiusMeters} metres.`};let s=i=>Math.round(i*1e6)/1e6;return{ok:!0,value:{name:a,lat:s(n),lng:s(r),radius:o}}}function Cl(t,e){let a=typeof t.placeId=="string"?t.placeId:"";if(!El.test(a))return{ok:!1,error:"Pick a place."};let n=t.on===void 0?"enter":t.on;if(n!=="enter"&&n!=="exit")return{ok:!1,error:"on must be enter or exit."};let r=typeof t.text=="string"?t.text.trim():"";if(!r)return{ok:!1,error:"Write what to remind you of."};if([...r].length>kl)return{ok:!1,error:`Keep it under ${kl} characters.`};let o=typeof t.agent=="string"?t.agent.trim():"";return o&&(!Jf.test(o)||!e(o))?{ok:!1,error:`There is no agent called ${o.slice(0,64)} on this computer.`}:t.repeat!==void 0&&typeof t.repeat!="boolean"?{ok:!1,error:"repeat must be true or false."}:{ok:!0,value:{placeId:a,on:n,text:r,...o?{agent:o}:{},repeat:t.repeat===!0}}}function Il(t){let e=typeof t.id=="string"?t.id:"";if(!Kf.test(e))return{ok:!1,error:"id must be 8 to 64 letters, digits, - or _"};let a=typeof t.place=="string"?t.place:"";if(!El.test(a))return{ok:!1,error:"place must be a place id"};let n=t.transition;if(n!=="enter"&&n!=="exit")return{ok:!1,error:"transition must be enter or exit"};let r=typeof t.time=="number"?t.time:typeof t.time=="string"?Date.parse(t.time):NaN;return Number.isFinite(r)?{ok:!0,value:{id:e,place:a,transition:n,time:r}}:{ok:!1,error:"time must be a timestamp"}}var ia=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse(Bf(this.path,"utf-8"));return!e||typeof e!="object"?Sl():{places:Array.isArray(e.places)?e.places:[],rules:Array.isArray(e.rules)?e.rules:[],seen:Array.isArray(e.seen)?e.seen.filter(a=>typeof a=="string"):[]}}catch{return Sl()}}write(e){Hf(Ff(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;qf(a,JSON.stringify(e,null,2)+`
|
|
16616
|
-
`,{mode:384}),
|
|
16617
|
-
`)}async function
|
|
16710
|
+
`}async function mn(t,e,a){try{let n=Ke(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(c=>c.peer===t.node);if(!l)return 0;n=Ke(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Ke(l.url)===n)?.agents.find(l=>l.id===t.agent)?.runningTasks?.filter(l=>l.chatId===`app:${t.id}`)??[],i=0;for(let l of s)(await e.nodePost(n,`/api/tasks/${encodeURIComponent(l.id)}/cancel`,{reason:`cancelled by operator (phone: ${a})`})).status<300&&i++;return i}catch{return 0}}function Ke(t){return t.replace(/\/+$/,"")}function B(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{Readable as Cf}from"stream";var If=/^\/api\/app\/files\/([^/]+)$/,Mf=15e3;async function fl(t,e,a,n,r,o){let s=If.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return Oe(e,405,{error:"GET only"});let i=o.store();if(!i)return Oe(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let c=i.getFile(r.id,l);if(!c)return Oe(e,404,{error:"no such file"});let d=await Lf(c.node,o);if(!d)return Oe(e,502,{error:`${c.node} is not linked to this computer's mesh any more.`});let p=new AbortController;e.on("close",()=>p.abort());let m=setTimeout(()=>p.abort(),Mf),g;try{let h=new URLSearchParams({agent:c.agent,file:c.path});g=await fetch(`${d.url}${br}?${h}`,{method:n,headers:{...d.token?{Authorization:`Bearer ${d.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:p.signal})}catch{return Oe(e,502,{error:"The computer that made this file did not answer."})}finally{clearTimeout(m)}if(g.status!==200&&g.status!==206){let h=await g.json().then(f=>f?.error).catch(()=>""),u=[403,404,413,415,416].includes(g.status)?g.status:502;return Oe(e,u,{error:h||`The computer that made this file answered HTTP ${g.status}.`})}let _=Number(g.headers.get("content-length")||0);if(_>de.bytes)return p.abort(),Oe(e,413,{error:"the file is too large"});let b=g.headers.get("content-range");if(e.writeHead(g.status,{...vr(c.mime,c.name,c.kind),...g.headers.get("content-length")?{"Content-Length":String(_)}:{},...g.status===206&&b?{"Content-Range":b}:{}}),n==="HEAD"||!g.body)return e.end(),!0;let S=0,T=Cf.fromWeb(g.body);return T.on("data",h=>{S+=h.length,S>de.bytes&&(T.destroy(),e.destroy())}),T.on("error",()=>e.destroy()),T.pipe(e),!0}async function Lf(t,e){if(t==="local")return{url:ml(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=ml(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function ml(t){return t.replace(/\/+$/,"")}function Oe(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),t.end(JSON.stringify(a)),!0}var gl=8e3;async function xl(t,e,a,n,r,o){if(a!=="/api/app/voice/transcribe"&&a!=="/api/app/voice/speak")return!1;if(n!=="POST")return Y(e,405,{error:"POST"});if(a==="/api/app/voice/transcribe"){let g=String(t.headers["content-type"]||"");if(!Cr(g))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let _=Ar(t.headers["x-audio-duration-ms"]);if(_)return t.resume(),Y(e,_.status,{error:_.error});let b=await Te(t,Tr.bytes);if(!b)return Y(e,413,{error:Ir()});if(!b.length)return Y(e,400,{error:"The recording is empty."});let S={"Content-Type":g,"X-Audio-Duration-Ms":String(t.headers["x-audio-duration-ms"]).trim()};return hl(e,o.daemon,"/voice/transcribe",b,S,18e4)}let s,i=await Te(t,64*1024);if(!i)return Y(e,413,{error:"request too large"});try{s=JSON.parse(i.toString("utf8")||"{}")}catch{return Y(e,400,{error:"expected JSON"})}let l=o.store();if(!l)return Y(e,503,{error:"The database on this computer is unavailable."});let c=l.get(r.id,String(s?.conversationId??""));if(!c)return Y(e,404,{error:"no such conversation"});let d=typeof s?.text=="string"?s.text.slice(0,gl):"";if(!d.trim())return Y(e,400,{error:"text is required"});if(!Pf(c.messages,d))return Y(e,404,{error:"no such answer in this conversation"});let p=s?.announce===!0?`${c.agentName||c.agent}: ${d}`:d,m={agent:c.agent,text:p,...c.node!=="local"?{peer:c.node}:{}};return hl(e,o.daemon,"/voice/speak",Buffer.from(JSON.stringify(m)),{"Content-Type":"application/json"},9e4)}async function hl(t,e,a,n,r,o){try{let s=await fetch(e.url.replace(/\/+$/,"")+a,{method:"POST",headers:{...r,...e.token?{Authorization:`Bearer ${e.token}`}:{}},body:new Uint8Array(n),signal:AbortSignal.timeout(o)}),i=s.headers.get("content-type")||"",l=Buffer.from(await s.arrayBuffer());return s.ok&&i.startsWith("audio/")?(t.writeHead(200,{"Content-Type":i,"Content-Length":l.length,"Cache-Control":"no-store"}),t.end(l),!0):s.status===404&&Array.isArray(Rf(l)?.endpoints)?Y(t,503,{error:"AgentX on this computer is too old for voice. Update it."}):(t.writeHead(s.status,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(i.includes("json")?l:JSON.stringify({error:`AgentX answered HTTP ${s.status}.`})),!0)}catch(s){return Y(t,502,{error:s?.name==="TimeoutError"?"AgentX took too long to answer.":"Could not reach AgentX on this computer."})}}function Y(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}function Rf(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function Pf(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===gl&&a.content.startsWith(e)))}var $f=new Set(["ring","offer","answer","ice","hangup"]),Je=/^[A-Za-z0-9_-]{4,64}$/,jf=128*1024,Of=24,Nf=2*1024*1024,Ne=new Map;async function vl(t,e,a,n,r){if(!a.startsWith("/api/app/camera/"))return!1;let o=r.daemon.url.replace(/\/+$/,""),s=r.daemon.token?{Authorization:`Bearer ${r.daemon.token}`}:{};if(a==="/api/app/camera/config"){if(n!=="GET")return M(e,405,{error:"GET"});try{let l=await fetch(`${o}/webrtc/config`,{headers:s,signal:AbortSignal.timeout(1e4)});if(l.status===404)return M(e,503,{error:"Calls are off on this computer. Set channels.webrtc.enabled to true in agentx.json."});if(!l.ok)return M(e,502,{error:`AgentX answered HTTP ${l.status}.`});let c=await l.json(),d=Ze(r.nodeName),p=(Array.isArray(c.peers)?c.peers:[]).filter(g=>Ze(String(g?.name??""))!==d),m=(Array.isArray(c.agents)?c.agents:[]).filter(g=>g&&typeof g.id=="string").map(g=>({id:g.id,name:typeof g.name=="string"&&g.name?g.name:g.id}));return M(e,200,{node:r.nodeName,iceServers:c.iceServers??[],peers:p,agents:m,camera:c.camera??null})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/signal"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,jf);if(!l)return M(e,413,{error:"signal too large"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=Hf(c,r.nodeName);if(typeof d=="string")return M(e,400,{error:d});let p=yl(d.to);if(p&&d.kind==="ring"){let m=await De(o,s,"POST","/webrtc/camera/watch",{callId:d.callId,agentId:p});return M(e,m.status,m.status<300?{ok:!0,watch:m.body.watch}:{error:m.body.error})}try{let m=await fetch(`${o}/webrtc/signal/out`,{method:"POST",headers:{"Content-Type":"application/json",...s},body:JSON.stringify(d),signal:AbortSignal.timeout(15e3)}),g=await m.json().catch(()=>({}));return M(e,m.ok?200:502,m.ok?{ok:!0}:{error:g?.error||`AgentX answered HTTP ${m.status}.`})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/events"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";return Je.test(l)?Bf(t,e,`${o}/webrtc/events?callId=${encodeURIComponent(l)}&as=${encodeURIComponent(r.nodeName)}`,s):M(e,400,{error:"callId is required"})}if(a==="/api/app/camera/look"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,4096);if(!l)return M(e,413,{error:"note too long"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=String(c?.callId??"");if(!Je.test(d))return M(e,400,{error:"callId is required"});let p=typeof c?.note=="string"?c.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/look`,{note:p},18e4);return M(e,m.status,m.status<300?{reply:m.body.reply,frame:m.body.frame}:{error:m.body.error})}if(a==="/api/app/camera/stream"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await bl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Je.test(c))return M(e,400,{error:"callId is required"});let d=Number(l.seconds??0);if(!Number.isFinite(d)||d<0)return M(e,400,{error:"seconds must be 0 or more"});let p=typeof l.note=="string"?l.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(c)}/stream`,{seconds:d,note:p});return M(e,m.status,m.status<300?{watch:m.body.watch}:{error:m.body.error})}if(a==="/api/app/camera/speak"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await bl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Je.test(c))return M(e,400,{error:"callId is required"});let d=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(c)}`);if(d.status>=300)return M(e,d.status,{error:d.body.error});let p=(Array.isArray(d.body.watch?.replies)?d.body.watch.replies:[]).find(b=>b&&b.at===l.at);if(!p||typeof p.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(d.body.watch.agentId??""),g=JSON.stringify([c,p.at,m,p.text]),_=Ne.get(g);return _?(Ne.delete(g),Ne.set(g,_),wl(e,_.type,_.bytes)):Df(e,o,s,{agent:m,text:p.text},(b,S)=>{if(!(S.length>Nf))for(Ne.set(g,{type:b,bytes:S});Ne.size>Of;)Ne.delete(Ne.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await De(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let c=(Array.isArray(l.body.calls)?l.body.calls:[]).map(d=>({id:d.id,agentId:d.agentId,reason:d.reason,createdAt:d.createdAt}));return M(e,200,{asks:c,ringSeconds:l.body.ringSeconds??null})}let i=/^\/api\/app\/camera\/asks\/([A-Za-z0-9_-]{4,64})\/(answer|decline)$/.exec(a);if(i){if(n!=="POST")return M(e,405,{error:"POST"});let l=await De(o,s,"POST",`/calls/${i[1]}/${i[2]}`,{});return M(e,l.status,l.status<300?{call:l.body.call}:{error:l.body.error})}if(a==="/api/app/camera/watch"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";if(!Je.test(l))return M(e,400,{error:"callId is required"});let c=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,c.status,c.status<300?{watch:c.body.watch}:{error:c.body.error})}return M(e,404,{error:"not found"})}function yl(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function De(t,e,a,n,r,o=15e3){try{let s=await fetch(`${t}${n}`,{method:a,headers:{"Content-Type":"application/json",...e},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(o)}),i=await s.json().catch(()=>({}));return s.status===404&&typeof i?.error=="string"&&/channels\.webrtc\.enabled/.test(i.error)?{status:503,body:i}:{status:s.ok?s.status:s.status>=500?502:s.status,body:s.ok?i:{error:i?.error||`AgentX answered HTTP ${s.status}.`}}}catch{return{status:502,body:{error:"Could not reach AgentX on this computer."}}}}async function bl(t,e){let a=await Te(t,e);if(!a)return null;try{let n=JSON.parse(a.toString("utf8")||"{}");return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}async function Df(t,e,a,n,r){try{let o=await fetch(`${e}/voice/speak`,{method:"POST",headers:{"Content-Type":"application/json",...a},body:JSON.stringify(n),signal:AbortSignal.timeout(9e4)}),s=o.headers.get("content-type")||"";if(o.ok&&s.startsWith("audio/")){let l=Buffer.from(await o.arrayBuffer());return r(s,l),wl(t,s,l)}let i=await o.json().catch(()=>({}));return o.ok||typeof i?.text=="string"?M(t,200,{text:typeof i?.text=="string"?i.text:n.text}):M(t,200,{text:n.text,error:i?.error||`AgentX answered HTTP ${o.status}.`})}catch{return M(t,200,{text:n.text,error:"Could not reach AgentX on this computer."})}}function wl(t,e,a){return t.writeHead(200,{"Content-Type":e,"Content-Length":String(a.length),"Cache-Control":"no-store"}),t.end(a),!0}function Hf(t,e){let a=String(t?.kind??"");if(!$f.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!Je.test(n))return"callId must be 4 to 64 letters, digits, - or _";let r=typeof t?.to=="string"?t.to.trim():"";if(!r||r.length>100)return"to must name a machine or an agent";if(r.startsWith("bot:")&&!yl(r))return"to must be bot:<agent id> for an agent";if(Ze(r)===Ze(e))return"pick another machine; this phone signals from this one";let o={kind:a,callId:n,from:e,to:r};if(a==="offer"||a==="answer"){if(typeof t.sdp!="string"||!t.sdp)return"sdp is required";o.sdp=t.sdp}if(a==="ice"){let s=t.candidate;if(!s||typeof s.candidate!="string")return"candidate is required";o.candidate={candidate:s.candidate,sdpMid:typeof s.sdpMid=="string"?s.sdpMid:null,sdpMLineIndex:typeof s.sdpMLineIndex=="number"?s.sdpMLineIndex:null,usernameFragment:typeof s.usernameFragment=="string"?s.usernameFragment:null}}return a==="ring"&&(o.reason="camera"),o}async function Bf(t,e,a,n){let r=new AbortController;t.on("close",()=>r.abort());let o;try{o=await fetch(a,{headers:{Accept:"text/event-stream",...n},signal:r.signal})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}if(!o.ok||!o.body)return o.status===404?M(e,503,{error:"Calls are off on this computer."}):M(e,502,{error:`AgentX answered HTTP ${o.status}.`});e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-store","X-Accel-Buffering":"no"});let s=o.body.getReader();try{for(;;){let{done:i,value:l}=await s.read();if(i)break;e.write(l)}}catch{}finally{r.abort(),e.end()}return!0}function M(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{mkdirSync as zf,readFileSync as qf,renameSync as Ff,writeFileSync as Uf}from"fs";import{dirname as Wf,isAbsolute as Gf,resolve as Xf}from"path";import{randomBytes as Kf}from"crypto";var kl=60,_l=500,Jf=200,Tl=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,Vf=/^[A-Za-z0-9_-]{8,64}$/,Yf=/^[A-Za-z0-9._-]{1,64}$/;function Al(t,e){return Gf(e)?e:Xf(t,e)}function Sl(t){return`${t}_${Kf(6).toString("hex")}`}function El(){return{places:[],rules:[],seen:[]}}function Cl(t,e){let a=typeof t.name=="string"?t.name.trim():"";if(!a)return{ok:!1,error:"Give the place a name."};if([...a].length>kl)return{ok:!1,error:`Keep the name under ${kl} characters.`};let n=Number(t.lat),r=Number(t.lng);if(t.lat===void 0||t.lat===""||!Number.isFinite(n)||n<-90||n>90)return{ok:!1,error:"Latitude must be a number from -90 to 90."};if(t.lng===void 0||t.lng===""||!Number.isFinite(r)||r<-180||r>180)return{ok:!1,error:"Longitude must be a number from -180 to 180."};let o=t.radius===void 0||t.radius===""?e.defaultRadiusMeters:Math.round(Number(t.radius));if(!Number.isFinite(o)||o<e.minRadiusMeters||o>e.maxRadiusMeters)return{ok:!1,error:`The radius must be from ${e.minRadiusMeters} to ${e.maxRadiusMeters} metres.`};let s=i=>Math.round(i*1e6)/1e6;return{ok:!0,value:{name:a,lat:s(n),lng:s(r),radius:o}}}function Il(t,e){let a=typeof t.placeId=="string"?t.placeId:"";if(!Tl.test(a))return{ok:!1,error:"Pick a place."};let n=t.on===void 0?"enter":t.on;if(n!=="enter"&&n!=="exit")return{ok:!1,error:"on must be enter or exit."};let r=typeof t.text=="string"?t.text.trim():"";if(!r)return{ok:!1,error:"Write what to remind you of."};if([...r].length>_l)return{ok:!1,error:`Keep it under ${_l} characters.`};let o=typeof t.agent=="string"?t.agent.trim():"";return o&&(!Yf.test(o)||!e(o))?{ok:!1,error:`There is no agent called ${o.slice(0,64)} on this computer.`}:t.repeat!==void 0&&typeof t.repeat!="boolean"?{ok:!1,error:"repeat must be true or false."}:{ok:!0,value:{placeId:a,on:n,text:r,...o?{agent:o}:{},repeat:t.repeat===!0}}}function Ml(t){let e=typeof t.id=="string"?t.id:"";if(!Vf.test(e))return{ok:!1,error:"id must be 8 to 64 letters, digits, - or _"};let a=typeof t.place=="string"?t.place:"";if(!Tl.test(a))return{ok:!1,error:"place must be a place id"};let n=t.transition;if(n!=="enter"&&n!=="exit")return{ok:!1,error:"transition must be enter or exit"};let r=typeof t.time=="number"?t.time:typeof t.time=="string"?Date.parse(t.time):NaN;return Number.isFinite(r)?{ok:!0,value:{id:e,place:a,transition:n,time:r}}:{ok:!1,error:"time must be a timestamp"}}var ia=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse(qf(this.path,"utf-8"));return!e||typeof e!="object"?El():{places:Array.isArray(e.places)?e.places:[],rules:Array.isArray(e.rules)?e.rules:[],seen:Array.isArray(e.seen)?e.seen.filter(a=>typeof a=="string"):[]}}catch{return El()}}write(e){zf(Wf(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;Uf(a,JSON.stringify(e,null,2)+`
|
|
16711
|
+
`,{mode:384}),Ff(a,this.path)}addPlace(e,a){let n=this.read();if(n.places.length>=a.maxPlaces)return{ok:!1,error:`You already have ${a.maxPlaces} places, the most allowed (app.places.maxPlaces). Remove one first.`};if(n.places.some(o=>o.name.toLowerCase()===e.name.toLowerCase()))return{ok:!1,error:`You already have a place called ${e.name}.`};let r={id:Sl("pl"),...e,createdAt:new Date(this.now()).toISOString()};return n.places.push(r),this.write(n),{ok:!0,place:r}}removePlace(e){let a=this.read(),n=a.places.length;return a.places=a.places.filter(r=>r.id!==e),a.places.length===n?!1:(a.rules=a.rules.filter(r=>r.placeId!==e),this.write(a),!0)}addRule(e,a){let n=this.read();if(!n.places.some(o=>o.id===e.placeId))return{ok:!1,error:"That place doesn't exist any more."};if(n.rules.filter(o=>o.placeId===e.placeId).length>=a.maxRulesPerPlace)return{ok:!1,error:`That place already has ${a.maxRulesPerPlace} reminders, the most allowed (app.places.maxRulesPerPlace).`};let r={id:Sl("pr"),...e,enabled:!0,createdAt:new Date(this.now()).toISOString()};return n.rules.push(r),this.write(n),{ok:!0,rule:r}}setRuleEnabled(e,a){let n=this.read(),r=n.rules.find(o=>o.id===e);return r?(r.enabled=a,this.write(n),r):null}removeRule(e){let a=this.read(),n=a.rules.length;return a.rules=a.rules.filter(r=>r.id!==e),a.rules.length===n?!1:(this.write(a),!0)}accept(e,a){let n=this.read();if(n.seen.includes(e.id))return{status:"duplicate"};n.seen=[...n.seen,e.id].slice(-Jf);let r=this.now(),o=n.places.find(i=>i.id===e.place),s;if(!o)s={status:"unknown-place"};else if(e.time<r-a.maxEventAgeMinutes*6e4)s={status:"too-old"};else{let i=a.cooldownMinutes*6e4,l=n.rules.filter(c=>c.placeId===o.id&&c.on===e.transition&&c.enabled&&!(c.lastFiredAt&&Date.parse(c.lastFiredAt)>r-i));for(let c of l)c.lastFiredAt=new Date(r).toISOString(),c.repeat||(c.enabled=!1);s=l.length?{status:"fired",place:o,rules:l.map(c=>({...c}))}:{status:"no-rules"}}return this.write(n),s}};Dn();function Qf(t,e){return e==="enter"?`Arrived at ${t.name}`:`Left ${t.name}`}function Zf(t,e,a){let n=new Date(a).toISOString().slice(0,16).replace("T"," ")+" UTC";return[`[Place reminder \xB7 ${e.on==="enter"?"the owner arrived at":"the owner left"} ${t.name} \xB7 ${n}]`,e.text,"","Your answer is sent to the owner's phone as a notification. Keep it short."].join(`
|
|
16712
|
+
`)}async function Ll(t,e,a,n,r){await Promise.all(a.map(async o=>{let s=Qf(e,o.on),i=o.text;if(o.agent)try{i=(await r.task(o.agent,Zf(e,o,n),o.id)).trim()||`${o.agent} had nothing to add.`}catch(l){i=`${o.text}
|
|
16618
16713
|
|
|
16619
|
-
(${o.agent} couldn't run this: ${String(l?.message||l).slice(0,160)})`}try{await r.push(t,s,i),r.log(`[places] ${o.id} on ${e.id}: pushed to ${t}`)}catch(l){r.log(`[places] ${o.id} on ${e.id}: push failed: ${String(l?.message||l).slice(0,200)}`)}}))}function
|
|
16620
|
-
${s}`,buttons:[{label:"Open",url:"/app#alerts"}]}),signal:AbortSignal.timeout(15e3)});if(!i.ok)throw new Error(`HTTP ${i.status} ${(await i.text().catch(()=>"")).slice(0,160)}`)},async task(r,o,s){let i=await fetch(a+"/task",{method:"POST",headers:{...n,...t.operatorKey?{[Nn]:t.operatorKey}:{}},body:JSON.stringify({agent:r,message:o,context:{channel:"app",chatId:`place:${s}`,sender:"places"}}),signal:AbortSignal.timeout(6e5)}),l=await i.json().catch(()=>({}));if(!i.ok||l.error)throw new Error(String(l.error||`HTTP ${i.status}`));return String(l.content??"")},log:e}}async function
|
|
16714
|
+
(${o.agent} couldn't run this: ${String(l?.message||l).slice(0,160)})`}try{await r.push(t,s,i),r.log(`[places] ${o.id} on ${e.id}: pushed to ${t}`)}catch(l){r.log(`[places] ${o.id} on ${e.id}: push failed: ${String(l?.message||l).slice(0,200)}`)}}))}function Rl(t,e=console.error){let a=t.url.replace(/\/+$/,""),n={"Content-Type":"application/json",...t.token?{Authorization:`Bearer ${t.token}`}:{}};return{async push(r,o,s){let i=await fetch(a+"/channel/send",{method:"POST",headers:n,body:JSON.stringify({channel:"push",chatId:r,text:`${o}
|
|
16715
|
+
${s}`,buttons:[{label:"Open",url:"/app#alerts"}]}),signal:AbortSignal.timeout(15e3)});if(!i.ok)throw new Error(`HTTP ${i.status} ${(await i.text().catch(()=>"")).slice(0,160)}`)},async task(r,o,s){let i=await fetch(a+"/task",{method:"POST",headers:{...n,...t.operatorKey?{[Nn]:t.operatorKey}:{}},body:JSON.stringify({agent:r,message:o,context:{channel:"app",chatId:`place:${s}`,sender:"places"}}),signal:AbortSignal.timeout(6e5)}),l=await i.json().catch(()=>({}));if(!i.ok||l.error)throw new Error(String(l.error||`HTTP ${i.status}`));return String(l.content??"")},log:e}}async function Pl(t,e,a,n,r,o){return a!=="/api/app/places"&&!a.startsWith("/api/app/places/")?!1:jl(t,e,a.slice(15),n,o,r)}async function $l(t,e,a,n,r){return a!=="/api/places"&&!a.startsWith("/api/places/")?!1:jl(t,e,a.slice(11),n,r,null)}async function jl(t,e,a,n,r,o){if(n==="GET"&&a===""){let i=r.enabled?r.store.read():{places:[],rules:[]};return z(e,200,{enabled:r.enabled,reason:r.enabled?null:"Place reminders are off on this computer (app.places.enabled).",pushAvailable:!!r.fire,pushReason:r.fire?null:r.pushReason??null,limits:{defaultRadiusMeters:r.limits.defaultRadiusMeters,minRadiusMeters:r.limits.minRadiusMeters,maxRadiusMeters:r.limits.maxRadiusMeters,maxPlaces:r.limits.maxPlaces},syncMinutes:r.syncMinutes,android:{packageName:r.androidPackage},places:i.places,rules:i.rules,agents:r.agents()})}if(n!=="POST")return z(e,404,{error:"not found"});if(!r.enabled)return z(e,403,{error:"Place reminders are off on this computer (app.places.enabled)."});let s;try{s=await yt(t,4096)}catch(i){return z(e,400,{error:i.message})}if(a==="/event"){if(!o)return z(e,404,{error:"not found"});let i=Ml(s);if(!i.ok)return z(e,400,{error:i.error});let l=r.store.accept(i.value,r.limits);return r.log(`[places] ${o.id} ${i.value.transition} ${i.value.place}: ${l.status}${l.status==="fired"?` (${l.rules.length})`:""}`),l.status==="fired"&&(r.fire?Ll(o.id,l.place,l.rules,i.value.time,r.fire).catch(c=>r.log(`[places] delivery failed: ${c?.message||c}`)):r.log(`[places] ${l.rules.length} reminder(s) not sent: ${r.pushReason??"this computer doesn't send pushes"}`)),z(e,202,{ok:!0,status:l.status,fired:l.status==="fired"?l.rules.length:0})}if(a==="/add"){let i=Cl(s,r.limits);if(!i.ok)return z(e,400,{error:i.error});let l=r.store.addPlace(i.value,r.limits);return l.ok?z(e,200,{ok:!0,place:l.place}):z(e,409,{error:l.error})}if(a==="/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removePlace(i)?z(e,200,{ok:!0}):z(e,404,{error:"No such place."})}if(a==="/rules/add"){let i=new Set(r.agents()),l=Il(s,d=>i.has(d));if(!l.ok)return z(e,400,{error:l.error});let c=r.store.addRule(l.value,r.limits);return c.ok?z(e,200,{ok:!0,rule:c.rule}):z(e,409,{error:c.error})}if(a==="/rules/enable"){if(typeof s.enabled!="boolean")return z(e,400,{error:"enabled must be true or false"});let i=r.store.setRuleEnabled(typeof s.id=="string"?s.id:"",s.enabled);return i?z(e,200,{ok:!0,rule:i}):z(e,404,{error:"No such reminder."})}if(a==="/rules/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removeRule(i)?z(e,200,{ok:!0}):z(e,404,{error:"No such reminder."})}return z(e,404,{error:"not found"})}function Ol(t,e,a,n){let r=t.app.places;return{enabled:r.enabled,limits:r,syncMinutes:r.syncMinutes,store:new ia(Al(e,r.file)),agents:()=>Object.keys(t.agents||{}).sort(),fire:a,pushReason:n,androidPackage:t.app.android.packageName,log:o=>console.error(o)}}function Nl(t){let e=t.app.android;return e.certFingerprints.length?[{relation:["delegate_permission/common.handle_all_urls"],target:{namespace:"android_app",package_name:e.packageName,sha256_cert_fingerprints:e.certFingerprints.map(a=>a.toUpperCase())}}]:null}function z(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var Dl=`
|
|
16621
16716
|
:root {
|
|
16622
16717
|
--ax-bg: #fff; --ax-surface: #fff; --ax-surface-2: #f4f5f7; --ax-surface-3: #f6f7f9;
|
|
16623
16718
|
--ax-text: #0b0d10; --ax-text-2: #5a616c; --ax-border: #e5e7eb;
|
|
@@ -16631,7 +16726,7 @@ ${s}`,buttons:[{label:"Open",url:"/app#alerts"}]}),signal:AbortSignal.timeout(15
|
|
|
16631
16726
|
--ax-accent: #6aa0ff; --ax-accent-2: #6aa0ff; --ax-accent-t: #1c2b47;
|
|
16632
16727
|
--phone-bubble: #1d2f52; --phone-green: #3dbe74;
|
|
16633
16728
|
}
|
|
16634
|
-
`,
|
|
16729
|
+
`,Hl=`
|
|
16635
16730
|
[hidden] { display: none !important; }
|
|
16636
16731
|
main > .sw-peek[hidden] { display: block !important; }
|
|
16637
16732
|
main > #panel-chat.sw-peek[hidden] { display: flex !important; }
|
|
@@ -16737,7 +16832,7 @@ main > #panel-chat.sw-peek { height: 100%; padding-top: 8px; }
|
|
|
16737
16832
|
@media (max-width: 360px) { #cam-btn span { display: none; } .bar { padding-left: 12px; } .bar-btns { gap: 4px; } .vx-row { gap: 24px; } }
|
|
16738
16833
|
@media (max-height: 540px) { .vx { gap: 4px; padding-top: 4px; } .cx-top { padding-bottom: 4px; } }
|
|
16739
16834
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; animation: none !important; } }
|
|
16740
|
-
`;var
|
|
16835
|
+
`;var Bl=`
|
|
16741
16836
|
window.AXSheet = function (sheet, onClose) {
|
|
16742
16837
|
var handle = document.createElement('button');
|
|
16743
16838
|
handle.type = 'button'; handle.className = 'sheet-handle';
|
|
@@ -16766,7 +16861,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
16766
16861
|
handle.addEventListener('pointercancel', reset);
|
|
16767
16862
|
sheet.addEventListener('close', function () { reset(); if (onClose) onClose(); });
|
|
16768
16863
|
};
|
|
16769
|
-
`;var
|
|
16864
|
+
`;var zl=`
|
|
16770
16865
|
(function () {
|
|
16771
16866
|
var fleetPanel = document.getElementById('panel-fleet');
|
|
16772
16867
|
var activityPanel = document.getElementById('panel-activity');
|
|
@@ -17057,7 +17152,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
17057
17152
|
setInterval(refresh, 15000);
|
|
17058
17153
|
refresh();
|
|
17059
17154
|
})();
|
|
17060
|
-
`;var
|
|
17155
|
+
`;var ql=`
|
|
17061
17156
|
.fx-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
17062
17157
|
.fx-head h2 { margin: 4px 0 0; }
|
|
17063
17158
|
.fx-sub { font-size: 15px; margin: 18px 0 8px; color: var(--ax-text-2); }
|
|
@@ -17122,7 +17217,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17122
17217
|
.fx-opt em { font-style: normal; font-size: 12px; color: var(--ax-ok); white-space: nowrap; }
|
|
17123
17218
|
.fx-error:empty { display: none; }
|
|
17124
17219
|
.fx-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
|
|
17125
|
-
`;var
|
|
17220
|
+
`;var Fl=`
|
|
17126
17221
|
(function () {
|
|
17127
17222
|
var panel = document.getElementById('panel-alerts');
|
|
17128
17223
|
if (!panel) return;
|
|
@@ -17333,7 +17428,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17333
17428
|
refresh();
|
|
17334
17429
|
loadRecent();
|
|
17335
17430
|
})();
|
|
17336
|
-
`;var
|
|
17431
|
+
`;var Ul=`
|
|
17337
17432
|
(function () {
|
|
17338
17433
|
var panel = document.getElementById('panel-alerts');
|
|
17339
17434
|
if (!panel) return;
|
|
@@ -17485,7 +17580,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17485
17580
|
document.addEventListener('visibilitychange', function () { if (!document.hidden && state) load(); });
|
|
17486
17581
|
load();
|
|
17487
17582
|
})();
|
|
17488
|
-
`,
|
|
17583
|
+
`,Wl=`
|
|
17489
17584
|
.pl-card { margin-top: 12px; }
|
|
17490
17585
|
.pl-list { margin-top: 8px; }
|
|
17491
17586
|
.pl-rules { list-style: none; margin: 6px 0 0; padding: 0; }
|
|
@@ -17504,7 +17599,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17504
17599
|
.pl-check { display: flex; align-items: center; gap: 8px; font-size: var(--ax-fs-sm); }
|
|
17505
17600
|
.pl-check input { width: 20px; height: 20px; }
|
|
17506
17601
|
#pl-here { justify-self: start; }
|
|
17507
|
-
`;function
|
|
17602
|
+
`;function Gl(t,e,a){return t!==1?"Could not find where you are. Try again outdoors, or type the coordinates.":e&&a!=="denied"?"The location was refused. If you tapped Don\u2019t allow, allow location for AgentX in the phone\u2019s settings. Otherwise Chrome hasn\u2019t linked the AgentX app yet: Force stop Chrome once (Settings \u203A Apps \u203A Chrome \u203A Force stop), then open AgentX again. Or type the coordinates.":"Location is blocked for this app. Allow it in the phone\u2019s settings, or type the coordinates."}var Xl=`
|
|
17508
17603
|
(function () {
|
|
17509
17604
|
var panel = document.getElementById('panel-alerts');
|
|
17510
17605
|
if (!panel) return;
|
|
@@ -17617,7 +17712,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17617
17712
|
}
|
|
17618
17713
|
load();
|
|
17619
17714
|
})();
|
|
17620
|
-
`;var
|
|
17715
|
+
`;var Kl=`
|
|
17621
17716
|
(function () {
|
|
17622
17717
|
var panel = document.getElementById('panel-chat');
|
|
17623
17718
|
var V = window.AXChatView;
|
|
@@ -17900,7 +17995,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17900
17995
|
var last = recall('ax-chat-conv');
|
|
17901
17996
|
if (!fromHash() && last) openConversation(last);
|
|
17902
17997
|
})();
|
|
17903
|
-
`;var
|
|
17998
|
+
`;var Jl=`
|
|
17904
17999
|
window.AXChatView = (function () {
|
|
17905
18000
|
var NL = String.fromCharCode(10), TAB = String.fromCharCode(9), FENCE = String.fromCharCode(96, 96, 96);
|
|
17906
18001
|
// Cut a half-written agentx:ui block from a streaming reply so its raw
|
|
@@ -18181,7 +18276,7 @@ window.AXChatView = (function () {
|
|
|
18181
18276
|
openViewer: openViewer, closeViewer: closeViewer, readStream: readStream,
|
|
18182
18277
|
cachePut: cachePut, cacheGet: cacheGet, cacheAll: cacheAll, cacheDrop: cacheDrop };
|
|
18183
18278
|
})();
|
|
18184
|
-
`;var
|
|
18279
|
+
`;var Vl=`
|
|
18185
18280
|
window.AXChatSheets = function (o) {
|
|
18186
18281
|
var V = o.V, picker = o.picker, hist = o.hist;
|
|
18187
18282
|
function loadPicker() {
|
|
@@ -18227,7 +18322,7 @@ window.AXChatSheets = function (o) {
|
|
|
18227
18322
|
});
|
|
18228
18323
|
return { loadPicker: loadPicker, loadHistory: loadHistory };
|
|
18229
18324
|
};
|
|
18230
|
-
`;var
|
|
18325
|
+
`;var Yl=`
|
|
18231
18326
|
window.AXChatLog = function (o) {
|
|
18232
18327
|
var V = o.V, log = o.log, empty = o.empty, NOTES = o.notes;
|
|
18233
18328
|
function scrollDown() { var m = log; if (m) m.scrollTop = m.scrollHeight; }
|
|
@@ -18290,7 +18385,7 @@ window.AXChatLog = function (o) {
|
|
|
18290
18385
|
return { scrollDown: scrollDown, clear: clear, userMsg: userMsg, queuedMsg: queuedMsg, agentMsg: agentMsg, setBody: setBody,
|
|
18291
18386
|
setNote: setNote, renderUi: renderUi, renderFiles: renderFiles, renderConversation: renderConversation, flash: flash };
|
|
18292
18387
|
};
|
|
18293
|
-
`;var
|
|
18388
|
+
`;var Ql=`
|
|
18294
18389
|
(function () {
|
|
18295
18390
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, V = window.AXChatView, O = window.AXOrb;
|
|
18296
18391
|
var top = panel && panel.querySelector('.cx-top');
|
|
@@ -18440,7 +18535,7 @@ window.AXChatLog = function (o) {
|
|
|
18440
18535
|
window.AXStrip = { poll: poll, update: update, banner: banner };
|
|
18441
18536
|
poll();
|
|
18442
18537
|
})();
|
|
18443
|
-
`;var
|
|
18538
|
+
`;var Zl=`
|
|
18444
18539
|
.cs { margin: 0 -2px; }
|
|
18445
18540
|
.cs[hidden] { display: none; }
|
|
18446
18541
|
.cs-list {
|
|
@@ -18496,7 +18591,7 @@ window.AXChatLog = function (o) {
|
|
|
18496
18591
|
@media (prefers-reduced-motion: reduce) {
|
|
18497
18592
|
.cs-thinking .cs-dot, .cs-answering .cs-dot, .cs-banner { animation: none; }
|
|
18498
18593
|
}
|
|
18499
|
-
`;function
|
|
18594
|
+
`;function ec(t,e,a=5){if(t.some(o=>o.key===e.key))return{queue:t.slice(),dropped:[]};let n=t.concat([e]),r=Math.max(0,n.length-Math.max(1,a));return{queue:n.slice(r),dropped:n.slice(0,r)}}function tc(t,e){return e||!t.length?{item:null,queue:t.slice()}:{item:t[0],queue:t.slice(1)}}var ac=`
|
|
18500
18595
|
body { height: 100dvh; }
|
|
18501
18596
|
main { min-height: 0; }
|
|
18502
18597
|
#panel-chat:not([hidden]) { display: flex; flex-direction: column; min-height: 100%; }
|
|
@@ -18606,7 +18701,7 @@ main { min-height: 0; }
|
|
|
18606
18701
|
background: color-mix(in oklch, var(--ax-accent) 15%, var(--ax-surface)); color: var(--ax-accent);
|
|
18607
18702
|
}
|
|
18608
18703
|
.cx-composer .fx-btn { border-radius: var(--ax-radius); }
|
|
18609
|
-
`;var
|
|
18704
|
+
`;var nc=`
|
|
18610
18705
|
window.AXOrb = (function () {
|
|
18611
18706
|
// Same list, order and hash as presenceLook (src/voice/presence.ts) and
|
|
18612
18707
|
// OrbMath.colorHex, for an agent whose colour did not come with it.
|
|
@@ -18723,7 +18818,7 @@ window.AXOrb = (function () {
|
|
|
18723
18818
|
}
|
|
18724
18819
|
return { create: create, colorFor: colorFor, levelFromRms: levelFromRms, speakingEnvelope: speakingEnvelope };
|
|
18725
18820
|
})();
|
|
18726
|
-
`;var
|
|
18821
|
+
`;var rc=`
|
|
18727
18822
|
window.AXVoiceIO = (function () {
|
|
18728
18823
|
var TYPES = ['audio/webm;codecs=opus', 'audio/mp4', 'audio/webm', 'audio/ogg;codecs=opus', 'audio/aac'];
|
|
18729
18824
|
var ac = null, playing = null;
|
|
@@ -18841,7 +18936,7 @@ window.AXVoiceIO = (function () {
|
|
|
18841
18936
|
|
|
18842
18937
|
return { canRecord: canRecord, mimeType: mimeType, unlock: unlock, record: record, playAudio: playAudio, speakText: speakText, stop: stopPlaying };
|
|
18843
18938
|
})();
|
|
18844
|
-
`;var
|
|
18939
|
+
`;var oc=`
|
|
18845
18940
|
(function () {
|
|
18846
18941
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, IO = window.AXVoiceIO, O = window.AXOrb;
|
|
18847
18942
|
if (!panel || !C || !IO || !O) return;
|
|
@@ -19054,7 +19149,7 @@ window.AXVoiceIO = (function () {
|
|
|
19054
19149
|
idle();
|
|
19055
19150
|
window.AXVoice = { show: show, orb: orb, state: function () { return v.state; }, queued: function () { return speech.length; } };
|
|
19056
19151
|
})();
|
|
19057
|
-
`;var
|
|
19152
|
+
`;var sc=`
|
|
19058
19153
|
.vx {
|
|
19059
19154
|
position: sticky; bottom: -16px; z-index: 1; display: grid; justify-items: center; gap: 4px;
|
|
19060
19155
|
margin: 0 0 -16px; padding: 8px 0 12px; background: var(--ax-bg);
|
|
@@ -19090,7 +19185,7 @@ window.AXVoiceIO = (function () {
|
|
|
19090
19185
|
.cx-typing-on .vx-orb { width: 88px; height: 88px; }
|
|
19091
19186
|
.cx-typing-on .vx-row { gap: 16px; }
|
|
19092
19187
|
@media (prefers-reduced-motion: reduce) { .vx-orb { transition: none; } }
|
|
19093
|
-
`;var
|
|
19188
|
+
`;var ic=`
|
|
19094
19189
|
<main class="card">
|
|
19095
19190
|
<h1>This phone isn't paired</h1>
|
|
19096
19191
|
<p>On the computer running AgentX, open a terminal in the folder that holds <code>agentx.json</code> and run <code>agentx app pair</code>. Scan the QR code it shows, or type the code under it.</p>
|
|
@@ -19104,7 +19199,7 @@ window.AXVoiceIO = (function () {
|
|
|
19104
19199
|
<p id="pair-msg" class="pair-msg" role="status" aria-live="polite"></p>
|
|
19105
19200
|
</form>
|
|
19106
19201
|
<p class="muted">If this phone was paired before, it may have been removed with <code>agentx app revoke</code>.</p>
|
|
19107
|
-
</main>`,
|
|
19202
|
+
</main>`,lc=`
|
|
19108
19203
|
.pair-form { display: grid; gap: 10px; margin: 20px 0 24px; }
|
|
19109
19204
|
.pair-form label { font-weight: 600; }
|
|
19110
19205
|
.pair-form input {
|
|
@@ -19126,7 +19221,7 @@ window.AXVoiceIO = (function () {
|
|
|
19126
19221
|
margin: 0; padding: 8px 12px; border-radius: var(--ax-radius-sm); font-size: var(--ax-fs-sm);
|
|
19127
19222
|
background: var(--ax-amber-t); color: var(--ax-amber-ink); border: 1px solid var(--ax-amber-e);
|
|
19128
19223
|
}
|
|
19129
|
-
`,
|
|
19224
|
+
`,cc=`
|
|
19130
19225
|
(function () {
|
|
19131
19226
|
var form = document.getElementById('pair-form');
|
|
19132
19227
|
var input = document.getElementById('pair-code');
|
|
@@ -19218,7 +19313,7 @@ window.AXVoiceIO = (function () {
|
|
|
19218
19313
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
19219
19314
|
}
|
|
19220
19315
|
})();
|
|
19221
|
-
`;var
|
|
19316
|
+
`;var dc=`
|
|
19222
19317
|
<div id="scan" class="scan" role="dialog" aria-modal="true" aria-labelledby="scan-title" hidden>
|
|
19223
19318
|
<video id="scan-video" playsinline muted autoplay></video>
|
|
19224
19319
|
<div class="scan-frame" aria-hidden="true"></div>
|
|
@@ -19227,7 +19322,7 @@ window.AXVoiceIO = (function () {
|
|
|
19227
19322
|
<button type="button" id="scan-close" class="scan-close">Close</button>
|
|
19228
19323
|
</div>
|
|
19229
19324
|
<p id="scan-msg" class="scan-msg" role="status" aria-live="polite">Point the camera at the QR code shown by agentx app pair.</p>
|
|
19230
|
-
</div>`,
|
|
19325
|
+
</div>`,pc=`
|
|
19231
19326
|
.pair-form .scan-btn {
|
|
19232
19327
|
color: var(--ax-accent-2, var(--ax-accent)); background: transparent; border: 2px solid var(--ax-accent);
|
|
19233
19328
|
}
|
|
@@ -19256,7 +19351,7 @@ window.AXVoiceIO = (function () {
|
|
|
19256
19351
|
}
|
|
19257
19352
|
.scan-msg.bad { color: #ffd0cc; font-weight: 600; }
|
|
19258
19353
|
body.scanning { overflow: hidden; }
|
|
19259
|
-
`,
|
|
19354
|
+
`,uc=`
|
|
19260
19355
|
(function () {
|
|
19261
19356
|
var openBtn = document.getElementById('scan-btn');
|
|
19262
19357
|
var box = document.getElementById('scan');
|
|
@@ -19422,7 +19517,7 @@ body.scanning { overflow: hidden; }
|
|
|
19422
19517
|
document.addEventListener('visibilitychange', function () { if (document.hidden) close(); });
|
|
19423
19518
|
window.addEventListener('pagehide', close);
|
|
19424
19519
|
})();
|
|
19425
|
-
`;var
|
|
19520
|
+
`;var hn=`
|
|
19426
19521
|
.cam { position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; background: var(--ax-bg); }
|
|
19427
19522
|
.cam[hidden] { display: none; }
|
|
19428
19523
|
.cam-live {
|
|
@@ -19481,7 +19576,7 @@ body.scanning { overflow: hidden; }
|
|
|
19481
19576
|
@keyframes cam-pulse { 50% { opacity: .3; } }
|
|
19482
19577
|
@media (prefers-reduced-motion: reduce) { .cam-live.is-stream .cam-dot { animation: none; } }
|
|
19483
19578
|
#cam-stream[aria-pressed="true"] { border-color: var(--ax-red); color: var(--ax-red-ink); }
|
|
19484
|
-
`;var
|
|
19579
|
+
`;var mc='<button type="button" id="cam-btn" class="icon-btn" aria-label="Share camera" aria-haspopup="dialog"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M3 6h12v12H3zM15 10l6-3v10l-6-3"/></svg><span>Share camera</span></button>',fc=`
|
|
19485
19580
|
<div id="cam" class="cam" role="dialog" aria-modal="true" aria-labelledby="cam-title" hidden>
|
|
19486
19581
|
<div class="cam-live" id="cam-live" role="status" aria-live="polite" hidden>
|
|
19487
19582
|
<span class="cam-dot" aria-hidden="true"></span>
|
|
@@ -19510,7 +19605,7 @@ body.scanning { overflow: hidden; }
|
|
|
19510
19605
|
<button type="button" id="cam-close" class="cam-secondary">Close</button>
|
|
19511
19606
|
</div>
|
|
19512
19607
|
</div>
|
|
19513
|
-
</div>`,
|
|
19608
|
+
</div>`,hc=`
|
|
19514
19609
|
(function () {
|
|
19515
19610
|
var btn = document.getElementById('cam-btn');
|
|
19516
19611
|
var sheet = document.getElementById('cam');
|
|
@@ -19984,7 +20079,7 @@ body.scanning { overflow: hidden; }
|
|
|
19984
20079
|
});
|
|
19985
20080
|
window.addEventListener('pagehide', function () { stop(); });
|
|
19986
20081
|
})();
|
|
19987
|
-
`;var
|
|
20082
|
+
`;var gc=`
|
|
19988
20083
|
<div id="cam-ask-bar" class="cam-askbar" role="alert" hidden>
|
|
19989
20084
|
<div class="cam-askbar-text">
|
|
19990
20085
|
<strong id="cam-ask-who">An agent</strong> wants to see through your camera
|
|
@@ -19994,7 +20089,7 @@ body.scanning { overflow: hidden; }
|
|
|
19994
20089
|
<button type="button" id="cam-ask-show" class="cam-askbar-show">Show</button>
|
|
19995
20090
|
<button type="button" id="cam-ask-no" class="cam-askbar-no">Decline</button>
|
|
19996
20091
|
</div>
|
|
19997
|
-
</div>`,
|
|
20092
|
+
</div>`,xc=`
|
|
19998
20093
|
.cam-askbar[hidden] { display: none; }
|
|
19999
20094
|
.cam-askbar {
|
|
20000
20095
|
display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
|
|
@@ -20009,7 +20104,7 @@ body.scanning { overflow: hidden; }
|
|
|
20009
20104
|
border: 2px solid #fff; background: #fff; color: var(--ax-accent);
|
|
20010
20105
|
}
|
|
20011
20106
|
.cam-askbar-no { background: transparent; color: #fff; }
|
|
20012
|
-
`,
|
|
20107
|
+
`,bc=`
|
|
20013
20108
|
(function () {
|
|
20014
20109
|
var bar = document.getElementById('cam-ask-bar');
|
|
20015
20110
|
if (!bar) return;
|
|
@@ -20079,7 +20174,7 @@ body.scanning { overflow: hidden; }
|
|
|
20079
20174
|
setInterval(poll, 5000);
|
|
20080
20175
|
document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible') poll(); });
|
|
20081
20176
|
})();
|
|
20082
|
-
`;function
|
|
20177
|
+
`;function vc(t,e){let a={width:1280,height:720,frameRate:15},n=t||a;return{audio:!1,video:{facingMode:{ideal:e==="user"?"user":"environment"},width:{ideal:n.width||a.width},height:{ideal:n.height||a.height},frameRate:{ideal:n.frameRate||a.frameRate}}}}function yc(t){let e=Math.max(0,Math.ceil(t/1e3)),a=Math.floor(e/60),n=e%60;return a+":"+(n<10?"0":"")+n}function wc(t){return t>=400?"send":"listen"}function kc(t){let e=Math.max(1,Math.round(t||60));return"Keep watching "+(e%60===0?e/60+" min":e+" s")}var _c=`
|
|
20083
20178
|
(function () {
|
|
20084
20179
|
var main = document.querySelector('main');
|
|
20085
20180
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
@@ -20198,7 +20293,7 @@ body.scanning { overflow: hidden; }
|
|
|
20198
20293
|
main.addEventListener('touchend', function () { end(false); });
|
|
20199
20294
|
main.addEventListener('touchcancel', function () { end(true); });
|
|
20200
20295
|
})();
|
|
20201
|
-
`,
|
|
20296
|
+
`,Sc=`
|
|
20202
20297
|
main { position: relative; }
|
|
20203
20298
|
main.sw-on { overflow: hidden; }
|
|
20204
20299
|
.sw-on > [role=tabpanel] { will-change: transform; }
|
|
@@ -20209,7 +20304,7 @@ main > .sw-peek {
|
|
|
20209
20304
|
}
|
|
20210
20305
|
main > #panel-chat.sw-peek { display: flex; flex-direction: column; }
|
|
20211
20306
|
@media (prefers-reduced-motion: reduce) { .sw-slide > [role=tabpanel] { transition: none; } }
|
|
20212
|
-
`;function
|
|
20307
|
+
`;function Ec(t){let e=["INPUT","TEXTAREA","SELECT","DIALOG"];return!t.some(a=>a.scrollsX||a.editable||a.touchAction==="none"||a.touchAction==="pan-x"||e.indexOf(a.tag)>=0)}function Tc(t,e){let a=Math.abs(t),n=Math.abs(e);return a<10&&n<10?"":a>n*1.5?"x":"y"}function Ac(t,e,a){return a>0&&t===0||a<0&&t===e-1?a/4:a}function Cc(t,e,a,n,r){if(!(Math.abs(r)>.5?r*a>0&&Math.abs(a)>30:Math.abs(a)>n/3))return t;let i=t+(a<0?1:-1);return i<0||i>=e?t:i}var gn=`
|
|
20213
20308
|
${q({afterUnauthorized:Ro})}
|
|
20214
20309
|
var CACHE = 'agentx-app-v3';
|
|
20215
20310
|
var STATIC = ['/app/manifest.webmanifest', '/app/icon-192.png', '/app/icon-512.png'];
|
|
@@ -20301,7 +20396,7 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20301
20396
|
return self.clients.openWindow(target);
|
|
20302
20397
|
}));
|
|
20303
20398
|
});
|
|
20304
|
-
`;var
|
|
20399
|
+
`;var eh="<script>(function(){var t;try{t=localStorage.getItem('ax-theme')}catch(e){}if(t!=='light'&&t!=='dark'){t=matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light'}document.documentElement.setAttribute('data-theme',t)})();</script>";function xn(t){return`<meta charset="utf-8">
|
|
20305
20400
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
20306
20401
|
<meta name="theme-color" content="#2979FF">
|
|
20307
20402
|
<meta name="referrer" content="no-referrer">
|
|
@@ -20312,58 +20407,58 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20312
20407
|
<link rel="icon" type="image/png" href="/app/icon-192.png">
|
|
20313
20408
|
<link rel="apple-touch-icon" href="/app/icon-192.png">
|
|
20314
20409
|
<title>${t}</title>
|
|
20315
|
-
${
|
|
20316
|
-
<style>${ze}${
|
|
20410
|
+
${eh}
|
|
20411
|
+
<style>${ze}${Dl}${rh}</style>`}var th={chat:"M21 11.5a8.5 8.5 0 0 1-8.5 8.5H4l-2 2V11.5a9.5 9.5 0 0 1 19 0Z",fleet:"M3 3h18v13H3zM8 21h8M12 16v5",activity:"M3 12h4l3-8 4 16 3-8h4",alerts:"M18 8a6 6 0 0 0-12 0c0 7-3 7-3 9h18c0-2-3-2-3-9M10 21h4"},Ic=[{id:"chat",label:"Chat",soon:"Loading your conversations\u2026"},{id:"fleet",label:"Fleet",soon:"Loading your machines\u2026"},{id:"activity",label:"Activity",soon:"Loading what your agents are doing\u2026"},{id:"alerts",label:"Alerts",soon:"Loading notifications\u2026"}];function Mc(){let t=Ic.map((a,n)=>`<button type="button" role="tab" id="tab-${a.id}" aria-controls="panel-${a.id}" aria-selected="${n===0}" tabindex="${n===0?0:-1}" data-tab="${a.id}"><span class="tab-icon"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="${th[a.id]}"/></svg></span><span>${a.label}</span></button>`).join(""),e=Ic.map((a,n)=>`<section role="tabpanel" id="panel-${a.id}" aria-labelledby="tab-${a.id}" tabindex="0"${n===0?"":" hidden"}>
|
|
20317
20412
|
<h2>${a.label}</h2>
|
|
20318
20413
|
<p class="soon">${a.soon}</p>
|
|
20319
20414
|
</section>`).join("");return`<!doctype html>
|
|
20320
20415
|
<html lang="en">
|
|
20321
|
-
<head>${
|
|
20416
|
+
<head>${xn("AgentX")}<style>${oh}${ql}${ac}${Zl}${sc}${hn}${xc}${Sc}${Wl}${Hl}</style></head>
|
|
20322
20417
|
<body>
|
|
20323
20418
|
<header class="bar">
|
|
20324
20419
|
<div>
|
|
20325
20420
|
<h1>AgentX</h1>
|
|
20326
20421
|
<p id="who" class="who">Connecting\u2026</p>
|
|
20327
20422
|
</div>
|
|
20328
|
-
<div class="bar-btns">${
|
|
20423
|
+
<div class="bar-btns">${mc}<button type="button" id="theme" class="icon-btn" aria-label="Switch to light theme"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 15.5A9 9 0 0 1 8.5 4 9 9 0 1 0 20 15.5Z"/></svg></button></div>
|
|
20329
20424
|
</header>
|
|
20330
20425
|
<p id="offline" class="offline" role="status" hidden>Offline. Showing the saved app; live data needs a connection.</p>
|
|
20331
|
-
${
|
|
20426
|
+
${gc}
|
|
20332
20427
|
<main>${e}</main>
|
|
20333
20428
|
<nav class="tabs" role="tablist" aria-label="Sections">${t}</nav>
|
|
20334
|
-
${
|
|
20335
|
-
<script>${
|
|
20336
|
-
<script>${q({swipeMayStart:
|
|
20337
|
-
<script>${Hl}</script>
|
|
20429
|
+
${fc}
|
|
20430
|
+
<script>${ah}</script>
|
|
20431
|
+
<script>${q({swipeMayStart:Ec,swipeAxis:Tc,swipeOffset:Ac,swipeLanding:Cc})}${_c}</script>
|
|
20338
20432
|
<script>${Bl}</script>
|
|
20339
|
-
<script>${
|
|
20340
|
-
<script>${
|
|
20341
|
-
<script>${Gl}</script>
|
|
20342
|
-
<script>${
|
|
20343
|
-
<script>${q({
|
|
20344
|
-
<script>${
|
|
20345
|
-
<script>${
|
|
20346
|
-
<script>${
|
|
20433
|
+
<script>${zl}</script>
|
|
20434
|
+
<script>${Fl}</script>
|
|
20435
|
+
<script>${q({locationErrorText:Gl})}${Ul}</script>
|
|
20436
|
+
<script>${Xl}</script>
|
|
20437
|
+
<script>${q({markdownToHtml:hr})}${Jl}${Yl}${Vl}${Kl}</script>
|
|
20438
|
+
<script>${q({queueSpeech:ec,nextSpeech:tc})}${nc}${rc}${oc}</script>
|
|
20439
|
+
<script>${Ql}</script>
|
|
20440
|
+
<script>${q({cameraConstraints:vc,shareClock:yc,streamLabel:kc,talkRelease:wc})}${hc}</script>
|
|
20441
|
+
<script>${bc}</script>
|
|
20347
20442
|
</body>
|
|
20348
|
-
</html>`}function
|
|
20443
|
+
</html>`}function Lc(){return`<!doctype html>
|
|
20349
20444
|
<html lang="en">
|
|
20350
|
-
<head>${
|
|
20445
|
+
<head>${xn("Pair \xB7 AgentX")}</head>
|
|
20351
20446
|
<body>
|
|
20352
20447
|
<main class="card">
|
|
20353
20448
|
<h1>Pairing this phone\u2026</h1>
|
|
20354
20449
|
<p id="msg" role="status">One moment.</p>
|
|
20355
20450
|
</main>
|
|
20356
|
-
<script>${
|
|
20451
|
+
<script>${nh}</script>
|
|
20357
20452
|
</body>
|
|
20358
|
-
</html>`}function
|
|
20453
|
+
</html>`}function Rc(){return`<!doctype html>
|
|
20359
20454
|
<html lang="en">
|
|
20360
|
-
<head>${
|
|
20361
|
-
<body>${
|
|
20455
|
+
<head>${xn("Not paired \xB7 AgentX")}<style>${lc}${pc}</style></head>
|
|
20456
|
+
<body>${ic}${dc}
|
|
20362
20457
|
<script>${q({mayBounce:Po,formatPairInput:Ft,parsePairScan:$o})}</script>
|
|
20363
|
-
<script>${
|
|
20364
|
-
<script>${
|
|
20458
|
+
<script>${cc}</script>
|
|
20459
|
+
<script>${uc}</script>
|
|
20365
20460
|
</body>
|
|
20366
|
-
</html>`}function
|
|
20461
|
+
</html>`}function Pc(){return JSON.stringify({id:"/app",name:"AgentX",short_name:"AgentX",description:"Talk to your agents and watch your fleet.",start_url:"/app",scope:"/app",display:"standalone",background_color:"#FFFFFF",theme_color:"#2979FF",icons:[{src:"/app/icon-192.png",sizes:"192x192",type:"image/png",purpose:"any"},{src:"/app/icon-512.png",sizes:"512x512",type:"image/png",purpose:"any"},{src:"/app/icon-512.png",sizes:"512x512",type:"image/png",purpose:"maskable"}]})}var ah=`
|
|
20367
20462
|
(function () {
|
|
20368
20463
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
20369
20464
|
function select(tab, focus, keepHash) {
|
|
@@ -20435,7 +20530,7 @@ ${mc}
|
|
|
20435
20530
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
20436
20531
|
}
|
|
20437
20532
|
})();
|
|
20438
|
-
`,
|
|
20533
|
+
`,nh=`
|
|
20439
20534
|
(function () {
|
|
20440
20535
|
var msg = document.getElementById('msg');
|
|
20441
20536
|
var m = /(?:^#|&)token=([^&]+)/.exec(location.hash);
|
|
@@ -20452,7 +20547,7 @@ ${mc}
|
|
|
20452
20547
|
: 'Pairing failed (HTTP ' + r.status + '). Try again.';
|
|
20453
20548
|
}).catch(function () { msg.textContent = 'Could not reach AgentX. Check this phone is on your tailnet, then try again.'; });
|
|
20454
20549
|
})();
|
|
20455
|
-
`,
|
|
20550
|
+
`,rh=`
|
|
20456
20551
|
html, body { margin: 0; background: var(--ax-bg); color: var(--ax-text); font-family: var(--ax-font); }
|
|
20457
20552
|
body { min-height: 100dvh; -webkit-text-size-adjust: 100%; }
|
|
20458
20553
|
code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surface-3); padding: 1px 6px; border-radius: 6px; }
|
|
@@ -20464,7 +20559,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
20464
20559
|
.card h1 { font-size: 22px; margin: 0 0 12px; }
|
|
20465
20560
|
.muted { color: var(--ax-text-2); }
|
|
20466
20561
|
:focus-visible { outline: 3px solid var(--ax-accent); outline-offset: 2px; }
|
|
20467
|
-
`,
|
|
20562
|
+
`,oh=`
|
|
20468
20563
|
body { display: flex; flex-direction: column; }
|
|
20469
20564
|
.bar {
|
|
20470
20565
|
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
|
@@ -20502,8 +20597,8 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20502
20597
|
}
|
|
20503
20598
|
.tabs [role=tab][aria-selected=true] { background: var(--ax-accent-t); color: var(--ax-accent-2); }
|
|
20504
20599
|
[data-theme="dark"] .tabs [role=tab][aria-selected=true] { color: var(--ax-text); }
|
|
20505
|
-
`;var la="agentx_app",
|
|
20506
|
-
`;rt=Buffer.concat([Buffer.from(a),
|
|
20600
|
+
`;var la="agentx_app",lh=400*86400,ch=new At,dh=new Ie;async function $c(t,e,a,n,r={}){if(a==="/.well-known/assetlinks.json"&&n==="GET"){let i=r.assetLinks?.()??null;return i?me(e,200,"application/json",JSON.stringify(i),"public, max-age=300"):_e(e,404,{error:"not found"})}if(a!=="/app"&&!a.startsWith("/app/")&&!a.startsWith("/api/app/"))return!1;let o=r.tokens??new G;if(n==="GET"){if(a==="/app/manifest.webmanifest")return me(e,200,"application/manifest+json",Pc());if(a==="/app/sw.js")return e.setHeader("Service-Worker-Allowed","/app"),me(e,200,"text/javascript; charset=utf-8",gn);if(a==="/app/icon-192.png")return me(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/app/icon-512.png")return me(e,200,"image/png",Fe(512),"public, max-age=86400");if(a==="/app/pair")return me(e,200,"text/html; charset=utf-8",Lc());if(a==="/app/qr.js"){let i=ph();return i?me(e,200,"text/javascript; charset=utf-8",i,"public, max-age=2592000"):_e(e,404,{error:"not found"})}}if(n==="POST"&&a==="/api/app/session"){let i=bn(ot(t),o);return i?(e.setHeader("Set-Cookie",vn(ot(t))),_e(e,200,{device:i.name})):_e(e,401,{error:"invalid or revoked device token"})}if(n==="POST"&&a==="/api/app/pair-code"){let i=await fr(t,{codes:r.pairCodes??new kt,limiter:r.pairLimiter??ch,verify:l=>bn(l,o)?.name??null,minMs:r.pairMinMs});return i.status===200&&e.setHeader("Set-Cookie",vn(i.token)),i.status===429&&e.setHeader("Retry-After",String(i.retryAfter)),_e(e,i.status,i.body)}let s=bn(uh(t),o);if(!s){let i=ot(t);return(r.rejectLog??dh).record(a.slice(0,120),Bt(t,qe(yn(t,la),o),i?qe(i,o):null)),a==="/app"?me(e,401,"text/html; charset=utf-8",Rc()):_e(e,401,{error:"this device is not paired",hint:"run: agentx app pair"})}if(n==="GET"&&a==="/app"){let i=yn(t,la);return i&&!ot(t)&&e.setHeader("Set-Cookie",vn(i)),me(e,200,"text/html; charset=utf-8",Mc())}return n==="GET"&&a==="/api/app/me"?_e(e,200,{id:s.id,device:s.name,node:r.nodeName??null}):r.fleet&&await ir(t,e,a,n,s.name,r.fleet)||r.push&&await lr(t,e,a,n,s,r.push)||r.announce&&await Zi(t,e,a,n,s,r.announce)||r.chat&&await dl(t,e,a,n,s,r.chat)||r.chat&&await fl(t,e,a,n,s,r.chat)||r.voice&&await xl(t,e,a,n,s,r.voice)||r.camera&&await vl(t,e,a,n,r.camera)||r.places&&await Pl(t,e,a,n,s,r.places)?!0:_e(e,404,{error:"not found"})}var rt;function ph(){if(rt!==void 0)return rt;try{let t=ih(import.meta.url),{version:e}=t("jsqr/package.json"),a=`/*! jsQR ${e} | Apache-2.0 | https://github.com/cozmo/jsQR */
|
|
20601
|
+
`;rt=Buffer.concat([Buffer.from(a),sh(t.resolve("jsqr"))])}catch(t){console.error(`[app] QR decoder unavailable (install the jsqr package): ${t.message}`),rt=null}return rt}function bn(t,e){if(!t)return null;let a=e.verify(t);return a&&Ee(a,"app")?a:null}function vn(t){return`${la}=${t}; Path=/; Max-Age=${lh}; HttpOnly; Secure; SameSite=Lax`}function uh(t){return ot(t)??yn(t,la)}function ot(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function yn(t,e){for(let a of(t.headers.cookie||"").split(";")){let n=a.indexOf("=");if(n>0&&a.slice(0,n).trim()===e)return a.slice(n+1).trim()||null}return null}function me(t,e,a,n,r="no-store"){return t.writeHead(e,{"Content-Type":a,"Cache-Control":r}),t.end(n),!0}function _e(t,e,a){return me(t,e,"application/json",JSON.stringify(a))}function jc(t){let e=pe({kicker:"Phone",title:"Places",lead:"Places your phone watches, and what to remind you of when you arrive or leave. The AgentX Android app on your phone notices the crossing and tells this computer only which place and which way: never where you are."})+`
|
|
20507
20602
|
<div class="pl-wrap">
|
|
20508
20603
|
<div id="pl-msg" class="pl-msg" role="status" aria-live="polite"></div>
|
|
20509
20604
|
<form id="pl-add" class="pl-form" autocomplete="off">
|
|
@@ -20515,7 +20610,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20515
20610
|
<button type="submit" class="ax-btn ax-btn--primary">Add place</button>
|
|
20516
20611
|
</form>
|
|
20517
20612
|
<ol id="pl-list" class="pl-list" aria-label="Places"><li class="pl-empty">Loading\u2026</li></ol>
|
|
20518
|
-
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:
|
|
20613
|
+
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:mh,scripts:`<script>${fh}</script>`})}var mh=`
|
|
20519
20614
|
.pl-wrap { max-width: 1040px; margin: 0 auto; padding: 0 24px 96px; box-sizing: border-box; }
|
|
20520
20615
|
.pl-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
20521
20616
|
.pl-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -20538,7 +20633,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20538
20633
|
.pl-rule-form { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
20539
20634
|
.pl-rule-form input[name=text] { flex: 1 1 240px; }
|
|
20540
20635
|
.pl-btns { margin-left: auto; display: flex; gap: 8px; }
|
|
20541
|
-
`,
|
|
20636
|
+
`,fh=`
|
|
20542
20637
|
(function () {
|
|
20543
20638
|
var list = document.getElementById('pl-list');
|
|
20544
20639
|
var msg = document.getElementById('pl-msg');
|
|
@@ -20617,7 +20712,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20617
20712
|
});
|
|
20618
20713
|
load();
|
|
20619
20714
|
})();
|
|
20620
|
-
`;import{randomBytes as
|
|
20715
|
+
`;import{randomBytes as Oc}from"crypto";var He={content:32e3,messagesPerConversation:200,conversationsPerDevice:100,toolsPerMessage:50,filesPerMessage:de.perMessage},hh=/^[a-f0-9]{32}$/,gh=/^c[a-z0-9]{8,32}$/,xh=/^#[0-9a-fA-F]{6}$/;function wn(t){return gh.test(t)}var st=class{constructor(e){this.db=e;e.exec(`CREATE TABLE IF NOT EXISTS app_chat_conversations (
|
|
20621
20716
|
id TEXT PRIMARY KEY, device_id TEXT NOT NULL, title TEXT NOT NULL,
|
|
20622
20717
|
node TEXT NOT NULL, node_name TEXT NOT NULL, agent TEXT NOT NULL, agent_name TEXT,
|
|
20623
20718
|
created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);
|
|
@@ -20630,39 +20725,39 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20630
20725
|
id TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, message_id INTEGER NOT NULL,
|
|
20631
20726
|
path TEXT NOT NULL, name TEXT NOT NULL, mime TEXT NOT NULL, kind TEXT NOT NULL, created_at INTEGER NOT NULL);
|
|
20632
20727
|
CREATE INDEX IF NOT EXISTS app_chat_files_conversation ON app_chat_files(conversation_id);`),e.prepare("PRAGMA table_info(app_chat_messages)").all().some(r=>r.name==="files")||e.exec("ALTER TABLE app_chat_messages ADD COLUMN files TEXT");let n=e.prepare("PRAGMA table_info(app_chat_conversations)").all();n.some(r=>r.name==="read_at")||e.transaction(()=>{e.prepare("PRAGMA table_info(app_chat_conversations)").all().some(o=>o.name==="read_at")||(e.exec("ALTER TABLE app_chat_conversations ADD COLUMN read_at INTEGER"),e.exec("UPDATE app_chat_conversations SET read_at = updated_at"))}).immediate(),n.some(r=>r.name==="color")||e.exec("ALTER TABLE app_chat_conversations ADD COLUMN color TEXT"),e.exec(`CREATE TABLE IF NOT EXISTS app_chat_delivered (
|
|
20633
|
-
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return
|
|
20634
|
-
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,c.title,c.node,c.nodeName,c.agent,c.agentName??null,l??null,r,r,r),this.pruneDevice(e),c}get(e,a){if(!
|
|
20728
|
+
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return wn(e)?this.db.prepare("SELECT device_id FROM app_chat_conversations WHERE id = ?").get(e)?.device_id??null:null}appendOnce(e,a,n,r,o=[],s=Date.now()){return!n||n.length>200?null:this.db.transaction(()=>!this.db.prepare("SELECT 1 FROM app_chat_conversations WHERE id = ? AND device_id = ?").get(a,e)||this.db.prepare("INSERT OR IGNORE INTO app_chat_delivered (key, conversation_id, at) VALUES (?, ?, ?)").run(n,a,s).changes===0?null:(this.db.prepare("DELETE FROM app_chat_delivered WHERE at < ?").run(s-30*24*60*6e4),this.appendWithFiles(e,a,r,o))).immediate()}create(e,a,n,r=Date.now()){let o=`c${r.toString(36)}${Oc(4).toString("hex")}`,{color:s,...i}=a,l=s&&xh.test(s)?s:void 0,c={id:o,title:vh(n),...i,...l?{color:l}:{},createdAt:r,updatedAt:r,messages:[]};return this.db.prepare(`INSERT INTO app_chat_conversations
|
|
20729
|
+
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,c.title,c.node,c.nodeName,c.agent,c.agentName??null,l??null,r,r,r),this.pruneDevice(e),c}get(e,a){if(!wn(a))return null;let n=this.db.prepare("SELECT * FROM app_chat_conversations WHERE id = ? AND device_id = ?").get(a,e);if(!n)return null;let r=this.db.prepare("SELECT * FROM app_chat_messages WHERE conversation_id = ? ORDER BY id").all(a).map(bh);return{...Nc(n),messages:r}}list(e,a=He.conversationsPerDevice){return this.db.prepare(`SELECT c.*,
|
|
20635
20730
|
(SELECT COUNT(*) FROM app_chat_messages m WHERE m.conversation_id = c.id) AS n,
|
|
20636
20731
|
(SELECT substr(m.content, 1, 240) FROM app_chat_messages m WHERE m.conversation_id = c.id ORDER BY m.id DESC LIMIT 1) AS last
|
|
20637
|
-
FROM app_chat_conversations c WHERE c.device_id = ? ORDER BY c.updated_at DESC, c.rowid DESC LIMIT ?`).all(e,Math.max(0,a)).map(r=>{let o=typeof r.last=="string"?r.last.replace(/\s+/g," ").trim().slice(0,120):"";return{...
|
|
20732
|
+
FROM app_chat_conversations c WHERE c.device_id = ? ORDER BY c.updated_at DESC, c.rowid DESC LIMIT ?`).all(e,Math.max(0,a)).map(r=>{let o=typeof r.last=="string"?r.last.replace(/\s+/g," ").trim().slice(0,120):"";return{...Nc(r),messages:r.n,...o?{last:o}:{}}})}markRead(e,a,n=Date.now()){wn(a)&&this.db.prepare("UPDATE app_chat_conversations SET read_at = MAX(COALESCE(read_at, 0), ?) WHERE id = ? AND device_id = ?").run(n,a,e)}unread(e,a){return this.db.prepare(`SELECT c.id, c.title, c.agent, c.agent_name, c.color,
|
|
20638
20733
|
substr(m.content, 1, 240) AS answer, m.status, m.at
|
|
20639
20734
|
FROM app_chat_conversations c
|
|
20640
20735
|
JOIN app_chat_messages m ON m.id = (SELECT MAX(id) FROM app_chat_messages WHERE conversation_id = c.id)
|
|
20641
20736
|
WHERE c.device_id = ? AND m.role = 'assistant' AND m.at > COALESCE(c.read_at, 0)
|
|
20642
20737
|
ORDER BY m.at DESC, m.id DESC LIMIT ?`).all(e,Math.max(0,a)).map(r=>({id:r.id,title:r.title,agent:r.agent,...r.agent_name?{agentName:r.agent_name}:{},...r.color?{color:r.color}:{},answer:String(r.answer??"").trim(),status:r.status==="error"||r.status==="stopped"?r.status:"done",at:r.at}))}append(e,a,n){return this.appendWithFiles(e,a,n)!==null}appendWithFiles(e,a,n,r=[]){if(!this.db.prepare("SELECT 1 FROM app_chat_conversations WHERE id = ? AND device_id = ?").get(a,e))return null;let s=n.content.length>He.content?n.content.slice(0,He.content)+`
|
|
20643
20738
|
|
|
20644
|
-
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,He.toolsPerMessage),l=[];for(let m of r){if(l.length>=He.filesPerMessage)break;let
|
|
20739
|
+
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,He.toolsPerMessage),l=[];for(let m of r){if(l.length>=He.filesPerMessage)break;let g=m.filename.trim(),_=Yn(g);if(!_||!g||g.length>de.pathChars||g.includes("\0"))continue;let b=(g.split(/[\\/]/).pop()||g).slice(0,120);l.push({id:Oc(16).toString("hex"),name:b,mime:_.mime,kind:_.kind,path:g})}let c=l.map(m=>({id:m.id,name:m.name,mime:m.mime,kind:m.kind})),d=this.db.prepare(`INSERT INTO app_chat_messages (conversation_id, role, content, status, error, ui, tools, files, at)
|
|
20645
20740
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(a,n.role,s,n.status??null,n.error?.slice(0,500)??null,n.ui?JSON.stringify(n.ui):null,i?.length?JSON.stringify(i):null,c.length?JSON.stringify(c):null,n.at),p=this.db.prepare(`INSERT INTO app_chat_files (id, conversation_id, message_id, path, name, mime, kind, created_at)
|
|
20646
20741
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);for(let m of l)p.run(m.id,a,Number(d.lastInsertRowid),m.path,m.name,m.mime,m.kind,n.at);return this.db.prepare(`DELETE FROM app_chat_messages WHERE conversation_id = ? AND id NOT IN
|
|
20647
20742
|
(SELECT id FROM app_chat_messages WHERE conversation_id = ? ORDER BY id DESC LIMIT ?)`).run(a,a,He.messagesPerConversation),this.db.prepare(`DELETE FROM app_chat_files WHERE conversation_id = ? AND message_id NOT IN
|
|
20648
|
-
(SELECT id FROM app_chat_messages WHERE conversation_id = ?)`).run(a,a),this.db.prepare("UPDATE app_chat_conversations SET updated_at = ? WHERE id = ?").run(n.at,a),c}getFile(e,a){if(!
|
|
20743
|
+
(SELECT id FROM app_chat_messages WHERE conversation_id = ?)`).run(a,a),this.db.prepare("UPDATE app_chat_conversations SET updated_at = ? WHERE id = ?").run(n.at,a),c}getFile(e,a){if(!hh.test(a))return null;let n=this.db.prepare(`SELECT f.*, c.node, c.agent FROM app_chat_files f
|
|
20649
20744
|
JOIN app_chat_conversations c ON c.id = f.conversation_id WHERE f.id = ? AND c.device_id = ?`).get(a,e);return n?{id:n.id,name:n.name,mime:n.mime,kind:n.kind,path:n.path,conversationId:n.conversation_id,node:n.node,agent:n.agent}:null}pruneDevice(e){let a=this.db.prepare(`SELECT id FROM app_chat_conversations WHERE device_id = ?
|
|
20650
|
-
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,He.conversationsPerDevice);for(let{id:n}of a)this.db.prepare("DELETE FROM app_chat_files WHERE conversation_id = ?").run(n),this.db.prepare("DELETE FROM app_chat_messages WHERE conversation_id = ?").run(n),this.db.prepare("DELETE FROM app_chat_conversations WHERE id = ?").run(n)}};function
|
|
20651
|
-
Live dashboard: http://${
|
|
20745
|
+
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,He.conversationsPerDevice);for(let{id:n}of a)this.db.prepare("DELETE FROM app_chat_files WHERE conversation_id = ?").run(n),this.db.prepare("DELETE FROM app_chat_messages WHERE conversation_id = ?").run(n),this.db.prepare("DELETE FROM app_chat_conversations WHERE id = ?").run(n)}};function Nc(t){return{id:t.id,title:t.title,node:t.node,nodeName:t.node_name,agent:t.agent,...t.agent_name?{agentName:t.agent_name}:{},...t.color?{color:t.color}:{},createdAt:t.created_at,updatedAt:t.updated_at}}function bh(t){let e=o=>{if(o)try{return JSON.parse(o)}catch{return}},a=e(t.ui),n=e(t.tools),r=e(t.files);return{role:t.role,content:t.content,at:t.at,...t.status?{status:t.status}:{},...t.error?{error:t.error}:{},...a?{ui:a}:{},...n?{tools:n}:{},...r?{files:r}:{}}}function vh(t){let e=t.replace(/\s+/g," ").trim();return(e.length>60?e.slice(0,59)+"\u2026":e)||"Untitled"}var yh=4e3,kn=100,wh=15,Dc=t=>t.replace(/\/+$/,""),ca=class{constructor(e){this.deps=e}cursor;retry=new Map;timer;running=!1;start(e=yh){this.timer||(this.timer=setInterval(()=>{this.tick()},e),this.timer.unref?.())}stop(){this.timer&&clearInterval(this.timer),this.timer=void 0}async tick(){if(this.running)return 0;this.running=!0;try{let e,a=!1;try{let o=await this.deps.recent(this.cursor,kn);e=Array.isArray(o)?o:o.events,a=!Array.isArray(o)&&o.gap===!0}catch{return 0}this.warnIfSkipped(e.length,a),e.length&&(this.cursor=e[e.length-1].id);let n=[...this.retry.values()].map(o=>o.event);for(let o of e)o.kind==="delegation"&&o.type==="reply"&&typeof o.ref=="string"&&o.ref&&!this.retry.has(o.id)&&n.push(o);let r=0;for(let o of n){let s=await this.file(o).catch(()=>"retry");if(s==="retry"){let i=(this.retry.get(o.id)?.left??wh)-1;i>0?this.retry.set(o.id,{event:o,left:i}):(this.retry.delete(o.id),this.deps.log?.(`[app] callback reply ${o.ref} from ${o.node} could not be read; it stays in the agent's session`))}else this.retry.delete(o.id),s==="filed"&&r++}return r}finally{this.running=!1}}warnIfSkipped(e,a){let n=this.deps.warn??this.deps.log,r=this.cursor?`after event ${this.cursor}`:"on the first read";a&&n?.(`[app] warning: callback event cursor ${this.cursor} is no longer in the daemon's event ring; replies published before the oldest kept event were skipped`),e>=kn&&n?.(`[app] warning: one poll returned ${e} delegation events, the most it reads (${kn}); older replies ${r} may have been skipped`)}async file(e){let a=this.deps.store();if(!a)return"retry";let n=await this.deps.nodeUrl(e.node);if(!n)return"retry";let r=await this.deps.fetchReply(n,e.ref);if(!r||r.taskId!==e.ref||r.channel!=="app"||!r.chatId.startsWith("app:"))return"skip";let o=r.chatId.slice(4),s=a.ownerOf(o);if(!s)return"skip";let i=a.get(s,o);if(!i)return"skip";let l=await this.deps.conversationUrl(i);if(!l||Dc(l)!==Dc(n)||i.agent!==r.agent)return this.deps.log?.(`[app] callback reply ${r.taskId} from ${e.node} does not match conversation ${o}; ignored`),"skip";let c=kh(r,this.deps.now?.()??Date.now());if(a.appendOnce(s,o,`dlg:${e.node}:${r.taskId}`,c.row,c.declared)===null)return"skip";let p=c.row.status,m=!!this.deps.finishAlerts?.(s),g={status:p,attached:!1,appOpen:this.deps.presence.open(s),enabled:m};return this.deps.notifyFinish&&oa(g)&&this.deps.notifyFinish(sa(s,i,p,c.row.content,c.row.error)).catch(()=>{}),"filed"}};function kh(t,e){let a=t.plain?{text:xt(t.text,!1),artifacts:[]}:gt(t.text,de.perMessage,!1),{cleanText:n,ui:r}=vt(a.text),o=t.plain?void 0:ln(r),s=t.status==="error"?"error":"done";return{row:{role:"assistant",content:n,status:s,...s==="error"?{error:_h(n)}:{},...o?{ui:o}:{},at:e},declared:a.artifacts}}function _h(t){return t.replace(/\s+/g," ").trim().slice(0,300)}On();function Ve(){let t=ut();return t&&ke(t,"dashboard"),t}function z0(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let g of a)try{s.set(g.id,jh(g,t))}catch(_){console.error(` Board "${g.id}" failed to initialize: ${_.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?it(process.cwd(),t.workflows.dir):void 0,c=new Wn(l?{baseDir:l}:void 0),d=new Gn(l?{baseDir:l,nodeId:i}:{nodeId:i}),p=new Xn(l?{baseDir:l}:void 0);xi(t),Ve(),kr({business:t.business?.enabled===!0});let m=Sh(async(g,_)=>{try{await Lh(g,_,{boards:a,sources:s,token:o,config:t,workflowStore:c,workflowRuns:d,workflowLayouts:p})}catch(b){w(_,500,{error:b.message||"internal error"})}});Qh(t).start(),m.listen(n,r,()=>{let g=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
|
|
20746
|
+
Live dashboard: http://${g}:${n}
|
|
20652
20747
|
`),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
|
|
20653
|
-
Kanban dashboard: http://${
|
|
20654
|
-
`),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 Ch=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/approvals","/people","/places","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki"]);async function Ih(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if((t.url||"/").split(/[?#]/)[0]!==r){k(e,404,{error:"not found"});return}if(yr(t.headers)==="foreign"&&wr(o)){k(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(await rs(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>tt(a.config.people),members:Hc(a.config.members.logRetentionDays),db:()=>Ve(),linkFor:(u,f)=>To(u,f,{gitlab:a.config.channels.gitlab?.host})})||await Pc(t,e,r,o,{nodeName:a.config.node?.name,fleet:Uc(a.config),push:An(a.config),announce:Zi(a.config),chat:Wc(a.config),voice:Yh(a.config),camera:Qh(a.config),places:Dc(a.config),assetLinks:()=>Ol(a.config)}))return;let s=o==="GET"?_o(r):null;if(s){e.writeHead(200,{"Content-Type":s.type,"Cache-Control":"public, max-age=86400"}),e.end(s.body);return}if(o==="GET"&&Ch.has(r)&&to("page",r),o==="GET"&&r==="/"){let u=zr();if(!u.configExists||u.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(rn({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(qi({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(rn({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Se(a.config);if(!u){k(e,503,{error:"no node available"});return}let f=await new Promise(y=>{let T="";t.on("data",g=>T+=g),t.on("end",()=>y(T)),t.on("error",()=>y(""))}),w=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:f||"{}"});e.writeHead(w.status,{"Content-Type":"application/json"}),e.end(await w.text())}catch(u){k(e,502,{error:"could not reach the node",message:String(u?.message||u)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let u=await Se(a.config),f=o==="POST"?void 0:n.searchParams.get("node"),w=o==="POST"?await me(t):void 0,y=w?.node??f,T=y?u.find(R=>R.url===y):u[0];if(!T){k(e,400,{error:"unknown node"});return}let g=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",A=await fetch(T.url+r+g,{method:o,headers:{"Content-Type":"application/json",...T.token?{Authorization:`Bearer ${T.token}`}:{}},...o==="POST"?{body:JSON.stringify({...w,node:void 0})}:{}});k(e,A.status,await A.json().catch(()=>({error:`HTTP ${A.status}`})))}catch(u){k(e,502,{error:"could not reach the node",message:u?.message||String(u)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let u=await me(t),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let w=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${w}/api/workflows/editor/chat`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),T=await y.json().catch(()=>({error:`HTTP ${y.status}`}));k(e,y.status,T)}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[u]=await Se(a.config);if(!u){k(e,200,{configured:!1,workflows:[]});return}let f=await fetch(u.url+"/api/n8n/workflows",{headers:u.token?{Authorization:`Bearer ${u.token}`}:{}});k(e,f.status,await f.json().catch(()=>({configured:!1,workflows:[]})))}catch{k(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fo({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mo({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(lo({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let u=new AbortController,f=setTimeout(()=>u.abort(),8e3);try{let w=Zn(await Se(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let R=await Promise.all(w.map(async _=>{try{let L=await fetch(_.url+"/monitor",{headers:_.token?{Authorization:`Bearer ${_.token}`}:{},signal:u.signal});if(!L.ok)throw new Error(`HTTP ${L.status}`);return{name:_.name,url:_.url,ok:!0,data:await L.json()}}catch(L){return{name:_.name,url:_.url,ok:!1,error:L.message}}}));k(e,200,{nodes:R});return}let y=w.find(R=>R.url===n.searchParams.get("node"));if(!y){k(e,400,{error:"Select a known node"});return}let T=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(T)||o==="POST"&&["register","ended","action","retry","clear"].includes(T))){k(e,405,{error:"Unknown monitor operation"});return}let g=o==="POST"?JSON.stringify(await Qn(t)):void 0,A=await fetch(y.url+"/monitor/"+T+(T==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):T==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:g,signal:u.signal,headers:{"Content-Type":"application/json",...y.token?{Authorization:`Bearer ${y.token}`}:{}}});k(e,A.status,await A.json())}catch(w){k(e,502,{error:w.message})}finally{clearTimeout(f)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ni({peers:D(a.config)}));return}if(o==="GET"&&r==="/places"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end($c({peers:D(a.config)}));return}if(o==="GET"&&r==="/guests"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Di({peers:D(a.config)}));return}if(o==="GET"&&r==="/api/guests"||o==="POST"&&/^\/api\/guests\/[^/]+\/(pause|resume|end|update)$/.test(r)){try{let u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),w=o==="POST"?await me(t).catch(()=>({})):void 0,y=await fetch(`${f}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...w!==void 0?{body:JSON.stringify(w??{})}:{}});k(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Fi({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ui({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wi({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Br({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let u=n.searchParams.get("agent")||"",f=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!u){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(Gi({taskId:decodeURIComponent(l[1]),agentId:u,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:f,peers:D(a.config)}));return}let c=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(c){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xi({agentId:decodeURIComponent(c[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"){qr(t,e);return}if(o==="POST"&&r==="/api/setup"){await Fr(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Ur(t,e);return}if(o==="GET"&&r==="/admin"){hs(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){Ls(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){ks(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}zs(t,e,D(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let u=n.searchParams.get("peer")==="fleet"?"fleet":String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(u==="fleet"){if(r==="/api/admin/activity-graph"){await rg(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await an(t,e,r,w=>Xc(w,a.config));return}let f=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(f){let w=decodeURIComponent(f[1]),y=w.indexOf("::");if(y>0){let T=w.slice(0,y),g=w.slice(y+2),A=a.config.node?.id||a.config.node?.name||"local";if(T===A)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(g)}`;else{let R=(a.config.dashboard?.daemons||[]).find(_=>(_.name||_.url)===T);if(R){let _=lt(R.url.replace(/\/+$/,""),a.config);if(_){await zc(t,e,_,`/api/admin/activity-graph/dispatch/${encodeURIComponent(g)}`);return}}k(e,404,{error:`unknown node "${T}" in fleet dispatch id`});return}}}}else if(u&&u!=="primary"){let f=lt(u,a.config);if(!f){k(e,404,{error:`unknown peer: ${u}`});return}let w=(n.search||"").replace(/[?&]peer=[^&]*/g,T=>T.startsWith("?")?"?":"");await zc(t,e,f,r+(w==="?"?"":w));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await qs(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await og(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-32YP26SJ.js"),w=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",y=await u({running:w});k(e,200,y)}catch(u){k(e,500,{error:u?.message||String(u)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Gs({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Ws(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xs({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ks({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 Oh(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 xi(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await an(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await vi(t,e,r))return;let d=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(d){ki(t,e,d[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let u=t.headers.authorization||"",f=u.startsWith("Bearer ")?u.slice(7):"";if(f!==a.token){let w=new G,y=f?w.verify(f):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await gs(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){k(e,200,Er()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await Rs(t,e,r,n);return}if(await $s(t,e,r,{people:()=>tt(a.config.people),members:Hc(a.config.members.logRetentionDays),root:process.cwd(),db:()=>Ve(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await _s(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await _i(t,e,r);return}if(r.startsWith("/api/admin/")){await xs(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(os);return}if(o==="GET"&&r.startsWith("/assets/")){let u=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(u)){k(e,400,{error:"invalid asset name"});return}let f=ag("web/"+u);try{let w=await ng(f),y=u.endsWith(".map")?"application/json; charset=utf-8":u.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",T=n.searchParams.has("v");e.writeHead(200,{"Content-Type":y,"Cache-Control":T?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(w)}catch{k(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let u=await Ye(a.config);k(e,200,u)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let u=n.searchParams.get("date")||new Date().toISOString().slice(0,10),f=n.searchParams.get("timezone")||"UTC",w=await Ye(a.config,{date:u,timezone:f});k(e,200,w)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(f,w,y,T)=>{let g=parseInt(n.searchParams.get(f)||"",10);return Number.isFinite(g)?Math.max(y,Math.min(T,g)):w};try{let f=await Se(a.config);k(e,200,await Hi(f,{days:u("days",30,0,180),tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",60,1,200)}))}catch(f){k(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let u=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(u)){k(e,400,{error:"day=YYYY-MM-DD query param required"});return}let f=(w,y,T,g)=>{let A=parseInt(n.searchParams.get(w)||"",10);return Number.isFinite(A)?Math.max(T,Math.min(g,A)):y};try{let w=await Se(a.config);k(e,200,await zi(w,{day:u,tzOffsetMinutes:f("tzOffset",0,-840,840),limit:f("limit",40,1,200)}))}catch(w){k(e,502,{error:w.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}let f=n.searchParams,w;if(r==="/api/mesh/thread"){let[y,T,g]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!T||!g){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/thread?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(g)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[y,T]=[f.get("kind"),f.get("key")];if(!y||!T){k(e,400,{error:"kind and key required"});return}w=`/analytics/job?kind=${encodeURIComponent(y)}&key=${encodeURIComponent(T)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[y,T,g]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!T||!g){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/conversation?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(g)}&tzOffset=${encodeURIComponent(f.get("tzOffset")||"0")}`}else{let y=f.get("task");if(!y){k(e,400,{error:"task required"});return}w=`/analytics/run/${encodeURIComponent(y)}`}try{await Bi(e,await Se(a.config),u,w)}catch(y){k(e,502,{error:y.message})}return}if(o==="GET"&&r==="/api/live/stream"){Fh(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task");if(!f||!w||!y){k(e,400,{error:"node, agent, task query params required"});return}await Uh(t,e,a,f,w,y);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task"),T=u.searchParams.get("limit")||"50";if(!f||!w){k(e,400,{error:"node and agent query params required"});return}await Xh(e,a,f,w,y,T);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),w=u.searchParams.get("task"),y=u.searchParams.get("kind");if(!f||!w||y!=="cancel"&&y!=="followup"){k(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Kh(t,e,a,f,w,y);return}if(o==="POST"&&r==="/api/voice/stop"){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await Tn(t,e,a,u,"/voice/stop");return}if(o==="GET"&&r==="/api/agents"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:u});if(!f.ok)throw new Error(`HTTP ${f.status}`);let w=await f.json();k(e,200,w)}catch(u){k(e,502,{error:u.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:u});if(!f.ok){k(e,f.status,{error:`HTTP ${f.status}`});return}k(e,200,await f.json())}catch(u){k(e,502,{error:u.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let u=await me(t);try{let f=await eg(a.config,u);k(e,200,f)}catch(f){k(e,502,{error:f.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let u=p[1];if(!Wh(t,e,[`agent:${u}`]))return;await Gh(t,e,a.config,u);return}if(o==="GET"&&r==="/api/node/build"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/health",{headers:u,signal:AbortSignal.timeout(3e3)});if(!f.ok)throw new Error(`HTTP ${f.status}`);k(e,200,Sr(await f.json()))}catch(u){k(e,502,{error:u.message||"daemon not reachable"})}return}if(r.startsWith("/api/")&&a.token){let u=t.headers.authorization||"",f=u.startsWith("Bearer ")?u.slice(7):"";if(f!==a.token){let w=new G,y=f?w.verify(f):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Nh(e,a.config,n.searchParams);return}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){k(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(await Pl(t,e,r,o,Dc(a.config)))return;if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await Tn(t,e,a,u,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let f=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let w=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(A=>({name:A.name,url:A.url,token:A.token}))],y={flag:!1},T=[];t.on("close",()=>{y.flag=!0;for(let A of T)try{A.abort()}catch{}});let g=setInterval(()=>{if(!y.flag)try{e.write(`: ping
|
|
20748
|
+
Kanban dashboard: http://${g}:${n}
|
|
20749
|
+
`),console.log(` Boards: ${a.map(_=>_.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 Mh=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/approvals","/people","/places","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki"]);async function Lh(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if((t.url||"/").split(/[?#]/)[0]!==r){w(e,404,{error:"not found"});return}if(yr(t.headers)==="foreign"&&wr(o)){w(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(await rs(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>tt(a.config.people),members:Bc(a.config.members.logRetentionDays),db:()=>Ve(),linkFor:(u,f)=>To(u,f,{gitlab:a.config.channels.gitlab?.host})})||await $c(t,e,r,o,{nodeName:a.config.node?.name,fleet:Wc(a.config),push:An(a.config),announce:el(a.config),chat:Gc(a.config),voice:Zh(a.config),camera:eg(a.config),places:Hc(a.config),assetLinks:()=>Nl(a.config)}))return;let s=o==="GET"?_o(r):null;if(s){e.writeHead(200,{"Content-Type":s.type,"Cache-Control":"public, max-age=86400"}),e.end(s.body);return}if(o==="GET"&&Mh.has(r)&&to("page",r),o==="GET"&&r==="/"){let u=zr();if(!u.configExists||u.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(on({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Fi({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(on({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Se(a.config);if(!u){w(e,503,{error:"no node available"});return}let f=await new Promise(v=>{let E="";t.on("data",x=>E+=x),t.on("end",()=>v(E)),t.on("error",()=>v(""))}),y=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:f||"{}"});e.writeHead(y.status,{"Content-Type":"application/json"}),e.end(await y.text())}catch(u){w(e,502,{error:"could not reach the node",message:String(u?.message||u)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let u=await Se(a.config),f=o==="POST"?void 0:n.searchParams.get("node"),y=o==="POST"?await le(t):void 0,v=y?.node??f,E=v?u.find(R=>R.url===v):u[0];if(!E){w(e,400,{error:"unknown node"});return}let x=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",A=await fetch(E.url+r+x,{method:o,headers:{"Content-Type":"application/json",...E.token?{Authorization:`Bearer ${E.token}`}:{}},...o==="POST"?{body:JSON.stringify({...y,node:void 0})}:{}});w(e,A.status,await A.json().catch(()=>({error:`HTTP ${A.status}`})))}catch(u){w(e,502,{error:"could not reach the node",message:u?.message||String(u)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let u=await le(t),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let y=a.config.dashboard.daemonUrl.replace(/\/+$/,""),v=await fetch(`${y}/api/workflows/editor/chat`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await v.json().catch(()=>({error:`HTTP ${v.status}`}));w(e,v.status,E)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[u]=await Se(a.config);if(!u){w(e,200,{configured:!1,workflows:[]});return}let f=await fetch(u.url+"/api/n8n/workflows",{headers:u.token?{Authorization:`Bearer ${u.token}`}:{}});w(e,f.status,await f.json().catch(()=>({configured:!1,workflows:[]})))}catch{w(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fo({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mo({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(lo({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let u=new AbortController,f=setTimeout(()=>u.abort(),8e3);try{let y=Zn(await Se(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let R=await Promise.all(y.map(async k=>{try{let L=await fetch(k.url+"/monitor",{headers:k.token?{Authorization:`Bearer ${k.token}`}:{},signal:u.signal});if(!L.ok)throw new Error(`HTTP ${L.status}`);return{name:k.name,url:k.url,ok:!0,data:await L.json()}}catch(L){return{name:k.name,url:k.url,ok:!1,error:L.message}}}));w(e,200,{nodes:R});return}let v=y.find(R=>R.url===n.searchParams.get("node"));if(!v){w(e,400,{error:"Select a known node"});return}let E=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(E)||o==="POST"&&["register","ended","action","retry","clear"].includes(E))){w(e,405,{error:"Unknown monitor operation"});return}let x=o==="POST"?JSON.stringify(await Qn(t)):void 0,A=await fetch(v.url+"/monitor/"+E+(E==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):E==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:x,signal:u.signal,headers:{"Content-Type":"application/json",...v.token?{Authorization:`Bearer ${v.token}`}:{}}});w(e,A.status,await A.json())}catch(y){w(e,502,{error:y.message})}finally{clearTimeout(f)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Di({peers:D(a.config)}));return}if(o==="GET"&&r==="/places"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(jc({peers:D(a.config)}));return}if(o==="GET"&&r==="/guests"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Hi({peers:D(a.config)}));return}if(o==="GET"&&r==="/api/guests"||o==="POST"&&/^\/api\/guests\/[^/]+\/(pause|resume|end|update)$/.test(r)){try{let u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=o==="POST"?await le(t).catch(()=>({})):void 0,v=await fetch(`${f}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...y!==void 0?{body:JSON.stringify(y??{})}:{}});w(e,v.status,await v.json().catch(()=>({error:`HTTP ${v.status}`})))}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ui({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wi({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Gi({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Br({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let u=n.searchParams.get("agent")||"",f=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!u){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(Xi({taskId:decodeURIComponent(l[1]),agentId:u,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:f,peers:D(a.config)}));return}let c=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(c){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ki({agentId:decodeURIComponent(c[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"){qr(t,e);return}if(o==="POST"&&r==="/api/setup"){await Fr(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Ur(t,e);return}if(o==="GET"&&r==="/admin"){hs(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){Rs(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){_s(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}qs(t,e,D(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let u=n.searchParams.get("peer")==="fleet"?"fleet":String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(u==="fleet"){if(r==="/api/admin/activity-graph"){await sg(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await nn(t,e,r,y=>Kc(y,a.config));return}let f=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(f){let y=decodeURIComponent(f[1]),v=y.indexOf("::");if(v>0){let E=y.slice(0,v),x=y.slice(v+2),A=a.config.node?.id||a.config.node?.name||"local";if(E===A)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`;else{let R=(a.config.dashboard?.daemons||[]).find(k=>(k.name||k.url)===E);if(R){let k=lt(R.url.replace(/\/+$/,""),a.config);if(k){await qc(t,e,k,`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`);return}}w(e,404,{error:`unknown node "${E}" in fleet dispatch id`});return}}}}else if(u&&u!=="primary"){let f=lt(u,a.config);if(!f){w(e,404,{error:`unknown peer: ${u}`});return}let y=(n.search||"").replace(/[?&]peer=[^&]*/g,E=>E.startsWith("?")?"?":"");await qc(t,e,f,r+(y==="?"?"":y));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Fs(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await ig(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-NBWYG743.js"),y=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",v=await u({running:y});w(e,200,v)}catch(u){w(e,500,{error:u?.message||String(u)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xs({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Gs(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ks({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Js({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 Dh(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 bi(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await nn(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await yi(t,e,r))return;let d=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(d){_i(t,e,d[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let u=t.headers.authorization||"",f=u.startsWith("Bearer ")?u.slice(7):"";if(f!==a.token){let y=new G,v=f?y.verify(f):null;if(!v||!Ee(v,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await gs(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){w(e,200,Er()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await Ps(t,e,r,n);return}if(await js(t,e,r,{people:()=>tt(a.config.people),members:Bc(a.config.members.logRetentionDays),root:process.cwd(),db:()=>Ve(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await Ss(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await Si(t,e,r);return}if(r.startsWith("/api/admin/")){await xs(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(os);return}if(o==="GET"&&r.startsWith("/assets/")){let u=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(u)){w(e,400,{error:"invalid asset name"});return}let f=rg("web/"+u);try{let y=await og(f),v=u.endsWith(".map")?"application/json; charset=utf-8":u.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",E=n.searchParams.has("v");e.writeHead(200,{"Content-Type":v,"Cache-Control":E?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(y)}catch{w(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let u=await Ye(a.config);w(e,200,u)}catch(u){w(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let u=n.searchParams.get("date")||new Date().toISOString().slice(0,10),f=n.searchParams.get("timezone")||"UTC",y=await Ye(a.config,{date:u,timezone:f});w(e,200,y)}catch(u){w(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(f,y,v,E)=>{let x=parseInt(n.searchParams.get(f)||"",10);return Number.isFinite(x)?Math.max(v,Math.min(E,x)):y};try{let f=await Se(a.config);w(e,200,await Bi(f,{days:u("days",30,0,180),tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",60,1,200)}))}catch(f){w(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let u=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(u)){w(e,400,{error:"day=YYYY-MM-DD query param required"});return}let f=(y,v,E,x)=>{let A=parseInt(n.searchParams.get(y)||"",10);return Number.isFinite(A)?Math.max(E,Math.min(x,A)):v};try{let y=await Se(a.config);w(e,200,await qi(y,{day:u,tzOffsetMinutes:f("tzOffset",0,-840,840),limit:f("limit",40,1,200)}))}catch(y){w(e,502,{error:y.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let u=n.searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}let f=n.searchParams,y;if(r==="/api/mesh/thread"){let[v,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!v||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}y=`/analytics/thread?agent=${encodeURIComponent(v)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[v,E]=[f.get("kind"),f.get("key")];if(!v||!E){w(e,400,{error:"kind and key required"});return}y=`/analytics/job?kind=${encodeURIComponent(v)}&key=${encodeURIComponent(E)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[v,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!v||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}y=`/analytics/conversation?agent=${encodeURIComponent(v)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(f.get("tzOffset")||"0")}`}else{let v=f.get("task");if(!v){w(e,400,{error:"task required"});return}y=`/analytics/run/${encodeURIComponent(v)}`}try{await zi(e,await Se(a.config),u,y)}catch(v){w(e,502,{error:v.message})}return}if(o==="GET"&&r==="/api/live/stream"){Wh(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),y=u.searchParams.get("agent"),v=u.searchParams.get("task");if(!f||!y||!v){w(e,400,{error:"node, agent, task query params required"});return}await Gh(t,e,a,f,y,v);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),y=u.searchParams.get("agent"),v=u.searchParams.get("task"),E=u.searchParams.get("limit")||"50";if(!f||!y){w(e,400,{error:"node and agent query params required"});return}await Jh(e,a,f,y,v,E);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),y=u.searchParams.get("task"),v=u.searchParams.get("kind");if(!f||!y||v!=="cancel"&&v!=="followup"){w(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Vh(t,e,a,f,y,v);return}if(o==="POST"&&r==="/api/voice/stop"){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}await ua(t,e,a,u,"/voice/stop");return}if(o==="GET"&&r==="/api/agents"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:u});if(!f.ok)throw new Error(`HTTP ${f.status}`);let y=await f.json();w(e,200,y)}catch(u){w(e,502,{error:u.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:u});if(!f.ok){w(e,f.status,{error:`HTTP ${f.status}`});return}w(e,200,await f.json())}catch(u){w(e,502,{error:u.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let u=await le(t);try{let f=await ag(a.config,u);w(e,200,f)}catch(f){w(e,502,{error:f.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let u=p[1];if(!Xh(t,e,[`agent:${u}`]))return;await Kh(t,e,a.config,u);return}if(o==="GET"&&r==="/api/node/build"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/health",{headers:u,signal:AbortSignal.timeout(3e3)});if(!f.ok)throw new Error(`HTTP ${f.status}`);w(e,200,Sr(await f.json()))}catch(u){w(e,502,{error:u.message||"daemon not reachable"})}return}if(r.startsWith("/api/")&&a.token){let u=t.headers.authorization||"",f=u.startsWith("Bearer ")?u.slice(7):"";if(f!==a.token){let y=new G,v=f?y.verify(f):null;if(!v||!Ee(v,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Hh(e,a.config,n.searchParams);return}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){w(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(r==="/api/wiki/curate"||r==="/api/wiki/curate/restore"){try{let u={"Content-Type":"application/json"};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=o==="POST"?JSON.stringify(await le(t)??{}):void 0,v=await fetch(`${f}${r}${n.search}`,{method:o,headers:u,...y?{body:y}:{}});w(e,v.status,await v.json().catch(()=>({error:`HTTP ${v.status}`})))}catch(u){w(e,502,{error:"daemon unreachable",message:u?.message||String(u)})}return}if(await $l(t,e,r,o,Hc(a.config)))return;if(o==="POST"&&(r==="/api/signals/stop"||r==="/api/signals/resume")){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}await ua(t,e,a,u,r);return}if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let u=n.searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}await ua(t,e,a,u,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let f=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let y=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(A=>({name:A.name,url:A.url,token:A.token}))],v={flag:!1},E=[];t.on("close",()=>{v.flag=!0;for(let A of E)try{A.abort()}catch{}});let x=setInterval(()=>{if(!v.flag)try{e.write(`: ping
|
|
20655
20750
|
|
|
20656
|
-
`)}catch{}},15e3);t.on("close",()=>clearInterval(
|
|
20751
|
+
`)}catch{}},15e3);t.on("close",()=>clearInterval(x));for(let A of y)(async()=>{let R={Accept:"text/event-stream"};A.token&&(R.Authorization=`Bearer ${A.token}`);let k=new AbortController;E.push(k);try{let L=await fetch(`${A.url.replace(/\/+$/,"")}/events${f?`?${f}`:""}`,{headers:R,signal:k.signal});if(!L.ok||!L.body)return;let j=L.body.getReader(),$=new TextDecoder,O="";for(;!v.flag;){let{done:W,value:ce}=await j.read();if(W)break;O+=$.decode(ce,{stream:!0});let Q;for(;(Q=O.indexOf(`
|
|
20657
20752
|
|
|
20658
|
-
`))>=0;){let re=O.slice(0,Q);if(O=O.slice(Q+2),
|
|
20753
|
+
`))>=0;){let re=O.slice(0,Q);if(O=O.slice(Q+2),v.flag)break;try{e.write(re+`
|
|
20659
20754
|
|
|
20660
|
-
`)}catch{
|
|
20661
|
-
`;
|
|
20755
|
+
`)}catch{v.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/follow-ups"){let u=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(x=>({url:x.url,token:x.token}))],f=[],y=await Promise.all(u.map(async x=>{let A={};x.token&&(A.Authorization=`Bearer ${x.token}`);try{let R=await fetch(`${x.url.replace(/\/+$/,"")}/api/workflows/runs?limit=500&summary=1`,{headers:A,signal:AbortSignal.timeout(5e3)});if(!R.ok)return f.push(x.url),[];let k=await R.json();return Array.isArray(k.runs)?k.runs:[]}catch{return f.push(x.url),[]}})),v=new Map;for(let x of a.workflowRuns.list({limit:500}))v.set(x.id,x);for(let x of y)for(let A of x)v.set(A.id,{...A,history:A.history??[],pending:A.pending??[]});let E=new Map(a.workflowStore.list().map(x=>[x.id,x.title]));w(e,200,{groups:Vn([...v.values()],x=>E.get(x)),unreachable:f});return}if(o==="GET"&&r==="/api/workflows/runs"){try{let u=new URL(t.url||"/","http://localhost"),f=Math.max(1,Math.min(500,Number(u.searchParams.get("limit")||50))),y=u.searchParams.get("workflowId")||void 0,v=u.searchParams.get("summary")==="1"||u.searchParams.get("summary")==="true",E=a.workflowRuns.list({limit:f,workflowId:y}),x=`?limit=${f}${y?`&workflowId=${encodeURIComponent(y)}`:""}${v?"&summary=1":""}`,A=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map($=>({url:$.url,token:$.token}))],R=await Promise.all(A.map(async $=>{let O={};$.token&&(O.Authorization=`Bearer ${$.token}`);try{let W=new AbortController,ce=setTimeout(()=>W.abort(),5e3);try{let Q=await fetch(`${$.url.replace(/\/+$/,"")}/api/workflows/runs${x}`,{headers:O,signal:W.signal});if(!Q.ok)return[];let re=await Q.json();return Array.isArray(re.runs)?re.runs:[]}finally{clearTimeout(ce)}}catch{return[]}})),k=new Map;for(let $ of E)k.set($.id,$);for(let $ of R)for(let O of $)k.set(O.id,O);let L=Array.from(k.values()).sort(($,O)=>$.updatedAt<O.updatedAt?1:-1).slice(0,f),j=v?L.map($=>$h($)):L;w(e,200,{runs:j})}catch(u){w(e,502,{error:"runs fetch failed",message:u.message||String(u)})}return}let g=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(g){let u=decodeURIComponent(g[1]),f=a.workflowRuns.get(u);if(f){w(e,200,{run:f});return}let y=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(v=>({url:v.url,token:v.token}))];for(let v of y)try{let E={};v.token&&(E.Authorization=`Bearer ${v.token}`);let x=await fetch(`${v.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(u)}`,{headers:E});if(x.ok){w(e,200,await x.json());return}}catch{}w(e,404,{error:"run not found on any configured peer"});return}if(o==="GET"&&r==="/api/actions/builtin"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let f=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${f}/api/actions/builtin`,{headers:u}),v=await y.json().catch(()=>({error:`HTTP ${y.status}`}));w(e,y.status,v)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}let _=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(_){try{let u=await le(t).catch(()=>({})),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let y=a.config.dashboard.daemonUrl.replace(/\/+$/,""),v=await fetch(`${y}/workflows/${encodeURIComponent(_[1])}/run`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await v.json().catch(()=>({error:`HTTP ${v.status}`}));w(e,v.status,E)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(r.startsWith("/api/workflows")&&Vi(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(f,y,v)=>{if(a.token)return!0;let E=Sa(f);if(!E)return!0;let x=new G().verify(E);if(!x)return w(y,401,{error:"invalid or revoked token"}),!1;for(let A of v)if(!Ee(x,A))return w(y,403,{error:`token missing scope: ${A}`,scopes:x.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){w(e,200,a.boards.map(u=>({id:u.id,name:u.name,source:u.source,primaryToolLabel:u.primaryToolLabel,labels:u.labels,columns:u.columns,timeRangeDays:u.timeRangeDays})));return}let b=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(b&&o==="GET"){let u=a.sources.get(b[1]);if(!u){w(e,404,{error:"unknown board"});return}try{let f=typeof u.listMembers=="function"?await u.listMembers():[];w(e,200,f)}catch(f){w(e,502,{error:f.message})}return}let S=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(S&&o==="GET"){let u=a.sources.get(S[1]);if(!u){w(e,404,{error:"unknown board"});return}try{let f=typeof u.listMilestones=="function"?await u.listMilestones():[];w(e,200,f)}catch(f){w(e,502,{error:f.message})}return}let T=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),h=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(T&&o==="PATCH"){let[,u,f]=T,y=decodeURIComponent(f),v=a.boards.find(k=>k.id===u);if(!v){w(e,404,{error:`unknown board: ${u}`});return}let E=a.sources.get(u);if(!E){w(e,503,{error:`board "${u}" source unavailable`});return}let x=await le(t),A=v.columns.find(k=>k.id===x.to),R=v.columns.find(k=>k.id===x.from);if(!A){w(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await Ph(E,y,R,A),_n({actor:Sn(t),action:"move",boardId:u,itemId:y,payload:{from:x.from,to:x.to}}),w(e,200,{ok:!0})}catch(k){w(e,502,{error:k.message||"transition failed"})}return}if(h){let[,u,f]=h,y=f?decodeURIComponent(f):void 0,v=a.boards.find(x=>x.id===u);if(!v){w(e,404,{error:`unknown board: ${u}`});return}let E=a.sources.get(u);if(!E){w(e,503,{error:`board "${u}" source unavailable`});return}if(o==="GET"&&!y){let{columns:x,totals:A}=await Rh(v,E,n.searchParams);w(e,200,{columns:x,totals:A});return}if(o==="GET"&&y){try{let x=typeof E.getItem=="function"?await E.getItem(y):null;if(!x){w(e,404,{error:"not found"});return}w(e,200,x)}catch(x){w(e,502,{error:x.message})}return}if(o==="PATCH"&&y){let x=await le(t);try{let A=typeof E.updateItem=="function"?await E.updateItem(y,x):null;if(!A){w(e,501,{error:"update unsupported"});return}_n({actor:Sn(t),action:"update",boardId:u,itemId:y,payload:x}),w(e,200,A)}catch(A){w(e,502,{error:A.message})}return}if(o==="POST"&&!y){let x=await le(t);if(!x.title){w(e,400,{error:"title required"});return}if(!E.capabilities.create||!E.create){w(e,400,{error:`source ${E.type} does not support create`});return}try{let A=await E.create({title:x.title,description:x.description,labels:x.labels,assigneeUsernames:x.assigneeUsernames,milestoneTitle:x.milestoneTitle,projectHint:x.projectHint});_n({actor:Sn(t),action:"create",boardId:u,itemId:A.id,payload:{title:x.title}}),w(e,201,A)}catch(A){w(e,502,{error:A.message})}return}}if(o==="GET"&&/^\/[a-z][a-z-]*\/?$/.test(r)){let u=r.replace(/^\/+|\/+$/g,""),y={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[u];if(y){e.writeHead(302,{Location:y}),e.end();return}}w(e,404,{error:"not found",path:r})}async function Rh(t,e,a){if(!e.capabilities.listAll||!e.listAll){let h={};for(let u of t.columns)h[u.id]=[];return{columns:h,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),d=t.columns.some(h=>h.kind!=="closed"),p=t.columns.some(h=>h.kind==="closed"),m=d?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],g=p?await e.listAll({sinceDays:c,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],_={};for(let h of t.columns)_[h.id]=[];let b=t.columns.find(h=>h.kind==="closed");for(let h of g)b&&_[b.id].push({...h,stage:b.id});let S=t.columns.filter(h=>h.kind!=="closed");for(let h of m){let u=Mn(h,S);if(!u)continue;let f=_[u];f&&f.push({...h,stage:u})}if(i)for(let h of Object.keys(_))_[h]=_[h].filter(u=>u.assignee===i);for(let h of Object.keys(_))_[h].sort((u,f)=>{let y=(u.priority??99)-(f.priority??99);return y!==0?y:(f.updatedAt||"").localeCompare(u.updatedAt||"")});let T=Object.fromEntries(Object.entries(_).map(([h,u])=>[h,u.length]));return{columns:_,totals:T}}async function Ph(t,e,a,n){let r=Ln(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 $h(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,...t.meta?{meta:t.meta}:{},...t.pausedAt?{pausedAt:Jn(t.pausedAt)}:{},createdAt:t.createdAt,updatedAt:t.updatedAt}}function jh(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 Mr(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function _n(t){try{let e=it(process.cwd(),".agentx");Fc(e)||Th(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
|
|
20756
|
+
`;Eh(it(e,"board-audit.jsonl"),a)}catch{}}function Sn(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}var Oh=2e3;async function Nh(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=h=>{let u=new AbortController,f=setTimeout(()=>u.abort(),Oh),y=()=>u.abort();return a?.addEventListener("abort",y,{once:!0}),fetch(t+h,{headers:r,signal:u.signal}).then(async v=>{let E=v.ok?await v.json().catch(()=>{}):void 0;return{ok:E!==void 0,json:async()=>E}}).catch(()=>null).finally(()=>{clearTimeout(f),a?.removeEventListener("abort",y)})},[l,c,d,p,m,g,_,b,S]=await Promise.all([i("/health"),fetch(t+"/agents",{headers:r,signal:a}).catch(()=>null),i("/mesh"),i("/crons"),i("/crons/runs"+s),i("/talk"),i("/routines"),i("/attach/sessions"),i("/api/signals/stopped?limit=20")]);if(!c||!c.ok)return o.error=c?`HTTP ${c.status}`:"unreachable",o;let T=await c.json();if(o.agents=T.map(h=>({id:h.id,name:h.name,tier:h.tier,model:h.model,...typeof h.color=="string"&&/^#[0-9a-fA-F]{6}$/.test(h.color)?{color:h.color}:{},skillCount:Number.isFinite(h.skillCount)?h.skillCount:void 0,active:h.active||0,total:h.total||0,errors:h.errors||0,lastActive:h.lastActive,lastSummary:h.lastSummary,hourlyTasks:Array.isArray(h.hourlyTasks)?h.hourlyTasks:void 0,runningTasks:Array.isArray(h.runningTasks)?h.runningTasks:[]})),l&&l.ok){let h=await l.json().catch(()=>({}));o.uptimeSec=h.uptime,typeof h.inflight?.total=="number"&&(o.inflight=h.inflight.total),h.restart&&typeof h.restart.state=="string"&&(o.restart=h.restart),o.name=h.node?.name||h.node?.id||t,o.id=h.node?.id||t,h.usage&&(o.usage=h.usage)}if(S&&S.ok){let h=await S.json().catch(()=>({})),u=Array.isArray(h?.tasks)?h.tasks:[];o.stoppedTasks=u.filter(f=>f&&f.state!=="resumed").slice(0,10).map(f=>({id:String(f.id),agentId:String(f.agentId),channel:String(f.channel??""),chatId:String(f.chatId??""),state:String(f.state),stoppedAt:String(f.stoppedAt),stoppedBy:String(f.stoppedBy??""),reason:typeof f.reason=="string"?f.reason:void 0,request:String(f.request??""),plan:f.plan&&typeof f.plan.text=="string"?{author:String(f.plan.author),text:f.plan.text,note:f.plan.note}:void 0,resumable:f.resumable===!0}))}if(p&&p.ok){let h=await p.json().then(u=>Array.isArray(u)?u:[],()=>[]);o.crons=h.map(u=>({id:u.id,enabled:u.enabled===!0,schedule:String(u.schedule||""),timezone:u.timezone,agent:String(u.agent||""),kind:typeof u.command=="string"&&u.command.trim()?"command":"agent",model:u.model,nextRun:u.nextRun,retryPending:u.retryPending===!0,consecutiveErrors:Number(u.consecutiveErrors)||0}))}if(m&&m.ok){let h=await m.json().catch(()=>({}));o.cronRuns=Array.isArray(h.runs)?h.runs:[]}if(_&&_.ok){let h=await _.json().catch(()=>null);h&&Array.isArray(h.routines)&&(o.routines=h.routines.slice(0,ar.routines))}if(g&&g.ok){let h=await g.json().catch(()=>null);h?.active&&h.kind==="lesson"&&(o.lesson={agentId:h.agentId??null,mode:String(h.mode||"teach"),goal:String(h.goal||""),step:Number(h.step)||0,saying:String(h.saying||""),startedAt:String(h.startedAt||"")})}if(b&&b.ok){let h=await b.json().catch(()=>null);h&&Array.isArray(h.sessions)&&Uh(o,h.sessions,h.saved??{})}o.reachable=!0,o._peers=Array.isArray(d?.ok?await d.json():null)?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var da=null;function Dh(t){if(da)return da;let e=it(process.cwd(),".agentx/wiki");return da=so({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph",curator:!0,curatorToken:()=>t.token}),da}async function ma(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 Hh(t,e,a){let n=Math.max(1,Math.min(200,Number(a.get("limit"))||50)),r=e.dashboard.daemonUrl.replace(/\/+$/,""),o=process.env.MESH_TOKEN||U(e.dashboard,r);try{let s=await fetch(`${r}/events/recent?skip=task:step&limit=${n}`,{headers:o?{Authorization:`Bearer ${o}`}:{},signal:AbortSignal.timeout(5e3)});if(!s.ok){w(t,502,{error:`daemon answered ${s.status}`});return}let i=await s.json();w(t,200,{node:e.node.name||e.node.id,events:i.events??[]})}catch(s){w(t,502,{error:s.message||"daemon unreachable"})}}async function Se(t,e){let a=t.dashboard,n=a.daemonUrl.replace(/\/+$/,""),r=U(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:U(a,l)})}let s=await ma(n,r,e);for(let i of s)o.has(i.url)||o.set(i.url,{...i,token:U(a,i.url)});return[...o.values()]}var Bh=3e3,zh=6e3,qh=5*6e4,Tn=new Map,pa=new Map;function Ye(t,e){let a=e?`${e.date}|${e.timezone}`:"live",n=pa.get(a);if(n)return n;let r=(async()=>{let o=await Se(t,AbortSignal.timeout(Bh)),s=await Promise.all(o.map(async i=>{let l=await Nh(i.url,i.token,AbortSignal.timeout(zh),e);return e?l:Fh(i.url,l)}));return{ts:new Date().toISOString(),nodes:s}})().finally(()=>pa.delete(a));return pa.set(a,r),r}function Fh(t,e,a=Date.now()){if(e.reachable&&!e.error)return Tn.set(t,{node:e,at:a}),e;let n=Tn.get(t);return!n||a-n.at>qh?e:{...n.node,stale:!0,staleSince:new Date(n.at).toISOString(),error:e.error}}function q0(){Tn.clear(),pa.clear()}function Uh(t,e,a){let n=s=>s?s.replace(/\/+$/,"").split("/").pop()||s:"",r=e.map(s=>({session:String(s.sessionId).slice(0,8),project:n(s.cwd),agentIds:Array.isArray(s.agentIds)?s.agentIds:[],mode:String(s.mode||"notify"),lastSeenAt:Number(s.lastSeenAt)||0,pending:Number(s.pending)||0})),o=new Set(e.map(s=>s.sessionId));for(let[s,i]of Object.entries(a))o.has(s)||!Array.isArray(i.agentIds)||i.agentIds.length===0||r.push({session:s.slice(0,8),project:n(i.cwd),agentIds:i.agentIds,mode:String(i.mode||"notify"),lastSeenAt:Number(i.savedAt)||0,pending:0,waiting:!0});t.attachSessions=r;for(let s of t.agents){let i=r.find(l=>l.agentIds.includes(s.id)&&!l.waiting)??r.find(l=>l.agentIds.includes(s.id));i&&(s.attached={session:i.session,project:i.project,mode:i.mode,lastSeenAt:i.lastSeenAt,waiting:i.waiting})}}function Wh(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=(l,c)=>{n||e.write(`event: ${l}
|
|
20662
20757
|
data: ${JSON.stringify(c)}
|
|
20663
20758
|
|
|
20664
|
-
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await Ye(a);r("snapshot",l)}catch(l){r("error",{message:l.message})}finally{o=!1}}};s();let i=setInterval(s,2e3);t.on("close",()=>{n=!0,clearInterval(i),e.end()})}async function
|
|
20665
|
-
${r.body}`,buttons:[{label:"Open",url:r.url}]}),signal:AbortSignal.timeout(1e4)});o.ok||console.error(`[app] finish notification not sent: HTTP ${o.status} ${(await o.text()).slice(0,160)}`)}catch(o){console.error(`[app] finish notification not sent: ${o?.message||o}`)}}}}function
|
|
20759
|
+
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await Ye(a);r("snapshot",l)}catch(l){r("error",{message:l.message})}finally{o=!1}}};s();let i=setInterval(s,2e3);t.on("close",()=>{n=!0,clearInterval(i),e.end()})}async function Gh(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let _ of a.config.dashboard.daemons)i.add(_.url.replace(/\/+$/,""));try{let _=await ma(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let b of _)i.add(b.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){w(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=U(a.config.dashboard,s),c={Accept:"text/event-stream"};l&&(c.Authorization=`Bearer ${l}`);let d=new AbortController,p;try{p=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:c,signal:d.signal})}catch(_){w(e,502,{error:_.message||"upstream connect failed"});return}if(!p.ok||!p.body){w(e,p.status||502,{error:`upstream HTTP ${p.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let m=p.body.getReader();(async()=>{try{for(;;){let{value:_,done:b}=await m.read();if(b)break;_&&e.write(_)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{d.abort();try{e.end()}catch{}})}function Xh(t,e,a){let n=Sa(t);if(!n)return w(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new G().verify(n);if(!r)return w(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!Ee(r,o))return w(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function Kh(t,e,a,n){let r=a.agents?.[n];if(!r){w(e,404,{error:"unknown agent"});return}if(r.access!=="public"){w(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await le(t)}catch{w(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){w(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||{}}})}),d=await c.text();e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(d)}catch(c){w(e,502,{error:c.message||"upstream call failed"})}}async function Jh(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of e.config.dashboard.daemons)i.add(p.url.replace(/\/+$/,""));try{let p=await ma(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let m of p)i.add(m.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){w(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=U(e.config.dashboard,s),c={Accept:"application/json"};l&&(c.Authorization=`Bearer ${l}`);let d=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let p=await fetch(`${s}${d}`,{headers:c}),m=await p.text();t.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json; charset=utf-8"}),t.end(m)}catch(p){w(t,502,{error:p.message||"upstream fetch failed"})}}async function Vh(t,e,a,n,r,o){await ua(t,e,a,n,`/api/tasks/${encodeURIComponent(r)}/${o}`)}async function ua(t,e,a,n,r){let o={};try{o=await le(t)??{}}catch{}let s=await Uc(a.config,n,r,o);e.writeHead(s.status,{"Content-Type":s.contentType}),e.end(s.text)}async function Uc(t,e,a,n){let r=(c,d)=>({status:c,text:JSON.stringify(d),contentType:"application/json"}),o=e.replace(/\/+$/,""),s=new Set;s.add(t.dashboard.daemonUrl.replace(/\/+$/,""));for(let c of t.dashboard.daemons)s.add(c.url.replace(/\/+$/,""));try{let c=await ma(t.dashboard.daemonUrl.replace(/\/+$/,""),t.dashboard.token);for(let d of c)s.add(d.url.replace(/\/+$/,""))}catch{}if(!s.has(o))return r(403,{error:"node not in dashboard allowlist",target:o});let i=U(t.dashboard,o),l={"Content-Type":"application/json",Accept:"application/json"};i&&(l.Authorization=`Bearer ${i}`);try{let c=await fetch(`${o}${a}`,{method:"POST",headers:l,body:JSON.stringify(n??{})});return{status:c.status,text:await c.text(),contentType:c.headers.get("content-type")||"application/json; charset=utf-8"}}catch(c){return r(502,{error:c.message||"upstream fetch failed"})}}function An(t){let e=t.channels.push,a=r=>({store:()=>null,publicKey:()=>null,keepRecent:0,allowedHosts:[],reason:r});if(!e.enabled)return a("Notifications are off. On the computer, run: agentx notifications push --enable");if(e.relayTo){let r=t.dashboard.daemonUrl.replace(/\/+$/,""),o=process.env.MESH_TOKEN||U(t.dashboard,r);return wt(),{...a(`Can't reach ${e.relayTo}, the computer that sends notifications`),async forward(s){let i=await fetch(`${r}/push/app`,{method:"POST",headers:{"Content-Type":"application/json",...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify({op:"app",call:s}),signal:AbortSignal.timeout(2e4)}),l=await i.json().catch(()=>({}));if(!i.ok||typeof l.status!="number")throw new Error(l.error||`the daemon answered ${i.status}`);return{status:l.status,body:l.body??{}}}}}let n=dr(e.keysFile);return{store:()=>{let r=Ve();return r?new Or(r):null},publicKey:()=>pr(n)?.publicKey??null,keepRecent:e.keepRecent,allowedHosts:e.allowedHosts,reason:"The database on this computer is unavailable, so notifications can't be saved."}}function Hc(t){let e=t.channels.push,a=t.dashboard.daemonUrl.replace(/\/+$/,""),n=e.enabled&&!e.relayTo?Rl({url:a,token:U(t.dashboard,a),operatorKey:va(process.cwd())??void 0}):null,r=e.relayTo?`this computer relays notifications to ${e.relayTo}; place reminders work on a phone paired with ${e.relayTo}.`:An(t).reason;return Ol(t,process.cwd(),n,r)}function Wc(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=n=>{try{return JSON.parse(n)}catch{return{error:n.slice(0,200)}}};return{snapshot:n=>Ye(t,n),async nodePost(n,r,o){let s=await Uc(t,n,r,o);return{status:s.status,body:a(s.text)}},async approvals(){let n={node:e,nodeName:t.node?.name||"this computer",items:[]};try{n.items=Et({root:process.cwd()}).items.map(zc)}catch(o){n.error=o.message}let r=await Promise.all(t.dashboard.daemons.map(async o=>{let s={node:o.url.replace(/\/+$/,""),nodeName:o.name,items:[]},i=lt(o.url,t);if(!i)return s;try{let l=await fetch(`${i.url}/api/admin/approvals`,{headers:{"X-Agentx-Peer":"primary",...i.token?{Authorization:`Bearer ${i.token}`}:{}},signal:AbortSignal.timeout(4e3)});if(!l.ok)return s.error=`HTTP ${l.status}`,s;let c=await l.json();s.items=(c.items??[]).map(zc)}catch(l){s.error=l.message||"unreachable"}return s}));return[n,...r]},async decide(n,r,o,s,i={}){let l=n.replace(/\/+$/,"");if(l===e){let d=Ae(),p=await Tt({root:process.cwd()},r,o,{laterHours:d.laterHours,by:s,...i});return p.ok?{status:200,body:{ok:!0,message:p.message}}:{status:409,body:{error:p.error}}}let c=lt(l,t);if(!c)return{status:403,body:{error:"node not in dashboard allowlist",target:l}};try{let d=await fetch(`${c.url}/api/admin/approvals/decide`,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"agentx-board","X-Agentx-Peer":"primary",...c.token?{Authorization:`Bearer ${c.token}`}:{}},body:JSON.stringify({key:r,action:o,...i}),signal:AbortSignal.timeout(1e4)});return{status:d.status,body:a(await d.text())}}catch(d){return{status:502,body:{error:d.message||"peer dashboard unreachable"}}}}}}var En=null;function Bc(t){return En?.days!==t&&(En={days:t,store:new ht(process.cwd(),Date.now,t)}),En.store}function Gc(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=U(t.dashboard,e),n=Wc(t);return{store:()=>{let r=Ve();return r?new st(r):null},daemon:{url:e,token:a,name:t.node?.name,operatorKey:va(process.cwd())??void 0},snapshot:()=>Ye(t),meshPeers:async()=>{let r=await fetch(e+"/mesh",{headers:a?{Authorization:`Bearer ${a}`}:{},signal:AbortSignal.timeout(3e3)});return r.ok?await r.json():[]},nodePost:(r,o,s)=>n.nodePost(r,o,s),tokenFor:r=>U(t.dashboard,r.replace(/\/+$/,"")),...Yh(t,e,a)}}function Yh(t,e,a){let n=An(t);return{finishAlerts:r=>{if(n.forward)return cr.finishOn(r);let o=n.store();return!!o&&o.chatFinishOn(r)&&o.list(r).length>0},notifyFinish:async r=>{try{let o=await fetch(e+"/channel/send",{method:"POST",headers:{"Content-Type":"application/json",...a?{Authorization:`Bearer ${a}`}:{}},body:JSON.stringify({channel:"push",chatId:r.deviceId,text:`${r.title}
|
|
20760
|
+
${r.body}`,buttons:[{label:"Open",url:r.url}]}),signal:AbortSignal.timeout(1e4)});o.ok||console.error(`[app] finish notification not sent: HTTP ${o.status} ${(await o.text()).slice(0,160)}`)}catch(o){console.error(`[app] finish notification not sent: ${o?.message||o}`)}}}}function Qh(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=o=>U(t.dashboard,o.replace(/\/+$/,"")),n=o=>{let s=a(o);return s?{Authorization:`Bearer ${s}`}:{}},r=Gc(t);return new ca({recent:async(o,s)=>{let i=new URLSearchParams({kind:"delegation",limit:String(s)});o&&i.set("since",o);let l=await fetch(`${e}/events/recent?${i}`,{headers:n(e),signal:AbortSignal.timeout(5e3)});if(!l.ok)throw new Error(`the daemon answered ${l.status}`);let c=await l.json();return{events:Array.isArray(c.events)?c.events:[],gap:c.gap===!0}},nodeUrl:async o=>{let i=(await Ye(t)).nodes.find(l=>l.name===o||l.id===o);return i?.url?i.url.replace(/\/+$/,""):null},conversationUrl:async o=>{if(o.node==="local")return e;let s=(await r.meshPeers().catch(()=>[])).find(i=>i.peer===o.node);return s?s.peerUrl.replace(/\/+$/,""):null},fetchReply:async(o,s)=>{let i=await fetch(`${o}/a2a/delegations/${encodeURIComponent(s)}/reply`,{headers:n(o),signal:AbortSignal.timeout(5e3)});if(i.status===404)return null;if(!i.ok)throw new Error(`the node answered ${i.status}`);return await i.json()},store:r.store,presence:cl(),finishAlerts:r.finishAlerts,notifyFinish:r.notifyFinish,log:o=>console.log(o),warn:o=>console.warn(o)})}function Zh(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{store:()=>{let a=Ve();return a?new st(a):null},daemon:{url:e,token:U(t.dashboard,e)}}}function eg(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{daemon:{url:e,token:U(t.dashboard,e)},nodeName:t.node.name}}function zc(t){return{key:t.key,title:t.title,ask:t.ask,recommend:t.recommend,yes:t.yes,no:t.no,raisedBy:t.raised_by,expires:t.expires,...t.choices?{choices:t.choices}:{},...t.draft?{draft:t.draft}:{}}}var tg=`
|
|
20666
20761
|
You are helping draft a new GitLab issue. Follow these conventions strictly.
|
|
20667
20762
|
|
|
20668
20763
|
Title pattern:
|
|
@@ -20694,16 +20789,16 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
|
|
|
20694
20789
|
Shape:
|
|
20695
20790
|
{ "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
|
|
20696
20791
|
If you don't have enough information to pick a label confidently, omit it rather than guessing.
|
|
20697
|
-
`;async function
|
|
20792
|
+
`;async function ag(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):
|
|
20698
20793
|
- ${r.knownLabels.slice(0,60).join(`
|
|
20699
20794
|
- `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
|
|
20700
|
-
`),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:
|
|
20795
|
+
`),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:tg}})});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 d=(c.content||"").toString(),p=ng(d);if(!p||typeof p.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+d.slice(0,400));let m=Array.isArray(p.labels)?p.labels.filter(g=>typeof g=="string"):[];return r.primaryLabel&&!m.includes(r.primaryLabel)&&m.unshift(r.primaryLabel),r.columnLabel&&!m.includes(r.columnLabel)&&m.unshift(r.columnLabel),{title:p.title.trim(),description:(p.description||"").toString(),labels:m,assigneeUsername:typeof p.assigneeUsername=="string"?p.assigneeUsername:void 0,kind:typeof p.kind=="string"?p.kind:void 0,raw:d}}function ng(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 rg(t){let e=Ih(Ch(import.meta.url));return it(e,t)}async function og(t){return Ah(t)}function w(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function le(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 Xc(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:Xc(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 sg(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;w(e,200,await ta(await Kc(r,a.config)))}async function Kc(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=an(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=lt(i.url.replace(/\/+$/,""),e);if(!l)return null;try{let c=new AbortController,d=setTimeout(()=>c.abort(),8e3);try{let p=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 p.ok?{nodeId:i.name||i.url,snap:await p.json()}:null}finally{clearTimeout(d)}}catch{return null}}));for(let i of s)i&&n.push(i);return hi(n)}async function ig(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 p=process.env.HOME||"",m=[p&&`${p}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),g=m.find(_=>Fc(_));if(!g){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:m}));return}r="tail",o=["-F","-n","200",g]}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}
|
|
20701
20796
|
|
|
20702
20797
|
`);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),i="",l=p=>{i+=p.toString("utf8");let m;for(;(m=i.indexOf(`
|
|
20703
|
-
`))>=0;){let
|
|
20704
|
-
data: ${
|
|
20798
|
+
`))>=0;){let g=i.slice(0,m).replace(/\r$/,"");i=i.slice(m+1);try{e.write(`event: line
|
|
20799
|
+
data: ${g.replace(/\n/g," ")}
|
|
20705
20800
|
|
|
20706
20801
|
`)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let c=setInterval(()=>{try{e.write(`: hb
|
|
20707
20802
|
|
|
20708
|
-
`)}catch{}},15e3),d=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",d),s.on("exit",d),s.on("error",d)}async function
|
|
20709
|
-
//# sourceMappingURL=board-dashboard-
|
|
20803
|
+
`)}catch{}},15e3),d=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",d),s.on("exit",d),s.on("error",d)}async function qc(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((p,m)=>{let g=[];t.on("data",_=>g.push(_)),t.on("end",()=>p(Buffer.concat(g))),t.on("error",m)}):void 0,l={},c=t.headers["content-type"];c&&(l["Content-Type"]=Array.isArray(c)?c[0]:c);let d=t.headers["x-requested-with"];d&&(l["X-Requested-With"]=Array.isArray(d)?d[0]:d),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let p=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),m=Buffer.from(await p.arrayBuffer());e.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(m)}catch(p){w(e,502,{error:`proxy to peer failed: ${p?.message||p}`,target:r})}}function lt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Xc(n),token:n.dashboardToken||n.token}:null}export{Uh as applyAttachSessions,Nh as fetchDaemonAgents,Lh as handleBoardRequest,q0 as resetLiveCaches,Se as resolveNodeTargets,z0 as startBoardDashboard,Fh as withLastGood};
|
|
20804
|
+
//# sourceMappingURL=board-dashboard-44JPXA7J.js.map
|