agentix-cli 0.154.2 → 0.155.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-6T6NVB7O.js → App-P4MLXD46.js} +2 -2
- package/dist/{ChatApp-QZBJ4NHC.js → ChatApp-DILDQOJL.js} +2 -2
- package/dist/{absorb-eval-EVX7LDXR.js → absorb-eval-DBC7EKU5.js} +2 -2
- package/dist/{agent-F2NT6B25.js → agent-OZ3KPI6Y.js} +2 -2
- package/dist/{board-dashboard-642BO7GV.js → board-dashboard-MWUCBHDN.js} +239 -233
- package/dist/board-dashboard-MWUCBHDN.js.map +1 -0
- package/dist/{chunk-KA2NV7H4.js → chunk-3ZAAUY2N.js} +2 -2
- package/dist/{chunk-743RAKLP.js → chunk-4RHM4XTI.js} +2 -2
- package/dist/{chunk-U4YTTWR6.js → chunk-6CXJAZZD.js} +2 -2
- package/dist/{chunk-AKCEMKQM.js → chunk-ACB6GRSP.js} +2 -2
- package/dist/{chunk-W2RB5XG7.js → chunk-AHZBWCXI.js} +2 -2
- package/dist/chunk-AVAR5KNN.js +36 -0
- package/dist/chunk-AVAR5KNN.js.map +1 -0
- package/dist/{chunk-E76HREC7.js → chunk-CTXHMJLZ.js} +3 -3
- package/dist/{chunk-IA4J3YLB.js → chunk-D65HXPIB.js} +2 -2
- package/dist/{chunk-S3EX64LR.js → chunk-EE3ZYIIB.js} +2 -2
- package/dist/{chunk-VRF4YW46.js → chunk-FTIJQLBX.js} +2 -2
- package/dist/{chunk-YL26FRKJ.js → chunk-GIFUJ3LL.js} +2 -2
- package/dist/chunk-H7DLFJBV.js +575 -0
- package/dist/chunk-H7DLFJBV.js.map +1 -0
- package/dist/{chunk-4CWACHEH.js → chunk-HGF73KFH.js} +2 -2
- package/dist/{chunk-JAML6222.js → chunk-HOVJVXEP.js} +2 -2
- package/dist/{chunk-GRVTLUQ6.js → chunk-IW4AZVJR.js} +2 -2
- package/dist/{chunk-IWWEUXZQ.js → chunk-J3IP3UZX.js} +2 -2
- package/dist/{chunk-67DWBJEO.js → chunk-J432IZXG.js} +333 -336
- package/dist/chunk-J432IZXG.js.map +1 -0
- package/dist/{chunk-37I654UJ.js → chunk-KYRF2FPT.js} +2 -2
- package/dist/{chunk-SD3CC4EX.js → chunk-NJEJU5XN.js} +2 -2
- package/dist/{chunk-CUAS4ITR.js → chunk-PI6CKUUH.js} +2 -2
- package/dist/{chunk-HUN6COOF.js → chunk-Q7LUTCNO.js} +2 -2
- package/dist/chunk-QHRQ3PUX.js +3 -0
- package/dist/chunk-QHRQ3PUX.js.map +1 -0
- package/dist/chunk-SQTL2CLY.js +76 -0
- package/dist/chunk-SQTL2CLY.js.map +1 -0
- package/dist/{chunk-EGTANAFI.js → chunk-SSFQWEPJ.js} +2 -2
- package/dist/{chunk-MLC5INGD.js → chunk-UK6MICKK.js} +5 -5
- package/dist/{chunk-MLC5INGD.js.map → chunk-UK6MICKK.js.map} +1 -1
- package/dist/{chunk-YJNUVAM4.js → chunk-WHMX2D2Q.js} +2 -2
- package/dist/{chunk-ABCQ6QMJ.js → chunk-YDAFHXDE.js} +2 -2
- package/dist/{chunk-GFRAHUAQ.js → chunk-YLAJOO5X.js} +2 -2
- package/dist/{chunk-B75BLZ2M.js → chunk-YXBQSLFV.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-OCLSGJYQ.js → client-7JINGNNU.js} +2 -2
- package/dist/{config-FZTWI3VG.js → config-S4ZZHOUZ.js} +2 -2
- package/dist/{config-mutate-X5IKMROK.js → config-mutate-U3KKAXVD.js} +2 -2
- package/dist/config-mutator-KKRVNVVV.js +2 -0
- package/dist/{contributions-KHGGVSR6.js → contributions-6F3MYSRR.js} +2 -2
- package/dist/{doctor-KNCRQ3YO.js → doctor-UDZI2OMU.js} +2 -2
- package/dist/{follow-up-tool-TGKEPA5C.js → follow-up-tool-MP6FOIQE.js} +2 -2
- package/dist/{hub-HQUAH5H6.js → hub-TSUVK7PH.js} +2 -2
- package/dist/index.d.ts +362 -61
- package/dist/index.js +1 -1
- package/dist/{program-CYOAZ43O.js → program-CMWF3BQS.js} +234 -232
- package/dist/program-CMWF3BQS.js.map +1 -0
- package/dist/{promote-VD4OVQGL.js → promote-YVOYLTXI.js} +2 -2
- package/dist/{push-bridge-P7HH25VN.js → push-bridge-CFPGPPO7.js} +2 -2
- package/dist/{query-5CPK6G2H.js → query-ZGXXMJ4M.js} +2 -2
- package/dist/{query-settings-35GDM3HU.js → query-settings-TNOGVKBX.js} +2 -2
- package/dist/{registry-JCHKHCRE.js → registry-R2X4YGUK.js} +2 -2
- package/dist/{request-planner-ZIG4YVXC.js → request-planner-QBNGJMF5.js} +2 -2
- package/dist/{review-candidates-LPZWOR2K.js → review-candidates-WCDKCFXR.js} +2 -2
- package/dist/{routing-BLOYDLU4.js → routing-RRRO2GDA.js} +2 -2
- package/dist/schedule-tool-2XZ3I5IL.js +2 -0
- package/dist/{scheduler-BEJRDQR3.js → scheduler-7O73TDCG.js} +2 -2
- package/dist/{seat-NU3UJC6C.js → seat-CCDGNARC.js} +2 -2
- package/dist/{select-IWAFX4XJ.js → select-VPZ4QDHV.js} +2 -2
- package/dist/{set-enabled-JF75TSFU.js → set-enabled-VYSPZXPC.js} +2 -2
- package/dist/{tool-PQBQJWM5.js → tool-K3PZOFC2.js} +2 -2
- package/dist/{tool-WTOOPTGC.js → tool-VPDXU3IZ.js} +2 -2
- package/dist/{wiki-DXG655NP.js → wiki-QA7BDTOR.js} +2 -2
- package/dist/wiki-enrich-ZIZ5QHQ3.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-642BO7GV.js.map +0 -1
- package/dist/chunk-67DWBJEO.js.map +0 -1
- package/dist/chunk-HSCZSNOX.js +0 -533
- package/dist/chunk-HSCZSNOX.js.map +0 -1
- package/dist/chunk-VKEH4IBA.js +0 -76
- package/dist/chunk-VKEH4IBA.js.map +0 -1
- package/dist/chunk-XOUK5ZIQ.js +0 -36
- package/dist/chunk-XOUK5ZIQ.js.map +0 -1
- package/dist/chunk-YMX3QCV7.js +0 -3
- package/dist/chunk-YMX3QCV7.js.map +0 -1
- package/dist/config-mutator-C5BMIBZO.js +0 -2
- package/dist/program-CYOAZ43O.js.map +0 -1
- package/dist/schedule-tool-7KFO3NPD.js +0 -2
- package/dist/wiki-enrich-5VQCT6BT.js +0 -2
- /package/dist/{App-6T6NVB7O.js.map → App-P4MLXD46.js.map} +0 -0
- /package/dist/{ChatApp-QZBJ4NHC.js.map → ChatApp-DILDQOJL.js.map} +0 -0
- /package/dist/{absorb-eval-EVX7LDXR.js.map → absorb-eval-DBC7EKU5.js.map} +0 -0
- /package/dist/{agent-F2NT6B25.js.map → agent-OZ3KPI6Y.js.map} +0 -0
- /package/dist/{chunk-KA2NV7H4.js.map → chunk-3ZAAUY2N.js.map} +0 -0
- /package/dist/{chunk-743RAKLP.js.map → chunk-4RHM4XTI.js.map} +0 -0
- /package/dist/{chunk-U4YTTWR6.js.map → chunk-6CXJAZZD.js.map} +0 -0
- /package/dist/{chunk-AKCEMKQM.js.map → chunk-ACB6GRSP.js.map} +0 -0
- /package/dist/{chunk-W2RB5XG7.js.map → chunk-AHZBWCXI.js.map} +0 -0
- /package/dist/{chunk-E76HREC7.js.map → chunk-CTXHMJLZ.js.map} +0 -0
- /package/dist/{chunk-IA4J3YLB.js.map → chunk-D65HXPIB.js.map} +0 -0
- /package/dist/{chunk-S3EX64LR.js.map → chunk-EE3ZYIIB.js.map} +0 -0
- /package/dist/{chunk-VRF4YW46.js.map → chunk-FTIJQLBX.js.map} +0 -0
- /package/dist/{chunk-YL26FRKJ.js.map → chunk-GIFUJ3LL.js.map} +0 -0
- /package/dist/{chunk-4CWACHEH.js.map → chunk-HGF73KFH.js.map} +0 -0
- /package/dist/{chunk-JAML6222.js.map → chunk-HOVJVXEP.js.map} +0 -0
- /package/dist/{chunk-GRVTLUQ6.js.map → chunk-IW4AZVJR.js.map} +0 -0
- /package/dist/{chunk-IWWEUXZQ.js.map → chunk-J3IP3UZX.js.map} +0 -0
- /package/dist/{chunk-37I654UJ.js.map → chunk-KYRF2FPT.js.map} +0 -0
- /package/dist/{chunk-SD3CC4EX.js.map → chunk-NJEJU5XN.js.map} +0 -0
- /package/dist/{chunk-CUAS4ITR.js.map → chunk-PI6CKUUH.js.map} +0 -0
- /package/dist/{chunk-HUN6COOF.js.map → chunk-Q7LUTCNO.js.map} +0 -0
- /package/dist/{chunk-EGTANAFI.js.map → chunk-SSFQWEPJ.js.map} +0 -0
- /package/dist/{chunk-YJNUVAM4.js.map → chunk-WHMX2D2Q.js.map} +0 -0
- /package/dist/{chunk-ABCQ6QMJ.js.map → chunk-YDAFHXDE.js.map} +0 -0
- /package/dist/{chunk-GFRAHUAQ.js.map → chunk-YLAJOO5X.js.map} +0 -0
- /package/dist/{chunk-B75BLZ2M.js.map → chunk-YXBQSLFV.js.map} +0 -0
- /package/dist/{client-OCLSGJYQ.js.map → client-7JINGNNU.js.map} +0 -0
- /package/dist/{config-FZTWI3VG.js.map → config-S4ZZHOUZ.js.map} +0 -0
- /package/dist/{config-mutate-X5IKMROK.js.map → config-mutate-U3KKAXVD.js.map} +0 -0
- /package/dist/{config-mutator-C5BMIBZO.js.map → config-mutator-KKRVNVVV.js.map} +0 -0
- /package/dist/{contributions-KHGGVSR6.js.map → contributions-6F3MYSRR.js.map} +0 -0
- /package/dist/{doctor-KNCRQ3YO.js.map → doctor-UDZI2OMU.js.map} +0 -0
- /package/dist/{follow-up-tool-TGKEPA5C.js.map → follow-up-tool-MP6FOIQE.js.map} +0 -0
- /package/dist/{hub-HQUAH5H6.js.map → hub-TSUVK7PH.js.map} +0 -0
- /package/dist/{promote-VD4OVQGL.js.map → promote-YVOYLTXI.js.map} +0 -0
- /package/dist/{push-bridge-P7HH25VN.js.map → push-bridge-CFPGPPO7.js.map} +0 -0
- /package/dist/{query-5CPK6G2H.js.map → query-ZGXXMJ4M.js.map} +0 -0
- /package/dist/{query-settings-35GDM3HU.js.map → query-settings-TNOGVKBX.js.map} +0 -0
- /package/dist/{registry-JCHKHCRE.js.map → registry-R2X4YGUK.js.map} +0 -0
- /package/dist/{request-planner-ZIG4YVXC.js.map → request-planner-QBNGJMF5.js.map} +0 -0
- /package/dist/{review-candidates-LPZWOR2K.js.map → review-candidates-WCDKCFXR.js.map} +0 -0
- /package/dist/{routing-BLOYDLU4.js.map → routing-RRRO2GDA.js.map} +0 -0
- /package/dist/{schedule-tool-7KFO3NPD.js.map → schedule-tool-2XZ3I5IL.js.map} +0 -0
- /package/dist/{scheduler-BEJRDQR3.js.map → scheduler-7O73TDCG.js.map} +0 -0
- /package/dist/{seat-NU3UJC6C.js.map → seat-CCDGNARC.js.map} +0 -0
- /package/dist/{select-IWAFX4XJ.js.map → select-VPZ4QDHV.js.map} +0 -0
- /package/dist/{set-enabled-JF75TSFU.js.map → set-enabled-VYSPZXPC.js.map} +0 -0
- /package/dist/{tool-PQBQJWM5.js.map → tool-K3PZOFC2.js.map} +0 -0
- /package/dist/{tool-WTOOPTGC.js.map → tool-VPDXU3IZ.js.map} +0 -0
- /package/dist/{wiki-DXG655NP.js.map → wiki-QA7BDTOR.js.map} +0 -0
- /package/dist/{wiki-enrich-5VQCT6BT.js.map → wiki-enrich-ZIZ5QHQ3.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as
|
|
1
|
+
import{A as vo,B as yo,C as wo,D as ko,H as _o,I as So,M as Bt,N as Co,O as Io,P as Mo,R as Ro,S as Lo,a as io,b as lo,c as co,d as po,j as uo,k as mo,l as fo,o as Me,p as ho,q as go,r as Ht,t as xo,z as bo}from"./chunk-Q7LUTCNO.js";import{a as Eo}from"./chunk-5NTWGUSJ.js";import{a as To,b as Ao}from"./chunk-NZQBS7GN.js";import"./chunk-XVTD6I34.js";import"./chunk-QAWKN2N4.js";import"./chunk-MTX4UPNB.js";import{a as C}from"./chunk-PI6CKUUH.js";import{a as ao}from"./chunk-LNY6N73E.js";import{a as so}from"./chunk-BKHIR2YJ.js";import{a as We,b as z,c as I,h as ue,i as Nt,j as se,k as K,l as Dt,m as no,n as ro,o as oo}from"./chunk-B2QYMUTD.js";import{A as Rr,L as Pr,R as Ct,S as $r,T as Ce,Ta as Wr,U as jr,V as It,Va as Gr,W as Mt,Wa as Xr,X as Rt,Xa as Kr,Y as Or,a as br,c as St,ca as Nr,d as Ia,da as Dr,db as Jr,e as vr,ea as Hr,fb as Ie,ib as Vr,kb as Ue,la as U,lb as Lt,ma as Br,mb as Pt,na as qr,nb as $t,o as Et,ob as jt,pb as Yr,qb as Qr,r as rt,rb as Zr,sb as Ot,t as yr,ub as eo,xb as to,y as Mr}from"./chunk-H7DLFJBV.js";import"./chunk-GTJIKXDB.js";import{h as gr,i as xr}from"./chunk-YLAJOO5X.js";import{D as wr,F as kr,a as mr,j as fr,k as hr}from"./chunk-AVAR5KNN.js";import{a as H,b as zr,c as Fr,g as Ur}from"./chunk-7LN4VKDU.js";import{a as ur}from"./chunk-IMLAPB7G.js";import{g as At}from"./chunk-LQE73AZR.js";import{b as Cr,c as Ir}from"./chunk-2D3RYIDU.js";import"./chunk-MRIVENBY.js";import{o as Lr}from"./chunk-LQS27HSV.js";import"./chunk-EE3ZYIIB.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import{b as G,c as Ae,d as _r,e as Ma}from"./chunk-EMGB23H5.js";import{a as Er,b as Fe,d as Tr,e as Ar,f as Tt}from"./chunk-QHRQ3PUX.js";import{b as Sr}from"./chunk-JWDJMFU6.js";import"./chunk-MNG2AMKZ.js";import"./chunk-ACB6GRSP.js";import"./chunk-KP7KDLZ2.js";import{F as cr,W as wt,X as kt,Y as _t,Z as pe,_ as pr,a as nr,f as rr,g as Aa,h as Ca,l as or,n as sr,o as ir,z as dr}from"./chunk-GIFUJ3LL.js";import"./chunk-MEFPXHQJ.js";import"./chunk-SZDACK6O.js";import"./chunk-AFRHKA7B.js";import"./chunk-5TTHN7DP.js";import"./chunk-AHZBWCXI.js";import{a as lr}from"./chunk-IW4AZVJR.js";import"./chunk-3UOTLMXD.js";import"./chunk-PE5V2LI7.js";import"./chunk-GQ76J72O.js";import"./chunk-ILEC3IAV.js";import"./chunk-GV7S5BAX.js";import"./chunk-GSX4NK2N.js";import"./chunk-6CXJAZZD.js";import"./chunk-D65HXPIB.js";import"./chunk-OWNQ2FD4.js";import"./chunk-KEXBEUSU.js";import"./chunk-ROLSSYXE.js";import{g as ar}from"./chunk-3ZAAUY2N.js";import"./chunk-WPNRDEHW.js";import"./chunk-4RHM4XTI.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-JNG3P5V2.js";import"./chunk-7I7IEX4S.js";import{I as ka,N as Dc,Na as Zn,O as _a,Oa as er,P as Sa,Pa as X,Qa as tr,W as Hc,Ya as yt,a as qn,b as zn,c as jc,ca as Kn,fa as Ea,ia as Jn,ka as vt,la as Vn,na as Yn,pa as Qn,ta as Ta,x as gt,y as Oc}from"./chunk-SQTL2CLY.js";import{a as Fn,b as xt,c as wa,d as Un,h as Wn}from"./chunk-BRK6M6LA.js";import{d as Gn,e as Nc,f as bt,n as Xn}from"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";function Ra(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 Po(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:Ra(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}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"/>',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"/>'},Re=(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>",qt=(t,e,a,n="")=>'<div class="ax-sec-label"><h3>'+Re(t,13)+e+(a?'<span class="ax-sec-label__n" id="'+a+'"></span>':"")+"</h3>"+n+"</div>";function $o(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>
|
|
@@ -7,8 +7,8 @@ import{A as xo,B as bo,C as vo,D as yo,H as wo,I as ko,M as Bt,N as To,O as Ao,P
|
|
|
7
7
|
</div>
|
|
8
8
|
<div class="bf-sync">
|
|
9
9
|
<span class="bf-sync__t" id="synced">Gathering…</span>
|
|
10
|
-
<a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${
|
|
11
|
-
<button class="ax-btn" id="refresh" title="Refresh now">${
|
|
10
|
+
<a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${Re(ie.pulse,13)} Activity</a>
|
|
11
|
+
<button class="ax-btn" id="refresh" title="Refresh now">${Re(ie.refresh)} Refresh</button>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
@@ -38,7 +38,7 @@ import{A as xo,B as bo,C as vo,D as yo,H as wo,I as ko,M as Bt,N as To,O as Ao,P
|
|
|
38
38
|
|
|
39
39
|
${qt(ie.file,"Session briefings","brief-count")}
|
|
40
40
|
<div class="bf-toolbar">
|
|
41
|
-
<div class="bf-search">${
|
|
41
|
+
<div class="bf-search">${Re(ie.search)}
|
|
42
42
|
<input id="search" type="search" placeholder="Search sessions…" aria-label="Search sessions">
|
|
43
43
|
</div>
|
|
44
44
|
<div class="bf-filters" id="filters" role="group" aria-label="Filter briefings"></div>
|
|
@@ -46,15 +46,15 @@ ${qt(ie.file,"Session briefings","brief-count")}
|
|
|
46
46
|
<div id="reviews" class="bf-col"></div>
|
|
47
47
|
|
|
48
48
|
<section class="ax-panel bf-connect">
|
|
49
|
-
<div class="bf-connect__head">${
|
|
49
|
+
<div class="bf-connect__head">${Re(ie.plug,17)}<h2>Connect a CLI session</h2>
|
|
50
50
|
<span class="bf-connect__note">Daemon-owned processes only</span></div>
|
|
51
51
|
<div class="bf-discover">
|
|
52
52
|
<div class="ax-field"><label for="node">Node</label><select id="node"></select></div>
|
|
53
|
-
<button class="ax-btn" id="discover">${
|
|
53
|
+
<button class="ax-btn" id="discover">${Re(ie.search)} Discover CLIs</button>
|
|
54
54
|
</div>
|
|
55
55
|
<div class="bf-cli" id="discovered"></div>
|
|
56
56
|
<details class="bf-manual">
|
|
57
|
-
<summary>${
|
|
57
|
+
<summary>${Re(ie.chev,12)} Register manually</summary>
|
|
58
58
|
<div class="bf-forms">
|
|
59
59
|
<form id="register" class="bf-form">
|
|
60
60
|
<div class="ax-sec-label"><h3>Register a session</h3></div>
|
|
@@ -85,7 +85,7 @@ ${qt(ie.file,"Session briefings","brief-count")}
|
|
|
85
85
|
</div>
|
|
86
86
|
</details>
|
|
87
87
|
</section>
|
|
88
|
-
</div>`,css:
|
|
88
|
+
</div>`,css:Bc,scripts:`<script>${z({decayOf:Ra,rankByDecay:Po})}const ICON = ${JSON.stringify(ie)};${qc}</script>`})}var Bc=`
|
|
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
|
+
}`,qc=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,13 +776,13 @@ 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 La(t,e=20*6e4,a=6){let n=[...t].sort((l,d)=>l.startedAt-d.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let l of n){let d=l.startedAt+Math.max(l.durationMs||0,0),p=r[r.length-1];p&&l.startedAt-p.to<=e?(p.to=Math.max(p.to,d),p.runs++):r.push({from:l.startedAt,to:d,runs:1})}for(;r.length>a;){let l=0,d=1/0;for(let p=1;p<r.length;p++){let c=r[p].from-r[p-1].to;c<d&&(d=c,l=p)}r[l-1].to=r[l].to,r[l-1].runs+=r[l].runs,r.splice(l,1)}let o=r.reduce((l,d)=>l+d.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,d)=>l.from-r[d].to);return{bands:s,gaps:i}}function Pa(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
|
|
779
|
+
})();`;function La(t,e=20*6e4,a=6){let n=[...t].sort((l,d)=>l.startedAt-d.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let l of n){let d=l.startedAt+Math.max(l.durationMs||0,0),p=r[r.length-1];p&&l.startedAt-p.to<=e?(p.to=Math.max(p.to,d),p.runs++):r.push({from:l.startedAt,to:d,runs:1})}for(;r.length>a;){let l=0,d=1/0;for(let p=1;p<r.length;p++){let c=r[p].from-r[p-1].to;c<d&&(d=c,l=p)}r[l-1].to=r[l].to,r[l-1].runs+=r[l].runs,r.splice(l,1)}let o=r.reduce((l,d)=>l+d.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,d)=>l.from-r[d].to);return{bands:s,gaps:i}}function Pa(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 jo(t,e=[],a){let{bands:n,gaps:r}=La(t,a);if(!n.length)return{bands:[],gaps:[],lanes:[],from:0,to:0};let o=new Map;for(let l of e){let d=o.get(l.runId);d?d.push(l):o.set(l.runId,[l])}let s=new Map;for(let l of t){let d=n.findIndex(b=>l.startedAt>=b.from&&l.startedAt<=b.to);if(d===-1)continue;let p=n[d],c=p.to-p.from||1,m=(l.startedAt-p.from)/c*100,g=Math.min(Math.max((l.durationMs||0)/c*100,1.2),100-m),k=s.get(l.laneKey)??{key:l.laneKey,label:l.laneLabel,sub:l.laneSub,tracks:1,runs:[]};k.runs.push({...l,band:d,track:0,left:m,width:g,marks:o.get(l.id)??[]}),s.set(l.laneKey,k)}let i=[...s.values()];for(let l of i)l.tracks=Math.max(...n.map((d,p)=>Pa(l.runs.filter(c=>c.band===p))),1);return i.sort((l,d)=>d.runs.length-l.runs.length||l.label.localeCompare(d.label)),{bands:n,gaps:r,lanes:i,from:n[0].from,to:n[n.length-1].to}}import{createHash as zc}from"crypto";import{readFileSync as Fc,statSync as Uc}from"fs";import{resolve as Wc,dirname as Gc}from"path";import{fileURLToPath as Xc}from"url";var Oo=new Map;function zt(t){let e=Oo.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=Gc(Xc(import.meta.url)),r=Wc(n,"web",t),o=Uc(r),s=o.size<8e6?zc("sha1").update(Fc(r)).digest("hex").slice(0,10):`${o.size}-${Math.floor(o.mtimeMs)}`;a=`/assets/${t}?v=${s}`}catch{}return Oo.set(t,a),a}var le={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"/>'},Ft=(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>",Kc=[["agent","Agent",le.bot],["client","Client",le.user],["project","Project",le.folder],["channel","Channel",le.route],["person","Person",le.user],["node","Node",le.mesh]],No={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 Do(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>
|
|
783
783
|
<div class="ac-kicker">Operations</div>
|
|
784
784
|
<h1>What ran, where, and what it decided</h1>
|
|
785
|
-
<p class="ac-sub" id="sub">${
|
|
785
|
+
<p class="ac-sub" id="sub">${No[e]}</p>
|
|
786
786
|
</div>
|
|
787
787
|
<div class="ac-tools">
|
|
788
788
|
<div class="ac-seg" id="view" role="radiogroup" aria-label="View">
|
|
@@ -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
|
+
${Kc.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${Ft(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="${zt("activity-graph.global.js")}"></div>
|
|
820
820
|
</div>
|
|
821
821
|
|
|
822
|
-
</div>`,css:
|
|
822
|
+
</div>`,css:Jc,scripts:`<script>${z({computeBands:La,packTracks:Pa,buildTimeline:jo})}const ICON = ${JSON.stringify(le)};const SUB = ${JSON.stringify(No)};${Vc}</script>`})}var Jc=`
|
|
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
|
+
`,Vc=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
|
|
1027
|
+
`;function Ho(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:Yc,scripts:`<script src="${zt("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var Yc=`
|
|
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
|
|
1048
|
+
`;import{createServer as xg}from"http";import{appendFileSync as bg,existsSync as Tc,mkdirSync as vg}from"fs";import{readFile as yg}from"fs/promises";import{fileURLToPath as wg}from"url";import{dirname as kg,resolve as mt}from"path";Jn();function Ge(t,e){if(!t)return"absent";let a=_r(t),n=e.list().find(r=>r.hash===a);return n&&(n.revokedAt||n.expiresAt&&Date.parse(n.expiresAt)<Date.now())?"revoked":"invalid"}var Le=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 Ut(t,e,a){let n={cookie:e};return a&&(n.bearer=a),n.mode=Bo(t.headers["sec-fetch-mode"]),n.site=Bo(t.headers["sec-fetch-site"]),n}function Bo(t){let e=Array.isArray(t)?t[0]:t;return e&&/^[a-z-]{1,20}$/.test(e)?e:"-"}import{deflateSync as ep}from"zlib";var Qc=[[[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]]],ke={x:100,y:393,width:979,height:547},$a="#1a1a18",ja="#ffffff",qo=Math.hypot(ke.width,ke.height)/2/ke.width,Wt={full:.74,safe:.37/qo,android:.29/qo,mac:.6};function Oa(t,e){let a=t*e/ke.width,n=t/2-(ke.x+ke.width/2)*a,r=t/2-(ke.y+ke.height/2)*a;return Qc.map(o=>o.map(([s,i])=>[s*a+n,i*a+r]))}function Zc(t,e){let a=n=>String(Math.round(n*100)/100);return Oa(t,e).map(n=>"M"+n.map(([r,o])=>`${a(r)},${a(o)}`).join("L")+"Z").join("")}function zo(t=64,e=Wt.full){return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${t} ${t}"><rect width="${t}" height="${t}" rx="${t*.18}" fill="${ja}"/><path fill="${$a}" d="${Zc(t,e)}"/></svg>`}var tp=Vo($a),Fo=Vo(ja),Uo=new Map;function Xe(t){let e=Uo.get(t);return e||(e=Jo({size:t,width:Wt.safe,background:"square"}),Uo.set(t,e)),e}var ap=zo();function Ko(t){return t==="/favicon.svg"?{type:"image/svg+xml",body:ap}:t==="/favicon.ico"?{type:"image/png",body:Go(32)}:t==="/apple-touch-icon.png"?{type:"image/png",body:Go(180)}:null}var Wo=new Map;function Go(t){let e=Wo.get(t);return e||(e=Jo({size:t,width:Wt.full,background:"square"}),Wo.set(t,e)),e}function Jo(t){let{size:e}=t,a=t.background==="mac"?Xo(e,[np(e)]):null,n=Xo(e,Oa(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,d=n[l],p=s*r+1+i*4;for(let c=0;c<3;c++)o[p+c]=Math.round(Fo[c]+(tp[c]-Fo[c])*d);o[p+3]=Math.round(255*(a?a[l]:1))}return rp(e,o)}function np(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,d]of s)for(let p=0;p<=12;p++){let c=(d+90*p/12)*Math.PI/180;o.push([i+r*Math.cos(c),l+r*Math.sin(c)])}return o}var Na=8;function Xo(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],[d,p]=o[(s+1)%o.length];l!==p&&n.push([i,l,d,p])}let r=[];for(let o=0;o<t;o++)for(let s=0;s<Na;s++){let i=o+(s+.5)/Na;r.length=0;for(let[l,d,p,c]of n)(i>=d&&i<c||i>=c&&i<d)&&r.push(l+(i-d)*(p-l)/(c-d));r.sort((l,d)=>l-d);for(let l=0;l+1<r.length;l+=2){let d=Math.max(0,r[l]),p=Math.min(t,r[l+1]);for(let c=Math.floor(d);c<p;c++){let m=Math.min(c+1,p)-Math.max(c,d);m>0&&(a[o*t+c]+=m/Na)}}}for(let o=0;o<a.length;o++)a[o]>1&&(a[o]=1);return a}function Vo(t){let e=parseInt(t.slice(1),16);return[e>>16&255,e>>8&255,e&255]}function rp(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]),Da("IHDR",a),Da("IDAT",ep(e)),Da("IEND",Buffer.alloc(0))])}function Da(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(sp(n)),Buffer.concat([a,n,r])}var op=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 sp(t){let e=4294967295;for(let a of t)e=op[(e^a)&255]^e>>>8;return(e^4294967295)>>>0}yt();Hc();var Gt=7,ip=["waiting_owner","needs_attention"],lp={gitlab:"GitLab",github:"GitHub",telegram:"Telegram",whatsapp:"WhatsApp",slack:"Slack",discord:"Discord",voice:"Voice",app:"Phone app",dashboard:"Dashboard",webrtc:"Call"};function Ke(t,e){let a=t.toLowerCase().split("@")[0],n=lp[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 Yo(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 Qo(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:Ke(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 (${_a.map(()=>"?").join(",")}) ORDER BY created_at, rowid`).all(e,..._a).map(i):[],d=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${Sa.map(()=>"?").join(",")}) AND COALESCE(closed_at, updated_at) >= ?
|
|
1049
1049
|
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...Sa,n-Gt*864e5).map(i):[],p=[];try{p=Ht(t,e,50).filter(b=>b.startedAt>=n-Gt*864e5)}catch{}let c=new Map;if(s&&p.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 (${p.map(()=>"?").join(",")})`).all(e,...p.map(S=>S.taskId));for(let S of b)c.set(S.ref,{id:S.id,state:S.state,evidence:S.evidence??null})}let m=p.map(b=>({...b,where:b.channel?{label:
|
|
1050
|
+
WHERE l.kind = 'run' AND r.person = ? AND l.ref IN (${p.map(()=>"?").join(",")})`).all(e,...p.map(S=>S.taskId));for(let S of b)c.set(S.ref,{id:S.id,state:S.state,evidence:S.evidence??null})}let m=p.map(b=>({...b,where:b.channel?{label:Ke(b.channel,b.chatId??""),url:a.linkFor?.(b.channel,b.chatId??"")??null}:null,request:c.get(b.taskId)??null})),g=new Set(m.map(b=>b.request?.id).filter(Boolean)),k=[...l.filter(b=>!ip.includes(b.state)),...d].filter(b=>!g.has(b.id));return{open:l,recent:d,runs:m,other:k}}Ta();Nc();var Zo={waiting:0,yours:0,ahead:null};function es(t,e,a={}){let n=Gn(t),r=new Map,o=[],s=new Map;for(let i of n){let l=`${i.agentId}\0${i.channel}\0${i.chatId}`,d=s.get(l)??0;s.set(l,d+1);let p=r.get(i.agentId)??{waiting:0,yours:0,ahead:null};p.waiting++,i.person===e&&(p.yours++,p.ahead===null&&(p.ahead=d),o.push({agentId:i.agentId,channel:i.channel,chatId:i.chatId,queuedAt:i.queuedAt,messagePreview:i.messagePreview,where:{label:Ke(i.channel,i.chatId),url:a.linkFor?.(i.channel,i.chatId)??null},ahead:d})),r.set(i.agentId,p)}return{byAgent:r,mine:o}}var dp=4e3;function ts(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-Gt*864e5).map(r=>r.agent_id)}function
|
|
1052
|
+
GROUP BY agent_id ORDER BY last DESC LIMIT 12`).all(e.id,a-Gt*864e5).map(r=>r.agent_id)}function as(t,e,a,n){let r=new Set(n.people.filter(l=>l.role==="owner").map(l=>l.id));r.add(vt);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 d=n.queue?.get(l)??Zo,p=s.get(l),c=p??i.get(l);if(!c)return{agentId:l,state:"free",by:null,at:null,text:null,fullText:null,where:null,queue:d};let m=o(c.person??null),g=c.status==="error"||c.status==="timeout",k=p?"working":g&&m==="you"?"blocked":"free",b=m==="you"&&c.channel!=="a2a",S=b&&c.channel;return{agentId:l,state:k,by:m,at:p?c.started_at:c.finished_at??c.started_at,text:p||b?c.message_preview??null:null,fullText:b&&p&&String(c.original_message??c.message_preview??"").slice(0,dp)||null,where:S?{label:Ke(c.channel,c.chat_id??""),url:n.linkFor?.(c.channel,c.chat_id??"")??null}:null,queue:d}})}function ns(t){return t>=200&&t<300?"retry":t===401?"lock":"keep"}function rs(t,e){return!t||e-t>=3e4||t>e}function Xt(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 os(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 Kt(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 Jt(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 ss(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 is(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 ls(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 ds(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 cs(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 ps=`
|
|
1053
1053
|
(function () {
|
|
1054
1054
|
var POLL_S = 30, RETRY_S = 20, GIVE_UP_MS = 15000;
|
|
1055
1055
|
var who = document.getElementById('who');
|
|
@@ -1364,7 +1364,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
1364
1364
|
.blank { padding: 28px 24px; border: var(--ax-border-w) dashed var(--ax-border-2); border-radius: var(--ax-radius-lg); }
|
|
1365
1365
|
.blank p + p { margin-top: 8px; color: var(--ax-text-2); }
|
|
1366
1366
|
.foot { margin-top: 28px; font-size: 14px; color: var(--ax-text-2); }
|
|
1367
|
-
`,
|
|
1367
|
+
`,us=`
|
|
1368
1368
|
.pair-form { display: grid; gap: 8px; margin-top: 20px; }
|
|
1369
1369
|
.pair-form label { font-weight: 600; margin-top: 8px; }
|
|
1370
1370
|
.pair-form input { width: 100%; min-height: 52px; padding: 10px 14px; font: inherit; font-size: 17px; color: var(--ax-text); background: var(--ax-surface); border: var(--ax-border-w) solid var(--ax-text-2); border-radius: var(--ax-radius-sm); }
|
|
@@ -1376,11 +1376,11 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
1376
1376
|
.card .pair-msg.bad { color: var(--ax-red-ink); }
|
|
1377
1377
|
[data-theme="dark"] .card .pair-msg.bad { color: var(--ax-red); }
|
|
1378
1378
|
.card .pair-offline { padding: 8px 12px; border-radius: var(--ax-radius-sm); font-size: 14px; background: var(--ax-amber-t); color: var(--ax-amber-ink); border: 1px solid var(--ax-amber-e); }
|
|
1379
|
-
`,
|
|
1379
|
+
`,ms=`
|
|
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 cp="<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 Ha(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,8 +1390,8 @@ 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
|
-
${
|
|
1394
|
-
<style>${
|
|
1393
|
+
${cp}
|
|
1394
|
+
<style>${We}${Vt}</style>`}function fs(){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 hs=`
|
|
1395
1395
|
var CACHE = 'agentx-member-v1';
|
|
1396
1396
|
var STATIC = ['/member/manifest.webmanifest', '/member/icon-192.png', '/member/icon-512.png'];
|
|
1397
1397
|
self.addEventListener('install', function (e) {
|
|
@@ -1424,7 +1424,7 @@ self.addEventListener('fetch', function (e) {
|
|
|
1424
1424
|
`;function Ba(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 qa=Ha,za=Ba;function
|
|
1427
|
+
</header>`}var qa=Ha,za=Ba;function gs(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 xs(){return`<!doctype html>
|
|
1428
1428
|
<html lang="en">
|
|
1429
1429
|
<head>${qa("My work \xB7 AgentX")}<style>${Yt}</style></head>
|
|
1430
1430
|
<body>
|
|
@@ -1439,15 +1439,15 @@ ${za("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>${z({workState:
|
|
1442
|
+
<script>${z({workState:pp,ageText:Fa,connectionNote:Kt,plainPreview:Jt,agentLine:ss,sentState:is,requestState:ls,summaryLine:ds,freedAgents:cs})}${ps}</script>
|
|
1443
1443
|
</body>
|
|
1444
|
-
</html>`}function
|
|
1444
|
+
</html>`}function bs(){return`<!doctype html>
|
|
1445
1445
|
<html lang="en">
|
|
1446
|
-
<head>${qa("Pair this machine \xB7 AgentX")}<style>${
|
|
1446
|
+
<head>${qa("Pair this machine \xB7 AgentX")}<style>${us}</style></head>
|
|
1447
1447
|
<body>
|
|
1448
1448
|
${za("This machine is not paired yet")}
|
|
1449
1449
|
<main class="narrow">
|
|
1450
|
-
${
|
|
1450
|
+
${gs(0)}
|
|
1451
1451
|
<div class="card">
|
|
1452
1452
|
<h2>Pair this machine</h2>
|
|
1453
1453
|
<p>The owner sent you a pairing code. Type it with a name for this machine. The owner then approves the machine, and your work page opens.</p>
|
|
@@ -1464,24 +1464,24 @@ ${za("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>${z({formatPairInput:Xt})}${
|
|
1467
|
+
<script>${z({formatPairInput:Xt})}${up}</script>
|
|
1468
1468
|
</body>
|
|
1469
|
-
</html>`}function
|
|
1469
|
+
</html>`}function vs(){return`<!doctype html>
|
|
1470
1470
|
<html lang="en">
|
|
1471
|
-
<head>${qa("Waiting for the owner \xB7 AgentX")}<style>${
|
|
1471
|
+
<head>${qa("Waiting for the owner \xB7 AgentX")}<style>${ms}</style></head>
|
|
1472
1472
|
<body>
|
|
1473
1473
|
${za("This machine is paired")}
|
|
1474
1474
|
<main class="narrow">
|
|
1475
|
-
${
|
|
1475
|
+
${gs(1)}
|
|
1476
1476
|
<div class="card">
|
|
1477
1477
|
<h2><span class="pulse" aria-hidden="true"></span>Waiting for the owner</h2>
|
|
1478
1478
|
<p id="msg" role="status">This machine is paired. The owner has to approve it once; this page opens your work by itself when they do.</p>
|
|
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>${mp}</script>
|
|
1483
1483
|
</body>
|
|
1484
|
-
</html>`}function
|
|
1484
|
+
</html>`}function pp(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 Fa(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 up=`
|
|
1485
1485
|
(function () {
|
|
1486
1486
|
var form = document.getElementById('pair-form');
|
|
1487
1487
|
var machine = document.getElementById('machine');
|
|
@@ -1525,7 +1525,7 @@ ${za("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
|
+
`,mp=`
|
|
1529
1529
|
(function () {
|
|
1530
1530
|
var msg = document.getElementById('msg');
|
|
1531
1531
|
function check() {
|
|
@@ -1536,13 +1536,13 @@ ${za("This machine is paired")}
|
|
|
1536
1536
|
}
|
|
1537
1537
|
setInterval(check, 5000);
|
|
1538
1538
|
})();
|
|
1539
|
-
`;function
|
|
1539
|
+
`;function ys(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 ws(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 ks(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 Ua="/member/client.webmanifest",ot="Your project";function _s(){return JSON.stringify({id:"/member?client",name:`${ot} \xB7 AgentX`,short_name:ot,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 fp=`
|
|
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
|
-
`;function
|
|
1543
|
+
`;function Ss(){return`<!doctype html>
|
|
1544
1544
|
<html lang="en">
|
|
1545
|
-
<head>${Ha(`${ot} \xB7 AgentX`,{manifest:Ua,appTitle:ot})}<style>${
|
|
1545
|
+
<head>${Ha(`${ot} \xB7 AgentX`,{manifest:Ua,appTitle:ot})}<style>${We}${Vt}${Yt}${fp}</style></head>
|
|
1546
1546
|
<body>
|
|
1547
1547
|
${Ba("Connecting\u2026",`
|
|
1548
1548
|
<button type="button" id="theme" class="icon-btn" aria-label="Switch theme">\u25D0</button>`,ot)}
|
|
@@ -1557,9 +1557,9 @@ ${Ba("Connecting\u2026",`
|
|
|
1557
1557
|
</section>
|
|
1558
1558
|
<p id="updated" class="foot"></p>
|
|
1559
1559
|
</main>
|
|
1560
|
-
<script>${z({ageText:Fa,connectionNote:Kt,plainPreview:Jt,clientSentState:
|
|
1560
|
+
<script>${z({ageText:Fa,connectionNote:Kt,plainPreview:Jt,clientSentState:ys,clientRequestState:ws,clientSummary:ks})}${hp}</script>
|
|
1561
1561
|
</body>
|
|
1562
|
-
</html>`}var
|
|
1562
|
+
</html>`}var hp=`
|
|
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 @@ ${Ba("Connecting\u2026",`
|
|
|
1666
1666
|
showConn();
|
|
1667
1667
|
load();
|
|
1668
1668
|
})();
|
|
1669
|
-
`;var Qt="agentx_member",pp=90*86400,up=new Rt,Ts=t=>t.replace(/^\[app\]/,"[member]"),mp=new Re(t=>console.log(Ts(t))),_s=new WeakMap;function fp(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return mp;let e=_s.get(t.log);return e||_s.set(t.log,e=new Re(a=>t.log(Ts(a)))),e}var Ss=null;function st(t,e=X){try{return Ss=e().people}catch{return Ss??t}}async function As(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 wt(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new At(r.root),limiter:r.pairLimiter??up,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return he(e,200,"application/manifest+json",us());if(a===Ua)return he(e,200,"application/manifest+json",ws());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),he(e,200,"text/javascript; charset=utf-8",ms);if(a==="/member/icon-192.png")return he(e,200,"image/png",Ge(192),"public, max-age=86400");if(a==="/member/icon-512.png")return he(e,200,"image/png",Ge(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let c=await xo(t,i);return c.status===200&&e.setHeader("Set-Cookie",Es(c.token)),c.status===429&&e.setHeader("Retry-After",String(c.retryAfter)),_e(e,c.status,c.body)}let l=vo(gp(t),i,go(t));if(!l.ok){if(l.status===401){let c=Wa(t);return fp(r).record(a.slice(0,120),Ut(t,We(Ga(t,Qt),o),c?We(c,o):null)),a==="/member"?he(e,401,"text/html; charset=utf-8",gs()):_e(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?he(e,202,"text/html; charset=utf-8",xs()):_e(e,403,{error:l.error,waiting:!0})}let d=r.people().find(c=>c.id===l.personId),p=d?.role==="client";if(n==="GET"&&a==="/member"){let c=Ga(t,Qt);return c&&!Wa(t)&&e.setHeader("Set-Cookie",Es(c)),he(e,200,"text/html; charset=utf-8",p?ks():hs())}if(n==="GET"&&a==="/api/member/me")return _e(e,200,{person:l.personId,name:d?.name??l.personId,role:d?.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 c=r.db?.()??null;if(!c)return _e(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),g=Vo(c,l.personId,{now:m,linkFor:r.linkFor}),k=(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=Qo(c,l.personId,{linkFor:r.linkFor})}catch(T){k("the line",T)}let S=[];if(p)return _e(e,200,{...hp(g),agents:S});try{let T=Zo(c,d??{id:l.personId},m);S=es(c,l.personId,T,{people:r.people(),linkFor:r.linkFor,queue:b.byAgent})}catch(T){k("agent cards",T)}return _e(e,200,{...g,agents:S,queued:b.mine})}return _e(e,404,{error:"not found"})}function hp(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 Es(t){return`${Qt}=${t}; Path=/; Max-Age=${pp}; HttpOnly; Secure; SameSite=Lax`}function gp(t){return Wa(t)??Ga(t,Qt)}function Wa(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Ga(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 he(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 he(t,e,"application/json",JSON.stringify(a))}Mc();var Cs='/*! 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 ea,readFileSync as Os,writeFileSync as Ns,rmSync as bb,mkdirSync as kp,copyFileSync as _p,readdirSync as Sp}from"fs";import{resolve as Je}from"path";Rc();function Ms(t){let e=gt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:gt.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 Zt(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=gt.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 Is=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function Rs(t){return Zt(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 Ls(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Zt((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:Is(t?.chats),senders:Is(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 Ps(t){let e=String(t?.id??"");return Zt(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 $s(t){let e=String(t?.id??"");return Zt(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}"`})}yt();var me={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 js(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=ue({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.`})+Nt([{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+bp()+to,css:yp,scripts:`${e}<script>${ao}
|
|
1670
|
-
${
|
|
1671
|
-
${
|
|
1672
|
-
${
|
|
1669
|
+
`;var Qt="agentx_member",gp=90*86400,xp=new Rt,Cs=t=>t.replace(/^\[app\]/,"[member]"),bp=new Le(t=>console.log(Cs(t))),Es=new WeakMap;function vp(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return bp;let e=Es.get(t.log);return e||Es.set(t.log,e=new Le(a=>t.log(Cs(a)))),e}var Ts=null;function st(t,e=X){try{return Ts=e().people}catch{return Ts??t}}async function Is(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 wt(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new At(r.root),limiter:r.pairLimiter??xp,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return he(e,200,"application/manifest+json",fs());if(a===Ua)return he(e,200,"application/manifest+json",_s());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),he(e,200,"text/javascript; charset=utf-8",hs);if(a==="/member/icon-192.png")return he(e,200,"image/png",Xe(192),"public, max-age=86400");if(a==="/member/icon-512.png")return he(e,200,"image/png",Xe(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let c=await vo(t,i);return c.status===200&&e.setHeader("Set-Cookie",As(c.token)),c.status===429&&e.setHeader("Retry-After",String(c.retryAfter)),_e(e,c.status,c.body)}let l=wo(wp(t),i,bo(t));if(!l.ok){if(l.status===401){let c=Wa(t);return vp(r).record(a.slice(0,120),Ut(t,Ge(Ga(t,Qt),o),c?Ge(c,o):null)),a==="/member"?he(e,401,"text/html; charset=utf-8",bs()):_e(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?he(e,202,"text/html; charset=utf-8",vs()):_e(e,403,{error:l.error,waiting:!0})}let d=r.people().find(c=>c.id===l.personId),p=d?.role==="client";if(n==="GET"&&a==="/member"){let c=Ga(t,Qt);return c&&!Wa(t)&&e.setHeader("Set-Cookie",As(c)),he(e,200,"text/html; charset=utf-8",p?Ss():xs())}if(n==="GET"&&a==="/api/member/me")return _e(e,200,{person:l.personId,name:d?.name??l.personId,role:d?.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 c=r.db?.()??null;if(!c)return _e(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),g=Qo(c,l.personId,{now:m,linkFor:r.linkFor}),k=(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=es(c,l.personId,{linkFor:r.linkFor})}catch(T){k("the line",T)}let S=[];if(p)return _e(e,200,{...yp(g),agents:S});try{let T=ts(c,d??{id:l.personId},m);S=as(c,l.personId,T,{people:r.people(),linkFor:r.linkFor,queue:b.byAgent})}catch(T){k("agent cards",T)}return _e(e,200,{...g,agents:S,queued:b.mine})}return _e(e,404,{error:"not found"})}function yp(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`${Qt}=${t}; Path=/; Max-Age=${gp}; HttpOnly; Secure; SameSite=Lax`}function wp(t){return Wa(t)??Ga(t,Qt)}function Wa(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Ga(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 he(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 he(t,e,"application/json",JSON.stringify(a))}jc();var Ms='/*! 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 ea,readFileSync as Ds,writeFileSync as Hs,rmSync as Sb,mkdirSync as Ap,copyFileSync as Cp,readdirSync as Ip}from"fs";import{resolve as Ve}from"path";Oc();function Ls(t){let e=gt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:gt.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 Zt(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=gt.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 Rs=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function Ps(t){return Zt(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 $s(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Zt((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:Rs(t?.chats),senders:Rs(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 js(t){let e=String(t?.id??"");return Zt(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 Os(t){let e=String(t?.id??"");return Zt(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}"`})}yt();var me={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 Ns(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=ue({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.`})+Nt([{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+_p()+no,css:Ep,scripts:`${e}<script>${ro}
|
|
1670
|
+
${oo}
|
|
1671
|
+
${kp}
|
|
1672
|
+
${Tp}</script>`})}var kp=`
|
|
1673
1673
|
(function(){
|
|
1674
1674
|
function fmt(n) { return n == null ? '\u2014' : String(n); }
|
|
1675
1675
|
async function voiceMissing() {
|
|
@@ -1763,8 +1763,8 @@ ${wp}</script>`})}var xp=`
|
|
|
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 _p(){let t=Fr().business?`<button data-tab="business">Business</button>
|
|
1767
|
+
`:"";return Sp.replace("__BUSINESS_TABS__",t)}var Sp=`
|
|
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>
|
|
@@ -2459,7 +2459,7 @@ ${wp}</script>`})}var xp=`
|
|
|
2459
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>
|
|
2460
2460
|
</section>
|
|
2461
2461
|
</main>
|
|
2462
|
-
`,
|
|
2462
|
+
`,Ep=`
|
|
2463
2463
|
|
|
2464
2464
|
/* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
|
|
2465
2465
|
nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
|
|
@@ -2667,7 +2667,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
|
|
|
2667
2667
|
.peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
|
|
2668
2668
|
padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
|
|
2669
2669
|
.peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
|
|
2670
|
-
`,
|
|
2670
|
+
`,Tp=`
|
|
2671
2671
|
const $ = (id) => document.getElementById(id);
|
|
2672
2672
|
let state = null;
|
|
2673
2673
|
|
|
@@ -5636,11 +5636,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
|
|
|
5636
5636
|
})();
|
|
5637
5637
|
|
|
5638
5638
|
refresh();
|
|
5639
|
-
`;function Ds(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(js({peers:a,localToken:n}))}async function Hs(t,e){let a=Ja();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function Bs(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Dp(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Ep(t),r={"GET /api/admin/state":()=>Ap(),"POST /api/admin/agents":()=>Pp(n),"PATCH /api/admin/agents":()=>$p(n),"DELETE /api/admin/agents":()=>jp(n),"POST /api/admin/agents/access":()=>Cp(n),"POST /api/admin/channels/telegram":()=>Op(n),"DELETE /api/admin/channels/telegram":()=>su(n),"POST /api/admin/channels/telegram/toggle":()=>iu(n),"POST /api/admin/crons":()=>lu(n),"DELETE /api/admin/crons":()=>du(n),"POST /api/admin/config/raw":()=>cu(n),"GET /api/admin/tokens":()=>Ip(),"POST /api/admin/tokens":()=>Mp(n),"DELETE /api/admin/tokens":()=>Rp(n),"POST /api/admin/agents/test":()=>Lp(n),"POST /api/admin/agents/integrations":()=>Up(n),"DELETE /api/admin/agents/integrations":()=>Wp(n),"PATCH /api/admin/agents/integrations":()=>Gp(n),"PATCH /api/admin/channels/telegram":()=>Np(n),"POST /api/admin/channels/slack":()=>Zp(n),"POST /api/admin/channels/slack/toggle":()=>eu(n),"POST /api/admin/channels/discord":()=>tu(n),"POST /api/admin/channels/discord/toggle":()=>au(n),"POST /api/admin/channels/gitlab":()=>nu(n),"POST /api/admin/channels/gitlab/toggle":()=>ru(n),"POST /api/admin/channels/request-status":()=>ko(n),"GET /api/admin/channels/whatsapp/state":()=>Ke("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>Ke("/webrtc/history"),"POST /api/admin/actions":()=>_u(n),"DELETE /api/admin/actions":()=>Su(n),"POST /api/admin/actions/run":()=>Eu(n),"GET /api/admin/channels/whatsapp/chats":()=>Ke("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>Ke("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>ge("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>ou(n),"POST /api/admin/webhooks":()=>Xp(n),"PATCH /api/admin/webhooks":()=>Kp(n),"DELETE /api/admin/webhooks":()=>Qp(n),"POST /api/admin/whatsapp-triage":()=>Rs(n),"POST /api/admin/whatsapp-triage/rules":()=>Ls(n),"PATCH /api/admin/whatsapp-triage/rules":()=>Ps(n),"DELETE /api/admin/whatsapp-triage/rules":()=>$s(n),"POST /api/admin/mesh/peers":()=>Jp(n),"DELETE /api/admin/mesh/peers":()=>Vp(n),"POST /api/admin/mesh/toggle":()=>Yp(n),"GET /api/admin/files":()=>Hp(t),"GET /api/admin/files/read":()=>Bp(t),"PUT /api/admin/files":()=>qp(n),"POST /api/admin/files/skill":()=>zp(n),"DELETE /api/admin/files/skill":()=>Fp(n),"POST /api/admin/business/orgchart":()=>pu(n),"DELETE /api/admin/business/orgchart":()=>uu(n),"POST /api/admin/business/project":()=>mu(n),"DELETE /api/admin/business/project":()=>gu(n),"POST /api/admin/business/client":()=>fu(n),"DELETE /api/admin/business/client":()=>hu(n),"POST /api/admin/business/contact":()=>xu(n),"DELETE /api/admin/business/contact":()=>bu(n),"POST /api/admin/boards":()=>vu(n),"DELETE /api/admin/boards":()=>yu(n),"POST /api/admin/boards/columns":()=>wu(n),"DELETE /api/admin/boards/columns":()=>ku(n),"POST /api/admin/notifications":()=>Cu(n),"POST /api/admin/wiki/curator":()=>Au(n),"POST /api/admin/screen":()=>Mu(n),"POST /api/admin/wiki-notes":()=>Iu(n),"GET /api/admin/wiki-notes/list":()=>Ke("/wiki/notes?status=all&limit=20"),"POST /api/admin/webhooks/triggers":()=>Ru(n),"POST /api/admin/mesh/health":()=>Tu(n),"GET /api/admin/projects":()=>Ke("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>ge("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>ge("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>ge("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>ge("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>ge("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>ge("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>ge("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>ge("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Xa(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();Xa(e,200,i)}catch(n){Xa(e,400,{error:n.message||"admin op failed"})}}function Xa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Ep(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 Tp(t){let e=Je(process.cwd(),t);if(!ea(e))return[];let a=[];for(let n of Sp(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(Os(Je(e,n.name),"utf-8")))}catch{}return a}function Ja(){let t=Je(process.cwd(),"agentx.json");return ea(t)?JSON.parse(Os(t,"utf-8")):null}function Ap(){let t=Ja();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 v=f.credentials||{},y={};for(let[E,x]of Object.entries(v))typeof x=="string"&&/^[A-Z][A-Z0-9_]*$/.test(x)?y[E]=process.env[x]?"set":"unset":typeof x=="string"&&(y[E]="literal");return{kind:f.kind,label:f.label,enabled:f.enabled!==!1,credentials:v,credStatus:y,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})),d=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||""})):[],p={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}},c=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:{}},k=t.notifications||{},b={longTaskThreshold:k.longTaskThreshold??30,destination:k.destination||null,on:{taskComplete:k.on?.taskComplete!==!1,taskError:k.on?.taskError!==!1,taskQueued:!!k.on?.taskQueued},local:wr(k.local),ntfy:To(t.channels?.ntfy)},S=[];try{S=Tp(".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:wo(t),whatsappTriage:Ms(t),crons:l,webhooks:d,mesh:p,daemonUrl:c,nodeName:t.node?.name,business:g,boards:T,notifications:b,screen:Qr(t.screen),wikiNotes:So(t.wikiNotes),actions:S,wikiCurator:Fs(t)}}function Cp(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 Ip(){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 Mp(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 Rp(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 Lp(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let p=X();r=p.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=p.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),d;try{d=JSON.parse(l)}catch{d={content:l}}if(!i.ok)throw new Error(d?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:d}}function Pp(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=zs(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=Je(process.cwd(),"agents",e),{summary:l}=C(p=>{if(p.agents=p.agents||{},p.agents[e])throw new Error(`Agent "${e}" already exists.`);let c={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(c.model=o),s&&(c.systemPrompt=s.slice(0,400)),p.agents[e]=c,`added agent "${e}"`}),d=Je(i,"CLAUDE.md");if(!ea(d))try{kp(i,{recursive:!0}),Ns(d,`# ${a}
|
|
5639
|
+
`;function Bs(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ns({peers:a,localToken:n}))}async function qs(t,e){let a=Ja();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function zs(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Fp(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Mp(t),r={"GET /api/admin/state":()=>Lp(),"POST /api/admin/agents":()=>Dp(n),"PATCH /api/admin/agents":()=>Hp(n),"DELETE /api/admin/agents":()=>Bp(n),"POST /api/admin/agents/access":()=>Pp(n),"POST /api/admin/channels/telegram":()=>qp(n),"DELETE /api/admin/channels/telegram":()=>pu(n),"POST /api/admin/channels/telegram/toggle":()=>uu(n),"POST /api/admin/crons":()=>mu(n),"DELETE /api/admin/crons":()=>fu(n),"POST /api/admin/config/raw":()=>hu(n),"GET /api/admin/tokens":()=>$p(),"POST /api/admin/tokens":()=>jp(n),"DELETE /api/admin/tokens":()=>Op(n),"POST /api/admin/agents/test":()=>Np(n),"POST /api/admin/agents/integrations":()=>Jp(n),"DELETE /api/admin/agents/integrations":()=>Vp(n),"PATCH /api/admin/agents/integrations":()=>Yp(n),"PATCH /api/admin/channels/telegram":()=>zp(n),"POST /api/admin/channels/slack":()=>ru(n),"POST /api/admin/channels/slack/toggle":()=>ou(n),"POST /api/admin/channels/discord":()=>su(n),"POST /api/admin/channels/discord/toggle":()=>iu(n),"POST /api/admin/channels/gitlab":()=>lu(n),"POST /api/admin/channels/gitlab/toggle":()=>du(n),"POST /api/admin/channels/request-status":()=>So(n),"GET /api/admin/channels/whatsapp/state":()=>Je("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>Je("/webrtc/history"),"POST /api/admin/actions":()=>Cu(n),"DELETE /api/admin/actions":()=>Iu(n),"POST /api/admin/actions/run":()=>Mu(n),"GET /api/admin/channels/whatsapp/chats":()=>Je("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>Je("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>ge("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>cu(n),"POST /api/admin/webhooks":()=>Qp(n),"PATCH /api/admin/webhooks":()=>Zp(n),"DELETE /api/admin/webhooks":()=>nu(n),"POST /api/admin/whatsapp-triage":()=>Ps(n),"POST /api/admin/whatsapp-triage/rules":()=>$s(n),"PATCH /api/admin/whatsapp-triage/rules":()=>js(n),"DELETE /api/admin/whatsapp-triage/rules":()=>Os(n),"POST /api/admin/mesh/peers":()=>eu(n),"DELETE /api/admin/mesh/peers":()=>tu(n),"POST /api/admin/mesh/toggle":()=>au(n),"GET /api/admin/files":()=>Up(t),"GET /api/admin/files/read":()=>Wp(t),"PUT /api/admin/files":()=>Gp(n),"POST /api/admin/files/skill":()=>Xp(n),"DELETE /api/admin/files/skill":()=>Kp(n),"POST /api/admin/business/orgchart":()=>gu(n),"DELETE /api/admin/business/orgchart":()=>xu(n),"POST /api/admin/business/project":()=>bu(n),"DELETE /api/admin/business/project":()=>wu(n),"POST /api/admin/business/client":()=>vu(n),"DELETE /api/admin/business/client":()=>yu(n),"POST /api/admin/business/contact":()=>ku(n),"DELETE /api/admin/business/contact":()=>_u(n),"POST /api/admin/boards":()=>Su(n),"DELETE /api/admin/boards":()=>Eu(n),"POST /api/admin/boards/columns":()=>Tu(n),"DELETE /api/admin/boards/columns":()=>Au(n),"POST /api/admin/notifications":()=>Pu(n),"POST /api/admin/wiki/curator":()=>Lu(n),"POST /api/admin/screen":()=>ju(n),"POST /api/admin/wiki-notes":()=>$u(n),"GET /api/admin/wiki-notes/list":()=>Je("/wiki/notes?status=all&limit=20"),"POST /api/admin/webhooks/triggers":()=>Ou(n),"POST /api/admin/mesh/health":()=>Ru(n),"GET /api/admin/projects":()=>Je("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>ge("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>ge("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>ge("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>ge("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>ge("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>ge("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>ge("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>ge("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Xa(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();Xa(e,200,i)}catch(n){Xa(e,400,{error:n.message||"admin op failed"})}}function Xa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Mp(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 Rp(t){let e=Ve(process.cwd(),t);if(!ea(e))return[];let a=[];for(let n of Ip(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(Ds(Ve(e,n.name),"utf-8")))}catch{}return a}function Ja(){let t=Ve(process.cwd(),"agentx.json");return ea(t)?JSON.parse(Ds(t,"utf-8")):null}function Lp(){let t=Ja();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 v=f.credentials||{},y={};for(let[E,x]of Object.entries(v))typeof x=="string"&&/^[A-Z][A-Z0-9_]*$/.test(x)?y[E]=process.env[x]?"set":"unset":typeof x=="string"&&(y[E]="literal");return{kind:f.kind,label:f.label,enabled:f.enabled!==!1,credentials:v,credStatus:y,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})),d=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||""})):[],p={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}},c=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:{}},k=t.notifications||{},b={longTaskThreshold:k.longTaskThreshold??30,destination:k.destination||null,on:{taskComplete:k.on?.taskComplete!==!1,taskError:k.on?.taskError!==!1,taskQueued:!!k.on?.taskQueued},local:wr(k.local),ntfy:Co(t.channels?.ntfy)},S=[];try{S=Rp(".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:_o(t),whatsappTriage:Ls(t),crons:l,webhooks:d,mesh:p,daemonUrl:c,nodeName:t.node?.name,business:g,boards:T,notifications:b,screen:eo(t.screen),wikiNotes:To(t.wikiNotes),actions:S,wikiCurator:Ws(t)}}function Pp(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 $p(){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 jp(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 Op(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 Np(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let p=X();r=p.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=p.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),d;try{d=JSON.parse(l)}catch{d={content:l}}if(!i.ok)throw new Error(d?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:d}}function Dp(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=Us(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=Ve(process.cwd(),"agents",e),{summary:l}=C(p=>{if(p.agents=p.agents||{},p.agents[e])throw new Error(`Agent "${e}" already exists.`);let c={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(c.model=o),s&&(c.systemPrompt=s.slice(0,400)),p.agents[e]=c,`added agent "${e}"`}),d=Ve(i,"CLAUDE.md");if(!ea(d))try{Ap(i,{recursive:!0}),Hs(d,`# ${a}
|
|
5640
5640
|
|
|
5641
5641
|
${s||"You are "+a+"."}
|
|
5642
|
-
`)}catch{}return{summary:l}}function $p(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=zs(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"&&Bt(o,a.wikiAbsorb),`updated agent "${e}"`});return{summary:n}}function jp(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 Op(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 Ke(t){let{url:e,headers:a}=Va(),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 ge(t,e){let{url:a,headers:n}=Va(),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 Dp(t,e){try{let{url:a,headers:n}=Va(),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 Va(){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 it(t){let a=Ja()?.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 Ka(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Hp(t){let e=Ka(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=Fe(it(e));return{agentId:e,...a}}function Bp(t){let e=Ka(t,"agent").trim(),a=Ka(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Lt(it(e),a)}function qp(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=Pt(it(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function zp(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=$t(it(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function Fp(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=jt(it(e),a);return{summary:`removed skill "${a}"`,...n}}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)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 d=o[l];if(typeof d=="string"&&d.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(d.trim()))throw new Error(`${l} must be uppercase identifier (got "${d}")`);r[l]=d.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,d]of Object.entries(t?.metadata||{}))(typeof d=="string"||typeof d=="number"||typeof d=="boolean")&&(s[l]=d);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(d=>d.kind===a&&d.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 Wp(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(d=>d.kind===a&&d.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 Gp(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 d=(i.integrations||[]).find(p=>p.kind===a&&p.label===n);if(!d)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(d.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(d.metadata={...d.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var qs=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function Xp(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(!qs.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(c=>c.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(p=>p.id===e))throw new Error(`Webhook "${e}" already exists.`);let d={id:e,source:a,agentId:n,enabled:!0};return r&&(d.secretEnv=r),o&&(d.description=o),s&&(d.node=s),l.webhooks.push(d),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function Kp(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"&&qs.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 Jp(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 Vp(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 Yp(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 Qp(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 Zp(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 eu(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 tu(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 au(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 nu(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 ru(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 ou(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-BEJRDQR3.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 su(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 iu(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 lu(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 du(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 cu(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(i){throw new Error(`Invalid JSON: ${i.message}`)}let n=Zn.safeParse(er(a)),r=n.success?tr(n.data):[];if(r.length)throw new Error(r.join(" "));let o=Je(process.cwd(),"agentx.json"),s=`${o}.bak.${Date.now()}`;if(ea(o))try{_p(o,s)}catch{}Ns(o,JSON.stringify(a,null,2)+`
|
|
5643
|
-
`,"utf-8");try{let l=X().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${l}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:s}}function zs(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function pu(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(d=>(d.business=d.business||{},d.business.orgChart=d.business.orgChart||{},d.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 uu(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 mu(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 fu(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 hu(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 gu(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 xu(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 bu(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 vu(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 d=l.boards.findIndex(c=>c.id===e),p={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(p.primaryToolLabel=r),d>=0){let c=l.boards[d];return l.boards[d]={...c,...p,columns:c.columns,labels:c.labels},`board "${e}" updated`}return l.boards.push(p),`board "${e}" added`});return{summary:i}}async function yu(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 wu(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(c=>c.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let d={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");d.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");d.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(d.accent=String(t.accent));let p=l.columns.findIndex(c=>c.id===a);return p>=0?(l.columns[p]={...l.columns[p],...d},`column "${a}" updated`):(l.columns.push(d),`column "${a}" added to board "${e}"`)});return{summary:o}}async function ku(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 _u(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 Su(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 Eu(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 Tu(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 Fs(t){let e=t?.wiki?.curator||{};return{enabled:e.enabled!==!1,agent:typeof e.agent=="string"?e.agent:""}}function Au(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=Fs(a);return`wiki.curator ${n.enabled?"on":"off"}, answered by ${n.agent||"the page owner"}`});return{summary:e}}async function Cu(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=kr(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=Ao(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 Iu(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=>Eo(n,e));return{summary:a}}async function Mu(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=Zr(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Ru(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}}yt();import{resolve as $u}from"path";function Us(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 Hp(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=Us(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"&&Bt(o,a.wikiAbsorb),`updated agent "${e}"`});return{summary:n}}function Bp(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 qp(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 zp(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 Je(t){let{url:e,headers:a}=Va(),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 ge(t,e){let{url:a,headers:n}=Va(),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 Fp(t,e){try{let{url:a,headers:n}=Va(),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 Va(){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 it(t){let a=Ja()?.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 Ka(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Up(t){let e=Ka(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=Ue(it(e));return{agentId:e,...a}}function Wp(t){let e=Ka(t,"agent").trim(),a=Ka(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Lt(it(e),a)}function Gp(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=Pt(it(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function Xp(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=$t(it(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function Kp(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=jt(it(e),a);return{summary:`removed skill "${a}"`,...n}}function Jp(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 d=o[l];if(typeof d=="string"&&d.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(d.trim()))throw new Error(`${l} must be uppercase identifier (got "${d}")`);r[l]=d.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,d]of Object.entries(t?.metadata||{}))(typeof d=="string"||typeof d=="number"||typeof d=="boolean")&&(s[l]=d);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(d=>d.kind===a&&d.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 Vp(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(d=>d.kind===a&&d.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 Yp(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 d=(i.integrations||[]).find(p=>p.kind===a&&p.label===n);if(!d)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(d.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(d.metadata={...d.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var Fs=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function Qp(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(!Fs.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(c=>c.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(p=>p.id===e))throw new Error(`Webhook "${e}" already exists.`);let d={id:e,source:a,agentId:n,enabled:!0};return r&&(d.secretEnv=r),o&&(d.description=o),s&&(d.node=s),l.webhooks.push(d),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function Zp(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"&&Fs.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 eu(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 tu(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 au(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 nu(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 ru(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 ou(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 su(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 iu(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 lu(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 du(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 cu(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-7O73TDCG.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 pu(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 uu(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 mu(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 fu(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 hu(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(i){throw new Error(`Invalid JSON: ${i.message}`)}let n=Zn.safeParse(er(a)),r=n.success?tr(n.data):[];if(r.length)throw new Error(r.join(" "));let o=Ve(process.cwd(),"agentx.json"),s=`${o}.bak.${Date.now()}`;if(ea(o))try{Cp(o,s)}catch{}Hs(o,JSON.stringify(a,null,2)+`
|
|
5643
|
+
`,"utf-8");try{let l=X().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${l}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:s}}function Us(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function gu(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(d=>(d.business=d.business||{},d.business.orgChart=d.business.orgChart||{},d.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 xu(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 bu(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 vu(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 yu(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 wu(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 ku(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 _u(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 Su(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 d=l.boards.findIndex(c=>c.id===e),p={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(p.primaryToolLabel=r),d>=0){let c=l.boards[d];return l.boards[d]={...c,...p,columns:c.columns,labels:c.labels},`board "${e}" updated`}return l.boards.push(p),`board "${e}" added`});return{summary:i}}async function Eu(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 Tu(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(c=>c.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let d={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");d.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");d.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(d.accent=String(t.accent));let p=l.columns.findIndex(c=>c.id===a);return p>=0?(l.columns[p]={...l.columns[p],...d},`column "${a}" updated`):(l.columns.push(d),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Au(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 Cu(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 Iu(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 Mu(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 Ru(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 Ws(t){let e=t?.wiki?.curator||{};return{enabled:e.enabled!==!1,agent:typeof e.agent=="string"?e.agent:""}}function Lu(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=Ws(a);return`wiki.curator ${n.enabled?"on":"off"}, answered by ${n.agent||"the page owner"}`});return{summary:e}}async function Pu(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=kr(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=Io(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 $u(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=>Ao(n,e));return{summary:a}}async function ju(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=to(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Ou(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}}yt();import{resolve as Hu}from"path";function Gs(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
5644
5644
|
|
|
5645
5645
|
<div id="disabled-banner" class="banner warn" style="display:none">
|
|
5646
5646
|
<b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
|
|
@@ -5695,7 +5695,7 @@ ${s||"You are "+a+"."}
|
|
|
5695
5695
|
<h2>Recent classifications</h2>
|
|
5696
5696
|
<p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
|
|
5697
5697
|
<div id="recent"></div>
|
|
5698
|
-
</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:Nu,scripts:`${e}<script>${Du}</script>`})}var Nu=`
|
|
5699
5699
|
main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
|
|
5700
5700
|
h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
|
|
5701
5701
|
.grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
|
|
@@ -5799,7 +5799,7 @@ details {
|
|
|
5799
5799
|
border-radius: 4px; padding: 8px 12px; margin-top: 8px;
|
|
5800
5800
|
}
|
|
5801
5801
|
details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
|
|
5802
|
-
details[open] summary { margin-bottom: 8px; }`,
|
|
5802
|
+
details[open] summary { margin-bottom: 8px; }`,Du=`
|
|
5803
5803
|
const $ = (id) => document.getElementById(id);
|
|
5804
5804
|
const state = { schema: null, nodes: [], pending: [], recent: [] };
|
|
5805
5805
|
|
|
@@ -6019,7 +6019,7 @@ $('btn-save-schema').addEventListener('click', async () => {
|
|
|
6019
6019
|
$('btn-reload-schema').addEventListener('click', refresh);
|
|
6020
6020
|
|
|
6021
6021
|
refresh();
|
|
6022
|
-
`;function
|
|
6022
|
+
`;function Ks(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Gs({peers:a,localToken:n}))}async function Js(t,e,a){try{let n=t.method==="GET"?void 0:await Ku(t),r=Bu(),o={"GET /api/admin/graph/state":()=>qu(r),"POST /api/admin/graph/classifications/approve":()=>zu(r,n),"POST /api/admin/graph/classifications/reject":()=>Fu(r,n),"POST /api/admin/graph/nodes":()=>Uu(r,n),"PATCH /api/admin/graph/nodes":()=>Wu(r,n),"DELETE /api/admin/graph/nodes":()=>Gu(r,n),"PUT /api/admin/graph/schema":()=>Xu(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){Ya(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();Ya(e,200,l)}catch(n){Ya(e,400,{error:n?.message||"graph op failed"})}}function Bu(){let t=X(),e=Hu(process.cwd(),t.graph.baseDir);return new ar({baseDir:e})}function qu(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 zu(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Vs(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=Qa(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function Fu(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=Vs(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function Vs(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 Uu(t,e){let a=Xs(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?Xs(String(e.parentId)):null,o=Qa({[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 Wu(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=Qa({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function Gu(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function Xu(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 Qa(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 Xs(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function Ya(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Ku(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 Ys=`
|
|
6023
6023
|
<section class="apv__req" id="req-section" aria-labelledby="req-h">
|
|
6024
6024
|
<h2 id="req-h">Open requests <span id="req-n"></span></h2>
|
|
6025
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>
|
|
@@ -6052,7 +6052,7 @@ refresh();
|
|
|
6052
6052
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
6053
6053
|
</form>
|
|
6054
6054
|
</details>
|
|
6055
|
-
</section>`,
|
|
6055
|
+
</section>`,Qs=`
|
|
6056
6056
|
.apv__req { margin-top: 32px; border-top: 1px solid var(--ax-border); padding-top: 16px; }
|
|
6057
6057
|
.apv__req h2 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
|
|
6058
6058
|
.apv__req h2 span { color: var(--ax-muted); font-family: var(--ax-mono); font-size: 12px; font-weight: 400; }
|
|
@@ -6086,7 +6086,7 @@ refresh();
|
|
|
6086
6086
|
.apv__loop .is-failed, .apv__loop .is-unverified { color: var(--ax-amber-ink); }
|
|
6087
6087
|
.apv__loop .is-verified { color: var(--ax-ok, inherit); }
|
|
6088
6088
|
.apv__stalled { color: var(--ax-err); }
|
|
6089
|
-
`,
|
|
6089
|
+
`,Zs=`
|
|
6090
6090
|
(function(){
|
|
6091
6091
|
var STATE = { in_progress: 'In progress', waiting_owner: 'Waiting on you', waiting_other: 'Waiting on another agent', needs_attention: 'Needs attention' };
|
|
6092
6092
|
function $(id){ return document.getElementById(id); }
|
|
@@ -6304,7 +6304,7 @@ function busy(){
|
|
|
6304
6304
|
}
|
|
6305
6305
|
setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) load(); }, 60000);
|
|
6306
6306
|
})();
|
|
6307
|
-
`;function
|
|
6307
|
+
`;function ei(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div class="apv">
|
|
6308
6308
|
<header class="apv__head">
|
|
6309
6309
|
<div>
|
|
6310
6310
|
<h1>Approvals</h1>
|
|
@@ -6326,7 +6326,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) l
|
|
|
6326
6326
|
<ol id="apv-list" class="apv__list" aria-label="Waiting for you"></ol>
|
|
6327
6327
|
<p id="apv-snoozed" class="apv__foot"></p>
|
|
6328
6328
|
|
|
6329
|
-
${
|
|
6329
|
+
${Ys}
|
|
6330
6330
|
|
|
6331
6331
|
<details class="apv__settings" id="apv-settings">
|
|
6332
6332
|
<summary>Settings: expiry, later, daily digest</summary>
|
|
@@ -6341,7 +6341,7 @@ ${Js}
|
|
|
6341
6341
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
6342
6342
|
</form>
|
|
6343
6343
|
</details>
|
|
6344
|
-
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
6344
|
+
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Ju+Qs,scripts:`${e}<script>${Vu}</script><script>${Zs}</script>`})}var Ju=`
|
|
6345
6345
|
.apv { max-width: 860px; margin: 0 auto; padding: 20px 16px 64px; color: var(--ax-text); }
|
|
6346
6346
|
.apv__head { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; }
|
|
6347
6347
|
.apv__head h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
@@ -6398,7 +6398,7 @@ ${Js}
|
|
|
6398
6398
|
@media (max-width: 560px) {
|
|
6399
6399
|
.apv__acts .ax-btn { flex: 1 1 0; }
|
|
6400
6400
|
}
|
|
6401
|
-
`,
|
|
6401
|
+
`,Vu=`
|
|
6402
6402
|
(function(){
|
|
6403
6403
|
var state = { items: [], snoozed: 0, kind: '', showAll: false, popup: false };
|
|
6404
6404
|
var LABEL = { card: 'Card', schedule: 'Schedule', memory: 'Memory fact', wiki: 'Wiki lesson', whatsapp: 'WhatsApp reply', request: 'Request' };
|
|
@@ -6622,7 +6622,7 @@ $('apv-form').addEventListener('submit', async function(ev){
|
|
|
6622
6622
|
load();
|
|
6623
6623
|
setInterval(function(){ if (document.visibilityState === 'visible' && !document.querySelector('.apv__item:focus-within, .apv__item[data-touched]')) load(); }, 60000);
|
|
6624
6624
|
})();
|
|
6625
|
-
`;import{existsSync as
|
|
6625
|
+
`;import{existsSync as Yu,readFileSync as Qu}from"fs";Dc();var xe="/api/admin/approvals/requests";function ti(t){let e=lr(t);if(!Yu(e))return[];try{let a=JSON.parse(Qu(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 Ye=t=>typeof t=="string"?t.split(",").map(e=>e.trim()).filter(Boolean):void 0;async function ta(t,e,a,n){try{return await Zu(t,e,a,n)}catch(r){return{status:400,body:{error:String(r?.message??r).slice(0,300)}}}}async function Zu(t,e,a,n){if(t==="GET"&&e===xe){let o=Ce(n),s=ti(n.configPath),i=Ct(n.configPath),l=new Set(s.map(m=>m.id)),d={staleAfterHours:i.staleAfterHours,now:n.now??Date.now(),isAgent:m=>l.has(m)},p=o?o.listOpen().map(m=>hr(m,o,jr(n),d)):[],c=Object.fromEntries(mr.map(m=>[m,0]));for(let m of p)m.stall&&c[m.stall.group]++;return{status:200,body:{items:p,agents:s,settings:i,stalled:c}}}let r=e===`${xe}/reply`?"reply":e===`${xe}/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=Ce(n),d=l?.get(o);if(!l||!d||d.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let p=r==="reply"?d.agentId:typeof a.agentId=="string"?a.agentId:"",c=ti(n.configPath).find(g=>g.id===p);if(r==="handoff"&&!c)return{status:400,body:{error:`"${p}" is not an agent on this node`}};if(!Ct(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,p,i,n.now??Date.now()))return{status:409,body:{error:`${o} is already closed`}};let m=c?.name??p;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===`${xe}/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=Ce(n),l=i?.get(o);if(!i||!l||l.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let d=typeof a.evidence=="string"&&a.evidence.trim()?a.evidence.trim():typeof a.reason=="string"&&a.reason.trim()?a.reason.trim():"",p=s==="done"?l.closeWhen?`closed by owner: ${d||"checked by hand"}`:d||"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",p,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===`${xe}/settings`){let o={},s=c=>{let m=a[c];if(m!==void 0){if(typeof m!="number"||!(m>0))throw new Error(`${c} must be a positive number`);return m}};typeof a.enabled=="boolean"&&(o.enabled=a.enabled),o.from=Ye(a.from),o.channels=Ye(a.channels),o.staleAfterHours=s("staleAfterHours"),o.retentionDays=s("retentionDays"),typeof a.headlines=="boolean"&&(o.headlines={enabled:a.headlines});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}if(i.approveKinds=Ye(a.approveKinds),i.disabledAgents=Ye(a.plansOffFor),i.requireForWork=Ye(a.planForWork),a.planOverMinutes!==void 0){if(typeof a.planOverMinutes!="number"||!(a.planOverMinutes>=0))throw new Error("planOverMinutes must be a number, 0 or more");i.requireOverMinutes=a.planOverMinutes}Object.values(i).some(c=>c!==void 0)&&(o.plans=i);let l={},d=Ye(a.checkKinds);if(d){let c=d.filter(m=>!ka.includes(m));if(c.length)throw new Error(`unknown check ${c.join(", ")}: use ${ka.join(", ")}`);l.enabled=d}l.checkEveryMinutes=s("checkEveryMinutes"),Object.values(l).some(c=>c!==void 0)&&(o.checkers=l);let p=await $r(o,{configPath:n.configPath,reload:n.reload});return p.success?{status:200,body:{ok:!0,settings:Ct(n.configPath)}}:{status:400,body:{error:p.error}}}return{status:404,body:{error:"Not found"}}}var em=["yes","no","later"];function te(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function aa(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 tm(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 ai(t,e,a){t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(ei({peers:e,localToken:a}))}async function ni(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(xe)){let i=await ta(o,a,o==="POST"?await aa(t):{},s);return te(e,i.status,i.body),!0}if(o==="GET"&&a==="/api/admin/approvals"){let i=It(s,{includeSnoozed:n.searchParams.get("all")==="1"});return te(e,200,{...i,settings:Me(s.configPath)}),!0}if(o==="POST"&&a==="/api/admin/approvals/decide"){let i=await aa(t),l=typeof i.key=="string"?i.key:"",d=i.action;if(!l||!em.includes(d))return te(e,400,{error:"send { key, action: yes | no | later }"}),!0;let p=Me(s.configPath),c=await Mt(s,l,d,{note:typeof i.note=="string"?i.note:void 0,force:i.force===!0,laterHours:p.laterHours,by:"operator (dashboard)",...tm(i)});return c.ok?(te(e,200,{ok:!0,message:c.message}),!0):(te(e,409,{error:c.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/popup"){let i=await aa(t),l=Nr(s,typeof i.key=="string"?i.key:"",!!Me(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 aa(t),l={},d=c=>{let m=i[c];if(m!==void 0){if(typeof m!="number"||!(m>0))throw new Error(`${c} must be a positive number`);return m}};if(l.defaultExpiryDays=d("defaultExpiryDays"),l.maxExpiryDays=d("maxExpiryDays"),l.laterHours=d("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 c=i.destination.trim();if(!c)l.destination=null;else{let m=ho(c);if(!m)throw new Error("digest destination takes channel:chat id, for example telegram:123456");l.destination=m}}let p=await go(l,{configPath:s.configPath,reload:s.reload});return p.success?(te(e,200,{ok:!0,settings:Me(s.configPath)}),!0):(te(e,400,{error:p.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}Ta();function ri(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=ue({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."})+`
|
|
6626
6626
|
<div class="pp">
|
|
6627
6627
|
<div id="pp-msg" class="pp-msg" role="status" aria-live="polite"></div>
|
|
6628
6628
|
<section id="pp-none" class="pp-none" hidden aria-labelledby="pp-none-title">
|
|
@@ -6635,7 +6635,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6635
6635
|
</ol>
|
|
6636
6636
|
</section>
|
|
6637
6637
|
<ol id="pp-list" class="pp-list" aria-label="People"><li class="pp-empty">Loading\u2026</li></ol>
|
|
6638
|
-
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:
|
|
6638
|
+
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:am,scripts:`${e}<script>${nm}</script>`})}var am=`
|
|
6639
6639
|
.pp { max-width: 1040px; margin: 0 auto; padding: 0 24px 64px; }
|
|
6640
6640
|
.pp-msg { min-height: 1.4em; margin: 4px 0 8px; font-size: var(--ax-fs-sm); }
|
|
6641
6641
|
.pp-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -6676,7 +6676,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6676
6676
|
.pp-text { overflow-wrap: anywhere; }
|
|
6677
6677
|
.pp-meta { margin-top: 2px; display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: var(--ax-fs-xs); color: var(--ax-text-2); }
|
|
6678
6678
|
@media (prefers-reduced-motion: reduce) { .pp-caret { transition: none; } }
|
|
6679
|
-
`,
|
|
6679
|
+
`,nm=`
|
|
6680
6680
|
(function () {
|
|
6681
6681
|
var list = document.getElementById('pp-list');
|
|
6682
6682
|
var msg = document.getElementById('pp-msg');
|
|
@@ -6814,7 +6814,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6814
6814
|
load();
|
|
6815
6815
|
setInterval(load, 30000);
|
|
6816
6816
|
})();
|
|
6817
|
-
`;var Za="/api/admin/people";function
|
|
6817
|
+
`;var Za="/api/admin/people";function rm(t,e){let a=yo(t,e);return a?{...e,answer:a}:e}function om(t){return t.state!=="pending"||!t.answer?t.state:t.answer==="yes"?"active":"removed"}function be(t,e,a){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a))}function sm(t,e){let a=(o,s)=>e.filter(i=>i.personId===o&&om(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:vt,name:"Owner of this machine",role:"owner",identities:[]}),builtIn:!0}),r}var im=(t,e)=>e.createdAt.localeCompare(t.createdAt);async function oi(t,e,a,n){if(a!=="/people"&&a!==Za&&!a.startsWith(`${Za}/`))return!1;let r=(t.method||"GET").toUpperCase();if(a==="/people")return r!=="GET"?(be(e,405,{error:"GET only"}),!0):(e.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end(ri({peers:n.peers,localToken:n.localToken})),!0);if(r!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return be(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;let o=d=>n.members.devices(d).map(p=>rm(n.root,p)),s=()=>sm(n.people(),o());if(r==="GET"&&a===Za){let d=s();return be(e,200,{people:d,paired:d.reduce((p,c)=>p+c.machines.active+c.machines.pending,0)}),!0}let i=a.match(/^\/api\/admin\/people\/([a-z0-9][a-z0-9_-]{0,39})$/);if(r==="GET"&&i){let d=s().find(g=>g.id===i[1]);if(!d)return be(e,404,{error:`no person "${i[1]}"`}),!0;let p=n.db(),c=[],m=[];try{p&&(c=xo(p,d.id))}catch{}try{p&&(m=Ht(p,d.id,20))}catch{}return be(e,200,{person:d,devices:o(d.id).sort(im),requests:c,runs:m,database:!!p}),!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[,d,p]=l,c=n.members.byToken(p);if(!c||c.personId!==d)return be(e,404,{error:"no such machine for this person"}),!0;if(c.state==="removed")return be(e,409,{error:"this machine's access has already ended"}),!0;let m=ko({tokens:n.tokens??new G,members:n.members,now:n.now},p,"removed by the owner (dashboard)");return be(e,200,{ok:!0,device:m}),!0}return be(e,404,{error:"not found"}),!0}import{resolve as um}from"path";import{existsSync as mm}from"fs";import fm from"better-sqlite3";var si=new WeakSet;function lm(t,e,a={}){if(si.has(t))return;si.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 d=i[l].bind(i);i[l]=(...p)=>{let c=r();try{return d(...p)}finally{let m=r()-c;m>=n&&e({sql:s,ms:m})}}}return i}}function dm(t,e=160){let a=t.replace(/\s+/g," ").trim();return a.length>e?`${a.slice(0,e-1)}\u2026`:a}function Se(t,e){lm(t,({sql:a,ms:n})=>console.error(`[${e}] slow query, ${Math.round(n)} ms: ${dm(a)}`))}function ii(t={}){let e=`<div class="ax-obs">
|
|
6818
6818
|
<header class="ax-obs__head">
|
|
6819
6819
|
<h1>Health</h1>
|
|
6820
6820
|
<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>
|
|
@@ -6936,7 +6936,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6936
6936
|
</div>
|
|
6937
6937
|
<div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
|
|
6938
6938
|
</section>
|
|
6939
|
-
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
6939
|
+
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:cm,scripts:`<script>${pm}</script>`})}var cm=`
|
|
6940
6940
|
.ax-obs { padding: 16px 24px; }
|
|
6941
6941
|
.ax-obs__head { margin-bottom: 16px; }
|
|
6942
6942
|
.ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
|
|
@@ -7053,7 +7053,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7053
7053
|
.ax-obs__doctor-title { font-size: 12px; font-weight: 500; }
|
|
7054
7054
|
.ax-obs__doctor-detail { font-size: 11px; color: var(--ax-muted); margin-top: 2px; font-family: 'IBM Plex Mono', monospace; word-break: break-word; }
|
|
7055
7055
|
.ax-obs__doctor-fix { font-size: 11px; color: var(--ax-accent, #3a7bd5); margin-top: 2px; }
|
|
7056
|
-
`,
|
|
7056
|
+
`,pm=`
|
|
7057
7057
|
(function(){
|
|
7058
7058
|
var panes = document.querySelectorAll('.ax-obs__pane');
|
|
7059
7059
|
var tabs = document.querySelectorAll('.ax-obs__tab');
|
|
@@ -7437,7 +7437,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7437
7437
|
|
|
7438
7438
|
load(current);
|
|
7439
7439
|
})();
|
|
7440
|
-
`;var
|
|
7440
|
+
`;var ci={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 pi(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function en(t){let e=ci[pi(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 hm(){let t=um(process.cwd(),".agentx/db.sqlite");if(!mm(t))return null;try{let e=new fm(t,{readonly:!0,fileMustExist:!0});return Se(e,"health"),{db:e,close:()=>e.close()}}catch{return null}}function ui(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ii({peers:a}))}function gm(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 ve(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function mi(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=hm();if(!r)return ve(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=gm(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let d=`
|
|
7441
7441
|
SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
|
|
7442
7442
|
FROM route_traces
|
|
7443
7443
|
${i.length?"WHERE "+i.join(" AND "):""}
|
|
@@ -7452,8 +7452,8 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7452
7452
|
FROM task_history
|
|
7453
7453
|
WHERE ${i.join(" AND ")}
|
|
7454
7454
|
ORDER BY started_at DESC LIMIT @limit
|
|
7455
|
-
`,c=r.db.prepare(d).all(l).map(m=>({...m,plain:
|
|
7456
|
-
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function
|
|
7455
|
+
`,c=r.db.prepare(d).all(l).map(m=>({...m,plain:fi(m.error)}));return ve(e,200,{rows:c}),!0}if(n==="summary"||n==="overview")return ve(e,200,xm(r.db)),!0;if(n==="activity")return ve(e,200,bm(r.db,{agent:s})),!0;if(n==="cost"){let i=new URL(t.url||"/","http://_"),l=li(i.searchParams.get("range"));return ve(e,200,di(r.db,l)),!0}if(n==="cost.csv"){let i=new URL(t.url||"/","http://_"),l=li(i.searchParams.get("range")),d=di(r.db,l),p=vm(d.days);return e.writeHead(200,{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="agentx-cost-${l||"all"}d-${Date.now()}.csv"`}),e.end(p),!0}return ve(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return ve(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function fi(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(`
|
|
7456
|
+
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function xm(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,d=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,p=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),c=x=>p.length?p[Math.min(p.length-1,Math.floor(p.length*x))].duration_ms:0,m=c(.5),g=c(.95),b=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((x,A)=>x+en(A),0),S=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((x,A)=>x+en(A),0),T=t.prepare(`
|
|
7457
7457
|
SELECT agent_id,
|
|
7458
7458
|
COUNT(*) AS tasks,
|
|
7459
7459
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
|
|
@@ -7476,7 +7476,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7476
7476
|
FROM task_history
|
|
7477
7477
|
WHERE status='error' AND started_at >= ?
|
|
7478
7478
|
ORDER BY started_at DESC LIMIT 5
|
|
7479
|
-
`).all(o).map(x=>({...x,plain:
|
|
7479
|
+
`).all(o).map(x=>({...x,plain:fi(x.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(d),p50DurationMs:m,p95DurationMs:g,spendToday:b,spendDelta:b-S,idleAgentCount:v.length},perAgent:T,perChannel:h,idleAgents:v,recentErrors:E}}function bm(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(`
|
|
7480
7480
|
SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
|
|
7481
7481
|
COUNT(*) AS tasks,
|
|
7482
7482
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
|
|
@@ -7503,7 +7503,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7503
7503
|
WHERE started_at >= @since
|
|
7504
7504
|
GROUP BY agent_id
|
|
7505
7505
|
ORDER BY tasks_24h DESC, tasks_7d DESC
|
|
7506
|
-
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function
|
|
7506
|
+
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function li(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 di(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
|
|
7507
7507
|
SELECT day, agent_id, model,
|
|
7508
7508
|
input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
|
|
7509
7509
|
tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
|
|
@@ -7511,20 +7511,20 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7511
7511
|
FROM usage_daily
|
|
7512
7512
|
${a}
|
|
7513
7513
|
ORDER BY day
|
|
7514
|
-
`).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,d=0,p=0,c=0,m=0,g=0,k=0,b=0,S=0,T={},h={};for(let _ of n){let R=en(_),j=
|
|
7514
|
+
`).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,d=0,p=0,c=0,m=0,g=0,k=0,b=0,S=0,T={},h={};for(let _ of n){let R=en(_),j=pi(_.model),$=ci[j],O=(_.tier2_input_tokens||0)/1e6*$.input*.5+(_.tier2_output_tokens||0)/1e6*$.output*.5+(_.tier2_cache_read_tokens||0)/1e6*$.cacheRead*.5+(_.tier2_cache_create_tokens||0)/1e6*$.cacheCreate*.5,W=(_.input_tokens||0)+(_.tier2_input_tokens||0),ce=(_.output_tokens||0)+(_.tier2_output_tokens||0),Q=(_.cache_read_tokens||0)+(_.tier2_cache_read_tokens||0),oe=(_.cache_create_tokens||0)+(_.tier2_cache_create_tokens||0);c+=R,_.day>=s&&(p+=R,k+=_.tasks||0),_.day>=i&&_.day<s&&(S+=R,b+=_.tasks||0),_.day===r&&(l+=R),_.day===o&&(d+=R),_.day===r&&(m+=O),_.day>=s&&(g+=O);let Z=T[_.day]||(T[_.day]={date:_.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});Z.tasks+=_.tasks||0,Z.input+=W,Z.output+=ce,Z.cacheRead+=Q,Z.cacheCreate+=oe,Z.cost+=R,Z.tier2+=O;let F=Z.agents[_.agent_id]||(Z.agents[_.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:_.model});F.tasks+=_.tasks||0,F.cost+=R,F.tier2+=O,F.input+=W,F.output+=ce,F.cacheRead+=Q,F.cacheCreate+=oe,_.model&&(F.model=_.model);let N=h[_.agent_id]||(h[_.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:_.model});N.tasks+=_.tasks||0,N.cost+=R,N.tier2+=O,N.input+=W,N.output+=ce,N.cacheRead+=Q,N.cacheCreate+=oe,_.model&&(N.model=_.model)}let u=Object.values(T).sort((_,R)=>_.date<R.date?-1:1),f=0,v=0,y=0,E=0,x=0,A=0;for(let _ of u)f+=_.tasks,v+=_.input,y+=_.output,E+=_.cacheRead,x+=_.cacheCreate,A+=_.cost;let L=Object.entries(h).map(([_,R])=>({agent_id:_,...R,tokens:R.input+R.output+R.cacheRead+R.cacheCreate})).sort((_,R)=>R.cost-_.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:l,spendYesterday:d,spend7d:p,spend30d:c,tier2Today:m,tier2_7d:g,tier2PctToday:l>0?m/l:0,spendRange:A,avgDailyRange:u.length?A/u.length:0,tasksRange:f,tokensRange:v+y+E+x,cacheHitRange:E+v>0?E/(E+v):0,costPerTaskRange:f>0?A/f:0,spendDeltaWoW:S>0?(p-S)/S:0,tasksDeltaWoW:b>0?(k-b)/b:0},days:u,perAgent:L}}function vm(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+`
|
|
7515
7515
|
`+a.join(`
|
|
7516
7516
|
`)+`
|
|
7517
|
-
`}import{resolve as
|
|
7517
|
+
`}import{resolve as ym}from"path";import{existsSync as wm}from"fs";import km from"better-sqlite3";function _m(){let t=ym(process.cwd(),".agentx/intent/ledger.sqlite");if(!wm(t))return null;try{let e=new km(t,{readonly:!0,fileMustExist:!0});return Se(e,"ledger-panel"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-hi>6e4&&(hi=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var hi=0;function Pe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Sm(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 gi(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=_m();if(!r)return Pe(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Sm(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",d=parseInt(o.searchParams.get("limit")||"50",10),p=Number.isFinite(d)?Math.max(1,Math.min(500,d)):50;if(n==="stats"){let c=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 ${c} GROUP BY source ORDER BY n DESC`).all({since:s}),k=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 ${c}`).get({since:s}).n,T=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${c} GROUP BY source ORDER BY n DESC`).all({since:s}),h=r.db.prepare(`
|
|
7518
7518
|
SELECT COUNT(*) AS n FROM intent_decisions d
|
|
7519
7519
|
LEFT JOIN intent_resolutions r
|
|
7520
7520
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7521
7521
|
WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
|
|
7522
|
-
`).get().n;return
|
|
7522
|
+
`).get().n;return Pe(e,200,{since:s??null,eventsBySource:g,totalDecisions:k,decisionsByOutcome:b,totalDivergences:S,divergencesBySource:T,inFlight:h}),!0}if(n==="events"){let c=[],m={limit:p};s!==void 0&&(c.push("ts >= @since"),m.since=s),i&&(c.push("source = @source"),m.source=i),l&&(c.push("project = @project"),m.project=l);let g=`
|
|
7523
7523
|
SELECT id, ts, source, source_event_id, project, subject, intent
|
|
7524
7524
|
FROM intent_events
|
|
7525
7525
|
${c.length?"WHERE "+c.join(" AND "):""}
|
|
7526
7526
|
ORDER BY ts DESC LIMIT @limit
|
|
7527
|
-
`;return
|
|
7527
|
+
`;return Pe(e,200,{rows:r.db.prepare(g).all(m)}),!0}if(n==="divergences"){let c=[],m={limit:p};s!==void 0&&(c.push("ts >= @since"),m.since=s),i&&(c.push("source = @source"),m.source=i);let g=`
|
|
7528
7528
|
SELECT ts, source, decided_by,
|
|
7529
7529
|
legacy_agent_id, legacy_outcome, legacy_reason,
|
|
7530
7530
|
ledger_agent_id, ledger_outcome, ledger_reason,
|
|
@@ -7532,7 +7532,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7532
7532
|
FROM intent_divergences
|
|
7533
7533
|
${c.length?"WHERE "+c.join(" AND "):""}
|
|
7534
7534
|
ORDER BY ts DESC LIMIT @limit
|
|
7535
|
-
`;return
|
|
7535
|
+
`;return Pe(e,200,{rows:r.db.prepare(g).all(m)}),!0}if(n==="active"){let c=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],m={limit:p};i&&(c.push("e.source = @source"),m.source=i);let g=`
|
|
7536
7536
|
SELECT e.id AS event_id, e.ts, e.source, e.project, e.subject, e.intent,
|
|
7537
7537
|
d.decided_by, d.decided_at, d.agent_id, d.reason
|
|
7538
7538
|
FROM intent_decisions d
|
|
@@ -7541,7 +7541,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7541
7541
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7542
7542
|
WHERE ${c.join(" AND ")}
|
|
7543
7543
|
ORDER BY d.decided_at DESC LIMIT @limit
|
|
7544
|
-
`;return
|
|
7544
|
+
`;return Pe(e,200,{rows:r.db.prepare(g).all(m)}),!0}return Pe(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Pe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function xi(t={}){return I({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
|
|
7545
7545
|
<header class="ax-led__head">
|
|
7546
7546
|
<h1>Intent ledger</h1>
|
|
7547
7547
|
<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>
|
|
@@ -7746,7 +7746,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7746
7746
|
}
|
|
7747
7747
|
load();
|
|
7748
7748
|
})();
|
|
7749
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
7749
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function bi(t={}){return I({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
|
|
7750
7750
|
<header class="ax-cost__head">
|
|
7751
7751
|
<div>
|
|
7752
7752
|
<h1>Cost</h1>
|
|
@@ -8319,7 +8319,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8319
8319
|
load();
|
|
8320
8320
|
setInterval(load, 30000);
|
|
8321
8321
|
})();
|
|
8322
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
8322
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function vi(t={}){let e=`<div class="ax-pj__root">
|
|
8323
8323
|
<aside class="ax-pj__list">
|
|
8324
8324
|
<header>
|
|
8325
8325
|
<h2>Projects</h2>
|
|
@@ -8346,7 +8346,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8346
8346
|
</header>
|
|
8347
8347
|
<div id="pj-detail-body" class="ax-pj__detail-body"></div>
|
|
8348
8348
|
</section>
|
|
8349
|
-
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
8349
|
+
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Em,scripts:`<script>${Tm}</script>`})}var Em=`
|
|
8350
8350
|
.ax-pj__root {
|
|
8351
8351
|
display: grid;
|
|
8352
8352
|
grid-template-columns: 360px 1fr;
|
|
@@ -8533,7 +8533,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8533
8533
|
}
|
|
8534
8534
|
.ax-pj__warn { color: var(--ax-warn, #facc15); border-top: 1px solid var(--ax-border); }
|
|
8535
8535
|
.ax-pj__hint { font-size: 11px; color: var(--ax-fg-muted, var(--ax-text)); margin-top: 4px; }
|
|
8536
|
-
`,
|
|
8536
|
+
`,Tm=`
|
|
8537
8537
|
(function(){
|
|
8538
8538
|
const $ = (sel) => document.querySelector(sel);
|
|
8539
8539
|
const esc = (s) => String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({"&":"&","<":"<",">":">","\\"":"""}[c]));
|
|
@@ -9183,9 +9183,9 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
9183
9183
|
load();
|
|
9184
9184
|
});
|
|
9185
9185
|
})();
|
|
9186
|
-
`;import{resolve as on,join as Nm}from"path";import{existsSync as sn,readdirSync as Dm,readFileSync as Hm}from"fs";import Bm from"better-sqlite3";var vi=String.raw`[\w.-]+(?:/[\w.-]+)+`,km=new RegExp(`^(?:chat:)?(${vi}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),_m=new RegExp(`^\\[(?:GitLab|GitHub) (${vi}) `);function bi(t){if(!t)return null;let e=t.match(km);return e?e[1]:null}function tn(t){if(!t)return null;let e=t.trimStart().match(_m);return e?e[1]:null}function na(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():bi(typeof n?.chatId=="string"?n.chatId:null)??bi(e)??tn(a)}function Sm(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function ra(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Em=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Tm=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Am=t=>/^issue/i.test(t)?"issue":"mr";function Cm(t){let e=t.subject.match(Em)??t.inputPreview.trimStart().match(Tm);return e?{kind:Am(e[1]),n:Number(e[2])}:null}function Im(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 yi(t){if(!Sm(t.projectId))return[];let e=Cm(t);return e?[e]:Im(t.inputPreview)}var Mm=6e4,Rm=5*6e4,Lm=40,wi=6,ki=new Map;function _i(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 yi(n)){let s=ra(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Lm)return[...e.values()]}}return[...e.values()]}async function Si(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=ra(s.project,s.ref),l=ki.get(i);l&&n-l.at<(s.github?Rm:Mm)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=wi)await Promise.all(o.slice(s,s+wi).map(async i=>{let l=ra(i.project,i.ref),d=null;try{d=i.github?await $m(i,e,a):await Pm(i,e,a)}catch{}ki.set(l,{at:n,item:d}),d&&(r[l]=d)}));return r}async function Ei(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 Pm(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 Ei(`${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 $m(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 Ei(`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}Wn();var an=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function Ti(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=xt(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=an(o.from,80);if(s){a.callback={from:s,status:an(o.status,20)??"done"};let i=an(o.peer,80);i&&(a.callback.peer=i)}}return a}Wn();Ta();var Ai={kind:"agentx",id:"agentx",name:"AgentX"},nn={kind:"person",id:"unknown",name:"Unknown"},jm=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),Ci=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),Pe=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function Om(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=Pe(o?.id)??(e==="whatsapp"?Pe(n?.from):void 0),i=Pe(o?.username)??Pe(o?.login);return s||i?{id:s,username:i,name:Pe(o?.name)}:null}function Ii(t){let e=s=>({kind:"person",id:`person:${s}`,name:Vn(t.people,s)}),a=(s,i)=>i||jm.has(s)?Ai:{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=Pe(n.person)??Qn(t.people,s)?.id;if(i)return e(i);let l=xt(s),d=l?.channel??t.channel;if(Un(s)==="human")return Ci(s?.senderUsername)?a(d,!1):nn;let p=!!Pe(n.senderAgentId)||wa(l?l.sender:s?.sender);return d==="desktop"&&!p?nn:a(d,p)}let r=Om(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Yn(t.people,t.channel,r);return o?e(o.id):wa(r.name)?Ai:Fn.has(t.channel)&&!Ci(r.username)?nn:a(t.channel,!1)}function ln(){let t=on(process.cwd(),".agentx/intent/ledger.sqlite");if(!sn(t))return null;try{let e=new Bm(t,{readonly:!0,fileMustExist:!0});return Se(e,"activity-graph"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-Mi>6e4&&(Mi=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var Mi=0;function ye(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var $e={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 qm(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in $e)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in $e)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in $e)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 $e)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 zm(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 $i(t,e,a){return vr(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 Fm(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&&!rn(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!rn(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:Wm(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,d=i||(s.id!=null?String(s.id):null)||l;if(d&&!rn(i||l||"")){let p=typeof n.channel=="string"?n.channel:"",c=Ri(p);return{id:d,name:l||i||d,avatar:J(l||i||d),kind:c}}}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,d=s.name||s.username;return{id:l,name:d,avatar:J(d),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:Ri(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 Um={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function Wm(t,e){let a=Um[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function Ri(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function rn(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 ji(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}
|
|
9186
|
+
`;import{resolve as on,join as zm}from"path";import{existsSync as sn,readdirSync as Fm,readFileSync as Um}from"fs";import Wm from"better-sqlite3";var wi=String.raw`[\w.-]+(?:/[\w.-]+)+`,Am=new RegExp(`^(?:chat:)?(${wi}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),Cm=new RegExp(`^\\[(?:GitLab|GitHub) (${wi}) `);function yi(t){if(!t)return null;let e=t.match(Am);return e?e[1]:null}function tn(t){if(!t)return null;let e=t.trimStart().match(Cm);return e?e[1]:null}function na(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():yi(typeof n?.chatId=="string"?n.chatId:null)??yi(e)??tn(a)}function Im(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function ra(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Mm=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Rm=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Lm=t=>/^issue/i.test(t)?"issue":"mr";function Pm(t){let e=t.subject.match(Mm)??t.inputPreview.trimStart().match(Rm);return e?{kind:Lm(e[1]),n:Number(e[2])}:null}function $m(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 ki(t){if(!Im(t.projectId))return[];let e=Pm(t);return e?[e]:$m(t.inputPreview)}var jm=6e4,Om=5*6e4,Nm=40,_i=6,Si=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 ki(n)){let s=ra(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Nm)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=ra(s.project,s.ref),l=Si.get(i);l&&n-l.at<(s.github?Om:jm)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=_i)await Promise.all(o.slice(s,s+_i).map(async i=>{let l=ra(i.project,i.ref),d=null;try{d=i.github?await Hm(i,e,a):await Dm(i,e,a)}catch{}Si.set(l,{at:n,item:d}),d&&(r[l]=d)}));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 Dm(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 Hm(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}Wn();var an=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function Ci(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=xt(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=an(o.from,80);if(s){a.callback={from:s,status:an(o.status,20)??"done"};let i=an(o.peer,80);i&&(a.callback.peer=i)}}return a}Wn();Ta();var Ii={kind:"agentx",id:"agentx",name:"AgentX"},nn={kind:"person",id:"unknown",name:"Unknown"},Bm=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),Mi=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),$e=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function qm(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=$e(o?.id)??(e==="whatsapp"?$e(n?.from):void 0),i=$e(o?.username)??$e(o?.login);return s||i?{id:s,username:i,name:$e(o?.name)}:null}function Ri(t){let e=s=>({kind:"person",id:`person:${s}`,name:Vn(t.people,s)}),a=(s,i)=>i||Bm.has(s)?Ii:{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=$e(n.person)??Qn(t.people,s)?.id;if(i)return e(i);let l=xt(s),d=l?.channel??t.channel;if(Un(s)==="human")return Mi(s?.senderUsername)?a(d,!1):nn;let p=!!$e(n.senderAgentId)||wa(l?l.sender:s?.sender);return d==="desktop"&&!p?nn:a(d,p)}let r=qm(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Yn(t.people,t.channel,r);return o?e(o.id):wa(r.name)?Ii:Fn.has(t.channel)&&!Mi(r.username)?nn:a(t.channel,!1)}function ln(){let t=on(process.cwd(),".agentx/intent/ledger.sqlite");if(!sn(t))return null;try{let e=new Wm(t,{readonly:!0,fileMustExist:!0});return Se(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 ye(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var je={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 Gm(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in je)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in je)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in je)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 je)return s}return"workflow"}return t}function ji(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 Xm(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 Oi(t,e,a){return vr(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 Km(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&&!rn(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!rn(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:Vm(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,d=i||(s.id!=null?String(s.id):null)||l;if(d&&!rn(i||l||"")){let p=typeof n.channel=="string"?n.channel:"",c=Pi(p);return{id:d,name:l||i||d,avatar:J(l||i||d),kind:c}}}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,d=s.name||s.username;return{id:l,name:d,avatar:J(d),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:Pi(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 Jm={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function Vm(t,e){let a=Jm[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function Pi(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function rn(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 Ni(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}
|
|
9187
9187
|
${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
|
|
9188
|
-
${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
|
|
9188
|
+
${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 Ym(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 Di(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
|
|
9189
9189
|
SELECT id, ts, source, project, subject, intent, raw_json
|
|
9190
9190
|
FROM intent_events WHERE ts >= ? ORDER BY ts ASC
|
|
9191
9191
|
`).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(","),L=Object.fromEntries(x.map((j,$)=>[`id${$}`,j])),_=t.prepare(`
|
|
@@ -9194,9 +9194,9 @@ ${e.issue.body}`:"")),e.pull_request?.title&&a.push(e.pull_request.title),typeof
|
|
|
9194
9194
|
`).all(L);for(let j of _)s.has(j.event_id)||s.set(j.event_id,[]),s.get(j.event_id).push(j);let R=t.prepare(`
|
|
9195
9195
|
SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
|
|
9196
9196
|
FROM intent_resolutions WHERE decision_event_id IN (${A})
|
|
9197
|
-
`).all(L);for(let j of R)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,d=new Map,p=new Map,c=new Map,m=[],g=e?.business?.projects??[],k=e?.business?.contactMap??[],b=Ia(e?.business??{}),S=e?.people??[];for(let x of o){let A=null;try{A=JSON.parse(x.raw_json)}catch{}let L
|
|
9197
|
+
`).all(L);for(let j of R)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,d=new Map,p=new Map,c=new Map,m=[],g=e?.business?.projects??[],k=e?.business?.contactMap??[],b=Ia(e?.business??{}),S=e?.people??[];for(let x of o){let A=null;try{A=JSON.parse(x.raw_json)}catch{}let L=Oi(x.source,A,k),_=Ni(x.source,A),R=Ci(A),j=x.project??na(A,x.subject,_),$=null,O=null;L?($=L.client,O=L.project||`${L.client}/_chat`):j&&($=St(j,g),O=j);let W=Gm(x.source,x.intent||"",A),ce=je[W]||{label:W,color:"#6b7280"};p.has(W)||p.set(W,{id:W,label:ce.label,color:ce.color});let Q=Ri({source:x.source,channel:W,raw:A,people:S,channelLabel:N=>je[N]?.label??N}),oe="__system",Z,F=Km(x.source,x.intent||"",A);if(F){oe=F.id,Z=F.kind;let N=L?.displayName||F.name;(!c.has(F.id)||L?.displayName)&&c.set(F.id,{id:F.id,name:N,avatar:J(N),kind:F.kind})}else c.has("__system")||c.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 Lc=`${x.id}|${N.decided_by}`,ht=i.get(Lc),Hn=N.decided_at,Bn=ht?.resolved_at??null,va=Bn===null,Pc=ht?.duration_ms??(va?n-Hn:0),$c=va?"active":ht?.status==="error"||ht?.status==="fail"?"error":"completed",ee,nt;if($)ee=$,nt=O;else{let ya=b.get(N.agent_id);ya?(ee=ya,nt=`${ya}/_${x.source}`):(ee="unmapped",nt=`unmapped/_${x.source}`)}l.has(ee)||l.set(ee,{id:ee,name:ee,color:ji(ee),projects:[]}),d.has(ee)||d.set(ee,new Set),d.get(ee).add(nt),m.push({id:`${x.id}|${N.decided_by}`,agentId:N.agent_id,clientId:ee,projectId:nt,channelId:W,initiatorId:oe,initiatorKind:Z,subject:Ym(x.subject),intent:x.intent||"",startedAt:Hn,resolvedAt:Bn,duration:Pc,active:va,outcome:$c,tokens:0,inputPreview:_,system:Xm(N.agent_id,e),...R,starter:Q})}}let T=[...l.values()].map(x=>({...x,projects:[...d.get(x.id)||[]].sort()})).sort((x,A)=>x.id.localeCompare(A.id)),h=[],u=new Set;if(e){let x=e.business??{},A=L=>{let _=x.orgChart?.[L]?.role,R=_?x.roles?.[_]?.title:void 0;return typeof R=="string"&&R.trim()?R.trim():void 0};for(let[L,_]of Object.entries(e.agents||{})){let R={id:L,name:_.name||L,tier:_.tier==="claude-code"?"lead":"worker",model:_.model||"",role:_.systemPrompt?_.systemPrompt.split(/[.\n]/)[0].slice(0,60):_.tier||"",title:A(L)};h.push(R),u.add(L)}}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=[],v=new Set;for(let[x,A]of Object.entries(je))f.push({id:x,label:A.label,color:A.color}),v.add(x);for(let x of p.values())v.has(x.id)||f.push(x);let y=[...c.values()];y.find(x=>x.id==="__system")||y.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:y,dispatches:m,forges:{gitlab:typeof E=="string"?E:void 0,github:"https://github.com"}}}function dn(t){let e=ln();if(!e)return null;try{return Di(e.db,Bi(),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:d,snap:p}of t){l.gitlab??=p.forges?.gitlab,l.github??=p.forges?.github,p.now>s&&(s=p.now),p.windowH>i&&(i=p.windowH);for(let c of p.clients){let m=e.get(c.id);if(!m)e.set(c.id,{...c,projects:[...c.projects]});else{let g=Array.from(new Set([...m.projects,...c.projects])).sort();e.set(c.id,{...m,projects:g})}}for(let c of p.agents)a.has(c.id)||a.set(c.id,c);for(let c of p.channels)n.has(c.id)||n.set(c.id,c);for(let c of p.initiators)r.has(c.id)||r.set(c.id,c);for(let c of p.dispatches){let m=Qm(c);if(m.clientId!==c.clientId&&!e.has(m.clientId)&&e.set(m.clientId,{id:m.clientId,name:m.clientId,color:ji(m.clientId),projects:[]}),m.projectId!==c.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:d,id:`${d}::${m.id}`})}}return{now:s||Date.now(),windowH:i||6,localNodeId:t[0]?.nodeId,forges:l,clients:[...e.values()].sort((d,p)=>d.id.localeCompare(p.id)),agents:[...a.values()].sort((d,p)=>d.id.localeCompare(p.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((d,p)=>p.startedAt-d.startedAt)}}function Qm(t){if(t.clientId!=="unmapped")return t;let e=tn(t.inputPreview);if(!e)return t;let a=we?.business?.projects??[];return{...t,projectId:e,clientId:St(e,a)}}async function oa(t){let e=we?.channels?.gitlab,a=await Ti(Ei(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 we=null;function Bi(){return we&&{...we,people:st(we.people)}}function qi(t){we=t}async function zi(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=ln();if(!n)return ye(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=Fi(parseInt(r.searchParams.get("hours")||"6",10));ye(e,200,await oa(Di(n.db,Bi(),o)))}catch(r){ye(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var Zm=5e3;async function cn(t,e,a,n=dn){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
|
|
9198
9198
|
|
|
9199
|
-
`);let r=new URL(t.url||"/","http://_"),o=
|
|
9199
|
+
`);let r=new URL(t.url||"/","http://_"),o=Fi(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
|
|
9200
9200
|
|
|
9201
9201
|
`)}catch{i()}},25e3);try{for(;!s;){try{let p=await n(o),c=p&&await oa(p);if(s)break;c?(e.write(`event: snapshot
|
|
9202
9202
|
`),e.write(`data: ${JSON.stringify(c)}
|
|
@@ -9207,7 +9207,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
|
|
|
9207
9207
|
`)}catch(p){e.write(`event: error
|
|
9208
9208
|
data: ${JSON.stringify({error:p?.message??String(p)})}
|
|
9209
9209
|
|
|
9210
|
-
`)}let d=Date.now();for(;!s&&Date.now()-d<
|
|
9210
|
+
`)}let d=Date.now();for(;!s&&Date.now()-d<Zm;)await new Promise(p=>setTimeout(p,200))}}finally{clearInterval(l);try{e.end()}catch{}}return!0}function Fi(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function ef(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=on(process.cwd(),".agentx/task-history",t,n);if(!sn(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=on(process.cwd(),".agentx/task-history",t,o);return sn(s)?$i(s,e,a):null}return $i(r,e,a)}function $i(t,e,a){let n=null,r=1/0;for(let o of Fm(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(Um(zm(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let p=Date.parse(i);if(!Number.isFinite(p))continue;l=p}else continue;let d=Math.abs(l-e);d<r&&d<=a&&(n=s,r=d)}return n}async function Ui(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 ye(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=ln();if(!l)return ye(e,503,{error:"ledger not available"}),!0;try{let d=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!d)return ye(e,404,{error:"event not found"}),!0;let p=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!p)return ye(e,404,{error:"decision not found"}),!0;let c=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(d.raw_json)}catch{}let g=Ni(d.source,m),k=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(p.agent_id){let y=ef(p.agent_id,p.decided_at);if(y){typeof y.responseText=="string"&&(b=y.responseText);let E=y.transcript;Array.isArray(E)&&(S=E.length)}}let T=we?.business?.projects??[],h=we?.business?.contactMap??[],u=Ia(we?.business??{}),f={client:"unmapped",project:`unmapped/_${d.source}`,via:"fallback"},v=Oi(d.source,m,h);if(v)f={client:v.client,project:v.project||`${v.client}/_chat`,via:`contactMap (channel=${v.channel??"*"}${v.username?` username=${v.username}`:""}${v.chatId?` chatId=${v.chatId}`:""})`};else if(d.project||na(m,d.subject,g)){let y=d.project||na(m,d.subject,g);f={client:St(y,T),project:y,via:d.project?`project namespace prefix (${y})`:`forge path in chat id / message (${y})`}}else if(p.agent_id){let y=u.get(p.agent_id);y&&(f={client:y,project:`${y}/_${d.source}`,via:`orgChart fallback (agent ${p.agent_id} reports up to a PM whose project belongs to ${y})`})}ye(e,200,{id:r,eventId:s,source:d.source,subject:d.subject,intent:d.intent,project:d.project,decidedBy:p.decided_by,agentId:p.agent_id,outcome:p.outcome,reason:p.reason,startedAt:p.decided_at,resolvedAt:c?.resolved_at??null,durationMs:c?.duration_ms??null,input:k,response:b,transcriptLen:S,resolutionStatus:c?.status??null,resultSummary:c?.result_summary??null,attribution:f})}catch(d){ye(e,500,{error:d?.message??String(d)})}finally{l.close()}return!0}import{existsSync as rf,readFileSync as of}from"fs";import{resolve as Gi}from"path";yt();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=tf.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:af,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>${nf}</script>`})}var tf=`
|
|
9211
9211
|
<!-- Breadcrumb -->
|
|
9212
9212
|
<div class="ax-crumb">
|
|
9213
9213
|
<a href="/admin">Settings</a>
|
|
@@ -9805,7 +9805,7 @@ data: ${JSON.stringify({error:p?.message??String(p)})}
|
|
|
9805
9805
|
</div>
|
|
9806
9806
|
</div>
|
|
9807
9807
|
</div>
|
|
9808
|
-
`,
|
|
9808
|
+
`,af=`
|
|
9809
9809
|
/* Agent-specific layout + legacy styles for bits the migration left in
|
|
9810
9810
|
* place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
|
|
9811
9811
|
* primitives live in components.css.ts. */
|
|
@@ -9924,7 +9924,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
|
|
|
9924
9924
|
|
|
9925
9925
|
/* Agent-specific button variant used in rail context (no ax-btn wrapper) */
|
|
9926
9926
|
.ax-btn.lg { padding: 9px 16px; font-size: 13px; }
|
|
9927
|
-
`,
|
|
9927
|
+
`,nf=`
|
|
9928
9928
|
const $ = (id) => document.getElementById(id);
|
|
9929
9929
|
const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
|
|
9930
9930
|
|
|
@@ -10783,15 +10783,15 @@ document.addEventListener('keydown', (e) => {
|
|
|
10783
10783
|
/* ===== Boot ===== */
|
|
10784
10784
|
initOptsToggles();
|
|
10785
10785
|
loadAgent();
|
|
10786
|
-
`;function
|
|
10787
|
-
`);return
|
|
10788
|
-
`);return
|
|
10786
|
+
`;function Xi(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 Ki(t,e,a){try{let n=t.method==="GET"?void 0:await Cf(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){sa(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",d=`${t.method} ${l}`,c={"GET ":()=>lt(i),"PATCH ":()=>sf(i,n),"PATCH capability":()=>cf(i,n),"POST mcp":()=>lf(i,n),"DELETE mcp":()=>df(i,n),"GET identity":()=>pf(i),"GET identity/file":()=>uf(i,String(o.path||"")),"PUT identity/file":()=>mf(i,n),"GET skills":()=>ff(i),"POST skills":()=>hf(i,n),"DELETE skills":()=>gf(i,n),"GET skills/tree":()=>xf(i,String(o.slug||"")),"GET skills/file":()=>bf(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>vf(i,n),"GET skills/deps":()=>yf(i,String(o.slug||"")),"POST skills/install":()=>wf(i,n,t),"POST skills/deps":()=>kf(i,n,t),"GET channels":()=>_f(i),"GET activity":()=>Sf(i,t),"GET handovers":()=>Ef(i),"POST handovers":()=>Tf(i,n),"DELETE handovers":()=>Af(n)}[d];if(!c){sa(e,404,{error:`unknown agent sub-endpoint: ${d}`});return}let m=await c();sa(e,200,m)}catch(n){sa(e,400,{error:n?.message||"agent op failed"})}}function Ji(){let t=Gi(process.cwd(),"agentx.json");return rf(t)?JSON.parse(of(t,"utf-8")):null}function V(t){let e=Ji();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 lt(t){let{def:e,cfg:a}=V(t),n=e.workspace?Ue(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 sf(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"&&(Bt(r.agents[t],e.wikiAbsorb),a.wikiAbsorb=e.wikiAbsorb),`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:lt(t)}}function lf(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:lt(t)}}function df(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:lt(t)}}function cf(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:lt(t)}}function pf(t){let{def:e}=V(t);return Ue(e.workspace)}function uf(t,e){if(!e)throw new Error("path query param required");let{def:a}=V(t);return Lt(a.workspace,e)}function mf(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=V(t);return Pt(n.workspace,a,String(e?.content??""))}function ff(t){let{def:e}=V(t),a=Ue(e.workspace);return{skills:a.skills,workspace:a.workspace}}function hf(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return $t(n.workspace,a,{title:e?.title,content:e?.content})}function gf(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return jt(n.workspace,a)}function xf(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t),n=Yr(a.workspace,e),r=Ot(a.workspace,e);return{slug:e,tree:n,deps:r}}function bf(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=V(t);return Qr(n.workspace,e,a)}function vf(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 Zr(r.workspace,a,n,String(e?.content??""))}function yf(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t);return Ot(a.workspace,e)}async function wf(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=Vi(e?.worker),{def:o}=V(t),s=fo(o.tier),i=s?.addSkillCommand(n,o.workspace);if(!s||!i)throw new Error(`agent "${t}" runs on ${o.tier}, which does not use skills`);let l=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: ${i}`,`Skills should land under ${s.skillDirs(o.workspace)[0]}/. Report what was installed and any errors.`].join(`
|
|
10787
|
+
`);return Yi(a,r,l,`install-${n}:${Date.now()}`)}async function kf(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=Vi(e?.worker),{def:o}=V(t),s=Ot(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=Gi(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(`
|
|
10788
|
+
`);return Yi(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function Vi(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 Yi(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}})}),d=await l.text(),p;try{p=JSON.parse(d)}catch{p={content:d}}if(!l.ok)throw new Error(p?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:p?.taskId,content:p?.content,duration:p?.duration,error:p?.error}}function _f(t){let e=Ji(),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 Sf(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 pn(){return new nr}function Ef(t){let e=pn(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function Tf(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,d=pn().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:d}}function Af(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:pn().remove(e,a,n)?"Released":"No active handover for that chat"}}function sa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Cf(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 Oe={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 Qi=[{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 un(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(Oe)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
|
|
10789
10789
|
<span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
|
|
10790
10790
|
<span id="conn-label">live</span>`,n=`<div class="ax-app-live">
|
|
10791
10791
|
<section id="statstrip" class="ax-statstrip"></section>
|
|
10792
10792
|
<main id="grid" class="ax-live__body"></main>
|
|
10793
10793
|
</div>
|
|
10794
|
-
`;return I({title:`${
|
|
10794
|
+
`;return I({title:`${Oe.brand} \xB7 ${Oe.subtitle}`,activeTab:"live",subtitle:Oe.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:If,scripts:e+`<script>${Mf}</script>`,headExtras:`<script>
|
|
10795
10795
|
// rightExtras for the topbar are injected at runtime \u2014 they reference
|
|
10796
10796
|
// IDs (#ts, #conn-dot) that the script below addresses directly.
|
|
10797
10797
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -10802,7 +10802,7 @@ loadAgent();
|
|
|
10802
10802
|
extras.innerHTML = ${JSON.stringify(a)};
|
|
10803
10803
|
right.insertBefore(extras, right.firstChild);
|
|
10804
10804
|
});
|
|
10805
|
-
</script>`})}var
|
|
10805
|
+
</script>`})}var If=`
|
|
10806
10806
|
/* --- Page frame --- */
|
|
10807
10807
|
.ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
|
|
10808
10808
|
|
|
@@ -11023,7 +11023,7 @@ loadAgent();
|
|
|
11023
11023
|
border-top-color: var(--ax-accent); border-radius: 50%;
|
|
11024
11024
|
animation: ax-spin 800ms linear infinite; display: inline-block;
|
|
11025
11025
|
}
|
|
11026
|
-
@keyframes ax-spin { to { transform: rotate(360deg); } }`,
|
|
11026
|
+
@keyframes ax-spin { to { transform: rotate(360deg); } }`,Mf=`
|
|
11027
11027
|
'use strict';
|
|
11028
11028
|
|
|
11029
11029
|
const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
|
|
@@ -11670,7 +11670,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11670
11670
|
});
|
|
11671
11671
|
}
|
|
11672
11672
|
|
|
11673
|
-
`;var
|
|
11673
|
+
`;var Zi=`
|
|
11674
11674
|
.mx-content{max-width:1180px;margin:0 auto;padding:0 24px 56px}
|
|
11675
11675
|
.mx-updated{margin:0;color:var(--ax-muted);font-size:11px;font-family:var(--ax-mono)}
|
|
11676
11676
|
.mx-section{margin-bottom:28px}.mx-section .ax-section-head{margin-bottom:14px}
|
|
@@ -11844,7 +11844,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11844
11844
|
.mx-summary{max-width:56vw}
|
|
11845
11845
|
}
|
|
11846
11846
|
@media(prefers-reduced-motion:reduce){.mx-drawer{transition:none}}
|
|
11847
|
-
`;var
|
|
11847
|
+
`;var el=`<script>
|
|
11848
11848
|
window.MX=(function(){
|
|
11849
11849
|
var ENT={'&':'&','<':'<','>':'>','"':'"',"'":'''};
|
|
11850
11850
|
function esc(v){return String(v==null?'':v).replace(/[&<>"']/g,function(c){return ENT[c]})}
|
|
@@ -11953,7 +11953,7 @@ window.MX=(function(){
|
|
|
11953
11953
|
verdict:verdict,verdictChip:verdictChip,mark:mark,causeLabel:causeLabel,
|
|
11954
11954
|
setHealth:setHealth,get:get};
|
|
11955
11955
|
})();
|
|
11956
|
-
</script>`;var
|
|
11956
|
+
</script>`;var tl=`<script>
|
|
11957
11957
|
window.MXD=(function(){
|
|
11958
11958
|
function el(id){return document.getElementById(id)}
|
|
11959
11959
|
function tz(){return -new Date().getTimezoneOffset()}
|
|
@@ -12167,7 +12167,7 @@ window.MXD=(function(){
|
|
|
12167
12167
|
|
|
12168
12168
|
return {openDay:openDay,openJob:openJob,openConversation:openConversation};
|
|
12169
12169
|
})();
|
|
12170
|
-
</script>`;var
|
|
12170
|
+
</script>`;var al=`<script>
|
|
12171
12171
|
(function(){
|
|
12172
12172
|
var LANES=[
|
|
12173
12173
|
{id:'cron',name:'Scheduled',hint:'cron jobs'},
|
|
@@ -12483,7 +12483,7 @@ window.MXD=(function(){
|
|
|
12483
12483
|
window.addEventListener('scroll',hideTip,{passive:true});
|
|
12484
12484
|
load();
|
|
12485
12485
|
})();
|
|
12486
|
-
</script>`;var
|
|
12486
|
+
</script>`;var nl=`<script>
|
|
12487
12487
|
(function(){
|
|
12488
12488
|
var showAll=document.getElementById('mx-show-all'),expanded=false;
|
|
12489
12489
|
var esc=MX.esc;
|
|
@@ -12661,7 +12661,7 @@ window.MXD=(function(){
|
|
|
12661
12661
|
}
|
|
12662
12662
|
load();setInterval(load,5000);
|
|
12663
12663
|
})();
|
|
12664
|
-
</script>`;var
|
|
12664
|
+
</script>`;var rl=`
|
|
12665
12665
|
.mx-rt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:12px}
|
|
12666
12666
|
.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}
|
|
12667
12667
|
.mx-rt-wrap > .mx-empty{border:0}
|
|
@@ -12702,7 +12702,7 @@ window.MXD=(function(){
|
|
|
12702
12702
|
.mx-rt-msg td{display:block}.mx-rt-msg td::before{content:none}
|
|
12703
12703
|
.mx-rt-name{max-width:100%}
|
|
12704
12704
|
}
|
|
12705
|
-
`,
|
|
12705
|
+
`,ol=`<script>
|
|
12706
12706
|
(function(){
|
|
12707
12707
|
var root=document.getElementById('mx-routines');
|
|
12708
12708
|
var bar=document.getElementById('mx-rt-filter');
|
|
@@ -12829,7 +12829,7 @@ window.MXD=(function(){
|
|
|
12829
12829
|
syncBar();
|
|
12830
12830
|
document.addEventListener('mx:snapshot',function(e){render(e.detail||{})});
|
|
12831
12831
|
})();
|
|
12832
|
-
</script>`;var
|
|
12832
|
+
</script>`;var sl=[{id:"all",label:"All"},{id:"peers",label:"Other machines"},{id:"announce",label:"Announcements"},{id:"problems",label:"Problems"}],il=`<script>
|
|
12833
12833
|
(function(){
|
|
12834
12834
|
var root=document.getElementById('mx-feed');
|
|
12835
12835
|
if(!root)return;
|
|
@@ -12904,12 +12904,12 @@ window.MXD=(function(){
|
|
|
12904
12904
|
}
|
|
12905
12905
|
load();setInterval(load,5000);
|
|
12906
12906
|
})();
|
|
12907
|
-
</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
|
|
12907
|
+
</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 Rf=[{id:"all",label:"All"},{id:"attention",label:"Flagged"},{id:"schedule",label:"Schedules"},{id:"event",label:"Events"}],Lf=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],Pf=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function ll(t){let e=ue({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+Nt([{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">
|
|
12908
12908
|
<div class="mx-tabs" role="tablist" aria-label="Mesh views">
|
|
12909
|
-
${
|
|
12909
|
+
${Lf.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("")}
|
|
12910
12910
|
</div>
|
|
12911
12911
|
<div class="mx-range" id="mx-range" role="group" aria-label="History window">
|
|
12912
|
-
${
|
|
12912
|
+
${Pf.map(i=>`<button type="button" data-days="${i.days}" aria-pressed="${i.days===30}">${i.label}</button>`).join("")}
|
|
12913
12913
|
</div>
|
|
12914
12914
|
</div>
|
|
12915
12915
|
<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">
|
|
@@ -12962,7 +12962,7 @@ window.MXD=(function(){
|
|
|
12962
12962
|
<section class="mx-section" aria-labelledby="mx-routines-title">
|
|
12963
12963
|
${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>')}
|
|
12964
12964
|
<div class="mx-rt-bar" id="mx-rt-filter" role="group" aria-label="Filter routines">
|
|
12965
|
-
${
|
|
12965
|
+
${Rf.map(i=>`<button class="mx-chip" type="button" data-rt-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12966
12966
|
</div>
|
|
12967
12967
|
<div class="mx-rt-wrap" id="mx-routines"><div class="mx-empty">Loading routines...</div></div>
|
|
12968
12968
|
</section>
|
|
@@ -12970,7 +12970,7 @@ window.MXD=(function(){
|
|
|
12970
12970
|
<section class="mx-section" aria-labelledby="mx-feed-title">
|
|
12971
12971
|
${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>')}
|
|
12972
12972
|
<div class="mx-rt-bar" role="group" aria-label="Filter the mesh feed">
|
|
12973
|
-
${
|
|
12973
|
+
${sl.map(i=>`<button class="mx-chip" type="button" data-feed-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12974
12974
|
</div>
|
|
12975
12975
|
<div class="ax-stack" id="mx-feed" aria-live="polite"><div class="mx-empty">Loading the mesh feed...</div></div>
|
|
12976
12976
|
</section>
|
|
@@ -13003,7 +13003,7 @@ window.MXD=(function(){
|
|
|
13003
13003
|
<button class="ax-btn ax-btn--ghost" id="mx-close" type="button" aria-label="Close details">Close</button>
|
|
13004
13004
|
</header>
|
|
13005
13005
|
<div class="mx-drawer__body" id="mx-drawer-body"></div>
|
|
13006
|
-
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:
|
|
13006
|
+
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:Zi+rl,scripts:el+$f+tl+al+ol+nl+il})}var $f=`<script>
|
|
13007
13007
|
(function(){
|
|
13008
13008
|
var tabs=Array.prototype.slice.call(document.querySelectorAll('.mx-tab'));
|
|
13009
13009
|
var range=document.getElementById('mx-range');
|
|
@@ -13031,10 +13031,10 @@ window.MXD=(function(){
|
|
|
13031
13031
|
var saved=null;try{saved=localStorage.getItem('mx-view')}catch(e){}
|
|
13032
13032
|
select(tabs.some(function(t){return t.dataset.view===saved})?saved:'activity');
|
|
13033
13033
|
})();
|
|
13034
|
-
</script>`;function
|
|
13034
|
+
</script>`;function dl(t){let e=ue({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."})+`
|
|
13035
13035
|
<div id="gm-msg" class="gm-msg" role="status" aria-live="polite"></div>
|
|
13036
13036
|
<ol id="gm-list" class="gm-list" aria-label="Grants"><li class="gm-empty">Loading\u2026</li></ol>
|
|
13037
|
-
<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:
|
|
13037
|
+
<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:jf,scripts:`<script>${Of}</script>`})}var jf=`
|
|
13038
13038
|
.gm-list { list-style: none; margin: 16px 0; padding: 0; display: grid; gap: 12px; }
|
|
13039
13039
|
.gm-empty { color: var(--ax-text-2); }
|
|
13040
13040
|
.gm-item { padding: 14px 16px; border: var(--ax-border-w) solid var(--ax-border); border-radius: var(--ax-radius); background: var(--ax-surface); }
|
|
@@ -13052,7 +13052,7 @@ window.MXD=(function(){
|
|
|
13052
13052
|
.gm-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
13053
13053
|
.gm-msg.is-bad { color: var(--ax-red-ink); }
|
|
13054
13054
|
.gm-note { color: var(--ax-text-2); font-size: var(--ax-fs-sm); }
|
|
13055
|
-
`,
|
|
13055
|
+
`,Of=`
|
|
13056
13056
|
(function () {
|
|
13057
13057
|
var list = document.getElementById('gm-list');
|
|
13058
13058
|
var msg = document.getElementById('gm-msg');
|
|
@@ -13099,7 +13099,7 @@ window.MXD=(function(){
|
|
|
13099
13099
|
load();
|
|
13100
13100
|
setInterval(load, 30000);
|
|
13101
13101
|
})();
|
|
13102
|
-
`;async function
|
|
13102
|
+
`;async function cl(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 d=await fetch(i.url+"/analytics/mesh"+o,{headers:l,signal:n.signal});return d.ok?{node:i,data:await d.json()}:{node:i,error:`HTTP ${d.status}`}}catch(d){return{node:i,error:d?.name==="AbortError"?"timeout":d?.message||"unreachable"}}}))}finally{clearTimeout(r)}return Nf(s,e.days)}function Nf(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=[],d=0,p=0,c=0,m=0,g=0,k=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);d+=T.rotations.total,p+=T.rotations.tokenSum||0,c+=T.rotations.tokenSamples||0,m=Math.max(m,T.rotations.maxTokens),g+=T.retention.traces,k+=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:d,byReason:[...s.entries()].map(([S,T])=>({reason:S,count:T})).sort((S,T)=>T.count-S.count),tokenSum:p,tokenSamples:c,maxTokens:m},retention:{traces:g,tracesWithSteps:k}}}async function pl(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 ul(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 d=await fetch(i.url+"/analytics/day"+o,{headers:l,signal:n.signal});return d.ok?{node:i,data:await d.json()}:{node:i,error:`HTTP ${d.status}`}}catch(d){return{node:i,error:d?.name==="AbortError"?"timeout":d?.message||"unreachable"}}}))}finally{clearTimeout(r)}return Df(s,e.day)}function Df(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 d=n.get(l.channel)||{channel:l.channel,runs:0,errors:0,ms:0};d.runs+=l.runs,d.errors+=l.errors,d.ms+=l.ms,n.set(l.channel,d)}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 ml(t={}){let e=`
|
|
13103
13103
|
<select id="boardPicker" title="Switch board"></select>
|
|
13104
13104
|
<div class="search">
|
|
13105
13105
|
<span class="icon">\u2315</span>
|
|
@@ -13200,7 +13200,7 @@ window.MXD=(function(){
|
|
|
13200
13200
|
</footer>
|
|
13201
13201
|
</div>
|
|
13202
13202
|
</div>
|
|
13203
|
-
<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
|
|
13203
|
+
<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:Hf,scripts:`<script>${Bf}</script>`,headExtras:`<script>
|
|
13204
13204
|
// The boards page has its own connection dot + wants body height:100%
|
|
13205
13205
|
// for the full-viewport kanban layout. Inject the dot into the topbar
|
|
13206
13206
|
// and override body height at runtime so the shared shell doesn't
|
|
@@ -13216,7 +13216,7 @@ window.MXD=(function(){
|
|
|
13216
13216
|
right.insertBefore(dot, right.firstChild);
|
|
13217
13217
|
}
|
|
13218
13218
|
});
|
|
13219
|
-
</script>`})}var
|
|
13219
|
+
</script>`})}var Hf=`
|
|
13220
13220
|
/* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
|
|
13221
13221
|
.ax-subheader select, .ax-subheader input, .ax-subheader button {
|
|
13222
13222
|
background: var(--col); color: var(--text); border: 1px solid var(--border);
|
|
@@ -13469,7 +13469,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
|
|
|
13469
13469
|
.draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
|
|
13470
13470
|
.draft-box .draft-row .hint.err { color: var(--red); }
|
|
13471
13471
|
.draft-box .draft-row .hint.ok { color: var(--green); }
|
|
13472
|
-
`,
|
|
13472
|
+
`,Bf=`
|
|
13473
13473
|
'use strict';
|
|
13474
13474
|
const state = {
|
|
13475
13475
|
boards: [], current: null, items: {},
|
|
@@ -14522,9 +14522,9 @@ function appendEvents(events) {
|
|
|
14522
14522
|
}
|
|
14523
14523
|
|
|
14524
14524
|
loadBoards().catch(e => toast('Init failed: ' + e.message));
|
|
14525
|
-
`;function
|
|
14525
|
+
`;function fl(t={}){let a=`<h1>Plain-English glossary</h1>
|
|
14526
14526
|
<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>
|
|
14527
|
-
${
|
|
14527
|
+
${Qi.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:`${Oe.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:qf})}var qf=`
|
|
14528
14528
|
main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
|
|
14529
14529
|
h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
|
|
14530
14530
|
.lead {
|
|
@@ -14554,7 +14554,7 @@ article.term .alias {
|
|
|
14554
14554
|
}
|
|
14555
14555
|
article.term p {
|
|
14556
14556
|
margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
|
|
14557
|
-
}`;function
|
|
14557
|
+
}`;function hl(t={}){let e=`<div class="ax-wf__root">
|
|
14558
14558
|
<aside class="ax-wf__list">
|
|
14559
14559
|
<header>
|
|
14560
14560
|
<h2>Workflows</h2>
|
|
@@ -14652,7 +14652,7 @@ article.term p {
|
|
|
14652
14652
|
</aside>
|
|
14653
14653
|
</div>
|
|
14654
14654
|
|
|
14655
|
-
<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:
|
|
14655
|
+
<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:zf,scripts:`<script>${z({workflowHealth:br})}${Ff}</script>`})}var zf=`
|
|
14656
14656
|
.ax-wf__root {
|
|
14657
14657
|
display: grid;
|
|
14658
14658
|
grid-template-columns: 340px 1fr;
|
|
@@ -15070,7 +15070,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15070
15070
|
font-size: 12px; z-index: 50;
|
|
15071
15071
|
}
|
|
15072
15072
|
.hint { color: var(--ax-muted); font-size: 11px; }
|
|
15073
|
-
`,
|
|
15073
|
+
`,Ff=`
|
|
15074
15074
|
(() => {
|
|
15075
15075
|
const $ = (sel) => document.querySelector(sel)
|
|
15076
15076
|
const $$ = (sel) => Array.from(document.querySelectorAll(sel))
|
|
@@ -15956,7 +15956,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15956
15956
|
setInterval(refresh, 15000)
|
|
15957
15957
|
})
|
|
15958
15958
|
})();
|
|
15959
|
-
`;function
|
|
15959
|
+
`;function gl(t={}){let e=`<div class="ax-proc__root">
|
|
15960
15960
|
<header class="ax-proc__header">
|
|
15961
15961
|
<h1>Procedures</h1>
|
|
15962
15962
|
<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>
|
|
@@ -16000,7 +16000,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16000
16000
|
<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>
|
|
16001
16001
|
<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>
|
|
16002
16002
|
</section>
|
|
16003
|
-
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
16003
|
+
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Uf,scripts:`<script>${Wf}</script>`})}var Uf=`
|
|
16004
16004
|
.ax-proc__root { padding: 18px 24px 40px; max-width: 1100px; margin: 0 auto; color: var(--ax-text); }
|
|
16005
16005
|
.ax-proc__header h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
16006
16006
|
.ax-proc__header .hint { color: var(--ax-muted); font-size: 12px; margin: 0 0 18px; }
|
|
@@ -16026,7 +16026,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16026
16026
|
.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); }
|
|
16027
16027
|
.ax-proc__link { color: var(--ax-accent, #6366f1); text-decoration: none; font-size: 11px; }
|
|
16028
16028
|
.ax-proc__link:hover { text-decoration: underline; }
|
|
16029
|
-
`,
|
|
16029
|
+
`,Wf=`
|
|
16030
16030
|
(function(){
|
|
16031
16031
|
function $(sel){ return document.querySelector(sel) }
|
|
16032
16032
|
function esc(s){ return String(s||"").replace(/[&<>"']/g, function(c){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c] }) }
|
|
@@ -16126,7 +16126,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16126
16126
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootAll)
|
|
16127
16127
|
else bootAll()
|
|
16128
16128
|
})();
|
|
16129
|
-
`;function
|
|
16129
|
+
`;function xl(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
|
|
16130
16130
|
data-task-id="${H(t.taskId)}"
|
|
16131
16131
|
data-agent-id="${H(t.agentId)}"
|
|
16132
16132
|
data-node-url="${H(t.nodeUrl)}"
|
|
@@ -16169,7 +16169,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16169
16169
|
<button type="button" id="task-send" class="ax-btn ax-btn--primary">send \u2192</button>
|
|
16170
16170
|
</div>
|
|
16171
16171
|
</footer>
|
|
16172
|
-
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
16172
|
+
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Gf,scripts:`<script>${Xf}</script>`})}var Gf=`
|
|
16173
16173
|
/* The shell gives <main> no padding, so page content butted straight against
|
|
16174
16174
|
the sticky topbar. Breathe. */
|
|
16175
16175
|
.ax-task-page {
|
|
@@ -16311,7 +16311,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16311
16311
|
line-height: 1.55; text-wrap: pretty; white-space: pre-wrap; word-break: break-word;
|
|
16312
16312
|
}
|
|
16313
16313
|
|
|
16314
|
-
`,
|
|
16314
|
+
`,Xf=`
|
|
16315
16315
|
(function () {
|
|
16316
16316
|
var root = document.querySelector('.ax-task-page');
|
|
16317
16317
|
if (!root) return;
|
|
@@ -16696,7 +16696,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16696
16696
|
});
|
|
16697
16697
|
|
|
16698
16698
|
})();
|
|
16699
|
-
`;function
|
|
16699
|
+
`;function bl(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
|
|
16700
16700
|
data-agent-id="${H(t.agentId)}"
|
|
16701
16701
|
data-agent-name="${H(e)}"
|
|
16702
16702
|
data-node-url="${H(t.nodeUrl)}">
|
|
@@ -16725,7 +16725,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16725
16725
|
<div class="ax-history__list" id="hist-list">
|
|
16726
16726
|
<div class="ax-history__empty">loading\u2026</div>
|
|
16727
16727
|
</div>
|
|
16728
|
-
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
16728
|
+
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Kf,scripts:`<script>${Jf}</script>`})}var Kf=`
|
|
16729
16729
|
/* <main> carries no padding in the shell \u2014 without this the breadcrumb sits
|
|
16730
16730
|
flush against the sticky topbar. */
|
|
16731
16731
|
.ax-history {
|
|
@@ -16777,7 +16777,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16777
16777
|
-webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
|
16778
16778
|
}
|
|
16779
16779
|
.ax-history__foot { margin-top: 6px; font-size: var(--ax-fs-xs); color: var(--ax-muted); font-family: var(--ax-mono); }
|
|
16780
|
-
`,
|
|
16780
|
+
`,Jf=`
|
|
16781
16781
|
(function () {
|
|
16782
16782
|
var root = document.querySelector('.ax-history');
|
|
16783
16783
|
if (!root) return;
|
|
@@ -16877,11 +16877,11 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16877
16877
|
listEl.innerHTML = '<div class="ax-history__empty" style="color:var(--ax-err)">' + esc(e.message) + '</div>';
|
|
16878
16878
|
});
|
|
16879
16879
|
})();
|
|
16880
|
-
`;function
|
|
16880
|
+
`;function yl(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 Qe(t,e,l=>vl(e,a,l,{mode:"create",convertFromYaml:i}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:Yf(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?Qe(t,e,i=>{let l=i,d=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return P(e,200,{ok:!0,emission:d})}):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"])?Qe(t,e,l=>{try{let d=a.layouts.save(s,l);return P(e,200,{layout:d})}catch(d){return P(e,400,{error:"invalid layout",message:d.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?Qe(t,e,l=>{let d=Aa.safeParse(l);if(!d.success)return P(e,200,{ok:!1,issues:d.error.issues.map(c=>({path:c.path.join("."),message:c.message}))});let p=Ca(d.data).map(c=>({path:"",message:c}));return P(e,200,{ok:p.length===0,issues:p,workflow:d.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,d=l.get("convertFromYaml")==="true"||l.get("convertFromYaml")==="1";return Qe(t,e,p=>vl(e,a,p,{mode:"update",id:s,convertFromYaml:d}))}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 Vf=["mesh"];function vl(t,e,a,n){let r=Aa.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=Ca(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,d=e.store.get(n.id);if(d)for(let p of Vf)!(p in l)&&p in d&&(o[p]=d[p])}let i;try{i=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(l){let d=l?.message||String(l),p=l?.yamlPath,c=!!p||/yaml round-trip failed/.test(d);return P(t,c?409:500,{error:c?"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).":d,kind:c?"yaml-authored":"save-failed",...p?{path:p}:{}})}return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),P(t,200,{workflow:i})}function Yf(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))),d=r.get("workflowId")||void 0,p=r.get("summary")==="1"||r.get("summary")==="true",c=a.runs.list({workflowId:d,limit:l});if(!p)return P(e,200,{runs:c});let m=c.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 Qe(t,e,d=>{let p=d?.status;return p!=="paused"&&p!=="running"&&p!=="canceled"?P(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,p)?P(e,200,{ok:!0,runId:l,status:p}):P(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return Qf(t,e,a,l);let d=a.runs.get(l);return d?P(e,200,{run:d}):P(e,404,{error:"run not found"})}return P(e,404,{error:"unknown runs endpoint"})}function Qf(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)}
|
|
16881
16881
|
|
|
16882
16882
|
`);let o=!1,s=()=>{o=!0,l?.(),clearInterval(p);try{e.end()}catch{}};t.on("close",s);let i=c=>{if(!o)try{e.write(`data: ${JSON.stringify(c)}
|
|
16883
16883
|
|
|
16884
|
-
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),d=r.updatedAt,p=setInterval(()=>{if(o)return;let c=a.runs.get(n);c&&c.updatedAt!==d&&(d=c.updatedAt,i(c))},2e3);return!0}function
|
|
16884
|
+
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),d=r.updatedAt,p=setInterval(()=>{if(o)return;let c=a.runs.get(n);c&&c.updatedAt!==d&&(d=c.updatedAt,i(c))},2e3);return!0}function Qe(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 Uh}from"fs";import{createRequire as Wh}from"module";var wl=4e3;async function kl(t,e,a,n,r){if(n==="GET"&&a==="/api/app/desk")return dt(e,200,await r.board());if(n!=="POST"||a!=="/api/app/desk/reply")return!1;let o;try{o=await Fe(t)}catch(d){return dt(e,400,{error:d.message})}let s=typeof o.id=="string"?o.id.trim():"",i=typeof o.text=="string"?o.text.trim():"";if(!s||!i)return dt(e,400,{error:"id and text are required"});if(i.length>wl)return dt(e,400,{error:`the answer is longer than ${wl} characters`});let l=await r.reply(s,i);return dt(e,l.status,l.body)}function dt(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}Xn();var Sl=50,Zf=280;async function El(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=eh(await o.recent(Sl))}catch(d){l=String(d?.message||"unreachable").slice(0,200)}return _l(e,200,{items:i,error:l,notify:s?s.on(r.id,"announce"):!1,notifyAvailable:!!s})}return _l(e,404,{error:"not found"})}function Tl(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 Tt();let r=bt();return r?new Sr(r):null}}}function eh(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:mn(typeof n.summary=="string"?n.summary:"",Zf),by:typeof n.agentId=="string"?mn(n.agentId,100):null,node:mn(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,Sl)}function mn(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}function _l(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var th="operator",ah=50,Al=4,Cl=500;function nh(t){let e={channel:"app",chatId:t.chatId,sender:th,...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 Il(t,e,a,n){let{path:r,body:o}=nh(e),s="",i=!1,l=[],d=new Map,p=(c,m,g)=>{let k=c!=="done",b=i?{text:_t(m,k),artifacts:[]}:kt(m,pe.perMessage,k),{cleanText:S,ui:T}=c==="done"?Et(b.text):{cleanText:b.text,ui:void 0},h=i?void 0:fn(T);return{status:c,text:S,tools:l,files:b.artifacts,...h?{ui:h}:{},...g?{error:g}:{}}};try{let c=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(!c.ok||!c.body){let m=await c.json().then(g=>g?.error).catch(()=>"");return p("error",s,m||`AgentX answered HTTP ${c.status}.`)}for await(let m of oh(c.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<ah){let k={name:String(g.name||"tool").slice(0,80),...g.arg?{arg:String(g.arg).slice(0,80)}:{}};l.push(k),g.id&&d.set(String(g.id),k)}else if(m.event==="tool"&&g.status==="result"&&g.error===!0&&d.has(String(g.id)))d.get(String(g.id)).error=!0;else{if(m.event==="done")return p("done",typeof g.content=="string"&&g.content?g.content:s);if(m.event==="error")return p("error",s,rh(g.error))}}return a.aborted?p("stopped",s):p("error",s,"The connection to the agent closed before it answered.")}catch(c){return a.aborted?p("stopped",s):p("error",s,`Could not reach AgentX: ${c?.message||c}`)}}function rh(t){let e=String(t||"The agent could not answer.");return rr(e)?"The agent is busy with other work. Send the message again when it is free.":e.slice(0,500)}function fn(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,Al).map(s=>s.slice(0,Cl));r.length&&(a.quickReplies=r);let o=(t.replies??[]).slice(0,Al).map(s=>({label:s.label.slice(0,80),reply:s.reply.slice(0,Cl)}));return o.length&&(a.replies=o),Object.keys(a).length?a:void 0}async function*oh(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,`
|
|
16885
16885
|
`);let s;for(;(s=n.indexOf(`
|
|
16886
16886
|
|
|
16887
16887
|
`))!==-1;){let i=n.slice(0,s);n=n.slice(s+2);let l="message",d=[];for(let p of i.split(`
|
|
@@ -16891,17 +16891,17 @@ data: ${JSON.stringify(s)}
|
|
|
16891
16891
|
|
|
16892
16892
|
`)},r=setInterval(()=>{a()&&e.write(`: ping
|
|
16893
16893
|
|
|
16894
|
-
`)},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
|
|
16895
|
-
`)){let n=
|
|
16896
|
-
`).map(
|
|
16894
|
+
`)},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 Rl(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=sh(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:hn(i.answer)||(i.status==="done"?"Answered.":i.status==="stopped"?"Stopped.":"The agent could not answer."),updatedAt:i.at}))}return r}function hn(t,e=120){for(let a of t.split(`
|
|
16895
|
+
`)){let n=Ll(a);if(n)return gn(n,e)}return""}function sh(t,e=120){let a=t.split(`
|
|
16896
|
+
`).map(Ll).filter(Boolean);return a.length?gn(a[a.length-1],e):""}function Ll(t){return t.replace(/^\s*(?:[#>]+|[-*+]\s|\d+\.\s)\s*/,"").replace(/[*_`]+/g,"").replace(/\s+/g," ").trim()}function gn(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}var la=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 da(t){return t.enabled&&!t.attached&&!t.appOpen&&t.status!=="stopped"}var Ml=140;function ca(t,e,a,n,r){let o=a==="error"?`Could not answer: ${hn(r||"",Ml-18)||"something went wrong."}`:hn(n,Ml)||"Answered.";return{deviceId:t,title:gn(e.agentName||e.agent,80),body:o,url:`/app#chat=${e.id}`}}var $l=8e3,lh=/^[A-Za-z0-9_.:-]{1,64}$/,Ne=new Map,xn=new Map,yn=new la;function jl(){return yn}async function Ol(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??yn;if(n==="GET"&&a==="/api/app/agents")return B(e,200,{nodes:await Nl(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:Rl(r.id,ph(),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 p=i.get(r.id,decodeURIComponent(l[1]));if(!p)return B(e,404,{error:"no such conversation"});new URL(t.url||a,"http://x").searchParams.get("peek")!=="1"&&i.markRead(r.id,p.id);let c=Ne.get(p.id);return B(e,200,{...p,running:!!c,...c?{partial:{text:c.text,tools:c.tools,...c.plain?{plain:!0}:{}}}:{}})}if(n==="GET"&&a==="/api/app/chat/attach"){let p=i.get(r.id,new URL(t.url||a,"http://x").searchParams.get("conversationId")||""),c=p&&Ne.get(p.id);if(!p||!c)return B(e,404,{error:"nothing is running in this conversation"});i.markRead(r.id,p.id),Dl(e);let{id:m,title:g,node:k,nodeName:b,agent:S,agentName:T}=p;return e.write(bn("conversation",{id:m,title:g,node:k,nodeName:b,agent:S,agentName:T})),e.write(bn("resume",{text:c.text,tools:c.tools,...c.plain?{plain:!0}:{}})),c.attach(e),!0}if(n!=="POST"||a!=="/api/app/chat"&&a!=="/api/app/chat/stop")return B(e,404,{error:"not found"});let d;try{d=await Fe(t,64*1024)}catch(p){return B(e,400,{error:p.message})}if(a==="/api/app/chat/stop"){let p=i.get(r.id,String(d.conversationId??""));if(!p)return B(e,404,{error:"no such conversation"});let c=Ne.get(p.id);return c?(c.ac.abort(),vn(p,o,r.name),B(e,200,{stopped:!0})):await vn(p,o,r.name)?B(e,200,{stopped:!0}):B(e,404,{error:"nothing is running in this conversation"})}return await ch(e,d,r,i,o),!0}function dh(t,e,a){let n=Ze(e.url),r=new Set,o=[];for(let s of t){let i=Ze(s.url),l=a.find(c=>Ze(c.peerUrl)===i);l&&r.add(l.peer);let d=i===n,p=s.agents.length?s.agents:l?.skills??[];o.push({target:d?"local":l?l.peer:null,name:s.reachable?s.name:(d?e.name:l?.peer)||s.name,online:d?s.reachable:l?l.healthy:!1,agents:p.map(c=>{let m=Array.isArray(c.runningTasks)?c.runningTasks.length:0;return{id:c.id,name:c.name||c.id,busy:m>0||(c.active??0)>0,running:m,...c.color?{color:c.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 Nl(t){let[e,a]=await Promise.all([t.snapshot().catch(()=>({nodes:[]})),t.meshPeers().catch(()=>[])]);return dh(e.nodes,t.daemon,a)}async function ch(t,e,a,n,r){let o=typeof e.message=="string"?e.message.trim():"";if(!o||o.length>$l){B(t,400,{error:`message must be 1\u2013${$l} 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 k=typeof e.node=="string"?e.node:"",b=typeof e.agent=="string"?e.agent:"";if(!lh.test(b)){B(t,400,{error:"pick an agent"});return}let S=(await Nl(r)).find(h=>h.target===k);if(!S){B(t,400,{error:`unknown node "${k}"`});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:k,nodeName:S.name,agent:b,agentName:T.name,...T.color?{color:T.color}:{}},o)}if(Ne.has(s.id)){B(t,409,{error:"The agent is still answering in this conversation."});return}let i=new ia(r.orphanLimitMs??18e5);Ne.set(s.id,i);let{id:l,title:d,node:p,nodeName:c,agent:m,agentName:g}=s;xn.set(l,{id:l,deviceId:a.id,title:d,agent:m,...g?{agentName:g}:{},...s.color?{color:s.color}:{}}),n.append(a.id,s.id,{role:"user",content:o,at:Date.now()}),Dl(t),t.write(bn("conversation",{id:l,title:d,node:p,nodeName:c,agent:m,agentName:g})),i.attach(t);try{let k=e.spoken===!0,b=await Il(r.daemon,{node:p,agent:m,message:o,chatId:`app:${l}`,spoken:k},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.`,vn(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??yn).open(a.id),enabled:!!r.finishAlerts?.(a.id)};r.notifyFinish&&da(h)&&r.notifyFinish(ca(a.id,s,b.status,b.text,b.error)).catch(()=>{})}finally{Ne.delete(l),xn.delete(l),i.finish()}}function ph(){let t=[];for(let[e,a]of xn){let n=Ne.get(e);n&&t.push({...a,text:n.text,startedAt:n.startedAt})}return t}function Dl(t){t.writeHead(200,{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-store","X-Accel-Buffering":"no"})}function bn(t,e){return`event: ${t}
|
|
16897
16897
|
data: ${JSON.stringify(e)}
|
|
16898
16898
|
|
|
16899
|
-
`}async function vn(t,e,a){try{let n=Qe(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(d=>d.peer===t.node);if(!l)return 0;n=Qe(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Qe(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 Qe(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 ih}from"stream";var lh=/^\/api\/app\/files\/([^/]+)$/,dh=15e3;async function Dl(t,e,a,n,r,o){let s=lh.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return Ne(e,405,{error:"GET only"});let i=o.store();if(!i)return Ne(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let d=i.getFile(r.id,l);if(!d)return Ne(e,404,{error:"no such file"});let p=await ch(d.node,o);if(!p)return Ne(e,502,{error:`${d.node} is not linked to this computer's mesh any more.`});let c=new AbortController;e.on("close",()=>c.abort());let m=setTimeout(()=>c.abort(),dh),g;try{let h=new URLSearchParams({agent:d.agent,file:d.path});g=await fetch(`${p.url}${Or}?${h}`,{method:n,headers:{...p.token?{Authorization:`Bearer ${p.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:c.signal})}catch{return Ne(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 Ne(e,u,{error:h||`The computer that made this file answered HTTP ${g.status}.`})}let k=Number(g.headers.get("content-length")||0);if(k>pe.bytes)return c.abort(),Ne(e,413,{error:"the file is too large"});let b=g.headers.get("content-range");if(e.writeHead(g.status,{...Nr(d.mime,d.name,d.kind),...g.headers.get("content-length")?{"Content-Length":String(k)}:{},...g.status===206&&b?{"Content-Range":b}:{}}),n==="HEAD"||!g.body)return e.end(),!0;let S=0,T=ih.fromWeb(g.body);return T.on("data",h=>{S+=h.length,S>pe.bytes&&(T.destroy(),e.destroy())}),T.on("error",()=>e.destroy()),T.pipe(e),!0}async function ch(t,e){if(t==="local")return{url:Nl(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=Nl(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function Nl(t){return t.replace(/\/+$/,"")}function Ne(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 Bl=8e3;async function ql(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(!Gr(g))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let k=Wr(t.headers["x-audio-duration-ms"]);if(k)return t.resume(),Y(e,k.status,{error:k.error});let b=await Ce(t,Ur.bytes);if(!b)return Y(e,413,{error:Xr()});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 Ce(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 d=l.get(r.id,String(s?.conversationId??""));if(!d)return Y(e,404,{error:"no such conversation"});let p=typeof s?.text=="string"?s.text.slice(0,Bl):"";if(!p.trim())return Y(e,400,{error:"text is required"});if(!uh(d.messages,p))return Y(e,404,{error:"no such answer in this conversation"});let c=s?.announce===!0?`${d.agentName||d.agent}: ${p}`:p,m={agent:d.agent,text:c,...d.node!=="local"?{peer:d.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(ph(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 ph(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function uh(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===Bl&&a.content.startsWith(e)))}var mh=new Set(["ring","offer","answer","ice","hangup"]),Ze=/^[A-Za-z0-9_-]{4,64}$/,fh=128*1024,hh=24,gh=2*1024*1024,De=new Map;async function Fl(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 d=await l.json(),p=rt(r.nodeName),c=(Array.isArray(d.peers)?d.peers:[]).filter(g=>rt(String(g?.name??""))!==p),m=(Array.isArray(d.agents)?d.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:d.iceServers??[],peers:c,agents:m,camera:d.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 Ce(t,fh);if(!l)return M(e,413,{error:"signal too large"});let d;try{d=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let p=bh(d,r.nodeName);if(typeof p=="string")return M(e,400,{error:p});let c=Ul(p.to);if(c&&p.kind==="ring"){let m=await He(o,s,"POST","/webrtc/camera/watch",{callId:p.callId,agentId:c});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(p),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 Ze.test(l)?vh(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 Ce(t,4096);if(!l)return M(e,413,{error:"note too long"});let d;try{d=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let p=String(d?.callId??"");if(!Ze.test(p))return M(e,400,{error:"callId is required"});let c=typeof d?.note=="string"?d.note:"",m=await He(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(p)}/look`,{note:c},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 zl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let d=String(l.callId??"");if(!Ze.test(d))return M(e,400,{error:"callId is required"});let p=Number(l.seconds??0);if(!Number.isFinite(p)||p<0)return M(e,400,{error:"seconds must be 0 or more"});let c=typeof l.note=="string"?l.note:"",m=await He(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/stream`,{seconds:p,note:c});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 zl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let d=String(l.callId??"");if(!Ze.test(d))return M(e,400,{error:"callId is required"});let p=await He(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(d)}`);if(p.status>=300)return M(e,p.status,{error:p.body.error});let c=(Array.isArray(p.body.watch?.replies)?p.body.watch.replies:[]).find(b=>b&&b.at===l.at);if(!c||typeof c.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(p.body.watch.agentId??""),g=JSON.stringify([d,c.at,m,c.text]),k=De.get(g);return k?(De.delete(g),De.set(g,k),Wl(e,k.type,k.bytes)):xh(e,o,s,{agent:m,text:c.text},(b,S)=>{if(!(S.length>gh))for(De.set(g,{type:b,bytes:S});De.size>hh;)De.delete(De.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await He(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let d=(Array.isArray(l.body.calls)?l.body.calls:[]).map(p=>({id:p.id,agentId:p.agentId,reason:p.reason,createdAt:p.createdAt}));return M(e,200,{asks:d,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 He(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(!Ze.test(l))return M(e,400,{error:"callId is required"});let d=await He(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,d.status,d.status<300?{watch:d.body.watch}:{error:d.body.error})}return M(e,404,{error:"not found"})}function Ul(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function He(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 zl(t,e){let a=await Ce(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 xh(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 bh(t,e){let a=String(t?.kind??"");if(!mh.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!Ze.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:")&&!Ul(r))return"to must be bot:<agent id> for an agent";if(rt(r)===rt(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 vh(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 yh,readFileSync as wh,renameSync as kh,writeFileSync as _h}from"fs";import{dirname as Sh,isAbsolute as Eh,resolve as Th}from"path";import{randomBytes as Ah}from"crypto";var Gl=60,Xl=500,Ch=200,Vl=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,Ih=/^[A-Za-z0-9_-]{8,64}$/,Mh=/^[A-Za-z0-9._-]{1,64}$/;function Yl(t,e){return Eh(e)?e:Th(t,e)}function Kl(t){return`${t}_${Ah(6).toString("hex")}`}function Jl(){return{places:[],rules:[],seen:[]}}function Ql(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>Gl)return{ok:!1,error:`Keep the name under ${Gl} 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 Zl(t,e){let a=typeof t.placeId=="string"?t.placeId:"";if(!Vl.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>Xl)return{ok:!1,error:`Keep it under ${Xl} characters.`};let o=typeof t.agent=="string"?t.agent.trim():"";return o&&(!Mh.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 ed(t){let e=typeof t.id=="string"?t.id:"";if(!Ih.test(e))return{ok:!1,error:"id must be 8 to 64 letters, digits, - or _"};let a=typeof t.place=="string"?t.place:"";if(!Vl.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 pa=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse(wh(this.path,"utf-8"));return!e||typeof e!="object"?Jl():{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 Jl()}}write(e){yh(Sh(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;_h(a,JSON.stringify(e,null,2)+`
|
|
16900
|
-
`,{mode:384}),
|
|
16901
|
-
`)}async function
|
|
16899
|
+
`}async function vn(t,e,a){try{let n=Ze(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(d=>d.peer===t.node);if(!l)return 0;n=Ze(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Ze(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 Ze(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 uh}from"stream";var mh=/^\/api\/app\/files\/([^/]+)$/,fh=15e3;async function Bl(t,e,a,n,r,o){let s=mh.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return De(e,405,{error:"GET only"});let i=o.store();if(!i)return De(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let d=i.getFile(r.id,l);if(!d)return De(e,404,{error:"no such file"});let p=await hh(d.node,o);if(!p)return De(e,502,{error:`${d.node} is not linked to this computer's mesh any more.`});let c=new AbortController;e.on("close",()=>c.abort());let m=setTimeout(()=>c.abort(),fh),g;try{let h=new URLSearchParams({agent:d.agent,file:d.path});g=await fetch(`${p.url}${Dr}?${h}`,{method:n,headers:{...p.token?{Authorization:`Bearer ${p.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:c.signal})}catch{return De(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 De(e,u,{error:h||`The computer that made this file answered HTTP ${g.status}.`})}let k=Number(g.headers.get("content-length")||0);if(k>pe.bytes)return c.abort(),De(e,413,{error:"the file is too large"});let b=g.headers.get("content-range");if(e.writeHead(g.status,{...Hr(d.mime,d.name,d.kind),...g.headers.get("content-length")?{"Content-Length":String(k)}:{},...g.status===206&&b?{"Content-Range":b}:{}}),n==="HEAD"||!g.body)return e.end(),!0;let S=0,T=uh.fromWeb(g.body);return T.on("data",h=>{S+=h.length,S>pe.bytes&&(T.destroy(),e.destroy())}),T.on("error",()=>e.destroy()),T.pipe(e),!0}async function hh(t,e){if(t==="local")return{url:Hl(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=Hl(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function Hl(t){return t.replace(/\/+$/,"")}function De(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 zl=8e3;async function Fl(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(!Kr(g))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let k=Xr(t.headers["x-audio-duration-ms"]);if(k)return t.resume(),Y(e,k.status,{error:k.error});let b=await Ie(t,Gr.bytes);if(!b)return Y(e,413,{error:Jr()});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 ql(e,o.daemon,"/voice/transcribe",b,S,18e4)}let s,i=await Ie(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 d=l.get(r.id,String(s?.conversationId??""));if(!d)return Y(e,404,{error:"no such conversation"});let p=typeof s?.text=="string"?s.text.slice(0,zl):"";if(!p.trim())return Y(e,400,{error:"text is required"});if(!xh(d.messages,p))return Y(e,404,{error:"no such answer in this conversation"});let c=s?.announce===!0?`${d.agentName||d.agent}: ${p}`:p,m={agent:d.agent,text:c,...d.node!=="local"?{peer:d.node}:{}};return ql(e,o.daemon,"/voice/speak",Buffer.from(JSON.stringify(m)),{"Content-Type":"application/json"},9e4)}async function ql(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(gh(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 gh(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function xh(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===zl&&a.content.startsWith(e)))}var bh=new Set(["ring","offer","answer","ice","hangup"]),et=/^[A-Za-z0-9_-]{4,64}$/,vh=128*1024,yh=24,wh=2*1024*1024,He=new Map;async function Wl(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 d=await l.json(),p=rt(r.nodeName),c=(Array.isArray(d.peers)?d.peers:[]).filter(g=>rt(String(g?.name??""))!==p),m=(Array.isArray(d.agents)?d.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:d.iceServers??[],peers:c,agents:m,camera:d.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 Ie(t,vh);if(!l)return M(e,413,{error:"signal too large"});let d;try{d=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let p=_h(d,r.nodeName);if(typeof p=="string")return M(e,400,{error:p});let c=Gl(p.to);if(c&&p.kind==="ring"){let m=await Be(o,s,"POST","/webrtc/camera/watch",{callId:p.callId,agentId:c});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(p),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 et.test(l)?Sh(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 Ie(t,4096);if(!l)return M(e,413,{error:"note too long"});let d;try{d=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let p=String(d?.callId??"");if(!et.test(p))return M(e,400,{error:"callId is required"});let c=typeof d?.note=="string"?d.note:"",m=await Be(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(p)}/look`,{note:c},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 Ul(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let d=String(l.callId??"");if(!et.test(d))return M(e,400,{error:"callId is required"});let p=Number(l.seconds??0);if(!Number.isFinite(p)||p<0)return M(e,400,{error:"seconds must be 0 or more"});let c=typeof l.note=="string"?l.note:"",m=await Be(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/stream`,{seconds:p,note:c});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 Ul(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let d=String(l.callId??"");if(!et.test(d))return M(e,400,{error:"callId is required"});let p=await Be(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(d)}`);if(p.status>=300)return M(e,p.status,{error:p.body.error});let c=(Array.isArray(p.body.watch?.replies)?p.body.watch.replies:[]).find(b=>b&&b.at===l.at);if(!c||typeof c.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(p.body.watch.agentId??""),g=JSON.stringify([d,c.at,m,c.text]),k=He.get(g);return k?(He.delete(g),He.set(g,k),Xl(e,k.type,k.bytes)):kh(e,o,s,{agent:m,text:c.text},(b,S)=>{if(!(S.length>wh))for(He.set(g,{type:b,bytes:S});He.size>yh;)He.delete(He.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await Be(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let d=(Array.isArray(l.body.calls)?l.body.calls:[]).map(p=>({id:p.id,agentId:p.agentId,reason:p.reason,createdAt:p.createdAt}));return M(e,200,{asks:d,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 Be(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(!et.test(l))return M(e,400,{error:"callId is required"});let d=await Be(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,d.status,d.status<300?{watch:d.body.watch}:{error:d.body.error})}return M(e,404,{error:"not found"})}function Gl(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function Be(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 Ul(t,e){let a=await Ie(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 kh(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),Xl(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 Xl(t,e,a){return t.writeHead(200,{"Content-Type":e,"Content-Length":String(a.length),"Cache-Control":"no-store"}),t.end(a),!0}function _h(t,e){let a=String(t?.kind??"");if(!bh.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!et.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:")&&!Gl(r))return"to must be bot:<agent id> for an agent";if(rt(r)===rt(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 Sh(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 Eh,readFileSync as Th,renameSync as Ah,writeFileSync as Ch}from"fs";import{dirname as Ih,isAbsolute as Mh,resolve as Rh}from"path";import{randomBytes as Lh}from"crypto";var Kl=60,Jl=500,Ph=200,Ql=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,$h=/^[A-Za-z0-9_-]{8,64}$/,jh=/^[A-Za-z0-9._-]{1,64}$/;function Zl(t,e){return Mh(e)?e:Rh(t,e)}function Vl(t){return`${t}_${Lh(6).toString("hex")}`}function Yl(){return{places:[],rules:[],seen:[]}}function ed(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 td(t,e){let a=typeof t.placeId=="string"?t.placeId:"";if(!Ql.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>Jl)return{ok:!1,error:`Keep it under ${Jl} characters.`};let o=typeof t.agent=="string"?t.agent.trim():"";return o&&(!jh.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 ad(t){let e=typeof t.id=="string"?t.id:"";if(!$h.test(e))return{ok:!1,error:"id must be 8 to 64 letters, digits, - or _"};let a=typeof t.place=="string"?t.place:"";if(!Ql.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 pa=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse(Th(this.path,"utf-8"));return!e||typeof e!="object"?Yl():{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 Yl()}}write(e){Eh(Ih(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;Ch(a,JSON.stringify(e,null,2)+`
|
|
16900
|
+
`,{mode:384}),Ah(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:Vl("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:Vl("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(-Ph);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(d=>d.placeId===o.id&&d.on===e.transition&&d.enabled&&!(d.lastFiredAt&&Date.parse(d.lastFiredAt)>r-i));for(let d of l)d.lastFiredAt=new Date(r).toISOString(),d.repeat||(d.enabled=!1);s=l.length?{status:"fired",place:o,rules:l.map(d=>({...d}))}:{status:"no-rules"}}return this.write(n),s}};Jn();function Oh(t,e){return e==="enter"?`Arrived at ${t.name}`:`Left ${t.name}`}function Nh(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(`
|
|
16901
|
+
`)}async function nd(t,e,a,n,r){await Promise.all(a.map(async o=>{let s=Oh(e,o.on),i=o.text;if(o.agent)try{i=(await r.task(o.agent,Nh(e,o,n),o.id)).trim()||`${o.agent} had nothing to add.`}catch(l){i=`${o.text}
|
|
16902
16902
|
|
|
16903
|
-
(${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
|
|
16904
|
-
${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?{[Kn]: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
|
|
16903
|
+
(${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 rd(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}
|
|
16904
|
+
${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?{[Kn]: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 od(t,e,a,n,r,o){return a!=="/api/app/places"&&!a.startsWith("/api/app/places/")?!1:id(t,e,a.slice(15),n,o,r)}async function sd(t,e,a,n,r){return a!=="/api/places"&&!a.startsWith("/api/places/")?!1:id(t,e,a.slice(11),n,r,null)}async function id(t,e,a,n,r,o){if(n==="GET"&&a===""){let i=r.enabled?r.store.read():{places:[],rules:[]};return q(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 q(e,404,{error:"not found"});if(!r.enabled)return q(e,403,{error:"Place reminders are off on this computer (app.places.enabled)."});let s;try{s=await Fe(t,4096)}catch(i){return q(e,400,{error:i.message})}if(a==="/event"){if(!o)return q(e,404,{error:"not found"});let i=ad(s);if(!i.ok)return q(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?nd(o.id,l.place,l.rules,i.value.time,r.fire).catch(d=>r.log(`[places] delivery failed: ${d?.message||d}`)):r.log(`[places] ${l.rules.length} reminder(s) not sent: ${r.pushReason??"this computer doesn't send pushes"}`)),q(e,202,{ok:!0,status:l.status,fired:l.status==="fired"?l.rules.length:0})}if(a==="/add"){let i=ed(s,r.limits);if(!i.ok)return q(e,400,{error:i.error});let l=r.store.addPlace(i.value,r.limits);return l.ok?q(e,200,{ok:!0,place:l.place}):q(e,409,{error:l.error})}if(a==="/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removePlace(i)?q(e,200,{ok:!0}):q(e,404,{error:"No such place."})}if(a==="/rules/add"){let i=new Set(r.agents()),l=td(s,p=>i.has(p));if(!l.ok)return q(e,400,{error:l.error});let d=r.store.addRule(l.value,r.limits);return d.ok?q(e,200,{ok:!0,rule:d.rule}):q(e,409,{error:d.error})}if(a==="/rules/enable"){if(typeof s.enabled!="boolean")return q(e,400,{error:"enabled must be true or false"});let i=r.store.setRuleEnabled(typeof s.id=="string"?s.id:"",s.enabled);return i?q(e,200,{ok:!0,rule:i}):q(e,404,{error:"No such reminder."})}if(a==="/rules/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removeRule(i)?q(e,200,{ok:!0}):q(e,404,{error:"No such reminder."})}return q(e,404,{error:"not found"})}function ld(t,e,a,n){let r=t.app.places;return{enabled:r.enabled,limits:r,syncMinutes:r.syncMinutes,store:new pa(Zl(e,r.file)),agents:()=>Object.keys(t.agents||{}).sort(),fire:a,pushReason:n,androidPackage:t.app.android.packageName,log:o=>console.error(o)}}function dd(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 q(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var cd=`
|
|
16905
16905
|
:root {
|
|
16906
16906
|
--ax-bg: #fff; --ax-surface: #fff; --ax-surface-2: #f4f5f7; --ax-surface-3: #f6f7f9;
|
|
16907
16907
|
--ax-text: #0b0d10; --ax-text-2: #5a616c; --ax-border: #e5e7eb;
|
|
@@ -16915,7 +16915,7 @@ ${s}`,buttons:[{label:"Open",url:"/app#alerts"}]}),signal:AbortSignal.timeout(15
|
|
|
16915
16915
|
--ax-accent: #6aa0ff; --ax-accent-2: #6aa0ff; --ax-accent-t: #1c2b47;
|
|
16916
16916
|
--phone-bubble: #1d2f52; --phone-green: #3dbe74;
|
|
16917
16917
|
}
|
|
16918
|
-
`,
|
|
16918
|
+
`,pd=`
|
|
16919
16919
|
[hidden] { display: none !important; }
|
|
16920
16920
|
main > .sw-peek[hidden] { display: block !important; }
|
|
16921
16921
|
main > #panel-chat.sw-peek[hidden] { display: flex !important; }
|
|
@@ -17021,7 +17021,7 @@ main > #panel-chat.sw-peek { height: 100%; padding-top: 8px; }
|
|
|
17021
17021
|
@media (max-width: 360px) { #cam-btn span { display: none; } .bar { padding-left: 12px; } .bar-btns { gap: 4px; } .vx-row { gap: 24px; } }
|
|
17022
17022
|
@media (max-height: 540px) { .vx { gap: 4px; padding-top: 4px; } .cx-top { padding-bottom: 4px; } }
|
|
17023
17023
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; animation: none !important; } }
|
|
17024
|
-
`;var
|
|
17024
|
+
`;var ud=`
|
|
17025
17025
|
window.AXSheet = function (sheet, onClose) {
|
|
17026
17026
|
var handle = document.createElement('button');
|
|
17027
17027
|
handle.type = 'button'; handle.className = 'sheet-handle';
|
|
@@ -17050,7 +17050,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
17050
17050
|
handle.addEventListener('pointercancel', reset);
|
|
17051
17051
|
sheet.addEventListener('close', function () { reset(); if (onClose) onClose(); });
|
|
17052
17052
|
};
|
|
17053
|
-
`;var
|
|
17053
|
+
`;var md=`
|
|
17054
17054
|
(function () {
|
|
17055
17055
|
var fleetPanel = document.getElementById('panel-fleet');
|
|
17056
17056
|
var activityPanel = document.getElementById('panel-activity');
|
|
@@ -17346,7 +17346,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
17346
17346
|
setInterval(refresh, 15000);
|
|
17347
17347
|
refresh();
|
|
17348
17348
|
})();
|
|
17349
|
-
`;var
|
|
17349
|
+
`;var fd=`
|
|
17350
17350
|
.fx-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
17351
17351
|
.fx-head h2 { margin: 4px 0 0; }
|
|
17352
17352
|
.fx-sub { font-size: 15px; margin: 18px 0 8px; color: var(--ax-text-2); }
|
|
@@ -17411,7 +17411,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17411
17411
|
.fx-opt em { font-style: normal; font-size: 12px; color: var(--ax-ok); white-space: nowrap; }
|
|
17412
17412
|
.fx-error:empty { display: none; }
|
|
17413
17413
|
.fx-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
|
|
17414
|
-
`;var
|
|
17414
|
+
`;var hd=`
|
|
17415
17415
|
(function () {
|
|
17416
17416
|
var panel = document.getElementById('panel-desk');
|
|
17417
17417
|
var ax = window.AXAsk;
|
|
@@ -17545,7 +17545,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17545
17545
|
setInterval(refresh, 15000);
|
|
17546
17546
|
refresh();
|
|
17547
17547
|
})();
|
|
17548
|
-
`;var
|
|
17548
|
+
`;var gd=`
|
|
17549
17549
|
.dk-figures { margin: 0 0 4px; line-height: 1.5; }
|
|
17550
17550
|
.dk-cols {
|
|
17551
17551
|
position: sticky; top: 0; z-index: 1; display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px;
|
|
@@ -17562,7 +17562,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17562
17562
|
.dk-opt { width: 100%; min-height: 48px; padding: 8px 14px; text-align: left; border-radius: var(--ax-radius-sm); overflow-wrap: anywhere; }
|
|
17563
17563
|
.dk-opt small { display: block; margin-top: 2px; font-weight: 400; color: var(--ax-text-2); }
|
|
17564
17564
|
.dk-opt em { font-style: normal; font-weight: 400; color: var(--ax-text-2); }
|
|
17565
|
-
`;var
|
|
17565
|
+
`;var xd=`
|
|
17566
17566
|
(function () {
|
|
17567
17567
|
var panel = document.getElementById('panel-alerts');
|
|
17568
17568
|
if (!panel) return;
|
|
@@ -17719,6 +17719,11 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17719
17719
|
var read = [], recent = [];
|
|
17720
17720
|
try { var saved = JSON.parse(localStorage.getItem('ax-alerts-read') || '[]'); if (Array.isArray(saved)) read = saved.slice(-200); } catch (e) {}
|
|
17721
17721
|
function key(it) { return String(it.id) + ':' + String(it.at); }
|
|
17722
|
+
// The computer learns what was read, so it knows the owner saw it (#1138 step B).
|
|
17723
|
+
// A mark that does not get there costs nothing: the list still shows it read.
|
|
17724
|
+
function tellRead(ids) {
|
|
17725
|
+
if (ids.length) api('POST', '/api/app/alerts/read', { ids: ids }).catch(function () { return null; });
|
|
17726
|
+
}
|
|
17722
17727
|
function saveRead() { read = read.slice(-200); try { localStorage.setItem('ax-alerts-read', JSON.stringify(read)); } catch (e) {} }
|
|
17723
17728
|
function paintRecent() {
|
|
17724
17729
|
var unread = recent.filter(function (it) { return read.indexOf(key(it)) < 0; }).length;
|
|
@@ -17742,7 +17747,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17742
17747
|
if (!row) return;
|
|
17743
17748
|
var it = recent[+row.getAttribute('data-alert')];
|
|
17744
17749
|
if (!it || read.indexOf(key(it)) >= 0) return;
|
|
17745
|
-
read.push(key(it)); saveRead();
|
|
17750
|
+
read.push(key(it)); saveRead(); tellRead([it.id]);
|
|
17746
17751
|
// Do not replace a focused button or interrupt a link's default action.
|
|
17747
17752
|
row.classList.remove('al-unread');
|
|
17748
17753
|
row.querySelector('button').setAttribute('aria-label', it.title + ', read');
|
|
@@ -17753,8 +17758,9 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17753
17758
|
document.getElementById('al-read-all').disabled = !unread;
|
|
17754
17759
|
});
|
|
17755
17760
|
document.getElementById('al-read-all').addEventListener('click', function () {
|
|
17756
|
-
|
|
17757
|
-
|
|
17761
|
+
var ids = [];
|
|
17762
|
+
recent.forEach(function (it) { if (read.indexOf(key(it)) < 0) { read.push(key(it)); ids.push(it.id); } });
|
|
17763
|
+
saveRead(); paintRecent(); tellRead(ids);
|
|
17758
17764
|
});
|
|
17759
17765
|
function loadRecent() {
|
|
17760
17766
|
return api('GET', '/api/app/alerts').then(function (b) {
|
|
@@ -17773,7 +17779,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17773
17779
|
refresh();
|
|
17774
17780
|
loadRecent();
|
|
17775
17781
|
})();
|
|
17776
|
-
`;var
|
|
17782
|
+
`;var bd=`
|
|
17777
17783
|
(function () {
|
|
17778
17784
|
var panel = document.getElementById('panel-alerts');
|
|
17779
17785
|
if (!panel) return;
|
|
@@ -17925,7 +17931,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17925
17931
|
document.addEventListener('visibilitychange', function () { if (!document.hidden && state) load(); });
|
|
17926
17932
|
load();
|
|
17927
17933
|
})();
|
|
17928
|
-
`,
|
|
17934
|
+
`,vd=`
|
|
17929
17935
|
.pl-card { margin-top: 12px; }
|
|
17930
17936
|
.pl-list { margin-top: 8px; }
|
|
17931
17937
|
.pl-rules { list-style: none; margin: 6px 0 0; padding: 0; }
|
|
@@ -17944,7 +17950,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17944
17950
|
.pl-check { display: flex; align-items: center; gap: 8px; font-size: var(--ax-fs-sm); }
|
|
17945
17951
|
.pl-check input { width: 20px; height: 20px; }
|
|
17946
17952
|
#pl-here { justify-self: start; }
|
|
17947
|
-
`;function
|
|
17953
|
+
`;function yd(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 wd='<nav id="pin-bar" class="pin-bar" aria-label="Pinned pages" hidden></nav>',kd=`
|
|
17948
17954
|
(function () {
|
|
17949
17955
|
var bar = document.getElementById('pin-bar');
|
|
17950
17956
|
var panel = document.getElementById('panel-alerts');
|
|
@@ -18069,7 +18075,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
18069
18075
|
document.addEventListener('visibilitychange', function () { if (!document.hidden) load(); });
|
|
18070
18076
|
load();
|
|
18071
18077
|
})();
|
|
18072
|
-
`,
|
|
18078
|
+
`,_d=`
|
|
18073
18079
|
.pin-bar {
|
|
18074
18080
|
display: flex; gap: 8px; overflow-x: auto; flex: none;
|
|
18075
18081
|
padding: 4px calc(12px + env(safe-area-inset-right)) 8px calc(16px + env(safe-area-inset-left));
|
|
@@ -18099,7 +18105,7 @@ body:has(#tab-chat[aria-selected=false]) > .pin-bar { display: none; }
|
|
|
18099
18105
|
width: 100%; box-sizing: border-box; min-height: 44px; padding: 8px 10px; font: inherit;
|
|
18100
18106
|
border: var(--ax-border-w) solid var(--ax-border); border-radius: var(--ax-radius-sm); background: var(--ax-surface-2); color: var(--ax-text);
|
|
18101
18107
|
}
|
|
18102
|
-
`;var
|
|
18108
|
+
`;var Sd=`
|
|
18103
18109
|
(function () {
|
|
18104
18110
|
var panel = document.getElementById('panel-alerts');
|
|
18105
18111
|
if (!panel) return;
|
|
@@ -18212,7 +18218,7 @@ body:has(#tab-chat[aria-selected=false]) > .pin-bar { display: none; }
|
|
|
18212
18218
|
}
|
|
18213
18219
|
load();
|
|
18214
18220
|
})();
|
|
18215
|
-
`;var
|
|
18221
|
+
`;var Ed=`
|
|
18216
18222
|
(function () {
|
|
18217
18223
|
var panel = document.getElementById('panel-chat');
|
|
18218
18224
|
var V = window.AXChatView;
|
|
@@ -18495,7 +18501,7 @@ body:has(#tab-chat[aria-selected=false]) > .pin-bar { display: none; }
|
|
|
18495
18501
|
var last = recall('ax-chat-conv');
|
|
18496
18502
|
if (!fromHash() && last) openConversation(last);
|
|
18497
18503
|
})();
|
|
18498
|
-
`;var
|
|
18504
|
+
`;var Td=`
|
|
18499
18505
|
window.AXChatView = (function () {
|
|
18500
18506
|
var NL = String.fromCharCode(10), TAB = String.fromCharCode(9), FENCE = String.fromCharCode(96, 96, 96);
|
|
18501
18507
|
// Cut a half-written agentx:ui block from a streaming reply so its raw
|
|
@@ -18776,7 +18782,7 @@ window.AXChatView = (function () {
|
|
|
18776
18782
|
openViewer: openViewer, closeViewer: closeViewer, readStream: readStream,
|
|
18777
18783
|
cachePut: cachePut, cacheGet: cacheGet, cacheAll: cacheAll, cacheDrop: cacheDrop };
|
|
18778
18784
|
})();
|
|
18779
|
-
`;var
|
|
18785
|
+
`;var Ad=`
|
|
18780
18786
|
window.AXChatSheets = function (o) {
|
|
18781
18787
|
var V = o.V, picker = o.picker, hist = o.hist;
|
|
18782
18788
|
function loadPicker() {
|
|
@@ -18822,7 +18828,7 @@ window.AXChatSheets = function (o) {
|
|
|
18822
18828
|
});
|
|
18823
18829
|
return { loadPicker: loadPicker, loadHistory: loadHistory };
|
|
18824
18830
|
};
|
|
18825
|
-
`;var
|
|
18831
|
+
`;var Cd=`
|
|
18826
18832
|
window.AXChatLog = function (o) {
|
|
18827
18833
|
var V = o.V, log = o.log, empty = o.empty, NOTES = o.notes;
|
|
18828
18834
|
function scrollDown() { var m = log; if (m) m.scrollTop = m.scrollHeight; }
|
|
@@ -18885,7 +18891,7 @@ window.AXChatLog = function (o) {
|
|
|
18885
18891
|
return { scrollDown: scrollDown, clear: clear, userMsg: userMsg, queuedMsg: queuedMsg, agentMsg: agentMsg, setBody: setBody,
|
|
18886
18892
|
setNote: setNote, renderUi: renderUi, renderFiles: renderFiles, renderConversation: renderConversation, flash: flash };
|
|
18887
18893
|
};
|
|
18888
|
-
`;var
|
|
18894
|
+
`;var Id=`
|
|
18889
18895
|
(function () {
|
|
18890
18896
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, V = window.AXChatView, O = window.AXOrb;
|
|
18891
18897
|
var top = panel && panel.querySelector('.cx-top');
|
|
@@ -19035,7 +19041,7 @@ window.AXChatLog = function (o) {
|
|
|
19035
19041
|
window.AXStrip = { poll: poll, update: update, banner: banner };
|
|
19036
19042
|
poll();
|
|
19037
19043
|
})();
|
|
19038
|
-
`;var
|
|
19044
|
+
`;var Md=`
|
|
19039
19045
|
.cs { margin: 0 -2px; }
|
|
19040
19046
|
.cs[hidden] { display: none; }
|
|
19041
19047
|
.cs-list {
|
|
@@ -19091,7 +19097,7 @@ window.AXChatLog = function (o) {
|
|
|
19091
19097
|
@media (prefers-reduced-motion: reduce) {
|
|
19092
19098
|
.cs-thinking .cs-dot, .cs-answering .cs-dot, .cs-banner { animation: none; }
|
|
19093
19099
|
}
|
|
19094
|
-
`;function
|
|
19100
|
+
`;function Rd(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 Ld(t,e){return e||!t.length?{item:null,queue:t.slice()}:{item:t[0],queue:t.slice(1)}}var Pd=`
|
|
19095
19101
|
body { height: 100dvh; }
|
|
19096
19102
|
main { min-height: 0; }
|
|
19097
19103
|
#panel-chat:not([hidden]) { display: flex; flex-direction: column; min-height: 100%; }
|
|
@@ -19201,7 +19207,7 @@ main { min-height: 0; }
|
|
|
19201
19207
|
background: color-mix(in oklch, var(--ax-accent) 15%, var(--ax-surface)); color: var(--ax-accent);
|
|
19202
19208
|
}
|
|
19203
19209
|
.cx-composer .fx-btn { border-radius: var(--ax-radius); }
|
|
19204
|
-
`;var
|
|
19210
|
+
`;var $d=`
|
|
19205
19211
|
window.AXOrb = (function () {
|
|
19206
19212
|
// Same list, order and hash as presenceLook (src/voice/presence.ts) and
|
|
19207
19213
|
// OrbMath.colorHex, for an agent whose colour did not come with it.
|
|
@@ -19318,7 +19324,7 @@ window.AXOrb = (function () {
|
|
|
19318
19324
|
}
|
|
19319
19325
|
return { create: create, colorFor: colorFor, levelFromRms: levelFromRms, speakingEnvelope: speakingEnvelope };
|
|
19320
19326
|
})();
|
|
19321
|
-
`;var
|
|
19327
|
+
`;var jd=`
|
|
19322
19328
|
window.AXVoiceIO = (function () {
|
|
19323
19329
|
var TYPES = ['audio/webm;codecs=opus', 'audio/mp4', 'audio/webm', 'audio/ogg;codecs=opus', 'audio/aac'];
|
|
19324
19330
|
var ac = null, playing = null;
|
|
@@ -19436,7 +19442,7 @@ window.AXVoiceIO = (function () {
|
|
|
19436
19442
|
|
|
19437
19443
|
return { canRecord: canRecord, mimeType: mimeType, unlock: unlock, record: record, playAudio: playAudio, speakText: speakText, stop: stopPlaying };
|
|
19438
19444
|
})();
|
|
19439
|
-
`;var
|
|
19445
|
+
`;var Od=`
|
|
19440
19446
|
(function () {
|
|
19441
19447
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, IO = window.AXVoiceIO, O = window.AXOrb;
|
|
19442
19448
|
if (!panel || !C || !IO || !O) return;
|
|
@@ -19649,7 +19655,7 @@ window.AXVoiceIO = (function () {
|
|
|
19649
19655
|
idle();
|
|
19650
19656
|
window.AXVoice = { show: show, orb: orb, state: function () { return v.state; }, queued: function () { return speech.length; } };
|
|
19651
19657
|
})();
|
|
19652
|
-
`;var
|
|
19658
|
+
`;var Nd=`
|
|
19653
19659
|
.vx {
|
|
19654
19660
|
position: sticky; bottom: -16px; z-index: 1; display: grid; justify-items: center; gap: 4px;
|
|
19655
19661
|
margin: 0 0 -16px; padding: 8px 0 12px; background: var(--ax-bg);
|
|
@@ -19685,7 +19691,7 @@ window.AXVoiceIO = (function () {
|
|
|
19685
19691
|
.cx-typing-on .vx-orb { width: 88px; height: 88px; }
|
|
19686
19692
|
.cx-typing-on .vx-row { gap: 16px; }
|
|
19687
19693
|
@media (prefers-reduced-motion: reduce) { .vx-orb { transition: none; } }
|
|
19688
|
-
`;var
|
|
19694
|
+
`;var Dd=`
|
|
19689
19695
|
<main class="card">
|
|
19690
19696
|
<h1>This phone isn't paired</h1>
|
|
19691
19697
|
<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>
|
|
@@ -19699,7 +19705,7 @@ window.AXVoiceIO = (function () {
|
|
|
19699
19705
|
<p id="pair-msg" class="pair-msg" role="status" aria-live="polite"></p>
|
|
19700
19706
|
</form>
|
|
19701
19707
|
<p class="muted">If this phone was paired before, it may have been removed with <code>agentx app revoke</code>.</p>
|
|
19702
|
-
</main>`,
|
|
19708
|
+
</main>`,Hd=`
|
|
19703
19709
|
.pair-form { display: grid; gap: 10px; margin: 20px 0 24px; }
|
|
19704
19710
|
.pair-form label { font-weight: 600; }
|
|
19705
19711
|
.pair-form input {
|
|
@@ -19721,7 +19727,7 @@ window.AXVoiceIO = (function () {
|
|
|
19721
19727
|
margin: 0; padding: 8px 12px; border-radius: var(--ax-radius-sm); font-size: var(--ax-fs-sm);
|
|
19722
19728
|
background: var(--ax-amber-t); color: var(--ax-amber-ink); border: 1px solid var(--ax-amber-e);
|
|
19723
19729
|
}
|
|
19724
|
-
`,
|
|
19730
|
+
`,Bd=`
|
|
19725
19731
|
(function () {
|
|
19726
19732
|
var form = document.getElementById('pair-form');
|
|
19727
19733
|
var input = document.getElementById('pair-code');
|
|
@@ -19813,7 +19819,7 @@ window.AXVoiceIO = (function () {
|
|
|
19813
19819
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
19814
19820
|
}
|
|
19815
19821
|
})();
|
|
19816
|
-
`;var
|
|
19822
|
+
`;var qd=`
|
|
19817
19823
|
<div id="scan" class="scan" role="dialog" aria-modal="true" aria-labelledby="scan-title" hidden>
|
|
19818
19824
|
<video id="scan-video" playsinline muted autoplay></video>
|
|
19819
19825
|
<div class="scan-frame" aria-hidden="true"></div>
|
|
@@ -19822,7 +19828,7 @@ window.AXVoiceIO = (function () {
|
|
|
19822
19828
|
<button type="button" id="scan-close" class="scan-close">Close</button>
|
|
19823
19829
|
</div>
|
|
19824
19830
|
<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>
|
|
19825
|
-
</div>`,
|
|
19831
|
+
</div>`,zd=`
|
|
19826
19832
|
.pair-form .scan-btn {
|
|
19827
19833
|
color: var(--ax-accent-2, var(--ax-accent)); background: transparent; border: 2px solid var(--ax-accent);
|
|
19828
19834
|
}
|
|
@@ -19851,7 +19857,7 @@ window.AXVoiceIO = (function () {
|
|
|
19851
19857
|
}
|
|
19852
19858
|
.scan-msg.bad { color: #ffd0cc; font-weight: 600; }
|
|
19853
19859
|
body.scanning { overflow: hidden; }
|
|
19854
|
-
`,
|
|
19860
|
+
`,Fd=`
|
|
19855
19861
|
(function () {
|
|
19856
19862
|
var openBtn = document.getElementById('scan-btn');
|
|
19857
19863
|
var box = document.getElementById('scan');
|
|
@@ -20076,7 +20082,7 @@ body.scanning { overflow: hidden; }
|
|
|
20076
20082
|
@keyframes cam-pulse { 50% { opacity: .3; } }
|
|
20077
20083
|
@media (prefers-reduced-motion: reduce) { .cam-live.is-stream .cam-dot { animation: none; } }
|
|
20078
20084
|
#cam-stream[aria-pressed="true"] { border-color: var(--ax-red); color: var(--ax-red-ink); }
|
|
20079
|
-
`;var
|
|
20085
|
+
`;var Ud='<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>',Wd=`
|
|
20080
20086
|
<div id="cam" class="cam" role="dialog" aria-modal="true" aria-labelledby="cam-title" hidden>
|
|
20081
20087
|
<div class="cam-live" id="cam-live" role="status" aria-live="polite" hidden>
|
|
20082
20088
|
<span class="cam-dot" aria-hidden="true"></span>
|
|
@@ -20105,7 +20111,7 @@ body.scanning { overflow: hidden; }
|
|
|
20105
20111
|
<button type="button" id="cam-close" class="cam-secondary">Close</button>
|
|
20106
20112
|
</div>
|
|
20107
20113
|
</div>
|
|
20108
|
-
</div>`,
|
|
20114
|
+
</div>`,Gd=`
|
|
20109
20115
|
(function () {
|
|
20110
20116
|
var btn = document.getElementById('cam-btn');
|
|
20111
20117
|
var sheet = document.getElementById('cam');
|
|
@@ -20579,7 +20585,7 @@ body.scanning { overflow: hidden; }
|
|
|
20579
20585
|
});
|
|
20580
20586
|
window.addEventListener('pagehide', function () { stop(); });
|
|
20581
20587
|
})();
|
|
20582
|
-
`;var
|
|
20588
|
+
`;var Xd=`
|
|
20583
20589
|
<div id="cam-ask-bar" class="cam-askbar" role="alert" hidden>
|
|
20584
20590
|
<div class="cam-askbar-text">
|
|
20585
20591
|
<strong id="cam-ask-who">An agent</strong> wants to see through your camera
|
|
@@ -20589,7 +20595,7 @@ body.scanning { overflow: hidden; }
|
|
|
20589
20595
|
<button type="button" id="cam-ask-show" class="cam-askbar-show">Show</button>
|
|
20590
20596
|
<button type="button" id="cam-ask-no" class="cam-askbar-no">Decline</button>
|
|
20591
20597
|
</div>
|
|
20592
|
-
</div>`,
|
|
20598
|
+
</div>`,Kd=`
|
|
20593
20599
|
.cam-askbar[hidden] { display: none; }
|
|
20594
20600
|
.cam-askbar {
|
|
20595
20601
|
display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
|
|
@@ -20604,7 +20610,7 @@ body.scanning { overflow: hidden; }
|
|
|
20604
20610
|
border: 2px solid #fff; background: #fff; color: var(--ax-accent);
|
|
20605
20611
|
}
|
|
20606
20612
|
.cam-askbar-no { background: transparent; color: #fff; }
|
|
20607
|
-
`,
|
|
20613
|
+
`,Jd=`
|
|
20608
20614
|
(function () {
|
|
20609
20615
|
var bar = document.getElementById('cam-ask-bar');
|
|
20610
20616
|
if (!bar) return;
|
|
@@ -20674,7 +20680,7 @@ body.scanning { overflow: hidden; }
|
|
|
20674
20680
|
setInterval(poll, 5000);
|
|
20675
20681
|
document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible') poll(); });
|
|
20676
20682
|
})();
|
|
20677
|
-
`;function
|
|
20683
|
+
`;function Vd(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 Yd(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 Qd(t){return t>=400?"send":"listen"}function Zd(t){let e=Math.max(1,Math.round(t||60));return"Keep watching "+(e%60===0?e/60+" min":e+" s")}var ec=`
|
|
20678
20684
|
(function () {
|
|
20679
20685
|
var main = document.querySelector('main');
|
|
20680
20686
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
@@ -20793,7 +20799,7 @@ body.scanning { overflow: hidden; }
|
|
|
20793
20799
|
main.addEventListener('touchend', function () { end(false); });
|
|
20794
20800
|
main.addEventListener('touchcancel', function () { end(true); });
|
|
20795
20801
|
})();
|
|
20796
|
-
`,
|
|
20802
|
+
`,tc=`
|
|
20797
20803
|
main { position: relative; }
|
|
20798
20804
|
main.sw-on { overflow: hidden; }
|
|
20799
20805
|
.sw-on > [role=tabpanel] { will-change: transform; }
|
|
@@ -20804,8 +20810,8 @@ main > .sw-peek {
|
|
|
20804
20810
|
}
|
|
20805
20811
|
main > #panel-chat.sw-peek { display: flex; flex-direction: column; }
|
|
20806
20812
|
@media (prefers-reduced-motion: reduce) { .sw-slide > [role=tabpanel] { transition: none; } }
|
|
20807
|
-
`;function
|
|
20808
|
-
${z({afterUnauthorized:
|
|
20813
|
+
`;function ac(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 nc(t,e){let a=Math.abs(t),n=Math.abs(e);return a<10&&n<10?"":a>n*1.5?"x":"y"}function rc(t,e,a){return a>0&&t===0||a<0&&t===e-1?a/4:a}function oc(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 kn=`
|
|
20814
|
+
${z({afterUnauthorized:ns})}
|
|
20809
20815
|
var CACHE = 'agentx-app-v3';
|
|
20810
20816
|
var STATIC = ['/app/manifest.webmanifest', '/app/icon-192.png', '/app/icon-512.png'];
|
|
20811
20817
|
self.addEventListener('install', function (e) {
|
|
@@ -20896,7 +20902,7 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20896
20902
|
return self.clients.openWindow(target);
|
|
20897
20903
|
}));
|
|
20898
20904
|
});
|
|
20899
|
-
`;var
|
|
20905
|
+
`;var Dh="<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 _n(t){return`<meta charset="utf-8">
|
|
20900
20906
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
20901
20907
|
<meta name="theme-color" content="#2979FF">
|
|
20902
20908
|
<meta name="referrer" content="no-referrer">
|
|
@@ -20907,43 +20913,43 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20907
20913
|
<link rel="icon" type="image/png" href="/app/icon-192.png">
|
|
20908
20914
|
<link rel="apple-touch-icon" href="/app/icon-192.png">
|
|
20909
20915
|
<title>${t}</title>
|
|
20910
|
-
${
|
|
20911
|
-
<style>${
|
|
20916
|
+
${Dh}
|
|
20917
|
+
<style>${We}${cd}${zh}</style>`}var Hh={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",desk:"M3 13l3-8h12l3 8v6H3zM3 13h5l1 3h6l1-3h5"},sc=[{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"},{id:"desk",label:"Desk",soon:"Loading what waits for you\u2026"}];function ic(){let t=sc.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="${Hh[a.id]}"/></svg></span><span>${a.label}</span></button>`).join(""),e=sc.map((a,n)=>`<section role="tabpanel" id="panel-${a.id}" aria-labelledby="tab-${a.id}" tabindex="0"${n===0?"":" hidden"}>
|
|
20912
20918
|
<h2>${a.label}</h2>
|
|
20913
20919
|
<p class="soon">${a.soon}</p>
|
|
20914
20920
|
</section>`).join("");return`<!doctype html>
|
|
20915
20921
|
<html lang="en">
|
|
20916
|
-
<head>${_n("AgentX")}<style>${
|
|
20922
|
+
<head>${_n("AgentX")}<style>${Fh}${fd}${gd}${Pd}${Md}${Nd}${wn}${Kd}${tc}${vd}${pd}${_d}</style></head>
|
|
20917
20923
|
<body>
|
|
20918
20924
|
<header class="bar">
|
|
20919
20925
|
<div>
|
|
20920
20926
|
<h1>AgentX</h1>
|
|
20921
20927
|
<p id="who" class="who">Connecting\u2026</p>
|
|
20922
20928
|
</div>
|
|
20923
|
-
<div class="bar-btns">${
|
|
20929
|
+
<div class="bar-btns">${Ud}<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>
|
|
20924
20930
|
</header>
|
|
20925
|
-
${
|
|
20931
|
+
${wd}
|
|
20926
20932
|
<p id="offline" class="offline" role="status" hidden>Offline. Showing the saved app; live data needs a connection.</p>
|
|
20927
|
-
${
|
|
20933
|
+
${Xd}
|
|
20928
20934
|
<main>${e}</main>
|
|
20929
20935
|
<nav class="tabs" role="tablist" aria-label="Sections">${t}</nav>
|
|
20930
|
-
${
|
|
20931
|
-
<script>${
|
|
20932
|
-
<script>${z({swipeMayStart:
|
|
20933
|
-
<script>${
|
|
20934
|
-
<script>${pd}</script>
|
|
20936
|
+
${Wd}
|
|
20937
|
+
<script>${Bh}</script>
|
|
20938
|
+
<script>${z({swipeMayStart:ac,swipeAxis:nc,swipeOffset:rc,swipeLanding:oc})}${ec}</script>
|
|
20939
|
+
<script>${ud}</script>
|
|
20935
20940
|
<script>${md}</script>
|
|
20936
20941
|
<script>${hd}</script>
|
|
20937
|
-
<script>${
|
|
20938
|
-
<script>${yd}</script>
|
|
20942
|
+
<script>${xd}</script>
|
|
20943
|
+
<script>${z({locationErrorText:yd})}${bd}</script>
|
|
20939
20944
|
<script>${kd}</script>
|
|
20940
|
-
<script>${
|
|
20941
|
-
<script>${z({
|
|
20942
|
-
<script>${
|
|
20943
|
-
<script>${
|
|
20944
|
-
<script>${
|
|
20945
|
+
<script>${Sd}</script>
|
|
20946
|
+
<script>${z({markdownToHtml:ur})}${Td}${Cd}${Ad}${Ed}</script>
|
|
20947
|
+
<script>${z({queueSpeech:Rd,nextSpeech:Ld})}${$d}${jd}${Od}</script>
|
|
20948
|
+
<script>${Id}</script>
|
|
20949
|
+
<script>${z({cameraConstraints:Vd,shareClock:Yd,streamLabel:Zd,talkRelease:Qd})}${Gd}</script>
|
|
20950
|
+
<script>${Jd}</script>
|
|
20945
20951
|
</body>
|
|
20946
|
-
</html>`}function
|
|
20952
|
+
</html>`}function lc(){return`<!doctype html>
|
|
20947
20953
|
<html lang="en">
|
|
20948
20954
|
<head>${_n("Pair \xB7 AgentX")}</head>
|
|
20949
20955
|
<body>
|
|
@@ -20951,17 +20957,17 @@ ${Fd}
|
|
|
20951
20957
|
<h1>Pairing this phone\u2026</h1>
|
|
20952
20958
|
<p id="msg" role="status">One moment.</p>
|
|
20953
20959
|
</main>
|
|
20954
|
-
<script>${
|
|
20960
|
+
<script>${qh}</script>
|
|
20955
20961
|
</body>
|
|
20956
|
-
</html>`}function
|
|
20962
|
+
</html>`}function dc(){return`<!doctype html>
|
|
20957
20963
|
<html lang="en">
|
|
20958
|
-
<head>${_n("Not paired \xB7 AgentX")}<style>${
|
|
20959
|
-
<body>${
|
|
20960
|
-
<script>${z({mayBounce:
|
|
20961
|
-
<script>${
|
|
20962
|
-
<script>${
|
|
20964
|
+
<head>${_n("Not paired \xB7 AgentX")}<style>${Hd}${zd}</style></head>
|
|
20965
|
+
<body>${Dd}${qd}
|
|
20966
|
+
<script>${z({mayBounce:rs,formatPairInput:Xt,parsePairScan:os})}</script>
|
|
20967
|
+
<script>${Bd}</script>
|
|
20968
|
+
<script>${Fd}</script>
|
|
20963
20969
|
</body>
|
|
20964
|
-
</html>`}function
|
|
20970
|
+
</html>`}function cc(){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 Bh=`
|
|
20965
20971
|
(function () {
|
|
20966
20972
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
20967
20973
|
function select(tab, focus, keepHash) {
|
|
@@ -21033,7 +21039,7 @@ ${Fd}
|
|
|
21033
21039
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
21034
21040
|
}
|
|
21035
21041
|
})();
|
|
21036
|
-
`,
|
|
21042
|
+
`,qh=`
|
|
21037
21043
|
(function () {
|
|
21038
21044
|
var msg = document.getElementById('msg');
|
|
21039
21045
|
var m = /(?:^#|&)token=([^&]+)/.exec(location.hash);
|
|
@@ -21050,7 +21056,7 @@ ${Fd}
|
|
|
21050
21056
|
: 'Pairing failed (HTTP ' + r.status + '). Try again.';
|
|
21051
21057
|
}).catch(function () { msg.textContent = 'Could not reach AgentX. Check this phone is on your tailnet, then try again.'; });
|
|
21052
21058
|
})();
|
|
21053
|
-
`,
|
|
21059
|
+
`,zh=`
|
|
21054
21060
|
html, body { margin: 0; background: var(--ax-bg); color: var(--ax-text); font-family: var(--ax-font); }
|
|
21055
21061
|
body { min-height: 100dvh; -webkit-text-size-adjust: 100%; }
|
|
21056
21062
|
code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surface-3); padding: 1px 6px; border-radius: 6px; }
|
|
@@ -21062,7 +21068,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
21062
21068
|
.card h1 { font-size: 22px; margin: 0 0 12px; }
|
|
21063
21069
|
.muted { color: var(--ax-text-2); }
|
|
21064
21070
|
:focus-visible { outline: 3px solid var(--ax-accent); outline-offset: 2px; }
|
|
21065
|
-
`,
|
|
21071
|
+
`,Fh=`
|
|
21066
21072
|
body { display: flex; flex-direction: column; }
|
|
21067
21073
|
.bar {
|
|
21068
21074
|
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
|
@@ -21100,8 +21106,8 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
21100
21106
|
}
|
|
21101
21107
|
.tabs [role=tab][aria-selected=true] { background: var(--ax-accent-t); color: var(--ax-accent-2); }
|
|
21102
21108
|
[data-theme="dark"] .tabs [role=tab][aria-selected=true] { color: var(--ax-text); }
|
|
21103
|
-
`;var ua="agentx_app",
|
|
21104
|
-
`;ct=Buffer.concat([Buffer.from(a),
|
|
21109
|
+
`;var ua="agentx_app",Gh=400*86400,Xh=new Rt,Kh=new Le;async function pc(t,e,a,n,r={}){if(a==="/.well-known/assetlinks.json"&&n==="GET"){let i=r.assetLinks?.()??null;return i?fe(e,200,"application/json",JSON.stringify(i),"public, max-age=300"):Ee(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 fe(e,200,"application/manifest+json",cc());if(a==="/app/sw.js")return e.setHeader("Service-Worker-Allowed","/app"),fe(e,200,"text/javascript; charset=utf-8",kn);if(a==="/app/icon-192.png")return fe(e,200,"image/png",Xe(192),"public, max-age=86400");if(a==="/app/icon-512.png")return fe(e,200,"image/png",Xe(512),"public, max-age=86400");if(a==="/app/pair")return fe(e,200,"text/html; charset=utf-8",lc());if(a==="/app/qr.js"){let i=Vh();return i?fe(e,200,"text/javascript; charset=utf-8",i,"public, max-age=2592000"):Ee(e,404,{error:"not found"})}}if(n==="POST"&&a==="/api/app/session"){let i=Sn(pt(t),o);return i?(e.setHeader("Set-Cookie",En(pt(t))),Ee(e,200,{device:i.name})):Ee(e,401,{error:"invalid or revoked device token"})}if(n==="POST"&&a==="/api/app/pair-code"){let i=await Or(t,{codes:r.pairCodes??new At,limiter:r.pairLimiter??Xh,verify:l=>Sn(l,o)?.name??null,minMs:r.pairMinMs});return i.status===200&&e.setHeader("Set-Cookie",En(i.token)),i.status===429&&e.setHeader("Retry-After",String(i.retryAfter)),Ee(e,i.status,i.body)}let s=Sn(Yh(t),o);if(!s){let i=pt(t);return(r.rejectLog??Kh).record(a.slice(0,120),Ut(t,Ge(Tn(t,ua),o),i?Ge(i,o):null)),a==="/app"?fe(e,401,"text/html; charset=utf-8",dc()):Ee(e,401,{error:"this device is not paired",hint:"run: agentx app pair"})}if(n==="GET"&&a==="/app"){let i=Tn(t,ua);return i&&!pt(t)&&e.setHeader("Set-Cookie",En(i)),fe(e,200,"text/html; charset=utf-8",ic())}return n==="GET"&&a==="/api/app/me"?Ee(e,200,{id:s.id,device:s.name,node:r.nodeName??null}):(r.reach?.touch("phone"),r.fleet&&await Er(t,e,a,n,s.name,r.fleet)||r.desk&&await kl(t,e,a,n,r.reach?Jh(r.desk,r.reach):r.desk)||r.push&&await Tr(t,e,a,n,s,r.push)||r.announce&&await El(t,e,a,n,s,r.announce)||r.chat&&await Ol(t,e,a,n,s,r.chat)||r.chat&&await Bl(t,e,a,n,s,r.chat)||r.voice&&await Fl(t,e,a,n,s,r.voice)||r.camera&&await Wl(t,e,a,n,r.camera)||r.places&&await od(t,e,a,n,s,r.places)||r.pins&&await mo(t,e,a,n,r.pins)?!0:Ee(e,404,{error:"not found"}))}function Jh(t,e){return{async board(){let a=await t.board();return e.deskSeen(a.cards.filter(n=>n.column!=="done").map(n=>n.key)),a},async reply(a,n){let r=await t.reply(a,n);return r.status>=200&&r.status<300&&e.deskAnswered(a),r}}}var ct;function Vh(){if(ct!==void 0)return ct;try{let t=Wh(import.meta.url),{version:e}=t("jsqr/package.json"),a=`/*! jsQR ${e} | Apache-2.0 | https://github.com/cozmo/jsQR */
|
|
21110
|
+
`;ct=Buffer.concat([Buffer.from(a),Uh(t.resolve("jsqr"))])}catch(t){console.error(`[app] QR decoder unavailable (install the jsqr package): ${t.message}`),ct=null}return ct}function Sn(t,e){if(!t)return null;let a=e.verify(t);return a&&Ae(a,"app")?a:null}function En(t){return`${ua}=${t}; Path=/; Max-Age=${Gh}; HttpOnly; Secure; SameSite=Lax`}function Yh(t){return pt(t)??Tn(t,ua)}function pt(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Tn(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 Ee(t,e,a){return fe(t,e,"application/json",JSON.stringify(a))}function uc(t){let e=null,a=()=>{let r=t.db();return r?(e?.db!==r&&(e={db:r,presence:new Mr(r),marks:new Rr(r)}),e):null},n=(r,o,s)=>{try{let i=a();return i?s(i):o}catch(i){return t.log(`[reach] ${r} not recorded: ${i?.message??i}`),o}};return{touch:r=>n(`${r} presence`,void 0,o=>o.presence.touch(r)),pushRead:r=>n("push read mark",0,o=>o.marks.seenPush(r,"phone")),deskSeen:r=>n("desk seen",void 0,o=>{o.presence.touch("desk");let s=new Set;for(let i of r)if(i.startsWith("request:"))s.add(i.slice(8));else if(i.startsWith("card:")){let l=t.requestOfCard(i.slice(5));l&&s.add(l)}o.marks.seenByRequest([...s],"desk")}),deskAnswered:r=>n("desk answer",void 0,o=>{o.marks.answeredByRequest([r],"desk")})}}function mc(t){let e=ue({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."})+`
|
|
21105
21111
|
<div class="pl-wrap">
|
|
21106
21112
|
<div id="pl-msg" class="pl-msg" role="status" aria-live="polite"></div>
|
|
21107
21113
|
<form id="pl-add" class="pl-form" autocomplete="off">
|
|
@@ -21113,7 +21119,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
21113
21119
|
<button type="submit" class="ax-btn ax-btn--primary">Add place</button>
|
|
21114
21120
|
</form>
|
|
21115
21121
|
<ol id="pl-list" class="pl-list" aria-label="Places"><li class="pl-empty">Loading\u2026</li></ol>
|
|
21116
|
-
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:
|
|
21122
|
+
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:Qh,scripts:`<script>${Zh}</script>`})}var Qh=`
|
|
21117
21123
|
.pl-wrap { max-width: 1040px; margin: 0 auto; padding: 0 24px 96px; box-sizing: border-box; }
|
|
21118
21124
|
.pl-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
21119
21125
|
.pl-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -21136,7 +21142,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
21136
21142
|
.pl-rule-form { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
21137
21143
|
.pl-rule-form input[name=text] { flex: 1 1 240px; }
|
|
21138
21144
|
.pl-btns { margin-left: auto; display: flex; gap: 8px; }
|
|
21139
|
-
`,
|
|
21145
|
+
`,Zh=`
|
|
21140
21146
|
(function () {
|
|
21141
21147
|
var list = document.getElementById('pl-list');
|
|
21142
21148
|
var msg = document.getElementById('pl-msg');
|
|
@@ -21215,7 +21221,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
21215
21221
|
});
|
|
21216
21222
|
load();
|
|
21217
21223
|
})();
|
|
21218
|
-
`;import{randomBytes as
|
|
21224
|
+
`;import{randomBytes as fc}from"crypto";var qe={content:32e3,messagesPerConversation:200,conversationsPerDevice:100,toolsPerMessage:50,filesPerMessage:pe.perMessage},eg=/^[a-f0-9]{32}$/,tg=/^c[a-z0-9]{8,32}$/,ag=/^#[0-9a-fA-F]{6}$/;function An(t){return tg.test(t)}var ut=class{constructor(e){this.db=e;e.exec(`CREATE TABLE IF NOT EXISTS app_chat_conversations (
|
|
21219
21225
|
id TEXT PRIMARY KEY, device_id TEXT NOT NULL, title TEXT NOT NULL,
|
|
21220
21226
|
node TEXT NOT NULL, node_name TEXT NOT NULL, agent TEXT NOT NULL, agent_name TEXT,
|
|
21221
21227
|
created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);
|
|
@@ -21228,39 +21234,39 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
21228
21234
|
id TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, message_id INTEGER NOT NULL,
|
|
21229
21235
|
path TEXT NOT NULL, name TEXT NOT NULL, mime TEXT NOT NULL, kind TEXT NOT NULL, created_at INTEGER NOT NULL);
|
|
21230
21236
|
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 (
|
|
21231
|
-
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return An(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)}${
|
|
21232
|
-
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,d.title,d.node,d.nodeName,d.agent,d.agentName??null,l??null,r,r,r),this.pruneDevice(e),d}get(e,a){if(!An(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(
|
|
21237
|
+
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return An(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)}${fc(4).toString("hex")}`,{color:s,...i}=a,l=s&&ag.test(s)?s:void 0,d={id:o,title:rg(n),...i,...l?{color:l}:{},createdAt:r,updatedAt:r,messages:[]};return this.db.prepare(`INSERT INTO app_chat_conversations
|
|
21238
|
+
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,d.title,d.node,d.nodeName,d.agent,d.agentName??null,l??null,r,r,r),this.pruneDevice(e),d}get(e,a){if(!An(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(ng);return{...hc(n),messages:r}}list(e,a=qe.conversationsPerDevice){return this.db.prepare(`SELECT c.*,
|
|
21233
21239
|
(SELECT COUNT(*) FROM app_chat_messages m WHERE m.conversation_id = c.id) AS n,
|
|
21234
21240
|
(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
|
|
21235
|
-
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{...
|
|
21241
|
+
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{...hc(r),messages:r.n,...o?{last:o}:{}}})}markRead(e,a,n=Date.now()){An(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,
|
|
21236
21242
|
substr(m.content, 1, 240) AS answer, m.status, m.at
|
|
21237
21243
|
FROM app_chat_conversations c
|
|
21238
21244
|
JOIN app_chat_messages m ON m.id = (SELECT MAX(id) FROM app_chat_messages WHERE conversation_id = c.id)
|
|
21239
21245
|
WHERE c.device_id = ? AND m.role = 'assistant' AND m.at > COALESCE(c.read_at, 0)
|
|
21240
|
-
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>
|
|
21246
|
+
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>qe.content?n.content.slice(0,qe.content)+`
|
|
21241
21247
|
|
|
21242
|
-
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,
|
|
21248
|
+
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,qe.toolsPerMessage),l=[];for(let m of r){if(l.length>=qe.filesPerMessage)break;let g=m.filename.trim(),k=pr(g);if(!k||!g||g.length>pe.pathChars||g.includes("\0"))continue;let b=(g.split(/[\\/]/).pop()||g).slice(0,120);l.push({id:fc(16).toString("hex"),name:b,mime:k.mime,kind:k.kind,path:g})}let d=l.map(m=>({id:m.id,name:m.name,mime:m.mime,kind:m.kind})),p=this.db.prepare(`INSERT INTO app_chat_messages (conversation_id, role, content, status, error, ui, tools, files, at)
|
|
21243
21249
|
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,d.length?JSON.stringify(d):null,n.at),c=this.db.prepare(`INSERT INTO app_chat_files (id, conversation_id, message_id, path, name, mime, kind, created_at)
|
|
21244
21250
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);for(let m of l)c.run(m.id,a,Number(p.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
|
|
21245
|
-
(SELECT id FROM app_chat_messages WHERE conversation_id = ? ORDER BY id DESC LIMIT ?)`).run(a,a,
|
|
21246
|
-
(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),d}getFile(e,a){if(!
|
|
21251
|
+
(SELECT id FROM app_chat_messages WHERE conversation_id = ? ORDER BY id DESC LIMIT ?)`).run(a,a,qe.messagesPerConversation),this.db.prepare(`DELETE FROM app_chat_files WHERE conversation_id = ? AND message_id NOT IN
|
|
21252
|
+
(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),d}getFile(e,a){if(!eg.test(a))return null;let n=this.db.prepare(`SELECT f.*, c.node, c.agent FROM app_chat_files f
|
|
21247
21253
|
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 = ?
|
|
21248
|
-
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,
|
|
21254
|
+
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,qe.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 hc(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 ng(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 rg(t){let e=t.replace(/\s+/g," ").trim();return(e.length>60?e.slice(0,59)+"\u2026":e)||"Untitled"}var og=4e3,Cn=100,sg=15,gc=t=>t.replace(/\/+$/,""),ma=class{constructor(e){this.deps=e}cursor;retry=new Map;timer;running=!1;start(e=og){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,Cn);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??sg)-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>=Cn&&n?.(`[app] warning: one poll returned ${e} delegation events, the most it reads (${Cn}); 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||gc(l)!==gc(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 d=ig(r,this.deps.now?.()??Date.now());if(a.appendOnce(s,o,`dlg:${e.node}:${r.taskId}`,d.row,d.declared)===null)return"skip";let c=d.row.status,m=!!this.deps.finishAlerts?.(s),g={status:c,attached:!1,appOpen:this.deps.presence.open(s),enabled:m};return this.deps.notifyFinish&&da(g)&&this.deps.notifyFinish(ca(s,i,c,d.row.content,d.row.error)).catch(()=>{}),"filed"}};function ig(t,e){let a=t.plain?{text:_t(t.text,!1),artifacts:[]}:kt(t.text,pe.perMessage,!1),{cleanText:n,ui:r}=Et(a.text),o=t.plain?void 0:fn(r),s=t.status==="error"?"error":"done";return{row:{role:"assistant",content:n,status:s,...s==="error"?{error:lg(n)}:{},...o?{ui:o}:{},at:e},declared:a.artifacts}}function lg(t){return t.replace(/\s+/g," ").trim().slice(0,300)}Xn();var dg=3,Mn=7,Rn=50,Ln=120,cg=280,In=600,bc=36e5,pg=24*bc;function vc(t){let e=new Set;for(let a of t)for(let n of a.runningTasks??[])n.traceId&&e.add(n.traceId);return e}function tt(t,e){let a=t.replace(/\s+/g," ").trim();return a.length>e?`${a.slice(0,e-1)}\u2026`:a}var fa=t=>new Date(t).toISOString();function ug(t,e,a){let n=e.key.slice(0,Math.max(0,e.key.indexOf(":")))||"card";return{key:e.key,kind:n,column:"yours",node:t.node,nodeName:t.nodeName,title:tt(e.title,Ln),...e.ask?{ask:tt(e.ask,In)}:{},...e.detail?{facts:tt(e.detail,cg)}:{},...e.recommend?{recommend:e.recommend}:{},...e.raisedBy?{agent:e.raisedBy}:{},...e.yes?{yes:e.yes}:{},...e.no?{no:e.no}:{},...e.choices?.length?{choices:e.choices}:{},...e.draft?{draft:e.draft}:{},...e.expires?{expires:e.expires}:{},...e.createdAt?{askedAt:e.createdAt}:{},can:{answer:!0,later:!0,reply:a&&n==="request"}}}var mg={done:"Done",declined:"Declined",dropped:"Dropped"};function fg(t,e,a){let{record:n,links:r}=e,o=fr(n,Ln),s={key:`request:${n.id}`,kind:"request",node:t.node,nodeName:t.nodeName,title:o.headline,need:o.need,...n.headline?{said:tt(o.said,In)}:{},agent:n.agentId,askedAt:fa(n.createdAt),changedAt:fa(n.stateChangedAt??n.updatedAt)};switch(n.state){case"candidate":case"needs_attention":return null;case"waiting_owner":return r.some(i=>i.kind==="card"&&a.has(`card:${i.ref}`))?null:{...s,column:"yours",...n.question?{ask:tt(n.question,In)}:{},can:{answer:!1,later:!1,reply:!0}};case"in_progress":case"waiting_other":{let i=r.some(d=>d.kind==="run"&&t.liveRuns.has(d.ref)),l=t.now-n.updatedAt<(t.quietHours??dg)*bc;return{...s,column:i||l?"agent":"quiet",...i?{live:i}:{},can:{answer:!1,later:!1,reply:!i}}}default:{let i=n.state==="done"?n.evidence:n.closeReason;return{...s,need:void 0,column:"done",changedAt:fa(n.closedAt??n.stateChangedAt??n.updatedAt),outcome:mg[n.state]??n.state,...i?{evidence:i}:{},can:{answer:!1,later:!1,reply:!1}}}}}function hg(t){return t.status==="decided"?t.verdict==="yes"?`Answered yes${t.choice?`: ${t.choice}`:""}`:"Answered no":t.status==="expired"?`No answer in time: ${t.outcome==="discard"?"discarded":t.outcome==="pause"?"paused":"kept"}`:"Closed by the agent"}function gg(t,e){return{key:`card:${e.id}`,kind:"card",column:"done",node:t.node,nodeName:t.nodeName,title:tt(e.title,Ln),ask:e.ask,agent:e.raised_by,askedAt:e.created_at,...e.decided_at?{changedAt:e.decided_at}:{},outcome:hg(e),...e.resolution?{evidence:e.resolution}:{},can:{answer:!1,later:!1,reply:!1}}}var de=t=>t&&Date.parse(t)||0,xc=(t,e)=>t.map(a=>a[e]).filter(a=>!!de(a)).sort((a,n)=>de(a)-de(n))[0];function yc(t){let e=[],a=[];for(let c of t.inbox){c.error&&a.push(`What waits on ${c.nodeName} could not be read: ${c.error}`);for(let m of c.items)e.push(ug(c,m,c.node===t.node))}let n=new Set([...e.filter(c=>c.node===t.node).map(c=>c.key),...t.deferred??[]]),r=[],o=[],s=[];for(let c of t.requests??[]){let m=fg(t,c,n);m&&{yours:e,agent:r,quiet:o,done:s}[m.column].push(m)}let i=t.now-(t.doneDays??Mn)*pg;for(let c of t.cards)c.status!=="pending"&&de(c.decided_at)>=i&&s.push(gg(t,c));r.sort((c,m)=>de(m.changedAt)-de(c.changedAt)),o.sort((c,m)=>de(c.changedAt)-de(m.changedAt)),s.sort((c,m)=>de(m.changedAt)-de(c.changedAt));let l=s.filter(c=>de(c.changedAt)>=i).slice(0,Rn),d=xc(e,"askedAt"),p=xc(o,"changedAt");return{ts:fa(t.now),cards:[...e,...r,...o,...l],figures:{yours:{count:e.length,...d?{oldest:d}:{}},agent:{count:r.length},quiet:{count:o.length,...p?{oldest:p}:{}},done:{count:l.length}},errors:a}}function ze(){let t=bt();return t&&Se(t,"dashboard"),t}function o1(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,Cg(g,t))}catch(k){console.error(` Board "${g.id}" failed to initialize: ${k.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?mt(process.cwd(),t.workflows.dir):void 0,d=new or(l?{baseDir:l}:void 0),p=new sr(l?{baseDir:l,nodeId:i}:{nodeId:i}),c=new ir(l?{baseDir:l}:void 0);qi(t),ze(),zr({business:t.business?.enabled===!0});let m=xg(async(g,k)=>{try{await Sg(g,k,{boards:a,sources:s,token:o,config:t,workflowStore:d,workflowRuns:p,workflowLayouts:c})}catch(b){w(k,500,{error:b.message||"internal error"})}});Gg(t).start(),m.listen(n,r,()=>{let g=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
|
|
21249
21255
|
Live dashboard: http://${g}:${n}
|
|
21250
21256
|
`),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
|
|
21251
21257
|
Kanban dashboard: http://${g}:${n}
|
|
21252
|
-
`),console.log(` Boards: ${a.map(k=>k.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 xg=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 bg(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(Dr(t.headers)==="foreign"&&Hr(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 As(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>st(a.config.people),members:vc(a.config.members.logRetentionDays),db:()=>tt(),linkFor:(u,f)=>Jo(u,f,{gitlab:a.config.channels.gitlab?.host})})||await dc(t,e,r,o,{nodeName:a.config.node?.name,fleet:Dn(a.config),desk:Dg(a.config),push:Nn(a.config),announce:Sl(a.config),chat:Sc(a.config),voice:qg(a.config),camera:zg(a.config),places:bc(a.config),pins:co(a.config,process.cwd()),assetLinks:()=>id(a.config)}))return;let s=o==="GET"?Go(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"&&xg.has(r)&&_o("page",r),o==="GET"&&r==="/"){let u=oo();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(un({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(pl({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(un({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Te(a.config);if(!u){w(e,503,{error:"no node available"});return}let f=await new Promise(y=>{let E="";t.on("data",x=>E+=x),t.on("end",()=>y(E)),t.on("error",()=>y(""))}),v=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:f||"{}"});e.writeHead(v.status,{"Content-Type":"application/json"}),e.end(await v.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 Te(a.config),f=o==="POST"?void 0:n.searchParams.get("node"),v=o==="POST"?await re(t):void 0,y=v?.node??f,E=y?u.find(L=>L.url===y):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({...v,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 re(t),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let v=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${v}/api/workflows/editor/chat`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await y.json().catch(()=>({error:`HTTP ${y.status}`}));w(e,y.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 Te(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(No({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Oo({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 v=xr(await Te(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let L=await Promise.all(v.map(async _=>{try{let R=await fetch(_.url+"/monitor",{headers:_.token?{Authorization:`Bearer ${_.token}`}:{},signal:u.signal});if(!R.ok)throw new Error(`HTTP ${R.status}`);return{name:_.name,url:_.url,ok:!0,data:await R.json()}}catch(R){return{name:_.name,url:_.url,ok:!1,error:R.message}}}));w(e,200,{nodes:L});return}let y=v.find(L=>L.url===n.searchParams.get("node"));if(!y){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 gr(t)):void 0,A=await fetch(y.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",...y.token?{Authorization:`Bearer ${y.token}`}:{}}});w(e,A.status,await A.json())}catch(v){w(e,502,{error:v.message})}finally{clearTimeout(f)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(sl({peers:D(a.config)}));return}if(o==="GET"&&r==="/places"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(cc({peers:D(a.config)}));return}if(o==="GET"&&r==="/guests"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(il({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(/\/+$/,""),v=o==="POST"?await re(t).catch(()=>({})):void 0,y=await fetch(`${f}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...v!==void 0?{body:JSON.stringify(v??{})}:{}});w(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.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(ul({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ml({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fl({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ro({}));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(hl({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 d=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(d){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gl({agentId:decodeURIComponent(d[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"){so(t,e);return}if(o==="POST"&&r==="/api/setup"){await io(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await lo(t,e);return}if(o==="GET"&&r==="/admin"){Ds(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){ei(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){Gs(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}ci(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 Kg(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await cn(t,e,r,v=>Tc(v,a.config));return}let f=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(f){let v=decodeURIComponent(f[1]),y=v.indexOf("::");if(y>0){let E=v.slice(0,y),x=v.slice(y+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 L=(a.config.dashboard?.daemons||[]).find(_=>(_.name||_.url)===E);if(L){let _=ft(L.url.replace(/\/+$/,""),a.config);if(_){await wc(t,e,_,`/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=ft(u,a.config);if(!f){w(e,404,{error:`unknown peer: ${u}`});return}let v=(n.search||"").replace(/[?&]peer=[^&]*/g,E=>E.startsWith("?")?"?":"");await wc(t,e,f,r+(v==="?"?"":v));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await pi(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Jg(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-KNCRQ3YO.js"),v=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",y=await u({running:v});w(e,200,y)}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(hi({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await fi(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gi({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(xi({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 Eg(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 cn(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await zi(t,e,r))return;let p=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(p){Wi(t,e,p[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 v=new G,y=f?v.verify(f):null;if(!y||!Ae(y,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await Hs(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){w(e,200,Fr()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await ti(t,e,r,n);return}if(await ni(t,e,r,{people:()=>st(a.config.people),members:vc(a.config.members.logRetentionDays),root:process.cwd(),db:()=>tt(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await Xs(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await Gi(t,e,r);return}if(r.startsWith("/api/admin/")){await Bs(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(Cs);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=Gg("web/"+u);try{let v=await Xg(f),y=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":y,"Cache-Control":E?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(v)}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 at(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",v=await at(a.config,{date:u,timezone:f});w(e,200,v)}catch(u){w(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(f,v,y,E)=>{let x=parseInt(n.searchParams.get(f)||"",10);return Number.isFinite(x)?Math.max(y,Math.min(E,x)):v};try{let f=await Te(a.config);w(e,200,await ll(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=(v,y,E,x)=>{let A=parseInt(n.searchParams.get(v)||"",10);return Number.isFinite(A)?Math.max(E,Math.min(x,A)):y};try{let v=await Te(a.config);w(e,200,await cl(v,{day:u,tzOffsetMinutes:f("tzOffset",0,-840,840),limit:f("limit",40,1,200)}))}catch(v){w(e,502,{error:v.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,v;if(r==="/api/mesh/thread"){let[y,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}v=`/analytics/thread?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[y,E]=[f.get("kind"),f.get("key")];if(!y||!E){w(e,400,{error:"kind and key required"});return}v=`/analytics/job?kind=${encodeURIComponent(y)}&key=${encodeURIComponent(E)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[y,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}v=`/analytics/conversation?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(f.get("tzOffset")||"0")}`}else{let y=f.get("task");if(!y){w(e,400,{error:"task required"});return}v=`/analytics/run/${encodeURIComponent(y)}`}try{await dl(e,await Te(a.config),u,v)}catch(y){w(e,502,{error:y.message})}return}if(o==="GET"&&r==="/api/live/stream"){Lg(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"),v=u.searchParams.get("agent"),y=u.searchParams.get("task");if(!f||!v||!y){w(e,400,{error:"node, agent, task query params required"});return}await Pg(t,e,a,f,v,y);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),v=u.searchParams.get("agent"),y=u.searchParams.get("task"),E=u.searchParams.get("limit")||"50";if(!f||!v){w(e,400,{error:"node and agent query params required"});return}await Og(e,a,f,v,y,E);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),v=u.searchParams.get("task"),y=u.searchParams.get("kind");if(!f||!v||y!=="cancel"&&y!=="followup"){w(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Ng(t,e,a,f,v,y);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 xa(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 v=await f.json();w(e,200,v)}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 re(t);try{let f=await Ug(a.config,u);w(e,200,f)}catch(f){w(e,502,{error:f.message||"draft failed"})}return}let c=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(c&&o==="POST"){let u=c[1];if(!$g(t,e,[`agent:${u}`]))return;await jg(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,zr(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 v=new G,y=f?v.verify(f):null;if(!y||!Ae(y,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Tg(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(/\/+$/,""),v=o==="POST"?JSON.stringify(await re(t)??{}):void 0,y=await fetch(`${f}${r}${n.search}`,{method:o,headers:u,...v?{body:v}:{}});w(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(u){w(e,502,{error:"daemon unreachable",message:u?.message||String(u)})}return}if(await rd(t,e,r,o,bc(a.config)))return;if(o==="POST"&&(r==="/api/signals/stop"||r==="/api/signals/resume"||r==="/api/signals/drop")){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}await xa(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 xa(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 v=[{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},E=[];t.on("close",()=>{y.flag=!0;for(let A of E)try{A.abort()}catch{}});let x=setInterval(()=>{if(!y.flag)try{e.write(`: ping
|
|
21258
|
+
`),console.log(` Boards: ${a.map(k=>k.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 _g=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 Sg(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(Br(t.headers)==="foreign"&&qr(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 Is(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>st(a.config.people),members:_c(a.config.members.logRetentionDays),db:()=>ze(),linkFor:(u,f)=>Yo(u,f,{gitlab:a.config.channels.gitlab?.host})})||await pc(t,e,r,o,{nodeName:a.config.node?.name,fleet:Dn(a.config),desk:Ug(a.config),push:Nn(a.config),announce:Tl(a.config),chat:Ic(a.config),voice:Xg(a.config),camera:Kg(a.config),places:kc(a.config),pins:uo(a.config,process.cwd()),reach:Cc(),assetLinks:()=>dd(a.config)}))return;let s=o==="GET"?Ko(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"&&_g.has(r)&&Eo("page",r),o==="GET"&&r==="/"){let u=io();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(un({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ml({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(un({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Te(a.config);if(!u){w(e,503,{error:"no node available"});return}let f=await new Promise(y=>{let E="";t.on("data",x=>E+=x),t.on("end",()=>y(E)),t.on("error",()=>y(""))}),v=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:f||"{}"});e.writeHead(v.status,{"Content-Type":"application/json"}),e.end(await v.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 Te(a.config),f=o==="POST"?void 0:n.searchParams.get("node"),v=o==="POST"?await re(t):void 0,y=v?.node??f,E=y?u.find(L=>L.url===y):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({...v,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 re(t),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let v=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${v}/api/workflows/editor/chat`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await y.json().catch(()=>({error:`HTTP ${y.status}`}));w(e,y.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 Te(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(Ho({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Do({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($o({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let u=new AbortController,f=setTimeout(()=>u.abort(),8e3);try{let v=xr(await Te(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let L=await Promise.all(v.map(async _=>{try{let R=await fetch(_.url+"/monitor",{headers:_.token?{Authorization:`Bearer ${_.token}`}:{},signal:u.signal});if(!R.ok)throw new Error(`HTTP ${R.status}`);return{name:_.name,url:_.url,ok:!0,data:await R.json()}}catch(R){return{name:_.name,url:_.url,ok:!1,error:R.message}}}));w(e,200,{nodes:L});return}let y=v.find(L=>L.url===n.searchParams.get("node"));if(!y){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 gr(t)):void 0,A=await fetch(y.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",...y.token?{Authorization:`Bearer ${y.token}`}:{}}});w(e,A.status,await A.json())}catch(v){w(e,502,{error:v.message})}finally{clearTimeout(f)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ll({peers:D(a.config)}));return}if(o==="GET"&&r==="/places"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mc({peers:D(a.config)}));return}if(o==="GET"&&r==="/guests"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(dl({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(/\/+$/,""),v=o==="POST"?await re(t).catch(()=>({})):void 0,y=await fetch(`${f}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...v!==void 0?{body:JSON.stringify(v??{})}:{}});w(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.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(fl({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(hl({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gl({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(so({}));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(xl({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 d=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(d){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(bl({agentId:decodeURIComponent(d[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"){lo(t,e);return}if(o==="POST"&&r==="/api/setup"){await co(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await po(t,e);return}if(o==="GET"&&r==="/admin"){Bs(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){ai(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}ui(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 ex(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await cn(t,e,r,v=>Rc(v,a.config));return}let f=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(f){let v=decodeURIComponent(f[1]),y=v.indexOf("::");if(y>0){let E=v.slice(0,y),x=v.slice(y+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 L=(a.config.dashboard?.daemons||[]).find(_=>(_.name||_.url)===E);if(L){let _=ft(L.url.replace(/\/+$/,""),a.config);if(_){await Ec(t,e,_,`/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=ft(u,a.config);if(!f){w(e,404,{error:`unknown peer: ${u}`});return}let v=(n.search||"").replace(/[?&]peer=[^&]*/g,E=>E.startsWith("?")?"?":"");await Ec(t,e,f,r+(v==="?"?"":v));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await mi(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await tx(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-UDZI2OMU.js"),v=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",y=await u({running:v});w(e,200,y)}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(xi({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await gi(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(bi({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(vi({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 Rg(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 zi(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await cn(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await Ui(t,e,r))return;let p=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(p){Xi(t,e,p[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 v=new G,y=f?v.verify(f):null;if(!y||!Ae(y,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await qs(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){w(e,200,Wr()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await ni(t,e,r,n);return}if(await oi(t,e,r,{people:()=>st(a.config.people),members:_c(a.config.members.logRetentionDays),root:process.cwd(),db:()=>ze(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await Js(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await Ki(t,e,r);return}if(r.startsWith("/api/admin/")){await zs(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(Ms);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=Qg("web/"+u);try{let v=await Zg(f),y=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":y,"Cache-Control":E?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(v)}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 at(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",v=await at(a.config,{date:u,timezone:f});w(e,200,v)}catch(u){w(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(f,v,y,E)=>{let x=parseInt(n.searchParams.get(f)||"",10);return Number.isFinite(x)?Math.max(y,Math.min(E,x)):v};try{let f=await Te(a.config);w(e,200,await cl(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=(v,y,E,x)=>{let A=parseInt(n.searchParams.get(v)||"",10);return Number.isFinite(A)?Math.max(E,Math.min(x,A)):y};try{let v=await Te(a.config);w(e,200,await ul(v,{day:u,tzOffsetMinutes:f("tzOffset",0,-840,840),limit:f("limit",40,1,200)}))}catch(v){w(e,502,{error:v.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,v;if(r==="/api/mesh/thread"){let[y,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}v=`/analytics/thread?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[y,E]=[f.get("kind"),f.get("key")];if(!y||!E){w(e,400,{error:"kind and key required"});return}v=`/analytics/job?kind=${encodeURIComponent(y)}&key=${encodeURIComponent(E)}&limit=${encodeURIComponent(f.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[y,E,x]=[f.get("agent"),f.get("channel"),f.get("chat")];if(!y||!E||!x){w(e,400,{error:"agent, channel, chat required"});return}v=`/analytics/conversation?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(E)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(f.get("tzOffset")||"0")}`}else{let y=f.get("task");if(!y){w(e,400,{error:"task required"});return}v=`/analytics/run/${encodeURIComponent(y)}`}try{await pl(e,await Te(a.config),u,v)}catch(y){w(e,502,{error:y.message})}return}if(o==="GET"&&r==="/api/live/stream"){Dg(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"),v=u.searchParams.get("agent"),y=u.searchParams.get("task");if(!f||!v||!y){w(e,400,{error:"node, agent, task query params required"});return}await Hg(t,e,a,f,v,y);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),v=u.searchParams.get("agent"),y=u.searchParams.get("task"),E=u.searchParams.get("limit")||"50";if(!f||!v){w(e,400,{error:"node and agent query params required"});return}await zg(e,a,f,v,y,E);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),f=u.searchParams.get("node"),v=u.searchParams.get("task"),y=u.searchParams.get("kind");if(!f||!v||y!=="cancel"&&y!=="followup"){w(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Fg(t,e,a,f,v,y);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 xa(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 v=await f.json();w(e,200,v)}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 re(t);try{let f=await Vg(a.config,u);w(e,200,f)}catch(f){w(e,502,{error:f.message||"draft failed"})}return}let c=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(c&&o==="POST"){let u=c[1];if(!Bg(t,e,[`agent:${u}`]))return;await qg(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,Ur(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 v=new G,y=f?v.verify(f):null;if(!y||!Ae(y,"dashboard:write")){w(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Lg(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(/\/+$/,""),v=o==="POST"?JSON.stringify(await re(t)??{}):void 0,y=await fetch(`${f}${r}${n.search}`,{method:o,headers:u,...v?{body:v}:{}});w(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(u){w(e,502,{error:"daemon unreachable",message:u?.message||String(u)})}return}if(await sd(t,e,r,o,kc(a.config)))return;if(o==="POST"&&(r==="/api/signals/stop"||r==="/api/signals/resume"||r==="/api/signals/drop")){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){w(e,400,{error:"node query param required"});return}await xa(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 xa(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 v=[{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},E=[];t.on("close",()=>{y.flag=!0;for(let A of E)try{A.abort()}catch{}});let x=setInterval(()=>{if(!y.flag)try{e.write(`: ping
|
|
21253
21259
|
|
|
21254
21260
|
`)}catch{}},15e3);t.on("close",()=>clearInterval(x));for(let A of v)(async()=>{let L={Accept:"text/event-stream"};A.token&&(L.Authorization=`Bearer ${A.token}`);let _=new AbortController;E.push(_);try{let R=await fetch(`${A.url.replace(/\/+$/,"")}/events${f?`?${f}`:""}`,{headers:L,signal:_.signal});if(!R.ok||!R.body)return;let j=R.body.getReader(),$=new TextDecoder,O="";for(;!y.flag;){let{done:W,value:ce}=await j.read();if(W)break;O+=$.decode(ce,{stream:!0});let Q;for(;(Q=O.indexOf(`
|
|
21255
21261
|
|
|
21256
21262
|
`))>=0;){let oe=O.slice(0,Q);if(O=O.slice(Q+2),y.flag)break;try{e.write(oe+`
|
|
21257
21263
|
|
|
21258
|
-
`)}catch{y.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=[],v=await Promise.all(u.map(async x=>{let A={};x.token&&(A.Authorization=`Bearer ${x.token}`);try{let L=await fetch(`${x.url.replace(/\/+$/,"")}/api/workflows/runs?limit=500&summary=1`,{headers:A,signal:AbortSignal.timeout(5e3)});if(!L.ok)return f.push(x.url),[];let _=await L.json();return Array.isArray(_.runs)?_.runs:[]}catch{return f.push(x.url),[]}})),y=new Map;for(let x of a.workflowRuns.list({limit:500}))y.set(x.id,x);for(let x of v)for(let A of x)y.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:cr([...y.values()],x=>E.get(x)),unreachable:f});return}if(r==="/api/workflows/required"){let u=()=>({settings:Io(),agents:Object.keys(a.config.agents??{}).sort()});if(o==="GET"){w(e,200,u());return}if(o!=="POST"){w(e,405,{error:"Method not allowed"});return}if(a.config.workflows?.editor!=="edit"){w(e,403,{error:"the workflow editor is read-only on this node (workflows.editor)"});return}let f=await re(t).catch(()=>({})),v={};if(typeof f.enabled=="boolean"&&(v.enabled=f.enabled),typeof f.exemptQuestions=="boolean"&&(v.exemptQuestions=f.exemptQuestions),typeof f.agentId=="string"&&f.agentId){if(!Object.prototype.hasOwnProperty.call(a.config.agents??{},f.agentId)){w(e,400,{error:`no agent "${f.agentId}" on this node`});return}let E=f.agentRequired;if(E!=="on"&&E!=="off"&&E!=="default"){w(e,400,{error:"agentRequired is on, off or default"});return}v.agent={id:f.agentId,value:E==="default"?null:E==="on"}}if(v.enabled===void 0&&v.exemptQuestions===void 0&&!v.agent){w(e,400,{error:"nothing to change"});return}let y=await Mo(v);if(!y.success){w(e,400,{error:y.error});return}w(e,200,{ok:!0,reloaded:!!y.reloaded,...u()});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))),v=u.searchParams.get("workflowId")||void 0,y=u.searchParams.get("summary")==="1"||u.searchParams.get("summary")==="true",E=a.workflowRuns.list({limit:f,workflowId:v}),x=`?limit=${f}${v?`&workflowId=${encodeURIComponent(v)}`:""}${y?"&summary=1":""}`,A=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map($=>({url:$.url,token:$.token}))],L=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 oe=await Q.json();return Array.isArray(oe.runs)?oe.runs:[]}finally{clearTimeout(ce)}}catch{return[]}})),_=new Map;for(let $ of E)_.set($.id,$);for(let $ of L)for(let O of $)_.set(O.id,O);let R=Array.from(_.values()).sort(($,O)=>$.updatedAt<O.updatedAt?1:-1).slice(0,f),j=y?R.map($=>wg($)):R;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 v=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(y=>({url:y.url,token:y.token}))];for(let y of v)try{let E={};y.token&&(E.Authorization=`Bearer ${y.token}`);let x=await fetch(`${y.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(/\/+$/,""),v=await fetch(`${f}/api/actions/builtin`,{headers:u}),y=await v.json().catch(()=>({error:`HTTP ${v.status}`}));w(e,v.status,y)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}let k=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(k){try{let u=await re(t).catch(()=>({})),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let v=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${v}/workflows/${encodeURIComponent(k[1])}/run`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await y.json().catch(()=>({error:`HTTP ${y.status}`}));w(e,y.status,E)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(r.startsWith("/api/workflows")&&bl(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(f,v,y)=>{if(a.token)return!0;let E=Ma(f);if(!E)return!0;let x=new G().verify(E);if(!x)return w(v,401,{error:"invalid or revoked token"}),!1;for(let A of y)if(!Ae(x,A))return w(v,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,v=decodeURIComponent(f),y=a.boards.find(_=>_.id===u);if(!y){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 re(t),A=y.columns.find(_=>_.id===x.to),L=y.columns.find(_=>_.id===x.from);if(!A){w(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await yg(E,v,L,A),Pn({actor:$n(t),action:"move",boardId:u,itemId:v,payload:{from:x.from,to:x.to}}),w(e,200,{ok:!0})}catch(_){w(e,502,{error:_.message||"transition failed"})}return}if(h){let[,u,f]=h,v=f?decodeURIComponent(f):void 0,y=a.boards.find(x=>x.id===u);if(!y){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"&&!v){let{columns:x,totals:A}=await vg(y,E,n.searchParams);w(e,200,{columns:x,totals:A});return}if(o==="GET"&&v){try{let x=typeof E.getItem=="function"?await E.getItem(v):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"&&v){let x=await re(t);try{let A=typeof E.updateItem=="function"?await E.updateItem(v,x):null;if(!A){w(e,501,{error:"update unsupported"});return}Pn({actor:$n(t),action:"update",boardId:u,itemId:v,payload:x}),w(e,200,A)}catch(A){w(e,502,{error:A.message})}return}if(o==="POST"&&!v){let x=await re(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});Pn({actor:$n(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,""),v={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[u];if(v){e.writeHead(302,{Location:v}),e.end();return}}w(e,404,{error:"not found",path:r})}async function vg(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),d=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),p=t.columns.some(h=>h.kind!=="closed"),c=t.columns.some(h=>h.kind==="closed"),m=p?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],g=c?await e.listAll({sinceDays:d,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],k={};for(let h of t.columns)k[h.id]=[];let b=t.columns.find(h=>h.kind==="closed");for(let h of g)b&&k[b.id].push({...h,stage:b.id});let S=t.columns.filter(h=>h.kind!=="closed");for(let h of m){let u=qn(h,S);if(!u)continue;let f=k[u];f&&f.push({...h,stage:u})}if(i)for(let h of Object.keys(k))k[h]=k[h].filter(u=>u.assignee===i);for(let h of Object.keys(k))k[h].sort((u,f)=>{let v=(u.priority??99)-(f.priority??99);return v!==0?v:(f.updatedAt||"").localeCompare(u.updatedAt||"")});let T=Object.fromEntries(Object.entries(k).map(([h,u])=>[h,u.length]));return{columns:k,totals:T}}async function yg(t,e,a,n){let r=zn(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 wg(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:dr(t.pausedAt)}:{},createdAt:t.createdAt,updatedAt:t.updatedAt}}function kg(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 Kr(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function Pn(t){try{let e=mt(process.cwd(),".agentx");kc(e)||mg(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
|
|
21259
|
-
`;
|
|
21264
|
+
`)}catch{y.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=[],v=await Promise.all(u.map(async x=>{let A={};x.token&&(A.Authorization=`Bearer ${x.token}`);try{let L=await fetch(`${x.url.replace(/\/+$/,"")}/api/workflows/runs?limit=500&summary=1`,{headers:A,signal:AbortSignal.timeout(5e3)});if(!L.ok)return f.push(x.url),[];let _=await L.json();return Array.isArray(_.runs)?_.runs:[]}catch{return f.push(x.url),[]}})),y=new Map;for(let x of a.workflowRuns.list({limit:500}))y.set(x.id,x);for(let x of v)for(let A of x)y.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:cr([...y.values()],x=>E.get(x)),unreachable:f});return}if(r==="/api/workflows/required"){let u=()=>({settings:Ro(),agents:Object.keys(a.config.agents??{}).sort()});if(o==="GET"){w(e,200,u());return}if(o!=="POST"){w(e,405,{error:"Method not allowed"});return}if(a.config.workflows?.editor!=="edit"){w(e,403,{error:"the workflow editor is read-only on this node (workflows.editor)"});return}let f=await re(t).catch(()=>({})),v={};if(typeof f.enabled=="boolean"&&(v.enabled=f.enabled),typeof f.exemptQuestions=="boolean"&&(v.exemptQuestions=f.exemptQuestions),typeof f.agentId=="string"&&f.agentId){if(!Object.prototype.hasOwnProperty.call(a.config.agents??{},f.agentId)){w(e,400,{error:`no agent "${f.agentId}" on this node`});return}let E=f.agentRequired;if(E!=="on"&&E!=="off"&&E!=="default"){w(e,400,{error:"agentRequired is on, off or default"});return}v.agent={id:f.agentId,value:E==="default"?null:E==="on"}}if(v.enabled===void 0&&v.exemptQuestions===void 0&&!v.agent){w(e,400,{error:"nothing to change"});return}let y=await Lo(v);if(!y.success){w(e,400,{error:y.error});return}w(e,200,{ok:!0,reloaded:!!y.reloaded,...u()});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))),v=u.searchParams.get("workflowId")||void 0,y=u.searchParams.get("summary")==="1"||u.searchParams.get("summary")==="true",E=a.workflowRuns.list({limit:f,workflowId:v}),x=`?limit=${f}${v?`&workflowId=${encodeURIComponent(v)}`:""}${y?"&summary=1":""}`,A=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map($=>({url:$.url,token:$.token}))],L=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 oe=await Q.json();return Array.isArray(oe.runs)?oe.runs:[]}finally{clearTimeout(ce)}}catch{return[]}})),_=new Map;for(let $ of E)_.set($.id,$);for(let $ of L)for(let O of $)_.set(O.id,O);let R=Array.from(_.values()).sort(($,O)=>$.updatedAt<O.updatedAt?1:-1).slice(0,f),j=y?R.map($=>Ag($)):R;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 v=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(y=>({url:y.url,token:y.token}))];for(let y of v)try{let E={};y.token&&(E.Authorization=`Bearer ${y.token}`);let x=await fetch(`${y.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(/\/+$/,""),v=await fetch(`${f}/api/actions/builtin`,{headers:u}),y=await v.json().catch(()=>({error:`HTTP ${v.status}`}));w(e,v.status,y)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}let k=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(k){try{let u=await re(t).catch(()=>({})),f={"Content-Type":"application/json"};a.config.dashboard.token&&(f.Authorization=`Bearer ${a.config.dashboard.token}`);let v=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${v}/workflows/${encodeURIComponent(k[1])}/run`,{method:"POST",headers:f,body:JSON.stringify(u??{})}),E=await y.json().catch(()=>({error:`HTTP ${y.status}`}));w(e,y.status,E)}catch(u){w(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(r.startsWith("/api/workflows")&&yl(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(f,v,y)=>{if(a.token)return!0;let E=Ma(f);if(!E)return!0;let x=new G().verify(E);if(!x)return w(v,401,{error:"invalid or revoked token"}),!1;for(let A of y)if(!Ae(x,A))return w(v,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,v=decodeURIComponent(f),y=a.boards.find(_=>_.id===u);if(!y){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 re(t),A=y.columns.find(_=>_.id===x.to),L=y.columns.find(_=>_.id===x.from);if(!A){w(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await Tg(E,v,L,A),Pn({actor:$n(t),action:"move",boardId:u,itemId:v,payload:{from:x.from,to:x.to}}),w(e,200,{ok:!0})}catch(_){w(e,502,{error:_.message||"transition failed"})}return}if(h){let[,u,f]=h,v=f?decodeURIComponent(f):void 0,y=a.boards.find(x=>x.id===u);if(!y){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"&&!v){let{columns:x,totals:A}=await Eg(y,E,n.searchParams);w(e,200,{columns:x,totals:A});return}if(o==="GET"&&v){try{let x=typeof E.getItem=="function"?await E.getItem(v):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"&&v){let x=await re(t);try{let A=typeof E.updateItem=="function"?await E.updateItem(v,x):null;if(!A){w(e,501,{error:"update unsupported"});return}Pn({actor:$n(t),action:"update",boardId:u,itemId:v,payload:x}),w(e,200,A)}catch(A){w(e,502,{error:A.message})}return}if(o==="POST"&&!v){let x=await re(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});Pn({actor:$n(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,""),v={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[u];if(v){e.writeHead(302,{Location:v}),e.end();return}}w(e,404,{error:"not found",path:r})}async function Eg(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),d=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),p=t.columns.some(h=>h.kind!=="closed"),c=t.columns.some(h=>h.kind==="closed"),m=p?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],g=c?await e.listAll({sinceDays:d,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],k={};for(let h of t.columns)k[h.id]=[];let b=t.columns.find(h=>h.kind==="closed");for(let h of g)b&&k[b.id].push({...h,stage:b.id});let S=t.columns.filter(h=>h.kind!=="closed");for(let h of m){let u=qn(h,S);if(!u)continue;let f=k[u];f&&f.push({...h,stage:u})}if(i)for(let h of Object.keys(k))k[h]=k[h].filter(u=>u.assignee===i);for(let h of Object.keys(k))k[h].sort((u,f)=>{let v=(u.priority??99)-(f.priority??99);return v!==0?v:(f.updatedAt||"").localeCompare(u.updatedAt||"")});let T=Object.fromEntries(Object.entries(k).map(([h,u])=>[h,u.length]));return{columns:k,totals:T}}async function Tg(t,e,a,n){let r=zn(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 Ag(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:dr(t.pausedAt)}:{},createdAt:t.createdAt,updatedAt:t.updatedAt}}function Cg(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 Vr(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function Pn(t){try{let e=mt(process.cwd(),".agentx");Tc(e)||vg(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
|
|
21265
|
+
`;bg(mt(e,"board-audit.jsonl"),a)}catch{}}function $n(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}var Ig=2e3;async function Mg(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(),Ig),v=()=>u.abort();return a?.addEventListener("abort",v,{once:!0}),fetch(t+h,{headers:r,signal:u.signal}).then(async y=>{let E=y.ok?await y.json().catch(()=>{}):void 0;return{ok:E!==void 0,json:async()=>E}}).catch(()=>null).finally(()=>{clearTimeout(f),a?.removeEventListener("abort",v)})},[l,d,p,c,m,g,k,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(!d||!d.ok)return o.error=d?`HTTP ${d.status}`:"unreachable",o;let T=await d.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,...f.workflow&&typeof f.workflow.runId=="string"?{workflow:{runId:f.workflow.runId,workflowId:String(f.workflow.workflowId??""),nodeId:String(f.workflow.nodeId??"")}}:{}}))}if(c&&c.ok){let h=await c.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(k&&k.ok){let h=await k.json().catch(()=>null);h&&Array.isArray(h.routines)&&(o.routines=h.routines.slice(0,yr.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)&&Ng(o,h.sessions,h.saved??{})}o.reachable=!0,o._peers=Array.isArray(p?.ok?await p.json():null)?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var ha=null;function Rg(t){if(ha)return ha;let e=mt(process.cwd(),".agentx/wiki");return ha=Mo({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph",curator:!0,curatorToken:()=>t.token}),ha}async function ba(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 Lg(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 Te(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 ba(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 Pg=3e3,$g=6e3,jg=5*6e4,On=new Map,ga=new Map;function at(t,e){let a=e?`${e.date}|${e.timezone}`:"live",n=ga.get(a);if(n)return n;let r=(async()=>{let o=await Te(t,AbortSignal.timeout(Pg)),s=await Promise.all(o.map(async i=>{let l=await Mg(i.url,i.token,AbortSignal.timeout($g),e);return e?l:Og(i.url,l)}));return{ts:new Date().toISOString(),nodes:s}})().finally(()=>ga.delete(a));return ga.set(a,r),r}function Og(t,e,a=Date.now()){if(e.reachable&&!e.error)return On.set(t,{node:e,at:a}),e;let n=On.get(t);return!n||a-n.at>jg?e:{...n.node,stale:!0,staleSince:new Date(n.at).toISOString(),error:e.error}}function s1(){On.clear(),ga.clear()}function Ng(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 Dg(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,d)=>{n||e.write(`event: ${l}
|
|
21260
21266
|
data: ${JSON.stringify(d)}
|
|
21261
21267
|
|
|
21262
|
-
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await at(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
|
|
21263
|
-
${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
|
|
21268
|
+
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await at(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 Hg(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let k of a.config.dashboard.daemons)i.add(k.url.replace(/\/+$/,""));try{let k=await ba(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let b of k)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),d={Accept:"text/event-stream"};l&&(d.Authorization=`Bearer ${l}`);let p=new AbortController,c;try{c=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:d,signal:p.signal})}catch(k){w(e,502,{error:k.message||"upstream connect failed"});return}if(!c.ok||!c.body){w(e,c.status||502,{error:`upstream HTTP ${c.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let m=c.body.getReader();(async()=>{try{for(;;){let{value:k,done:b}=await m.read();if(b)break;k&&e.write(k)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{p.abort();try{e.end()}catch{}})}function Bg(t,e,a){let n=Ma(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(!Ae(r,o))return w(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function qg(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 re(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 d=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),p=await d.text();e.writeHead(d.status,{"Content-Type":d.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(p)}catch(d){w(e,502,{error:d.message||"upstream call failed"})}}async function zg(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let c of e.config.dashboard.daemons)i.add(c.url.replace(/\/+$/,""));try{let c=await ba(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let m of c)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),d={Accept:"application/json"};l&&(d.Authorization=`Bearer ${l}`);let p=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let c=await fetch(`${s}${p}`,{headers:d}),m=await c.text();t.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8"}),t.end(m)}catch(c){w(t,502,{error:c.message||"upstream fetch failed"})}}async function Fg(t,e,a,n,r,o){await xa(t,e,a,n,`/api/tasks/${encodeURIComponent(r)}/${o}`)}async function xa(t,e,a,n,r){let o={};try{o=await re(t)??{}}catch{}let s=await Ac(a.config,n,r,o);e.writeHead(s.status,{"Content-Type":s.contentType}),e.end(s.text)}async function Ac(t,e,a,n){let r=(d,p)=>({status:d,text:JSON.stringify(p),contentType:"application/json"}),o=e.replace(/\/+$/,""),s=new Set;s.add(t.dashboard.daemonUrl.replace(/\/+$/,""));for(let d of t.dashboard.daemons)s.add(d.url.replace(/\/+$/,""));try{let d=await ba(t.dashboard.daemonUrl.replace(/\/+$/,""),t.dashboard.token);for(let p of d)s.add(p.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 d=await fetch(`${o}${a}`,{method:"POST",headers:l,body:JSON.stringify(n??{})});return{status:d.status,text:await d.text(),contentType:d.headers.get("content-type")||"application/json; charset=utf-8"}}catch(d){return r(502,{error:d.message||"upstream fetch failed"})}}var wc=null;function Cc(){return wc??=uc({db:()=>ze(),requestOfCard:t=>{try{return Ce({root:process.cwd()})?.byLink("card",t)?.id??null}catch(e){return console.warn(`[reach] request of card ${t} not read: ${e?.message??e}`),null}},log:t=>console.warn(t)}),wc}function Nn(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 Tt(),{...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=Cr(e.keysFile);return{store:()=>{let r=ze();return r?new ao(r):null},publicKey:()=>Ir(n)?.publicKey??null,keepRecent:e.keepRecent,allowedHosts:e.allowedHosts,reason:"The database on this computer is unavailable, so notifications can't be saved.",alertsRead:r=>Cc().pushRead(r)}}function kc(t){let e=t.channels.push,a=t.dashboard.daemonUrl.replace(/\/+$/,""),n=e.enabled&&!e.relayTo?rd({url:a,token:U(t.dashboard,a),operatorKey:Ea(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}.`:Nn(t).reason;return ld(t,process.cwd(),n,r)}function Dn(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=n=>{try{return JSON.parse(n)}catch{return{error:n.slice(0,200)}}};return{snapshot:n=>at(t,n),async nodePost(n,r,o){let s=await Ac(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=It({root:process.cwd()}).items.map(Sc)}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=ft(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 d=await l.json();s.items=(d.items??[]).map(Sc)}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 p=Me(),c=await Mt({root:process.cwd()},r,o,{laterHours:p.laterHours,by:s,...i});return c.ok?{status:200,body:{ok:!0,message:c.message}}:{status:409,body:{error:c.error}}}let d=ft(l,t);if(!d)return{status:403,body:{error:"node not in dashboard allowlist",target:l}};try{let p=await fetch(`${d.url}/api/admin/approvals/decide`,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"agentx-board","X-Agentx-Peer":"primary",...d.token?{Authorization:`Bearer ${d.token}`}:{}},body:JSON.stringify({key:r,action:o,...i}),signal:AbortSignal.timeout(1e4)});return{status:p.status,body:a(await p.text())}}catch(p){return{status:502,body:{error:p.message||"peer dashboard unreachable"}}}}}}function Ug(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=Dn(t),n={root:process.cwd()};return{async board(){let[r,o]=await Promise.all([a.approvals(),a.snapshot()]),s=new Set,i=[],l=o.nodes.find(k=>k.url.replace(/\/+$/,"")===e);!l||!l.reachable||l.stale?i.push("The running tasks could not be read, so no request is shown as working now."):s=vc(l.agents);let d=Date.now(),p=null;try{let k=Ce(n);k&&(p=[...k.listOpen(),...k.listClosedSince(d-Mn*864e5,Rn)].map(b=>({record:b,links:k.links(b.id)})))}catch(k){i.push(`Requests could not be read: ${k.message}`)}let c=[];try{c=Lr(n.root).filter(k=>k.status!=="pending")}catch(k){i.push(`Finished cards could not be read: ${k.message}`)}let m=new Set(Object.entries(Pr(n.root).snoozed).filter(([,k])=>Date.parse(k)>d).map(([k])=>k)),g=yc({now:d,node:e,nodeName:t.node?.name||"this computer",inbox:r,requests:p,cards:c,liveRuns:s,deferred:m});return{...g,errors:[...g.errors,...i]}},async reply(r,o){return ta("POST",`${xe}/reply`,{id:r,text:o},n)}}}var jn=null;function _c(t){return jn?.days!==t&&(jn={days:t,store:new wt(process.cwd(),Date.now,t)}),jn.store}function Ic(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=U(t.dashboard,e),n=Dn(t);return{store:()=>{let r=ze();return r?new ut(r):null},daemon:{url:e,token:a,name:t.node?.name,operatorKey:Ea(process.cwd())??void 0},snapshot:()=>at(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(/\/+$/,"")),...Wg(t,e,a)}}function Wg(t,e,a){let n=Nn(t);return{finishAlerts:r=>{if(n.forward)return Ar.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}
|
|
21269
|
+
${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 Gg(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=Ic(t);return new ma({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 d=await l.json();return{events:Array.isArray(d.events)?d.events:[],gap:d.gap===!0}},nodeUrl:async o=>{let i=(await at(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:jl(),finishAlerts:r.finishAlerts,notifyFinish:r.notifyFinish,log:o=>console.log(o),warn:o=>console.warn(o)})}function Xg(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{store:()=>{let a=ze();return a?new ut(a):null},daemon:{url:e,token:U(t.dashboard,e)}}}function Kg(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{daemon:{url:e,token:U(t.dashboard,e)},nodeName:t.node.name}}function Sc(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}:{},...t.detail?{detail:t.detail}:{},...t.created_at?{createdAt:t.created_at}:{}}}var Jg=`
|
|
21264
21270
|
You are helping draft a new GitLab issue. Follow these conventions strictly.
|
|
21265
21271
|
|
|
21266
21272
|
Title pattern:
|
|
@@ -21292,10 +21298,10 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
|
|
|
21292
21298
|
Shape:
|
|
21293
21299
|
{ "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
|
|
21294
21300
|
If you don't have enough information to pick a label confidently, omit it rather than guessing.
|
|
21295
|
-
`;async function
|
|
21301
|
+
`;async function Vg(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):
|
|
21296
21302
|
- ${r.knownLabels.slice(0,60).join(`
|
|
21297
21303
|
- `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
|
|
21298
|
-
`),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:
|
|
21304
|
+
`),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:Jg}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let d=await l.json();if(d.error)throw new Error(String(d.error));let p=(d.content||"").toString(),c=Yg(p);if(!c||typeof c.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+p.slice(0,400));let m=Array.isArray(c.labels)?c.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:c.title.trim(),description:(c.description||"").toString(),labels:m,assigneeUsername:typeof c.assigneeUsername=="string"?c.assigneeUsername:void 0,kind:typeof c.kind=="string"?c.kind:void 0,raw:p}}function Yg(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 Qg(t){let e=kg(wg(import.meta.url));return mt(e,t)}async function Zg(t){return yg(t)}function w(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function re(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 Mc(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:Mc(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 ex(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;w(e,200,await oa(await Rc(r,a.config)))}async function Rc(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=dn(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=ft(i.url.replace(/\/+$/,""),e);if(!l)return null;try{let d=new AbortController,p=setTimeout(()=>d.abort(),8e3);try{let c=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:d.signal});return c.ok?{nodeId:i.name||i.url,snap:await c.json()}:null}finally{clearTimeout(p)}}catch{return null}}));for(let i of s)i&&n.push(i);return Hi(n)}async function tx(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 c=process.env.HOME||"",m=[c&&`${c}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),g=m.find(k=>Tc(k));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}
|
|
21299
21305
|
|
|
21300
21306
|
`);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),i="",l=c=>{i+=c.toString("utf8");let m;for(;(m=i.indexOf(`
|
|
21301
21307
|
`))>=0;){let g=i.slice(0,m).replace(/\r$/,"");i=i.slice(m+1);try{e.write(`event: line
|
|
@@ -21303,5 +21309,5 @@ data: ${g.replace(/\n/g," ")}
|
|
|
21303
21309
|
|
|
21304
21310
|
`)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let d=setInterval(()=>{try{e.write(`: hb
|
|
21305
21311
|
|
|
21306
|
-
`)}catch{}},15e3),p=()=>{clearInterval(d);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",p),s.on("exit",p),s.on("error",p)}async function
|
|
21307
|
-
//# sourceMappingURL=board-dashboard-
|
|
21312
|
+
`)}catch{}},15e3),p=()=>{clearInterval(d);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",p),s.on("exit",p),s.on("error",p)}async function Ec(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((c,m)=>{let g=[];t.on("data",k=>g.push(k)),t.on("end",()=>c(Buffer.concat(g))),t.on("error",m)}):void 0,l={},d=t.headers["content-type"];d&&(l["Content-Type"]=Array.isArray(d)?d[0]:d);let p=t.headers["x-requested-with"];p&&(l["X-Requested-With"]=Array.isArray(p)?p[0]:p),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let c=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),m=Buffer.from(await c.arrayBuffer());e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(m)}catch(c){w(e,502,{error:`proxy to peer failed: ${c?.message||c}`,target:r})}}function ft(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:Mc(n),token:n.dashboardToken||n.token}:null}export{Ng as applyAttachSessions,Mg as fetchDaemonAgents,Sg as handleBoardRequest,s1 as resetLiveCaches,Te as resolveNodeTargets,o1 as startBoardDashboard,Og as withLastGood};
|
|
21313
|
+
//# sourceMappingURL=board-dashboard-MWUCBHDN.js.map
|