agentix-cli 0.121.0 → 0.122.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-AMIGKAXO.js → App-2D5W26LY.js} +2 -2
- package/dist/{ChatApp-WMI4HQSY.js → ChatApp-FZFZD2XY.js} +2 -2
- package/dist/{agent-TQQOAVMU.js → agent-PCRE3TRK.js} +2 -2
- package/dist/{board-dashboard-FNMZAP7A.js → board-dashboard-ZDJ4UDW4.js} +264 -230
- package/dist/board-dashboard-ZDJ4UDW4.js.map +1 -0
- package/dist/{chunk-MORRCYJE.js → chunk-2UDSIG5K.js} +2 -2
- package/dist/{chunk-6FVFD5WU.js → chunk-54XX2LSW.js} +4 -4
- package/dist/{chunk-6FVFD5WU.js.map → chunk-54XX2LSW.js.map} +1 -1
- package/dist/{chunk-RMA7KKR7.js → chunk-5SLTRG66.js} +2 -2
- package/dist/chunk-7ZGTRXWS.js +4 -0
- package/dist/chunk-7ZGTRXWS.js.map +1 -0
- package/dist/{chunk-EI7D5V2L.js → chunk-BRVQZC6P.js} +2 -2
- package/dist/{chunk-6TUQHOO3.js → chunk-C52IPIKJ.js} +2 -2
- package/dist/chunk-DMPTCBX6.js +532 -0
- package/dist/chunk-DMPTCBX6.js.map +1 -0
- package/dist/{chunk-4GDLXWCH.js → chunk-EHKI2RKD.js} +2 -2
- package/dist/{chunk-CAS2IWSM.js → chunk-NFS2VR3L.js} +2 -2
- package/dist/{chunk-43CLFC4B.js → chunk-NYAMY7EA.js} +2 -2
- package/dist/{chunk-7ZABMMSW.js → chunk-QCPSGOSK.js} +2 -2
- package/dist/{chunk-BLEW5WQL.js → chunk-SB7WMFJV.js} +2 -2
- package/dist/{chunk-7KY7EEEI.js → chunk-TLCURHW3.js} +2 -2
- package/dist/{chunk-H5Z42X7W.js → chunk-TYFGL2YS.js} +2 -2
- package/dist/{chunk-I4IDZSGF.js → chunk-UVV6GUOG.js} +232 -228
- package/dist/chunk-UVV6GUOG.js.map +1 -0
- package/dist/{chunk-ELUEF4NC.js → chunk-WJDFR3WE.js} +2 -2
- package/dist/{chunk-IKBWV7YJ.js → chunk-XBRVV4ZT.js} +2 -2
- package/dist/{chunk-2NGXOYTS.js → chunk-XLCUHG3N.js} +69 -69
- package/dist/chunk-XLCUHG3N.js.map +1 -0
- package/dist/{chunk-2IMK3NGJ.js → chunk-XX6MLDTL.js} +2 -2
- package/dist/{chunk-PAWCJIPZ.js → chunk-YCMO3KZ4.js} +2 -2
- package/dist/{chunk-Y4PR5LR3.js → chunk-YUNMSLZN.js} +2 -2
- package/dist/{chunk-OPNZWQ6Y.js → chunk-ZLUROC2Y.js} +5 -5
- package/dist/chunk-ZLUROC2Y.js.map +1 -0
- package/dist/{chunk-25XR6QK2.js → chunk-ZWZADDXV.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-ICDRAZBU.js → client-TFZEASIJ.js} +2 -2
- package/dist/config-IXCOAOPZ.js +2 -0
- package/dist/config-mutator-EPYIZVSG.js +2 -0
- package/dist/{doctor-LRTOOCM6.js → doctor-G5TM5GVF.js} +2 -2
- package/dist/{grants-ZMHSJMYE.js → grants-NGBKFONG.js} +2 -2
- package/dist/index.d.ts +161 -79
- package/dist/index.js +1 -1
- package/dist/{program-OKPC77BN.js → program-CGPPGRMR.js} +201 -199
- package/dist/program-CGPPGRMR.js.map +1 -0
- package/dist/{promote-4LW53AMH.js → promote-VTVIPRTC.js} +2 -2
- package/dist/{query-4OPS5PET.js → query-3CVDT2GZ.js} +2 -2
- package/dist/{registry-YHSHGJ4K.js → registry-NOJMMWE3.js} +2 -2
- package/dist/{request-planner-GDXSBNN4.js → request-planner-E2Q5O66N.js} +2 -2
- package/dist/{review-candidates-TUVDG2LR.js → review-candidates-I36HEYKX.js} +2 -2
- package/dist/{routing-OKDZ4VYH.js → routing-KBUZON5R.js} +2 -2
- package/dist/schedule-tool-GUHHYYTO.js +2 -0
- package/dist/scheduler-PGUELFMB.js +2 -0
- package/dist/{seat-K6FNHYMY.js → seat-NGY2BMP6.js} +2 -2
- package/dist/{select-QMJXHNUP.js → select-X7VBGZ6X.js} +2 -2
- package/dist/{set-enabled-I77LPL6Q.js → set-enabled-6NP63KCU.js} +2 -2
- package/dist/{tool-QTGNWXUA.js → tool-EZIILXYL.js} +2 -2
- package/dist/tool-WKIF52OH.js +6 -0
- package/dist/tool-WKIF52OH.js.map +1 -0
- package/dist/wiki-7BFVMMNR.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-FNMZAP7A.js.map +0 -1
- package/dist/chunk-2NGXOYTS.js.map +0 -1
- package/dist/chunk-BWHHZJNJ.js +0 -482
- package/dist/chunk-BWHHZJNJ.js.map +0 -1
- package/dist/chunk-DJQMG6TH.js +0 -4
- package/dist/chunk-DJQMG6TH.js.map +0 -1
- package/dist/chunk-I4IDZSGF.js.map +0 -1
- package/dist/chunk-OPNZWQ6Y.js.map +0 -1
- package/dist/config-K4UYPR7W.js +0 -2
- package/dist/config-mutator-IGA6D4S5.js +0 -2
- package/dist/program-OKPC77BN.js.map +0 -1
- package/dist/schedule-tool-MJLXMXN5.js +0 -2
- package/dist/scheduler-E5SASFAH.js +0 -2
- package/dist/tool-BQUKONSF.js +0 -4
- package/dist/tool-BQUKONSF.js.map +0 -1
- package/dist/wiki-F6EZBBUH.js +0 -2
- /package/dist/{App-AMIGKAXO.js.map → App-2D5W26LY.js.map} +0 -0
- /package/dist/{ChatApp-WMI4HQSY.js.map → ChatApp-FZFZD2XY.js.map} +0 -0
- /package/dist/{agent-TQQOAVMU.js.map → agent-PCRE3TRK.js.map} +0 -0
- /package/dist/{chunk-MORRCYJE.js.map → chunk-2UDSIG5K.js.map} +0 -0
- /package/dist/{chunk-RMA7KKR7.js.map → chunk-5SLTRG66.js.map} +0 -0
- /package/dist/{chunk-EI7D5V2L.js.map → chunk-BRVQZC6P.js.map} +0 -0
- /package/dist/{chunk-6TUQHOO3.js.map → chunk-C52IPIKJ.js.map} +0 -0
- /package/dist/{chunk-4GDLXWCH.js.map → chunk-EHKI2RKD.js.map} +0 -0
- /package/dist/{chunk-CAS2IWSM.js.map → chunk-NFS2VR3L.js.map} +0 -0
- /package/dist/{chunk-43CLFC4B.js.map → chunk-NYAMY7EA.js.map} +0 -0
- /package/dist/{chunk-7ZABMMSW.js.map → chunk-QCPSGOSK.js.map} +0 -0
- /package/dist/{chunk-BLEW5WQL.js.map → chunk-SB7WMFJV.js.map} +0 -0
- /package/dist/{chunk-7KY7EEEI.js.map → chunk-TLCURHW3.js.map} +0 -0
- /package/dist/{chunk-H5Z42X7W.js.map → chunk-TYFGL2YS.js.map} +0 -0
- /package/dist/{chunk-ELUEF4NC.js.map → chunk-WJDFR3WE.js.map} +0 -0
- /package/dist/{chunk-IKBWV7YJ.js.map → chunk-XBRVV4ZT.js.map} +0 -0
- /package/dist/{chunk-2IMK3NGJ.js.map → chunk-XX6MLDTL.js.map} +0 -0
- /package/dist/{chunk-PAWCJIPZ.js.map → chunk-YCMO3KZ4.js.map} +0 -0
- /package/dist/{chunk-Y4PR5LR3.js.map → chunk-YUNMSLZN.js.map} +0 -0
- /package/dist/{chunk-25XR6QK2.js.map → chunk-ZWZADDXV.js.map} +0 -0
- /package/dist/{client-ICDRAZBU.js.map → client-TFZEASIJ.js.map} +0 -0
- /package/dist/{config-K4UYPR7W.js.map → config-IXCOAOPZ.js.map} +0 -0
- /package/dist/{config-mutator-IGA6D4S5.js.map → config-mutator-EPYIZVSG.js.map} +0 -0
- /package/dist/{doctor-LRTOOCM6.js.map → doctor-G5TM5GVF.js.map} +0 -0
- /package/dist/{grants-ZMHSJMYE.js.map → grants-NGBKFONG.js.map} +0 -0
- /package/dist/{promote-4LW53AMH.js.map → promote-VTVIPRTC.js.map} +0 -0
- /package/dist/{query-4OPS5PET.js.map → query-3CVDT2GZ.js.map} +0 -0
- /package/dist/{registry-YHSHGJ4K.js.map → registry-NOJMMWE3.js.map} +0 -0
- /package/dist/{request-planner-GDXSBNN4.js.map → request-planner-E2Q5O66N.js.map} +0 -0
- /package/dist/{review-candidates-TUVDG2LR.js.map → review-candidates-I36HEYKX.js.map} +0 -0
- /package/dist/{routing-OKDZ4VYH.js.map → routing-KBUZON5R.js.map} +0 -0
- /package/dist/{schedule-tool-MJLXMXN5.js.map → schedule-tool-GUHHYYTO.js.map} +0 -0
- /package/dist/{scheduler-E5SASFAH.js.map → scheduler-PGUELFMB.js.map} +0 -0
- /package/dist/{seat-K6FNHYMY.js.map → seat-NGY2BMP6.js.map} +0 -0
- /package/dist/{select-QMJXHNUP.js.map → select-X7VBGZ6X.js.map} +0 -0
- /package/dist/{set-enabled-I77LPL6Q.js.map → set-enabled-6NP63KCU.js.map} +0 -0
- /package/dist/{tool-QTGNWXUA.js.map → tool-EZIILXYL.js.map} +0 -0
- /package/dist/{wiki-F6EZBBUH.js.map → wiki-7BFVMMNR.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{A as
|
|
1
|
+
import{A as Zr,B as eo,C as to,a as C,b as Dr,c as Br,d as Hr,e as zr,f as Ae,g as qr,h as Fr,i as jt,k as Ur,q as Wr,r as Gr,s as Xr,t as Kr,u as Jr,y as Vr,z as Yr}from"./chunk-2UDSIG5K.js";import{a as Qr}from"./chunk-5NTWGUSJ.js";import{a as Pr}from"./chunk-LNY6N73E.js";import{a as Nr}from"./chunk-4VDA4UM7.js";import{a as ze,b as q,c as I,h as de,i as Pt,j as oe,k as K,l as $t,m as $r,n as jr,o as Or}from"./chunk-SCJ5ZXEN.js";import{$a as Mr,A as cr,B as St,Ba as _r,C as dr,Ca as Sr,D as Et,Da as Er,E as Tt,F as At,G as pr,H as mr,K as fr,L as hr,La as Tr,M as gr,Na as Te,Sa as Ar,T as U,U as xr,Ua as He,V as vr,Va as Ct,Wa as It,Xa as Mt,Ya as Lt,Za as Cr,_a as Ir,a as Yn,ab as Rt,c as vt,cb as Lr,d as wa,e as Qn,fb as Rr,i as bt,l as Qe,n as Zn,z as _t,za as kr}from"./chunk-DMPTCBX6.js";import"./chunk-GTJIKXDB.js";import{h as Jn,i as Vn}from"./chunk-NFS2VR3L.js";import{p as er,t as tr}from"./chunk-S2GAEH2F.js";import{a as ur,b as B,c as br,d as yr,h as wr}from"./chunk-BGG3ZSMW.js";import{a as rr,b as yt,d as or,e as sr,f as wt}from"./chunk-WCXXXAHV.js";import{g as kt}from"./chunk-LQE73AZR.js";import{b as ir,c as lr}from"./chunk-2D3RYIDU.js";import"./chunk-54XX2LSW.js";import"./chunk-TYFGL2YS.js";import"./chunk-2AXFYDWF.js";import"./chunk-AQASR6KR.js";import{b as G,c as Ee,d as ar,e as ka}from"./chunk-EMGB23H5.js";import{b as nr}from"./chunk-JWDJMFU6.js";import{a as qn,f as Fn,g as ba,h as ya,l as Un,m as Wn,n as Gn,u as ht,v as gt,w as xt,x as ce,y as Kn}from"./chunk-TLCURHW3.js";import"./chunk-GLQLCBJS.js";import"./chunk-6W74CHNW.js";import"./chunk-Y4CYQV7G.js";import"./chunk-SHEUCITK.js";import"./chunk-SB7WMFJV.js";import"./chunk-GV7S5BAX.js";import"./chunk-SZDACK6O.js";import"./chunk-AFRHKA7B.js";import"./chunk-ZWZADDXV.js";import{a as Xn}from"./chunk-XX6MLDTL.js";import"./chunk-7ZGTRXWS.js";import"./chunk-XBRVV4ZT.js";import"./chunk-KA2UIZXG.js";import"./chunk-GQ76J72O.js";import"./chunk-ILEC3IAV.js";import"./chunk-GSX4NK2N.js";import"./chunk-QD6IICK7.js";import"./chunk-CECHWYJ2.js";import{g as zn}from"./chunk-WJDFR3WE.js";import"./chunk-WPNRDEHW.js";import"./chunk-56KNKUFF.js";import"./chunk-EHKI2RKD.js";import"./chunk-72SZI2UW.js";import"./chunk-FX3D7YON.js";import"./chunk-FCPTN6NF.js";import"./chunk-QOYAX2FT.js";import"./chunk-2PJKGZWP.js";import"./chunk-7I7IEX4S.js";import{B as Jc,I as On,L as xa,O as Nn,Q as mt,R as Dn,T as Bn,V as Hn,Z as va,a as In,b as Mn,c as Gc,ka as X,na as ft,u as dt,v as Xc,w as ha,x as ga}from"./chunk-ZLUROC2Y.js";import{a as Ln,b as pt,c as fa,d as Rn,h as Pn}from"./chunk-BRK6M6LA.js";import{d as $n,e as Kc,f as ut,n as jn}from"./chunk-UIBUZ2N3.js";import"./chunk-2QNT5JDS.js";import"./chunk-RGDKHYY2.js";import"./chunk-QIJLFPWE.js";function _a(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 ao(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:_a(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}var se={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',alert:'<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',gavel:'<path d="M12 3 6 9"/><path d="m9 6 6 6"/><path d="M15 9 9 15"/><path d="m12 12 6 6"/><path d="M4 21h10"/>',loop:'<path d="M17 2l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 22l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>',broom:'<path d="M3 21h18"/><path d="M12 3v9"/><path d="m7 12 5-3 5 3-1.5 6h-7Z"/>',server:'<rect x="2" y="3" width="20" height="7" rx="2"/><rect x="2" y="14" width="20" height="7" rx="2"/><path d="M6 6.5h.01"/><path d="M6 17.5h.01"/>',inbox:'<path d="M21 12h-6l-2 3h-2l-2-3H3"/><path d="M5 5h14l2 7v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Z"/>',cross:'<circle cx="12" cy="12" r="9"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/>',file:'<path d="M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7Z"/><path d="M14 2v5h5"/>',search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',chev:'<path d="m6 9 6 6 6-6"/>',chevr:'<path d="m9 6 6 6-6 6"/>',ext:'<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',pulse:'<path d="M3 12h4l3-8 4 16 3-8h4"/>',plug:'<path d="M9 2v6"/><path d="M15 2v6"/><path d="M6 8h12v3a6 6 0 0 1-12 0Z"/><path d="M12 17v5"/>',check:'<path d="M20 6 9 17l-5-5"/>',route:'<circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h6a4 4 0 0 0 0-8H9a4 4 0 0 1 0-8h6"/>',branch:'<circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="8" r="3"/><path d="M18 11v1a3 3 0 0 1-3 3H9"/><path d="M6 9v6"/>',send:'<path d="M22 2 11 13"/><path d="M22 2l-7 20-4-9-9-4Z"/>',msg:'<path d="M21 11.5a8.4 8.4 0 0 1-12.9 7.5L3 21l2-5.1A8.4 8.4 0 1 1 21 11.5Z"/>',code:'<path d="m9 18-6-6 6-6"/><path d="m15 6 6 6-6 6"/>',hash:'<path d="M4 9h16"/><path d="M4 15h16"/><path d="M10 3 8 21"/><path d="M16 3l-2 18"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',trace:'<path d="M4 4v16h16"/><path d="m7 15 4-4 3 3 5-6"/>'},Ce=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",Ot=(t,e,a,n="")=>'<div class="ax-sec-label"><h3>'+Ce(t,13)+e+(a?'<span class="ax-sec-label__n" id="'+a+'"></span>':"")+"</h3>"+n+"</div>";function no(t={}){return I({title:"AgentX \xB7 Monitor",activeTab:"monitor",subtitle:"Monitor",peers:t.peers,body:`<div class="bf">
|
|
2
2
|
|
|
3
3
|
<div class="bf-head">
|
|
4
4
|
<div>
|
|
@@ -85,7 +85,7 @@ ${Ot(se.file,"Session briefings","brief-count")}
|
|
|
85
85
|
</div>
|
|
86
86
|
</details>
|
|
87
87
|
</section>
|
|
88
|
-
</div>`,css:
|
|
88
|
+
</div>`,css:Vc,scripts:`<script>${q({decayOf:_a,rankByDecay:ao})}const ICON = ${JSON.stringify(se)};${Yc}</script>`})}var Vc=`
|
|
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
|
+
}`,Yc=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
|
|
779
|
+
})();`;function Sa(t,e=20*6e4,a=6){let n=[...t].sort((l,c)=>l.startedAt-c.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let l of n){let c=l.startedAt+Math.max(l.durationMs||0,0),d=r[r.length-1];d&&l.startedAt-d.to<=e?(d.to=Math.max(d.to,c),d.runs++):r.push({from:l.startedAt,to:c,runs:1})}for(;r.length>a;){let l=0,c=1/0;for(let d=1;d<r.length;d++){let p=r[d].from-r[d-1].to;p<c&&(c=p,l=d)}r[l-1].to=r[l].to,r[l-1].runs+=r[l].runs,r.splice(l,1)}let o=r.reduce((l,c)=>l+c.runs,0)||1,s=r.map(l=>({from:l.from,to:Math.max(l.to,l.from+1),weight:l.runs/o,runs:l.runs})),i=r.slice(1).map((l,c)=>l.from-r[c].to);return{bands:s,gaps:i}}function Ea(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 ro(t,e=[],a){let{bands:n,gaps:r}=Sa(t,a);if(!n.length)return{bands:[],gaps:[],lanes:[],from:0,to:0};let o=new Map;for(let l of e){let c=o.get(l.runId);c?c.push(l):o.set(l.runId,[l])}let s=new Map;for(let l of t){let c=n.findIndex(v=>l.startedAt>=v.from&&l.startedAt<=v.to);if(c===-1)continue;let d=n[c],p=d.to-d.from||1,m=(l.startedAt-d.from)/p*100,f=Math.min(Math.max((l.durationMs||0)/p*100,1.2),100-m),_=s.get(l.laneKey)??{key:l.laneKey,label:l.laneLabel,sub:l.laneSub,tracks:1,runs:[]};_.runs.push({...l,band:c,track:0,left:m,width:f,marks:o.get(l.id)??[]}),s.set(l.laneKey,_)}let i=[...s.values()];for(let l of i)l.tracks=Math.max(...n.map((c,d)=>Ea(l.runs.filter(p=>p.band===d))),1);return i.sort((l,c)=>c.runs.length-l.runs.length||l.label.localeCompare(c.label)),{bands:n,gaps:r,lanes:i,from:n[0].from,to:n[n.length-1].to}}import{createHash as Qc}from"crypto";import{readFileSync as Zc,statSync as ed}from"fs";import{resolve as td,dirname as ad}from"path";import{fileURLToPath as nd}from"url";var oo=new Map;function Nt(t){let e=oo.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=ad(nd(import.meta.url)),r=td(n,"web",t),o=ed(r),s=o.size<8e6?Qc("sha1").update(Zc(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 ie={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',bot:'<rect x="4" y="8" width="16" height="12" rx="2"/><path d="M12 8V5M9 14h.01M15 14h.01"/>',user:'<circle cx="12" cy="8" r="3.5"/><path d="M5 21a7 7 0 0 1 14 0"/>',folder:'<path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/>',map:'<path d="M9 4 3 6v14l6-2 6 2 6-2V4l-6 2-6-2z"/><path d="M9 4v14M15 6v14"/>',timeline:'<path d="M3 6h10M7 12h14M3 18h8"/>',mesh:'<circle cx="5" cy="19" r="2.5"/><circle cx="19" cy="19" r="2.5"/><circle cx="12" cy="5" r="2.5"/><path d="M7 17.5l4-10M17 17.5l-4-10"/>',route:'<circle cx="6" cy="6" r="3"/><circle cx="18" cy="18" r="3"/><path d="M9 6h6a3 3 0 0 1 0 6H9a3 3 0 0 0 0 6h6"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',x:'<path d="M18 6L6 18M6 6l12 12"/>',alert:'<path d="M12 9v4M12 17h.01"/><path d="M10.3 3.9L1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0z"/>'},Dt=(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>",rd=[["agent","Agent",ie.bot],["client","Client",ie.user],["project","Project",ie.folder],["channel","Channel",ie.route],["person","Person",ie.user],["node","Node",ie.mesh]],so={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 io(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">${so[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
|
+
${rd.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${Dt(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="${Nt("activity-graph.global.js")}"></div>
|
|
820
820
|
</div>
|
|
821
821
|
|
|
822
|
-
</div>`,css:
|
|
822
|
+
</div>`,css:od,scripts:`<script>${q({computeBands:Sa,packTracks:Ea,buildTimeline:ro})}const ICON = ${JSON.stringify(ie)};const SUB = ${JSON.stringify(so)};${sd}</script>`})}var od=`
|
|
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
|
+
`,sd=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 lo(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:id,scripts:`<script src="${Nt("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var id=`
|
|
1028
1028
|
/* Preload the fonts the redesign's CSS references. Placed in the shell so
|
|
1029
1029
|
* they start fetching while the React bundle is still parsing. */
|
|
1030
1030
|
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif&display=swap");
|
|
@@ -1045,11 +1045,11 @@ body { margin: 0; overflow: hidden; }
|
|
|
1045
1045
|
font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
|
|
1046
1046
|
text-align: center;
|
|
1047
1047
|
}
|
|
1048
|
-
`;import{createServer as
|
|
1049
|
-
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...
|
|
1050
|
-
WHERE l.kind = 'run' AND r.person = ? AND l.ref IN (${d.map(()=>"?").join(",")})`).all(e,...d.map(E=>E.taskId));for(let E of
|
|
1048
|
+
`;import{createServer as gh}from"http";import{appendFileSync as xh,existsSync as Nc,mkdirSync as vh}from"fs";import{readFile as bh}from"fs/promises";import{fileURLToPath as yh}from"url";import{dirname as wh,resolve as it}from"path";Nn();function qe(t,e){if(!t)return"absent";let a=ar(t),n=e.list().find(r=>r.hash===a);return n&&(n.revokedAt||n.expiresAt&&Date.parse(n.expiresAt)<Date.now())?"revoked":"invalid"}var Ie=class{constructor(e=r=>console.log(r),a=Date.now,n=6e4){this.log=e;this.now=a;this.everyMs=n}last=new Map;record(e,a){let n=Object.entries(a).map(([i,l])=>`${i}=${l}`).join(" "),r=`${e} ${a.cookie??""} ${a.bearer??""}`,o=this.now(),s=this.last.get(r);s!==void 0&&o-s<this.everyMs||(this.last.size>500&&this.prune(o),this.last.set(r,o),this.log(`[app] unauthenticated ${e} ${n}`))}prune(e){for(let[a,n]of this.last)e-n>=this.everyMs&&this.last.delete(a);this.last.size>500&&this.last.clear()}};function Bt(t,e,a){let n={cookie:e};return a&&(n.bearer=a),n.mode=co(t.headers["sec-fetch-mode"]),n.site=co(t.headers["sec-fetch-site"]),n}function co(t){let e=Array.isArray(t)?t[0]:t;return e&&/^[a-z-]{1,20}$/.test(e)?e:"-"}import{deflateSync as dd}from"zlib";var ld=[[[441,393],[600,393],[614,396],[625,401],[634,410],[1028,940],[846,940],[833,937],[823,931],[818,925],[440,414],[435,406],[436,398]],[[893,393],[1079,393],[861,653],[771,535]],[[413,439],[510,574],[282,874],[100,874]],[[451,709],[610,709],[615,712],[698,824],[599,939],[447,719],[446,713]]],ye={x:100,y:393,width:979,height:547},Ta="#1a1a18",Aa="#ffffff",po=Math.hypot(ye.width,ye.height)/2/ye.width,Ht={full:.74,safe:.37/po,android:.29/po,mac:.6};function Ca(t,e){let a=t*e/ye.width,n=t/2-(ye.x+ye.width/2)*a,r=t/2-(ye.y+ye.height/2)*a;return ld.map(o=>o.map(([s,i])=>[s*a+n,i*a+r]))}function cd(t,e){let a=n=>String(Math.round(n*100)/100);return Ca(t,e).map(n=>"M"+n.map(([r,o])=>`${a(r)},${a(o)}`).join("L")+"Z").join("")}function uo(t=64,e=Ht.full){return`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 ${t} ${t}"><rect width="${t}" height="${t}" rx="${t*.18}" fill="${Aa}"/><path fill="${Ta}" d="${cd(t,e)}"/></svg>`}var pd=yo(Ta),mo=yo(Aa),fo=new Map;function Fe(t){let e=fo.get(t);return e||(e=bo({size:t,width:Ht.safe,background:"square"}),fo.set(t,e)),e}var ud=uo();function vo(t){return t==="/favicon.svg"?{type:"image/svg+xml",body:ud}:t==="/favicon.ico"?{type:"image/png",body:go(32)}:t==="/apple-touch-icon.png"?{type:"image/png",body:go(180)}:null}var ho=new Map;function go(t){let e=ho.get(t);return e||(e=bo({size:t,width:Ht.full,background:"square"}),ho.set(t,e)),e}function bo(t){let{size:e}=t,a=t.background==="mac"?xo(e,[md(e)]):null,n=xo(e,Ca(e,t.width)),r=1+e*4,o=Buffer.alloc(r*e);for(let s=0;s<e;s++)for(let i=0;i<e;i++){let l=s*e+i,c=n[l],d=s*r+1+i*4;for(let p=0;p<3;p++)o[d+p]=Math.round(mo[p]+(pd[p]-mo[p])*c);o[d+3]=Math.round(255*(a?a[l]:1))}return fd(e,o)}function md(t){let e=t/1024,a=100*e,n=924*e,r=185*e,o=[],s=[[n-r,a+r,-90],[n-r,n-r,0],[a+r,n-r,90],[a+r,a+r,180]];for(let[i,l,c]of s)for(let d=0;d<=12;d++){let p=(c+90*d/12)*Math.PI/180;o.push([i+r*Math.cos(p),l+r*Math.sin(p)])}return o}var Ia=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],[c,d]=o[(s+1)%o.length];l!==d&&n.push([i,l,c,d])}let r=[];for(let o=0;o<t;o++)for(let s=0;s<Ia;s++){let i=o+(s+.5)/Ia;r.length=0;for(let[l,c,d,p]of n)(i>=c&&i<p||i>=p&&i<c)&&r.push(l+(i-c)*(d-l)/(p-c));r.sort((l,c)=>l-c);for(let l=0;l+1<r.length;l+=2){let c=Math.max(0,r[l]),d=Math.min(t,r[l+1]);for(let p=Math.floor(c);p<d;p++){let m=Math.min(p+1,d)-Math.max(p,c);m>0&&(a[o*t+p]+=m/Ia)}}}for(let o=0;o<a.length;o++)a[o]>1&&(a[o]=1);return a}function yo(t){let e=parseInt(t.slice(1),16);return[e>>16&255,e>>8&255,e&255]}function fd(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]),Ma("IHDR",a),Ma("IDAT",dd(e)),Ma("IEND",Buffer.alloc(0))])}function Ma(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(gd(n)),Buffer.concat([a,n,r])}var hd=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 gd(t){let e=4294967295;for(let a of t)e=hd[(e^a)&255]^e>>>8;return(e^4294967295)>>>0}ft();Jc();var zt=7,xd=["waiting_owner","needs_attention"],vd={gitlab:"GitLab",github:"GitHub",telegram:"Telegram",whatsapp:"WhatsApp",slack:"Slack",discord:"Discord",voice:"Voice",app:"Phone app",dashboard:"Dashboard",webrtc:"Call"};function Ue(t,e){let a=t.toLowerCase().split("@")[0],n=vd[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 wo(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 ko(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(v=>v.name==="person"),i=v=>({id:v.id,state:v.state,agentId:v.agent_id,text:v.text,channel:v.channel,chatId:v.chat_id,createdAt:v.created_at,updatedAt:v.updated_at,closedAt:v.closed_at??null,question:v.question??null,attentionReason:v.attention_reason??null,evidence:v.evidence??null,where:{label:Ue(v.channel,v.chat_id),url:a.linkFor?.(v.channel,v.chat_id)??null}}),l=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${ha.map(()=>"?").join(",")}) ORDER BY created_at, rowid`).all(e,...ha).map(i):[],c=s?t.prepare(`SELECT * FROM requests WHERE person = ? AND state IN (${ga.map(()=>"?").join(",")}) AND COALESCE(closed_at, updated_at) >= ?
|
|
1049
|
+
ORDER BY COALESCE(closed_at, updated_at) DESC LIMIT 50`).all(e,...ga,n-zt*864e5).map(i):[],d=[];try{d=jt(t,e,50).filter(v=>v.startedAt>=n-zt*864e5)}catch{}let p=new Map;if(s&&d.length){let v=t.prepare(`SELECT l.ref, r.id, r.state, r.evidence FROM request_links l JOIN requests r ON r.id = l.request_id
|
|
1050
|
+
WHERE l.kind = 'run' AND r.person = ? AND l.ref IN (${d.map(()=>"?").join(",")})`).all(e,...d.map(E=>E.taskId));for(let E of v)p.set(E.ref,{id:E.id,state:E.state,evidence:E.evidence??null})}let m=d.map(v=>({...v,where:v.channel?{label:Ue(v.channel,v.chatId??""),url:a.linkFor?.(v.channel,v.chatId??"")??null}:null,request:p.get(v.taskId)??null})),f=new Set(m.map(v=>v.request?.id).filter(Boolean)),_=[...l.filter(v=>!xd.includes(v.state)),...c].filter(v=>!f.has(v.id));return{open:l,recent:c,runs:m,other:_}}va();Kc();var _o={waiting:0,yours:0,ahead:null};function So(t,e,a={}){let n=$n(t),r=new Map,o=[],s=new Map;for(let i of n){let l=`${i.agentId}\0${i.channel}\0${i.chatId}`,c=s.get(l)??0;s.set(l,c+1);let d=r.get(i.agentId)??{waiting:0,yours:0,ahead:null};d.waiting++,i.person===e&&(d.yours++,d.ahead===null&&(d.ahead=c),o.push({agentId:i.agentId,channel:i.channel,chatId:i.chatId,queuedAt:i.queuedAt,messagePreview:i.messagePreview,where:{label:Ue(i.channel,i.chatId),url:a.linkFor?.(i.channel,i.chatId)??null},ahead:c})),r.set(i.agentId,d)}return{byAgent:r,mine:o}}var bd=4e3;function Eo(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-zt*864e5).map(r=>r.agent_id)}function
|
|
1052
|
+
GROUP BY agent_id ORDER BY last DESC LIMIT 12`).all(e.id,a-zt*864e5).map(r=>r.agent_id)}function To(t,e,a,n){let r=new Set(n.people.filter(l=>l.role==="owner").map(l=>l.id));r.add(mt);let o=l=>l===e?"you":l&&r.has(l)?"owner":"other",s=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status = 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1"),i=t.prepare("SELECT * FROM task_traces WHERE agent_id = ? AND status != 'in-flight' ORDER BY started_at DESC, rowid DESC LIMIT 1");return a.map(l=>{let c=n.queue?.get(l)??_o,d=s.get(l),p=d??i.get(l);if(!p)return{agentId:l,state:"free",by:null,at:null,text:null,fullText:null,where:null,queue:c};let m=o(p.person??null),f=p.status==="error"||p.status==="timeout",_=d?"working":f&&m==="you"?"blocked":"free",v=m==="you"&&p.channel!=="a2a",E=v&&p.channel;return{agentId:l,state:_,by:m,at:d?p.started_at:p.finished_at??p.started_at,text:d||v?p.message_preview??null:null,fullText:v&&d&&String(p.original_message??p.message_preview??"").slice(0,bd)||null,where:E?{label:Ue(p.channel,p.chat_id??""),url:n.linkFor?.(p.channel,p.chat_id??"")??null}:null,queue:c}})}function Ao(t){return t>=200&&t<300?"retry":t===401?"lock":"keep"}function Co(t,e){return!t||e-t>=3e4||t>e}function qt(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 Io(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 Ft(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 Ut(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 Mo(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 Lo(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 Ro(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 Po(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 $o(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 jo=`
|
|
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
|
+
`,Oo=`
|
|
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
|
+
`,No=`
|
|
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 yd="<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 La(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>${ze}${Wt}</style>`}function
|
|
1393
|
+
${yd}
|
|
1394
|
+
<style>${ze}${Wt}</style>`}function Do(){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 Bo=`
|
|
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) {
|
|
@@ -1421,14 +1421,14 @@ self.addEventListener('fetch', function (e) {
|
|
|
1421
1421
|
e.respondWith(caches.match(url.pathname).then(function (hit) { return hit || fetch(req); }));
|
|
1422
1422
|
}
|
|
1423
1423
|
});
|
|
1424
|
-
`;function
|
|
1424
|
+
`;function Ra(t,e="",a="My work"){return`<header class="bar">
|
|
1425
1425
|
<img class="mark" src="/member/icon-192.png" alt="" width="36" height="36">
|
|
1426
1426
|
<div class="grow"><h1>${a}</h1><p id="who" class="who">${t}</p></div>${e}
|
|
1427
|
-
</header>`}var
|
|
1427
|
+
</header>`}var Pa=La,$a=Ra;function Ho(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 zo(){return`<!doctype html>
|
|
1428
1428
|
<html lang="en">
|
|
1429
|
-
<head>${
|
|
1429
|
+
<head>${Pa("My work \xB7 AgentX")}<style>${Gt}</style></head>
|
|
1430
1430
|
<body>
|
|
1431
|
-
${
|
|
1431
|
+
${$a("Connecting\u2026",`
|
|
1432
1432
|
<button type="button" id="theme" class="icon-btn" aria-label="Switch theme">\u25D0</button>`)}
|
|
1433
1433
|
<p id="offline" class="strip" role="status" hidden><span id="offline-text"></span><button type="button" id="retry" hidden>Try now</button></p>
|
|
1434
1434
|
<aside id="install" class="install" aria-label="Keep this window" hidden>To keep this window on your desktop: in Edge or Chrome open the browser menu, then <b>Apps</b>, then <b>Install this site as an app</b>.</aside>
|
|
@@ -1439,15 +1439,15 @@ ${Pa("Connecting\u2026",`
|
|
|
1439
1439
|
<section aria-labelledby="h-sent"><h2 id="h-sent" tabindex="-1">What you sent <span class="n">(last 7 days)</span></h2><ul id="sent" class="rows" role="list"></ul></section>
|
|
1440
1440
|
<p id="updated" class="foot"></p>
|
|
1441
1441
|
</main>
|
|
1442
|
-
<script>${q({workState:
|
|
1442
|
+
<script>${q({workState:wd,ageText:ja,connectionNote:Ft,plainPreview:Ut,agentLine:Mo,sentState:Lo,requestState:Ro,summaryLine:Po,freedAgents:$o})}${jo}</script>
|
|
1443
1443
|
</body>
|
|
1444
|
-
</html>`}function
|
|
1444
|
+
</html>`}function qo(){return`<!doctype html>
|
|
1445
1445
|
<html lang="en">
|
|
1446
|
-
<head>${
|
|
1446
|
+
<head>${Pa("Pair this machine \xB7 AgentX")}<style>${Oo}</style></head>
|
|
1447
1447
|
<body>
|
|
1448
|
-
${
|
|
1448
|
+
${$a("This machine is not paired yet")}
|
|
1449
1449
|
<main class="narrow">
|
|
1450
|
-
${
|
|
1450
|
+
${Ho(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 @@ ${Pa("This machine is not paired yet")}
|
|
|
1464
1464
|
<p class="help">No code? Ask the person who invited you for one. A code works once, for 10 minutes.</p>
|
|
1465
1465
|
</div>
|
|
1466
1466
|
</main>
|
|
1467
|
-
<script>${q({formatPairInput:qt})}${
|
|
1467
|
+
<script>${q({formatPairInput:qt})}${kd}</script>
|
|
1468
1468
|
</body>
|
|
1469
|
-
</html>`}function
|
|
1469
|
+
</html>`}function Fo(){return`<!doctype html>
|
|
1470
1470
|
<html lang="en">
|
|
1471
|
-
<head>${
|
|
1471
|
+
<head>${Pa("Waiting for the owner \xB7 AgentX")}<style>${No}</style></head>
|
|
1472
1472
|
<body>
|
|
1473
|
-
${
|
|
1473
|
+
${$a("This machine is paired")}
|
|
1474
1474
|
<main class="narrow">
|
|
1475
|
-
${
|
|
1475
|
+
${Ho(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>${_d}</script>
|
|
1483
1483
|
</body>
|
|
1484
|
-
</html>`}function
|
|
1484
|
+
</html>`}function wd(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 ja(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 kd=`
|
|
1485
1485
|
(function () {
|
|
1486
1486
|
var form = document.getElementById('pair-form');
|
|
1487
1487
|
var machine = document.getElementById('machine');
|
|
@@ -1525,7 +1525,7 @@ ${Pa("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
|
+
`,_d=`
|
|
1529
1529
|
(function () {
|
|
1530
1530
|
var msg = document.getElementById('msg');
|
|
1531
1531
|
function check() {
|
|
@@ -1536,15 +1536,15 @@ ${Pa("This machine is paired")}
|
|
|
1536
1536
|
}
|
|
1537
1537
|
setInterval(check, 5000);
|
|
1538
1538
|
})();
|
|
1539
|
-
`;function
|
|
1539
|
+
`;function Uo(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 Wo(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 Go(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 Oa="/member/client.webmanifest",Ze="Your project";function Xo(){return JSON.stringify({id:"/member?client",name:`${Ze} \xB7 AgentX`,short_name:Ze,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 Sd=`
|
|
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 Ko(){return`<!doctype html>
|
|
1544
1544
|
<html lang="en">
|
|
1545
|
-
<head>${
|
|
1545
|
+
<head>${La(`${Ze} \xB7 AgentX`,{manifest:Oa,appTitle:Ze})}<style>${ze}${Wt}${Gt}${Sd}</style></head>
|
|
1546
1546
|
<body>
|
|
1547
|
-
${
|
|
1547
|
+
${Ra("Connecting\u2026",`
|
|
1548
1548
|
<button type="button" id="theme" class="icon-btn" aria-label="Switch theme">\u25D0</button>`,Ze)}
|
|
1549
1549
|
<p id="offline" class="strip" role="status" hidden><span id="offline-text"></span><button type="button" id="retry" hidden>Try now</button></p>
|
|
1550
1550
|
<aside id="install" class="install" aria-label="Keep this window" hidden>To keep this window on your desktop: in Edge or Chrome open the browser menu, then <b>Apps</b>, then <b>Install this site as an app</b>.</aside>
|
|
@@ -1557,9 +1557,9 @@ ${La("Connecting\u2026",`
|
|
|
1557
1557
|
</section>
|
|
1558
1558
|
<p id="updated" class="foot"></p>
|
|
1559
1559
|
</main>
|
|
1560
|
-
<script>${q({ageText
|
|
1560
|
+
<script>${q({ageText:ja,connectionNote:Ft,plainPreview:Ut,clientSentState:Uo,clientRequestState:Wo,clientSummary:Go})}${Ed}</script>
|
|
1561
1561
|
</body>
|
|
1562
|
-
</html>`}var
|
|
1562
|
+
</html>`}var Ed=`
|
|
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 @@ ${La("Connecting\u2026",`
|
|
|
1666
1666
|
showConn();
|
|
1667
1667
|
load();
|
|
1668
1668
|
})();
|
|
1669
|
-
`;var Xt="agentx_member",Ed=90*86400,Td=new At,Vo=t=>t.replace(/^\[app\]/,"[member]"),Ad=new Ie(t=>console.log(Vo(t))),Xo=new WeakMap;function Cd(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return Ad;let e=Xo.get(t.log);return e||Xo.set(t.log,e=new Ie(a=>t.log(Vo(a)))),e}var Ko=null;function et(t,e=X){try{return Ko=e().people}catch{return Ko??t}}async function Yo(t,e,a,n,r){if(a!=="/member"&&!a.startsWith("/member/")&&!a.startsWith("/api/member/"))return!1;let o=r.tokens??new G(r.root),s=r.members??new ht(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new kt(r.root),limiter:r.pairLimiter??Td,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return fe(e,200,"application/manifest+json",Oo());if(a===ja)return fe(e,200,"application/manifest+json",Wo());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),fe(e,200,"text/javascript; charset=utf-8",No);if(a==="/member/icon-192.png")return fe(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/member/icon-512.png")return fe(e,200,"image/png",Fe(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let p=await Ur(t,i);return p.status===200&&e.setHeader("Set-Cookie",Jo(p.token)),p.status===429&&e.setHeader("Retry-After",String(p.retryAfter)),we(e,p.status,p.body)}let l=Gr(Md(t),i,Fr(t));if(!l.ok){if(l.status===401){let p=Oa(t);return Cd(r).record(a.slice(0,120),Bt(t,qe(Na(t,Xt),o),p?qe(p,o):null)),a==="/member"?fe(e,401,"text/html; charset=utf-8",Ho()):we(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?fe(e,202,"text/html; charset=utf-8",zo()):we(e,403,{error:l.error,waiting:!0})}let c=r.people().find(p=>p.id===l.personId),d=c?.role==="client";if(n==="GET"&&a==="/member"){let p=Na(t,Xt);return p&&!Oa(t)&&e.setHeader("Set-Cookie",Jo(p)),fe(e,200,"text/html; charset=utf-8",d?Go():Bo())}if(n==="GET"&&a==="/api/member/me")return we(e,200,{person:l.personId,name:c?.name??l.personId,role:c?.role??"member",device:l.device.name,since:l.device.approvedAt??l.device.createdAt,node:r.nodeName??null});if(n==="GET"&&a==="/api/member/work"){let p=r.db?.()??null;if(!p)return we(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),f=yo(p,l.personId,{now:m,linkFor:r.linkFor}),_=(x,g)=>{let u=g instanceof Error?g.message:String(g);/no such table/i.test(u)||r.log?.(`[member] ${x} failed: ${u}`)},b={byAgent:new Map,mine:[]};try{b=ko(p,l.personId,{linkFor:r.linkFor})}catch(x){_("the line",x)}let E=[];if(d)return we(e,200,{...Id(f),agents:E});try{let x=_o(p,c??{id:l.personId},m);E=So(p,l.personId,x,{people:r.people(),linkFor:r.linkFor,queue:b.byAgent})}catch(x){_("agent cards",x)}return we(e,200,{...f,agents:E,queued:b.mine})}return we(e,404,{error:"not found"})}function Id(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 Jo(t){return`${Xt}=${t}; Path=/; Max-Age=${Ed}; HttpOnly; Secure; SameSite=Lax`}function Md(t){return Oa(t)??Na(t,Xt)}function Oa(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Na(t,e){for(let a of(t.headers.cookie||"").split(";")){let n=a.indexOf("=");if(n>0&&a.slice(0,n).trim()===e)return a.slice(n+1).trim()||null}return null}function fe(t,e,a,n,r="no-store"){return t.writeHead(e,{"Content-Type":a,"Cache-Control":r}),t.end(n),!0}function we(t,e,a){return fe(t,e,"application/json",JSON.stringify(a))}Wc();var Qo='/*! 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 Jt,readFileSync as ss,writeFileSync as is,rmSync as wx,mkdirSync as Od,copyFileSync as Nd,readdirSync as Dd}from"fs";import{resolve as We}from"path";Gc();function es(t){let e=dt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:dt.parse({});return{enabled:a.enabled,secretEnv:a.secretEnv,secretSet:!!process.env[a.secretEnv],batchSeconds:a.batchSeconds,allowAutoAck:a.allowAutoAck,rules:a.rules,...e.success?{}:{error:e.error.issues[0]?.message??"invalid whatsappTriage section"}}}function Kt(t){return C(e=>{let a=e.whatsappTriage&&typeof e.whatsappTriage=="object"?e.whatsappTriage:{};a.rules=Array.isArray(a.rules)?a.rules:[];let n=t(a,e),r=dt.safeParse(a);if(!r.success){let o=r.error.issues[0];throw new Error(`${o?.path.join(".")||"whatsappTriage"}: ${o?.message??"invalid"}`)}return e.whatsappTriage=a,n})}var Zo=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function ts(t){return Kt(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 as(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Kt((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:Zo(t?.chats),senders:Zo(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 ns(t){let e=String(t?.id??"");return Kt(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 rs(t){let e=String(t?.id??"");return Kt(a=>{if(!a.rules.some(n=>n.id===e))throw new Error(`Watch rule "${e}" not found.`);return a.rules=a.rules.filter(n=>n.id!==e),`removed watch rule "${e}"`})}ft();var pe={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>',actions:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>'};function os(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=de({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+Pt([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">')+'<div class="ax-wit" id="ax-voice-missing" style="display:none"><span class="ax-wit__icon">!</span><div></div></div>';return I({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Rd()+Rr,css:$d,scripts:`${e}<script>${Pr}
|
|
1670
|
-
${
|
|
1671
|
-
${
|
|
1672
|
-
${
|
|
1669
|
+
`;var Xt="agentx_member",Td=90*86400,Ad=new At,Qo=t=>t.replace(/^\[app\]/,"[member]"),Cd=new Ie(t=>console.log(Qo(t))),Jo=new WeakMap;function Id(t){if(t.rejectLog)return t.rejectLog;if(!t.log)return Cd;let e=Jo.get(t.log);return e||Jo.set(t.log,e=new Ie(a=>t.log(Qo(a)))),e}var Vo=null;function et(t,e=X){try{return Vo=e().people}catch{return Vo??t}}async function Zo(t,e,a,n,r){if(a!=="/member"&&!a.startsWith("/member/")&&!a.startsWith("/api/member/"))return!1;let o=r.tokens??new G(r.root),s=r.members??new ht(r.root),i={tokens:o,members:s,people:r.people,root:r.root,codes:r.pairCodes??new kt(r.root),limiter:r.pairLimiter??Ad,minMs:r.pairMinMs,log:r.log,now:r.now};if(n==="GET"){if(a==="/member/manifest.webmanifest")return fe(e,200,"application/manifest+json",Do());if(a===Oa)return fe(e,200,"application/manifest+json",Xo());if(a==="/member/sw.js")return e.setHeader("Service-Worker-Allowed","/member"),fe(e,200,"text/javascript; charset=utf-8",Bo);if(a==="/member/icon-192.png")return fe(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/member/icon-512.png")return fe(e,200,"image/png",Fe(512),"public, max-age=86400")}if(n==="POST"&&a==="/api/member/pair-code"){let p=await Gr(t,i);return p.status===200&&e.setHeader("Set-Cookie",Yo(p.token)),p.status===429&&e.setHeader("Retry-After",String(p.retryAfter)),we(e,p.status,p.body)}let l=Kr(Ld(t),i,Wr(t));if(!l.ok){if(l.status===401){let p=Na(t);return Id(r).record(a.slice(0,120),Bt(t,qe(Da(t,Xt),o),p?qe(p,o):null)),a==="/member"?fe(e,401,"text/html; charset=utf-8",qo()):we(e,401,{error:l.error,hint:"ask the owner to run: agentx people invite <you>"})}return a==="/member"?fe(e,202,"text/html; charset=utf-8",Fo()):we(e,403,{error:l.error,waiting:!0})}let c=r.people().find(p=>p.id===l.personId),d=c?.role==="client";if(n==="GET"&&a==="/member"){let p=Da(t,Xt);return p&&!Na(t)&&e.setHeader("Set-Cookie",Yo(p)),fe(e,200,"text/html; charset=utf-8",d?Ko():zo())}if(n==="GET"&&a==="/api/member/me")return we(e,200,{person:l.personId,name:c?.name??l.personId,role:c?.role??"member",device:l.device.name,since:l.device.approvedAt??l.device.createdAt,node:r.nodeName??null});if(n==="GET"&&a==="/api/member/work"){let p=r.db?.()??null;if(!p)return we(e,503,{error:"the work list needs the database"});let m=(r.now??Date.now)(),f=ko(p,l.personId,{now:m,linkFor:r.linkFor}),_=(x,g)=>{let u=g instanceof Error?g.message:String(g);/no such table/i.test(u)||r.log?.(`[member] ${x} failed: ${u}`)},v={byAgent:new Map,mine:[]};try{v=So(p,l.personId,{linkFor:r.linkFor})}catch(x){_("the line",x)}let E=[];if(d)return we(e,200,{...Md(f),agents:E});try{let x=Eo(p,c??{id:l.personId},m);E=To(p,l.personId,x,{people:r.people(),linkFor:r.linkFor,queue:v.byAgent})}catch(x){_("agent cards",x)}return we(e,200,{...f,agents:E,queued:v.mine})}return we(e,404,{error:"not found"})}function Md(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 Yo(t){return`${Xt}=${t}; Path=/; Max-Age=${Td}; HttpOnly; Secure; SameSite=Lax`}function Ld(t){return Na(t)??Da(t,Xt)}function Na(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function Da(t,e){for(let a of(t.headers.cookie||"").split(";")){let n=a.indexOf("=");if(n>0&&a.slice(0,n).trim()===e)return a.slice(n+1).trim()||null}return null}function fe(t,e,a,n,r="no-store"){return t.writeHead(e,{"Content-Type":a,"Cache-Control":r}),t.end(n),!0}function we(t,e,a){return fe(t,e,"application/json",JSON.stringify(a))}Gc();var es='/*! 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 Jt,readFileSync as ls,writeFileSync as cs,rmSync as kx,mkdirSync as Nd,copyFileSync as Dd,readdirSync as Bd}from"fs";import{resolve as We}from"path";Xc();function as(t){let e=dt.safeParse(t?.whatsappTriage??{}),a=e.success?e.data:dt.parse({});return{enabled:a.enabled,secretEnv:a.secretEnv,secretSet:!!process.env[a.secretEnv],batchSeconds:a.batchSeconds,allowAutoAck:a.allowAutoAck,rules:a.rules,...e.success?{}:{error:e.error.issues[0]?.message??"invalid whatsappTriage section"}}}function Kt(t){return C(e=>{let a=e.whatsappTriage&&typeof e.whatsappTriage=="object"?e.whatsappTriage:{};a.rules=Array.isArray(a.rules)?a.rules:[];let n=t(a,e),r=dt.safeParse(a);if(!r.success){let o=r.error.issues[0];throw new Error(`${o?.path.join(".")||"whatsappTriage"}: ${o?.message??"invalid"}`)}return e.whatsappTriage=a,n})}var ts=t=>(Array.isArray(t)?t:String(t??"").split(/[,\n]/)).map(e=>String(e).trim()).filter(Boolean);function ns(t){return Kt(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 rs(t){let e=String(t?.id??"").trim(),a=String(t?.agent??"").trim();return Kt((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:ts(t?.chats),senders:ts(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 os(t){let e=String(t?.id??"");return Kt(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 ss(t){let e=String(t?.id??"");return Kt(a=>{if(!a.rules.some(n=>n.id===e))throw new Error(`Watch rule "${e}" not found.`);return a.rules=a.rules.filter(n=>n.id!==e),`removed watch rule "${e}"`})}ft();var pe={agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>',channels:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z"/></svg>',schedules:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg>',webhooks:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M10 12a3 3 0 1 0 3-3m-8 11a3 3 0 1 0 2.6-1.5L10 12m7 3a3 3 0 1 0-2-5.5"/></svg>',mesh:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="6" cy="18" r="2"/><circle cx="18" cy="18" r="2"/><circle cx="12" cy="12" r="2"/><path d="M7.4 7.4l3.2 3.2M13.4 13.4l3.2 3.2M16.6 7.4l-3.2 3.2M10.6 13.4l-3.2 3.2"/></svg>',tokens:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M21 2l-2 2m-8 8a4 4 0 1 1-6 6m6-6l5-5 3 3-5 5m-3-3l3 3"/></svg>',advanced:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><path d="M8 4h8l4 4v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/><path d="M9 13l2 2 4-4"/></svg>',actions:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>'};function is(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=de({kicker:"Settings",title:"Your team's control room",lead:`Manage the agents, the places they answer from, and who's allowed to reach them. Everything here writes to <span class="mono muted">agentx.json</span> on your machine \u2014 nothing leaves.`})+Pt([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">')+'<div class="ax-wit" id="ax-voice-missing" style="display:none"><span class="ax-wit__icon">!</span><div></div></div>';return I({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Pd()+$r,css:jd,scripts:`${e}<script>${jr}
|
|
1670
|
+
${Or}
|
|
1671
|
+
${Rd}
|
|
1672
|
+
${Od}</script>`})}var Rd=`
|
|
1673
1673
|
(function(){
|
|
1674
1674
|
function fmt(n) { return n == null ? '\u2014' : String(n); }
|
|
1675
1675
|
async function voiceMissing() {
|
|
@@ -1763,8 +1763,8 @@ ${jd}</script>`})}var Ld=`
|
|
|
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 Pd(){let t=yr().business?`<button data-tab="business">Business</button>
|
|
1767
|
+
`:"";return $d.replace("__BUSINESS_TABS__",t)}var $d=`
|
|
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>
|
|
@@ -2423,7 +2423,7 @@ ${jd}</script>`})}var Ld=`
|
|
|
2423
2423
|
<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>
|
|
2424
2424
|
</section>
|
|
2425
2425
|
</main>
|
|
2426
|
-
|
|
2426
|
+
`,jd=`
|
|
2427
2427
|
|
|
2428
2428
|
/* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
|
|
2429
2429
|
nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
|
|
@@ -2631,7 +2631,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
|
|
|
2631
2631
|
.peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
|
|
2632
2632
|
padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
|
|
2633
2633
|
.peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
|
|
2634
|
-
`,
|
|
2634
|
+
`,Od=`
|
|
2635
2635
|
const $ = (id) => document.getElementById(id);
|
|
2636
2636
|
let state = null;
|
|
2637
2637
|
|
|
@@ -5515,11 +5515,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
|
|
|
5515
5515
|
})();
|
|
5516
5516
|
|
|
5517
5517
|
refresh();
|
|
5518
|
-
`;function ls(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(os({peers:a,localToken:n}))}async function cs(t,e){let a=Ha();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function ds(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Qd(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Bd(t),r={"GET /api/admin/state":()=>zd(),"POST /api/admin/agents":()=>Xd(n),"PATCH /api/admin/agents":()=>Kd(n),"DELETE /api/admin/agents":()=>Jd(n),"POST /api/admin/agents/access":()=>qd(n),"POST /api/admin/channels/telegram":()=>Vd(n),"DELETE /api/admin/channels/telegram":()=>yp(n),"POST /api/admin/channels/telegram/toggle":()=>wp(n),"POST /api/admin/crons":()=>kp(n),"DELETE /api/admin/crons":()=>_p(n),"POST /api/admin/config/raw":()=>Sp(n),"GET /api/admin/tokens":()=>Fd(),"POST /api/admin/tokens":()=>Ud(n),"DELETE /api/admin/tokens":()=>Wd(n),"POST /api/admin/agents/test":()=>Gd(n),"POST /api/admin/agents/integrations":()=>rp(n),"DELETE /api/admin/agents/integrations":()=>op(n),"PATCH /api/admin/agents/integrations":()=>sp(n),"PATCH /api/admin/channels/telegram":()=>Yd(n),"POST /api/admin/channels/slack":()=>mp(n),"POST /api/admin/channels/slack/toggle":()=>fp(n),"POST /api/admin/channels/discord":()=>hp(n),"POST /api/admin/channels/discord/toggle":()=>gp(n),"POST /api/admin/channels/gitlab":()=>xp(n),"POST /api/admin/channels/gitlab/toggle":()=>bp(n),"POST /api/admin/channels/request-status":()=>Jr(n),"GET /api/admin/channels/whatsapp/state":()=>tt("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>tt("/webrtc/history"),"POST /api/admin/actions":()=>Np(n),"DELETE /api/admin/actions":()=>Dp(n),"POST /api/admin/actions/run":()=>Bp(n),"GET /api/admin/channels/whatsapp/chats":()=>tt("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>tt("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>he("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>vp(n),"POST /api/admin/webhooks":()=>ip(n),"PATCH /api/admin/webhooks":()=>lp(n),"DELETE /api/admin/webhooks":()=>up(n),"POST /api/admin/whatsapp-triage":()=>ts(n),"POST /api/admin/whatsapp-triage/rules":()=>as(n),"PATCH /api/admin/whatsapp-triage/rules":()=>ns(n),"DELETE /api/admin/whatsapp-triage/rules":()=>rs(n),"POST /api/admin/mesh/peers":()=>cp(n),"DELETE /api/admin/mesh/peers":()=>dp(n),"POST /api/admin/mesh/toggle":()=>pp(n),"GET /api/admin/files":()=>Zd(t),"GET /api/admin/files/read":()=>ep(t),"PUT /api/admin/files":()=>tp(n),"POST /api/admin/files/skill":()=>ap(n),"DELETE /api/admin/files/skill":()=>np(n),"POST /api/admin/business/orgchart":()=>Ep(n),"DELETE /api/admin/business/orgchart":()=>Tp(n),"POST /api/admin/business/project":()=>Ap(n),"DELETE /api/admin/business/project":()=>Mp(n),"POST /api/admin/business/client":()=>Cp(n),"DELETE /api/admin/business/client":()=>Ip(n),"POST /api/admin/business/contact":()=>Lp(n),"DELETE /api/admin/business/contact":()=>Rp(n),"POST /api/admin/boards":()=>Pp(n),"DELETE /api/admin/boards":()=>$p(n),"POST /api/admin/boards/columns":()=>jp(n),"DELETE /api/admin/boards/columns":()=>Op(n),"POST /api/admin/notifications":()=>zp(n),"POST /api/admin/screen":()=>qp(n),"POST /api/admin/webhooks/triggers":()=>Fp(n),"POST /api/admin/mesh/health":()=>Hp(n),"GET /api/admin/projects":()=>tt("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>he("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>he("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>he("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>he("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>he("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>he("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>he("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>he("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Da(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();Da(e,200,i)}catch(n){Da(e,400,{error:n.message||"admin op failed"})}}function Da(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Bd(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 Hd(t){let e=We(process.cwd(),t);if(!Jt(e))return[];let a=[];for(let n of Dd(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(ss(We(e,n.name),"utf-8")))}catch{}return a}function Ha(){let t=We(process.cwd(),"agentx.json");return Jt(t)?JSON.parse(ss(t,"utf-8")):null}function zd(){let t=Ha();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([g,u])=>({id:g,name:u.name,tier:u.tier,model:u.model,mentions:u.mentions||[],workspace:u.workspace,access:u.access||"private",systemPrompt:u.systemPrompt||"",maxConcurrent:u.maxConcurrent??1,maxExecutionMinutes:u.maxExecutionMinutes??20,permissionMode:u.permissionMode||"default",integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(h=>{let w=h.credentials||{},y={};for(let[T,v]of Object.entries(w))typeof v=="string"&&/^[A-Z][A-Z0-9_]*$/.test(v)?y[T]=process.env[v]?"set":"unset":typeof v=="string"&&(y[T]="literal");return{kind:h.kind,label:h.label,enabled:h.enabled!==!1,credentials:w,credStatus:y,metadata:h.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([g,u])=>({id:g,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(([g,u])=>({id:g,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(g=>({id:g.id,source:g.source,agentId:g.agentId,secretEnv:g.secretEnv||"",description:g.description||"",enabled:g.enabled!==!1,triggers:g.triggers&&typeof g.triggers=="object"?g.triggers:{},defaultWorkflow:g.defaultWorkflow||""})):[],d={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(g=>({url:g.url,name:g.name,hasToken:!!g.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},p=t.dashboard?.daemonUrl||"http://localhost:18800",m=t.business||{},f={enabled:!!m.enabled,timezone:m.timezone||"UTC",orgChart:m.orgChart||{},projects:Array.isArray(m.projects)?m.projects:[],contactMap:Array.isArray(m.contactMap)?m.contactMap:[],clients:m.clients&&typeof m.clients=="object"?m.clients:{}},_=t.notifications||{},b={longTaskThreshold:_.longTaskThreshold??30,destination:_.destination||null,on:{taskComplete:_.on?.taskComplete!==!1,taskError:_.on?.taskError!==!1,taskQueued:!!_.on?.taskQueued},local:Zn(_.local),ntfy:Yr(t.channels?.ntfy)},E=[];try{E=Hd(".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,h)=>u.id.localeCompare(h.id))}catch{}let x=(Array.isArray(t.boards)?t.boards:[]).map(g=>({id:g.id,name:g.name,source:g.source||{type:"gitlab",projects:[]},primaryToolLabel:g.primaryToolLabel||"",timeRangeDays:g.timeRangeDays??30,closedWindowDays:g.closedWindowDays??30,columns:Array.isArray(g.columns)?g.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,requestStatus:Kr(t),whatsappTriage:es(t),crons:l,webhooks:c,mesh:d,daemonUrl:p,nodeName:t.node?.name,business:f,boards:x,notifications:b,screen:Ir(t.screen),actions:E}}function qd(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 Fd(){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 Ud(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 Wd(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 Gd(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let d=X();r=d.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=d.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),c;try{c=JSON.parse(l)}catch{c={content:l}}if(!i.ok)throw new Error(c?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:c}}function Xd(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=We(process.cwd(),"agents",e),{summary:l}=C(d=>{if(d.agents=d.agents||{},d.agents[e])throw new Error(`Agent "${e}" already exists.`);let p={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(p.model=o),s&&(p.systemPrompt=s.slice(0,400)),d.agents[e]=p,`added agent "${e}"`}),c=We(i,"CLAUDE.md");if(!Jt(c))try{Od(i,{recursive:!0}),is(c,`# ${a}
|
|
5518
|
+
`;function ds(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(is({peers:a,localToken:n}))}async function ps(t,e){let a=za();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function us(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Zd(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Hd(t),r={"GET /api/admin/state":()=>qd(),"POST /api/admin/agents":()=>Kd(n),"PATCH /api/admin/agents":()=>Jd(n),"DELETE /api/admin/agents":()=>Vd(n),"POST /api/admin/agents/access":()=>Fd(n),"POST /api/admin/channels/telegram":()=>Yd(n),"DELETE /api/admin/channels/telegram":()=>wp(n),"POST /api/admin/channels/telegram/toggle":()=>kp(n),"POST /api/admin/crons":()=>_p(n),"DELETE /api/admin/crons":()=>Sp(n),"POST /api/admin/config/raw":()=>Ep(n),"GET /api/admin/tokens":()=>Ud(),"POST /api/admin/tokens":()=>Wd(n),"DELETE /api/admin/tokens":()=>Gd(n),"POST /api/admin/agents/test":()=>Xd(n),"POST /api/admin/agents/integrations":()=>op(n),"DELETE /api/admin/agents/integrations":()=>sp(n),"PATCH /api/admin/agents/integrations":()=>ip(n),"PATCH /api/admin/channels/telegram":()=>Qd(n),"POST /api/admin/channels/slack":()=>fp(n),"POST /api/admin/channels/slack/toggle":()=>hp(n),"POST /api/admin/channels/discord":()=>gp(n),"POST /api/admin/channels/discord/toggle":()=>xp(n),"POST /api/admin/channels/gitlab":()=>vp(n),"POST /api/admin/channels/gitlab/toggle":()=>bp(n),"POST /api/admin/channels/request-status":()=>Yr(n),"GET /api/admin/channels/whatsapp/state":()=>tt("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>tt("/webrtc/history"),"POST /api/admin/actions":()=>Dp(n),"DELETE /api/admin/actions":()=>Bp(n),"POST /api/admin/actions/run":()=>Hp(n),"GET /api/admin/channels/whatsapp/chats":()=>tt("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>tt("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>he("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>yp(n),"POST /api/admin/webhooks":()=>lp(n),"PATCH /api/admin/webhooks":()=>cp(n),"DELETE /api/admin/webhooks":()=>mp(n),"POST /api/admin/whatsapp-triage":()=>ns(n),"POST /api/admin/whatsapp-triage/rules":()=>rs(n),"PATCH /api/admin/whatsapp-triage/rules":()=>os(n),"DELETE /api/admin/whatsapp-triage/rules":()=>ss(n),"POST /api/admin/mesh/peers":()=>dp(n),"DELETE /api/admin/mesh/peers":()=>pp(n),"POST /api/admin/mesh/toggle":()=>up(n),"GET /api/admin/files":()=>ep(t),"GET /api/admin/files/read":()=>tp(t),"PUT /api/admin/files":()=>ap(n),"POST /api/admin/files/skill":()=>np(n),"DELETE /api/admin/files/skill":()=>rp(n),"POST /api/admin/business/orgchart":()=>Tp(n),"DELETE /api/admin/business/orgchart":()=>Ap(n),"POST /api/admin/business/project":()=>Cp(n),"DELETE /api/admin/business/project":()=>Lp(n),"POST /api/admin/business/client":()=>Ip(n),"DELETE /api/admin/business/client":()=>Mp(n),"POST /api/admin/business/contact":()=>Rp(n),"DELETE /api/admin/business/contact":()=>Pp(n),"POST /api/admin/boards":()=>$p(n),"DELETE /api/admin/boards":()=>jp(n),"POST /api/admin/boards/columns":()=>Op(n),"DELETE /api/admin/boards/columns":()=>Np(n),"POST /api/admin/notifications":()=>qp(n),"POST /api/admin/screen":()=>Fp(n),"POST /api/admin/webhooks/triggers":()=>Up(n),"POST /api/admin/mesh/health":()=>zp(n),"GET /api/admin/projects":()=>tt("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>he("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>he("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>he("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>he("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>he("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>he("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>he("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>he("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Ba(e,404,{error:`unknown admin endpoint: ${o}`});return}let i=await s();Ba(e,200,i)}catch(n){Ba(e,400,{error:n.message||"admin op failed"})}}function Ba(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Hd(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 zd(t){let e=We(process.cwd(),t);if(!Jt(e))return[];let a=[];for(let n of Bd(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(ls(We(e,n.name),"utf-8")))}catch{}return a}function za(){let t=We(process.cwd(),"agentx.json");return Jt(t)?JSON.parse(ls(t,"utf-8")):null}function qd(){let t=za();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([g,u])=>({id:g,name:u.name,tier:u.tier,model:u.model,mentions:u.mentions||[],workspace:u.workspace,access:u.access||"private",systemPrompt:u.systemPrompt||"",maxConcurrent:u.maxConcurrent??1,maxExecutionMinutes:u.maxExecutionMinutes??20,permissionMode:u.permissionMode||"default",integrations:(Array.isArray(u.integrations)?u.integrations:[]).map(h=>{let w=h.credentials||{},y={};for(let[T,b]of Object.entries(w))typeof b=="string"&&/^[A-Z][A-Z0-9_]*$/.test(b)?y[T]=process.env[b]?"set":"unset":typeof b=="string"&&(y[T]="literal");return{kind:h.kind,label:h.label,enabled:h.enabled!==!1,credentials:w,credStatus:y,metadata:h.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([g,u])=>({id:g,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(([g,u])=>({id:g,schedule:u.schedule,agent:u.agent,prompt:(u.prompt||"").slice(0,200),enabled:u.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(g=>({id:g.id,source:g.source,agentId:g.agentId,secretEnv:g.secretEnv||"",description:g.description||"",enabled:g.enabled!==!1,triggers:g.triggers&&typeof g.triggers=="object"?g.triggers:{},defaultWorkflow:g.defaultWorkflow||""})):[],d={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(g=>({url:g.url,name:g.name,hasToken:!!g.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},p=t.dashboard?.daemonUrl||"http://localhost:18800",m=t.business||{},f={enabled:!!m.enabled,timezone:m.timezone||"UTC",orgChart:m.orgChart||{},projects:Array.isArray(m.projects)?m.projects:[],contactMap:Array.isArray(m.contactMap)?m.contactMap:[],clients:m.clients&&typeof m.clients=="object"?m.clients:{}},_=t.notifications||{},v={longTaskThreshold:_.longTaskThreshold??30,destination:_.destination||null,on:{taskComplete:_.on?.taskComplete!==!1,taskError:_.on?.taskError!==!1,taskQueued:!!_.on?.taskQueued},local:er(_.local),ntfy:Zr(t.channels?.ntfy)},E=[];try{E=zd(".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,h)=>u.id.localeCompare(h.id))}catch{}let x=(Array.isArray(t.boards)?t.boards:[]).map(g=>({id:g.id,name:g.name,source:g.source||{type:"gitlab",projects:[]},primaryToolLabel:g.primaryToolLabel||"",timeRangeDays:g.timeRangeDays??30,closedWindowDays:g.closedWindowDays??30,columns:Array.isArray(g.columns)?g.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:i,requestStatus:Vr(t),whatsappTriage:as(t),crons:l,webhooks:c,mesh:d,daemonUrl:p,nodeName:t.node?.name,business:f,boards:x,notifications:v,screen:Lr(t.screen),actions:E}}function Fd(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 Ud(){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 Wd(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 Gd(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 Xd(t){let e=String(t?.agent||t?.id||"").trim(),a=String(t?.message||"").trim(),n=String(t?.chatId||"").trim()||`admin-${Date.now()}`;if(!e)throw new Error("Agent id is required.");if(!a)throw new Error("Message is required.");let r="http://127.0.0.1:18800",o;try{let d=X();r=d.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=d.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let i=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),l=await i.text(),c;try{c=JSON.parse(l)}catch{c={content:l}}if(!i.ok)throw new Error(c?.error||`daemon HTTP ${i.status}`);return{chatId:n,response:c}}function Kd(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=fs(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=We(process.cwd(),"agents",e),{summary:l}=C(d=>{if(d.agents=d.agents||{},d.agents[e])throw new Error(`Agent "${e}" already exists.`);let p={name:a,workspace:i,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(p.model=o),s&&(p.systemPrompt=s.slice(0,400)),d.agents[e]=p,`added agent "${e}"`}),c=We(i,"CLAUDE.md");if(!Jt(c))try{Nd(i,{recursive:!0}),cs(c,`# ${a}
|
|
5519
5519
|
|
|
5520
5520
|
${s||"You are "+a+"."}
|
|
5521
|
-
`)}catch{}return{summary:l}}function Kd(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),`updated agent "${e}"`});return{summary:n}}function Jd(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 Vd(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 Yd(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 tt(t){let{url:e,headers:a}=za(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function he(t,e){let{url:a,headers:n}=za(),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 Qd(t,e){try{let{url:a,headers:n}=za(),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 za(){let t="http://127.0.0.1:18800",e={};try{let a=X();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function at(t){let a=Ha()?.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 Ba(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Zd(t){let e=Ba(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=He(at(e));return{agentId:e,...a}}function ep(t){let e=Ba(t,"agent").trim(),a=Ba(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Ct(at(e),a)}function tp(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=It(at(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function ap(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=Mt(at(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function np(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=Lt(at(e),a);return{summary:`removed skill "${a}"`,...n}}function rp(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a)throw new Error("kind is required");if(!n)throw new Error("label is required");let r={},o=t?.credentials||{};for(let l of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[l];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${l} must be uppercase identifier (got "${c}")`);r[l]=c.trim()}}if(o.auth==="keyring"&&(r.auth="keyring"),typeof o.sessionDir=="string"&&o.sessionDir.trim()&&(r.sessionDir=o.sessionDir.trim()),Object.keys(r).length===0)throw new Error("at least one credential field required");let s={};for(let[l,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[l]=c);let{summary:i}=C(l=>{if(!l.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(l.agents[e].integrations=Array.isArray(l.agents[e].integrations)?l.agents[e].integrations:[],l.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return l.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:i}}function op(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let{summary:r}=C(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let i=s.integrations||[],l=i.findIndex(c=>c.kind===a&&c.label===n);if(l===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return i.splice(l,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function sp(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let r=t?.patch||{},{summary:o}=C(s=>{let i=s.agents?.[e];if(!i)throw new Error(`Unknown agent "${e}"`);let c=(i.integrations||[]).find(d=>d.kind===a&&d.label===n);if(!c)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(c.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(c.metadata={...c.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var ps=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function ip(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(!ps.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:i}=C(l=>{if(s){if(!(l.mesh?.peers||[]).find(p=>p.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(d=>d.id===e))throw new Error(`Webhook "${e}" already exists.`);let c={id:e,source:a,agentId:n,enabled:!0};return r&&(c.secretEnv=r),o&&(c.description=o),s&&(c.node=s),l.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function lp(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"&&ps.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 cp(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 dp(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 pp(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 up(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 mp(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 fp(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 hp(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 gp(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 xp(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 bp(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 vp(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-E5SASFAH.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 yp(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 wp(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 kp(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 _p(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 Sp(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=We(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Jt(n))try{Nd(n,r)}catch{}is(n,JSON.stringify(a,null,2)+`
|
|
5522
|
-
`,"utf-8");try{let s=X().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function us(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function Ep(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=C(c=>(c.business=c.business||{},c.business.orgChart=c.business.orgChart||{},c.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function Tp(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 Ap(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 Cp(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 Ip(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 Mp(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 Lp(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 Rp(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 Pp(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=C(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let c=l.boards.findIndex(p=>p.id===e),d={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(d.primaryToolLabel=r),c>=0){let p=l.boards[c];return l.boards[c]={...p,...d,columns:p.columns,labels:p.labels},`board "${e}" updated`}return l.boards.push(d),`board "${e}" added`});return{summary:i}}async function $p(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 jp(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=C(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(p=>p.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let c={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");c.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");c.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(c.accent=String(t.accent));let d=l.columns.findIndex(p=>p.id===a);return d>=0?(l.columns[d]={...l.columns[d],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Op(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 Np(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 Dp(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 Bp(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 Hp(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=C(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function zp(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=er(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=Qr(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 qp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=Mr(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Fp(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=C(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}ft();import{resolve as Gp}from"path";function ms(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
5521
|
+
`)}catch{}return{summary:l}}function Jd(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=fs(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function Vd(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 Yd(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 Qd(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 tt(t){let{url:e,headers:a}=qa(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function he(t,e){let{url:a,headers:n}=qa(),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 Zd(t,e){try{let{url:a,headers:n}=qa(),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 qa(){let t="http://127.0.0.1:18800",e={};try{let a=X();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function at(t){let a=za()?.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 Ha(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function ep(t){let e=Ha(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=He(at(e));return{agentId:e,...a}}function tp(t){let e=Ha(t,"agent").trim(),a=Ha(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Ct(at(e),a)}function ap(t){let e=String(t?.agent||"").trim(),a=String(t?.path||"").trim(),n=typeof t?.content=="string"?t.content:"";if(!e||!a)throw new Error("agent and path are required.");let r=It(at(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function np(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim(),n=t?.title?String(t.title):void 0,r=t?.content?String(t.content):void 0;if(!e)throw new Error("agent is required.");let o=Mt(at(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function rp(t){let e=String(t?.agent||"").trim(),a=String(t?.slug||"").trim();if(!e||!a)throw new Error("agent and slug are required.");let n=Lt(at(e),a);return{summary:`removed skill "${a}"`,...n}}function op(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a)throw new Error("kind is required");if(!n)throw new Error("label is required");let r={},o=t?.credentials||{};for(let l of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[l];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${l} must be uppercase identifier (got "${c}")`);r[l]=c.trim()}}if(o.auth==="keyring"&&(r.auth="keyring"),typeof o.sessionDir=="string"&&o.sessionDir.trim()&&(r.sessionDir=o.sessionDir.trim()),Object.keys(r).length===0)throw new Error("at least one credential field required");let s={};for(let[l,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[l]=c);let{summary:i}=C(l=>{if(!l.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(l.agents[e].integrations=Array.isArray(l.agents[e].integrations)?l.agents[e].integrations:[],l.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return l.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:i}}function sp(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let{summary:r}=C(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let i=s.integrations||[],l=i.findIndex(c=>c.kind===a&&c.label===n);if(l===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return i.splice(l,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function ip(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a||!n)throw new Error("kind and label are required");let r=t?.patch||{},{summary:o}=C(s=>{let i=s.agents?.[e];if(!i)throw new Error(`Unknown agent "${e}"`);let c=(i.integrations||[]).find(d=>d.kind===a&&d.label===n);if(!c)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return typeof r.enabled=="boolean"&&(c.enabled=r.enabled),r.metadata&&typeof r.metadata=="object"&&(c.metadata={...c.metadata||{},...r.metadata}),`updated integration (${a}, ${n}) on ${e}`});return{summary:o}}var ms=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function lp(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(!ms.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:i}=C(l=>{if(s){if(!(l.mesh?.peers||[]).find(p=>p.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!l.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(l.webhooks=Array.isArray(l.webhooks)?l.webhooks:[],l.webhooks.find(d=>d.id===e))throw new Error(`Webhook "${e}" already exists.`);let c={id:e,source:a,agentId:n,enabled:!0};return r&&(c.secretEnv=r),o&&(c.description=o),s&&(c.node=s),l.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:i}}function cp(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"&&ms.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 dp(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 pp(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 up(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 mp(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 fp(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 hp(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 gp(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 xp(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 vp(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 bp(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 yp(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-PGUELFMB.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 wp(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 kp(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 _p(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 Sp(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 Ep(t){let e=String(t?.raw||"");if(!e.trim())throw new Error("Config body is empty.");let a;try{a=JSON.parse(e)}catch(o){throw new Error(`Invalid JSON: ${o.message}`)}let n=We(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Jt(n))try{Dd(n,r)}catch{}cs(n,JSON.stringify(a,null,2)+`
|
|
5522
|
+
`,"utf-8");try{let s=X().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function fs(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function Tp(t){let e=String(t?.agentId||"").trim(),a=String(t?.role||"").trim();if(!e)throw new Error("agentId required");if(!a)throw new Error("role required");let n=Array.isArray(t?.days)&&t.days.length>0?t.days:["mon","tue","wed","thu","fri"],r=String(t?.start||"09:00"),o=String(t?.end||"17:00"),s=t?.reportsTo?String(t.reportsTo).trim():"",i=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:l}=C(c=>(c.business=c.business||{},c.business.orgChart=c.business.orgChart||{},c.business.orgChart[e]={role:a,...s?{reportsTo:s}:{},schedule:{days:n,start:r,end:o},utilizationTarget:i},`orgChart "${e}" upserted`));return{summary:l}}async function Ap(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 Cp(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 Ip(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 Mp(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 Lp(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 Rp(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 Pp(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 $p(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(l=>l.trim()).filter(Boolean);if(!e)throw new Error("id required");if(!a)throw new Error("name required");if(n.length===0)throw new Error("at least one project path required");let r=t?.primaryToolLabel?String(t.primaryToolLabel).trim():"",o=Number.isFinite(Number(t?.timeRangeDays))?Number(t.timeRangeDays):30,s=Number.isFinite(Number(t?.closedWindowDays))?Number(t.closedWindowDays):30,{summary:i}=C(l=>{l.boards=Array.isArray(l.boards)?l.boards:[];let c=l.boards.findIndex(p=>p.id===e),d={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(d.primaryToolLabel=r),c>=0){let p=l.boards[c];return l.boards[c]={...p,...d,columns:p.columns,labels:p.labels},`board "${e}" updated`}return l.boards.push(d),`board "${e}" added`});return{summary:i}}async function jp(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 Op(t){let e=String(t?.boardId||"").trim(),a=String(t?.columnId||"").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"-"),n=String(t?.title||"").trim(),r=String(t?.kind||"scoped-label");if(!e)throw new Error("boardId required");if(!a)throw new Error("columnId required");if(!n)throw new Error("title required");if(!["open-backlog","scoped-label","closed","label"].includes(r))throw new Error("kind must be open-backlog | scoped-label | closed | label");let{summary:o}=C(s=>{let l=(Array.isArray(s.boards)?s.boards:[]).find(p=>p.id===e);if(!l)throw new Error(`board "${e}" not found`);l.columns=Array.isArray(l.columns)?l.columns:[];let c={id:a,title:n,kind:r,scopedPrefix:t?.scopedPrefix||"Status"};if(r==="scoped-label"){if(!t?.scopedLabel)throw new Error("scopedLabel required for kind=scoped-label");c.scopedLabel=String(t.scopedLabel)}if(r==="label"){if(!t?.mapsToLabel)throw new Error("mapsToLabel required for kind=label");c.mapsToLabel=String(t.mapsToLabel)}t?.accent&&(c.accent=String(t.accent));let d=l.columns.findIndex(p=>p.id===a);return d>=0?(l.columns[d]={...l.columns[d],...c},`column "${a}" updated`):(l.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Np(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 Dp(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 Bp(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 Hp(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 zp(t){let e=t?.interval!==void 0?Number(t.interval):void 0,a=t?.timeout!==void 0?Number(t.timeout):void 0;if(e!==void 0&&(!Number.isFinite(e)||e<5||e>3600))throw new Error("interval must be 5..3600 seconds");if(a!==void 0&&(!Number.isFinite(a)||a<1||a>60))throw new Error("timeout must be 1..60 seconds");if(e===void 0&&a===void 0)throw new Error("nothing to update");let{summary:n}=C(r=>(r.mesh=r.mesh||{},r.mesh.healthCheck=r.mesh.healthCheck||{},e!==void 0&&(r.mesh.healthCheck.interval=e),a!==void 0&&(r.mesh.healthCheck.timeout=a),`mesh.healthCheck updated (interval=${r.mesh.healthCheck.interval}s, timeout=${r.mesh.healthCheck.timeout}s)`));return{summary:n}}async function qp(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=tr(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=eo(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 Fp(t){if(!t||typeof t!="object")throw new Error("nothing to update");let{summary:e}=C(a=>(a.screen=Rr(a.screen,t),`screen updated (buffer ${a.screen.buffer?.enabled?"on":"off"})`));return{summary:e}}async function Up(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=C(n=>{let o=(Array.isArray(n.webhooks)?n.webhooks:[]).find(s=>s.id===e);if(!o)throw new Error(`webhook "${e}" not found`);if("triggers"in t){if(t.triggers===null||typeof t.triggers=="object"&&Object.keys(t.triggers).length===0)delete o.triggers;else if(typeof t.triggers=="object"){let s={};for(let[i,l]of Object.entries(t.triggers))typeof l=="string"&&l.trim()&&(s[String(i)]=l.trim());Object.keys(s).length===0?delete o.triggers:o.triggers=s}}return"defaultWorkflow"in t&&(t.defaultWorkflow?o.defaultWorkflow=String(t.defaultWorkflow).trim():delete o.defaultWorkflow),`webhook "${e}" triggers/defaultWorkflow updated`});return{summary:a}}ft();import{resolve as Xp}from"path";function hs(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
5523
5523
|
|
|
5524
5524
|
<div id="disabled-banner" class="banner warn" style="display:none">
|
|
5525
5525
|
<b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
|
|
@@ -5574,7 +5574,7 @@ ${s||"You are "+a+"."}
|
|
|
5574
5574
|
<h2>Recent classifications</h2>
|
|
5575
5575
|
<p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
|
|
5576
5576
|
<div id="recent"></div>
|
|
5577
|
-
</section>`;return I({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
5577
|
+
</section>`;return I({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Wp,scripts:`${e}<script>${Gp}</script>`})}var Wp=`
|
|
5578
5578
|
main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
|
|
5579
5579
|
h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
|
|
5580
5580
|
.grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
|
|
@@ -5678,7 +5678,7 @@ details {
|
|
|
5678
5678
|
border-radius: 4px; padding: 8px 12px; margin-top: 8px;
|
|
5679
5679
|
}
|
|
5680
5680
|
details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
|
|
5681
|
-
details[open] summary { margin-bottom: 8px; }`,
|
|
5681
|
+
details[open] summary { margin-bottom: 8px; }`,Gp=`
|
|
5682
5682
|
const $ = (id) => document.getElementById(id);
|
|
5683
5683
|
const state = { schema: null, nodes: [], pending: [], recent: [] };
|
|
5684
5684
|
|
|
@@ -5898,7 +5898,7 @@ $('btn-save-schema').addEventListener('click', async () => {
|
|
|
5898
5898
|
$('btn-reload-schema').addEventListener('click', refresh);
|
|
5899
5899
|
|
|
5900
5900
|
refresh();
|
|
5901
|
-
`;function
|
|
5901
|
+
`;function xs(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(hs({peers:a,localToken:n}))}async function vs(t,e,a){try{let n=t.method==="GET"?void 0:await au(t),r=Kp(),o={"GET /api/admin/graph/state":()=>Jp(r),"POST /api/admin/graph/classifications/approve":()=>Vp(r,n),"POST /api/admin/graph/classifications/reject":()=>Yp(r,n),"POST /api/admin/graph/nodes":()=>Qp(r,n),"PATCH /api/admin/graph/nodes":()=>Zp(r,n),"DELETE /api/admin/graph/nodes":()=>eu(r,n),"PUT /api/admin/graph/schema":()=>tu(r,n)},s=`${t.method} ${a}`,i=o[s];if(!i){Fa(e,404,{error:`unknown graph endpoint: ${s}`});return}let l=await i();Fa(e,200,l)}catch(n){Fa(e,400,{error:n?.message||"graph op failed"})}}function Kp(){let t=X(),e=Xp(process.cwd(),t.graph.baseDir);return new zn({baseDir:e})}function Jp(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 Vp(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=bs(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=Ua(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function Yp(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=bs(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function bs(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 Qp(t,e){let a=gs(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?gs(String(e.parentId)):null,o=Ua({[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 Zp(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=Ua({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function eu(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function tu(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 Ua(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 gs(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function Fa(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function au(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=`
|
|
5902
5902
|
<section class="apv__req" id="req-section" aria-labelledby="req-h">
|
|
5903
5903
|
<h2 id="req-h">Open requests <span id="req-n"></span></h2>
|
|
5904
5904
|
<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>
|
|
@@ -5912,10 +5912,15 @@ refresh();
|
|
|
5912
5912
|
<label>Channels to record on (separated by commas; empty for all)<input type="text" name="channels" placeholder="voice, app, telegram" autocomplete="off"></label>
|
|
5913
5913
|
<label>Comes back after this many hours without activity<input type="number" min="1" step="1" name="staleAfterHours" required></label>
|
|
5914
5914
|
<label>Keep closed requests for (days)<input type="number" min="1" step="1" name="retentionDays" required></label>
|
|
5915
|
+
<label class="apv__check"><input type="checkbox" name="plansEnabled"> Follow requests of two or more steps as plans</label>
|
|
5916
|
+
<label>Nudge a plan step's agent after this many minutes without progress<input type="number" min="1" step="1" name="stallMinutes" required></label>
|
|
5917
|
+
<label>Nudges per step before you are told it is blocked<input type="number" min="0" step="1" name="maxNudges" required></label>
|
|
5918
|
+
<label>Step kinds you approve once, when the plan is made (separated by commas)<input type="text" name="approveKinds" placeholder="message" autocomplete="off"></label>
|
|
5919
|
+
<label>Agents that may not open a plan (separated by commas)<input type="text" name="plansOffFor" autocomplete="off"></label>
|
|
5915
5920
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
5916
5921
|
</form>
|
|
5917
5922
|
</details>
|
|
5918
|
-
</section>`,
|
|
5923
|
+
</section>`,ws=`
|
|
5919
5924
|
.apv__req { margin-top: 32px; border-top: 1px solid var(--ax-border); padding-top: 16px; }
|
|
5920
5925
|
.apv__req h2 { margin: 0 0 4px; font-size: 17px; font-weight: 600; }
|
|
5921
5926
|
.apv__req h2 span { color: var(--ax-muted); font-family: var(--ax-mono); font-size: 12px; font-weight: 400; }
|
|
@@ -5937,7 +5942,13 @@ refresh();
|
|
|
5937
5942
|
.apv__req select { min-height: 40px; max-width: 100%; }
|
|
5938
5943
|
.apv__mic.is-on { border-color: var(--ax-err); color: var(--ax-err); }
|
|
5939
5944
|
.apv__acts + .apv__acts { margin-top: 8px; }
|
|
5940
|
-
|
|
5945
|
+
.apv__plan { margin: 8px 0; padding-left: 22px; font-size: 13px; line-height: 1.5; }
|
|
5946
|
+
.apv__plan li { margin: 2px 0; overflow-wrap: anywhere; }
|
|
5947
|
+
.apv__plan .apv__state { font-size: 11px; margin-left: 4px; }
|
|
5948
|
+
.apv__plan .is-done { color: var(--ax-ok, inherit); }
|
|
5949
|
+
.apv__plan .is-blocked { color: var(--ax-err); }
|
|
5950
|
+
.apv__plan small { display: block; color: var(--ax-muted); }
|
|
5951
|
+
`,ks=`
|
|
5941
5952
|
(function(){
|
|
5942
5953
|
var STATE = { in_progress: 'In progress', waiting_owner: 'Waiting on you', waiting_other: 'Waiting on another agent', needs_attention: 'Needs attention' };
|
|
5943
5954
|
function $(id){ return document.getElementById(id); }
|
|
@@ -5954,6 +5965,18 @@ function when(ms){ return new Date(ms).toISOString().slice(0, 16).replace('T', '
|
|
|
5954
5965
|
var AGENTS = [];
|
|
5955
5966
|
var SpeechRec = window.SpeechRecognition || window.webkitSpeechRecognition;
|
|
5956
5967
|
function agentName(id){ for (var i = 0; i < AGENTS.length; i++) if (AGENTS[i].id === id) return AGENTS[i].name; return id; }
|
|
5968
|
+
var STEP = { pending: 'Not started', active: 'In progress', done: 'Done', blocked: 'Blocked', skipped: 'Skipped' };
|
|
5969
|
+
// Each step of a tracked plan (#788), escaped here.
|
|
5970
|
+
function plan(p){
|
|
5971
|
+
if (!p || !p.steps || !p.steps.length) return '';
|
|
5972
|
+
return '<ol class="apv__plan" aria-label="Plan">' + p.steps.map(function(s){
|
|
5973
|
+
var extra = s.state === 'done' && s.evidence ? s.evidence : (s.state === 'blocked' || s.state === 'skipped') && s.note ? s.note
|
|
5974
|
+
: s.approval && s.approval !== 'approved' ? 'Your approval: ' + s.approval : s.nudges ? s.nudges + ' nudge' + (s.nudges === 1 ? '' : 's') : '';
|
|
5975
|
+
return '<li>' + esc(s.name) + ' <span class="apv__with">(' + esc(agentName(s.agentId)) + ')</span>' +
|
|
5976
|
+
'<span class="apv__state is-' + esc(s.state) + '">' + esc(STEP[s.state] || s.state) + '</span>' +
|
|
5977
|
+
(extra ? '<small>' + esc(extra) + '</small>' : '') + '</li>';
|
|
5978
|
+
}).join('') + '</ol>';
|
|
5979
|
+
}
|
|
5957
5980
|
function more(label, html){ return html ? '<details class="apv__detail"><summary>' + esc(label) + '</summary><div class="apv__md">' + html + '</div></details>' : ''; }
|
|
5958
5981
|
|
|
5959
5982
|
// summary, why and the ids are escaped here; textHtml, ownerNoteHtml and
|
|
@@ -5966,7 +5989,7 @@ function item(r){
|
|
|
5966
5989
|
'<div class="apv__meta"><span class="apv__state is-' + esc(r.state) + '">' + esc(STATE[r.state] || r.state) + '</span>' +
|
|
5967
5990
|
'<span class="apv__with">With <b>' + esc(agentName(r.agentId)) + '</b></span>' +
|
|
5968
5991
|
'<span>' + esc(when(r.createdAt)) + '</span><span>' + esc(r.channel) + '</span><code>' + esc(r.id) + '</code></div>' +
|
|
5969
|
-
'<p class="apv__title" dir="auto">' + esc(r.summary) + '</p>' + why +
|
|
5992
|
+
'<p class="apv__title" dir="auto">' + esc(r.summary) + '</p>' + why + plan(r.plan) +
|
|
5970
5993
|
more(r.channel === 'voice' ? 'What you said' : 'What you asked', r.textHtml) +
|
|
5971
5994
|
more('Your last reply', r.ownerNoteHtml) +
|
|
5972
5995
|
(r.lastAnswer ? more('Last answer from ' + agentName(r.lastAnswer.agentId) + ' (' + when(r.lastAnswer.at) + ')', r.lastAnswer.html) : '') +
|
|
@@ -5992,6 +6015,12 @@ function fill(s){
|
|
|
5992
6015
|
f.channels.value = (s.channels || []).join(', ');
|
|
5993
6016
|
f.staleAfterHours.value = s.staleAfterHours;
|
|
5994
6017
|
f.retentionDays.value = s.retentionDays;
|
|
6018
|
+
var p = s.plans || {};
|
|
6019
|
+
f.plansEnabled.checked = p.enabled !== false;
|
|
6020
|
+
f.stallMinutes.value = p.stallMinutes || 30;
|
|
6021
|
+
f.maxNudges.value = p.maxNudges == null ? 3 : p.maxNudges;
|
|
6022
|
+
f.approveKinds.value = (p.approveKinds || []).join(', ');
|
|
6023
|
+
f.plansOffFor.value = (p.disabledAgents || []).join(', ');
|
|
5995
6024
|
$('req-off').hidden = !!s.enabled;
|
|
5996
6025
|
}
|
|
5997
6026
|
|
|
@@ -6058,7 +6087,12 @@ $('req-form').addEventListener('submit', async function(ev){
|
|
|
6058
6087
|
from: f.from.value,
|
|
6059
6088
|
channels: f.channels.value,
|
|
6060
6089
|
staleAfterHours: Number(f.staleAfterHours.value),
|
|
6061
|
-
retentionDays: Number(f.retentionDays.value)
|
|
6090
|
+
retentionDays: Number(f.retentionDays.value),
|
|
6091
|
+
plansEnabled: f.plansEnabled.checked,
|
|
6092
|
+
stallMinutes: Number(f.stallMinutes.value),
|
|
6093
|
+
maxNudges: Number(f.maxNudges.value),
|
|
6094
|
+
approveKinds: f.approveKinds.value,
|
|
6095
|
+
plansOffFor: f.plansOffFor.value
|
|
6062
6096
|
};
|
|
6063
6097
|
try {
|
|
6064
6098
|
var r = await fetch('/api/admin/approvals/requests/settings', { method: 'POST', headers: headers(true), body: JSON.stringify(body) });
|
|
@@ -6079,7 +6113,7 @@ function busy(){
|
|
|
6079
6113
|
}
|
|
6080
6114
|
setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) load(); }, 60000);
|
|
6081
6115
|
})();
|
|
6082
|
-
`;function
|
|
6116
|
+
`;function _s(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div class="apv">
|
|
6083
6117
|
<header class="apv__head">
|
|
6084
6118
|
<div>
|
|
6085
6119
|
<h1>Approvals</h1>
|
|
@@ -6101,7 +6135,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !busy()) l
|
|
|
6101
6135
|
<ol id="apv-list" class="apv__list" aria-label="Waiting for you"></ol>
|
|
6102
6136
|
<p id="apv-snoozed" class="apv__foot"></p>
|
|
6103
6137
|
|
|
6104
|
-
${
|
|
6138
|
+
${ys}
|
|
6105
6139
|
|
|
6106
6140
|
<details class="apv__settings" id="apv-settings">
|
|
6107
6141
|
<summary>Settings: expiry, later, daily digest</summary>
|
|
@@ -6116,7 +6150,7 @@ ${bs}
|
|
|
6116
6150
|
<div><button type="submit" class="ax-btn ax-btn--primary">Save settings</button></div>
|
|
6117
6151
|
</form>
|
|
6118
6152
|
</details>
|
|
6119
|
-
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
6153
|
+
</div>`;return I({title:"AgentX \xB7 Approvals",activeTab:"approvals",subtitle:"Approvals",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:nu+ws,scripts:`${e}<script>${ru}</script><script>${ks}</script>`})}var nu=`
|
|
6120
6154
|
.apv { max-width: 860px; margin: 0 auto; padding: 20px 16px 64px; color: var(--ax-text); }
|
|
6121
6155
|
.apv__head { display: flex; flex-wrap: wrap; gap: 12px; justify-content: space-between; align-items: flex-end; margin-bottom: 14px; }
|
|
6122
6156
|
.apv__head h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
@@ -6173,7 +6207,7 @@ ${bs}
|
|
|
6173
6207
|
@media (max-width: 560px) {
|
|
6174
6208
|
.apv__acts .ax-btn { flex: 1 1 0; }
|
|
6175
6209
|
}
|
|
6176
|
-
`,
|
|
6210
|
+
`,ru=`
|
|
6177
6211
|
(function(){
|
|
6178
6212
|
var state = { items: [], snoozed: 0, kind: '', showAll: false, popup: false };
|
|
6179
6213
|
var LABEL = { card: 'Card', schedule: 'Schedule', memory: 'Memory fact', wiki: 'Wiki lesson', whatsapp: 'WhatsApp reply', request: 'Request' };
|
|
@@ -6397,7 +6431,7 @@ $('apv-form').addEventListener('submit', async function(ev){
|
|
|
6397
6431
|
load();
|
|
6398
6432
|
setInterval(function(){ if (document.visibilityState === 'visible' && !document.querySelector('.apv__item:focus-within, .apv__item[data-touched]')) load(); }, 60000);
|
|
6399
6433
|
})();
|
|
6400
|
-
`;import{existsSync as
|
|
6434
|
+
`;import{existsSync as ou,readFileSync as su}from"fs";var Me="/api/admin/approvals/requests";function Ss(t){let e=Xn(t);if(!ou(e))return[];try{let a=JSON.parse(su(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 Vt=t=>typeof t=="string"?t.split(",").map(e=>e.trim()).filter(Boolean):void 0;async function Es(t,e,a,n){try{return await iu(t,e,a,n)}catch(r){return{status:400,body:{error:String(r?.message??r).slice(0,300)}}}}async function iu(t,e,a,n){if(t==="GET"&&e===Me){let o=St(n);return{status:200,body:{items:o?o.listOpen().map(s=>mr(s,o,dr(n))):[],agents:Ss(n.configPath),settings:_t(n.configPath)}}}let r=e===`${Me}/reply`?"reply":e===`${Me}/handoff`?"handoff":null;if(t==="POST"&&r){let o=typeof a.id=="string"?a.id:"",s=r==="reply"?a.text:a.note,i=typeof s=="string"?s.trim():"";if(!o||r==="reply"&&!i)return{status:400,body:{error:r==="reply"?"send { id, text }":"send { id, agentId, note? }"}};let l=St(n),c=l?.get(o);if(!l||!c||c.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let d=r==="reply"?c.agentId:typeof a.agentId=="string"?a.agentId:"",p=Ss(n.configPath).find(f=>f.id===d);if(r==="handoff"&&!p)return{status:400,body:{error:`"${d}" is not an agent on this node`}};if(!_t(n.configPath).enabled)return{status:409,body:{error:"Requests are off, so nothing would tell the agent. Turn them on in the settings below."}};if(!l.handOff(o,d,i,n.now??Date.now()))return{status:409,body:{error:`${o} is already closed`}};let m=p?.name??d;return{status:200,body:{ok:!0,message:r==="reply"?`Reply sent: ${m} will go on with ${o}`:`${m} has ${o} now and will be told within a minute`}}}if(t==="POST"&&e===`${Me}/close`){let o=typeof a.id=="string"?a.id:"",s=a.action;if(!o||s!=="done"&&s!=="drop")return{status:400,body:{error:"send { id, action: done | drop }"}};let i=St(n),l=i?.get(o);if(!i||!l||l.state==="candidate")return{status:404,body:{error:`no request "${o}"`}};let c=s==="done"?typeof a.evidence=="string"&&a.evidence.trim()?a.evidence:"closed by the owner (dashboard)":typeof a.reason=="string"&&a.reason.trim()?a.reason:"dropped by the owner (dashboard)";return i.close(o,s==="done"?"done":"dropped",c,n.now??Date.now())?{status:200,body:{ok:!0,message:s==="done"?`${o} closed as done`:`${o} dropped`}}:{status:409,body:{error:`${o} is already closed`}}}if(t==="POST"&&e===`${Me}/settings`){let o={},s=c=>{let d=a[c];if(d!==void 0){if(typeof d!="number"||!(d>0))throw new Error(`${c} must be a positive number`);return d}};typeof a.enabled=="boolean"&&(o.enabled=a.enabled),o.from=Vt(a.from),o.channels=Vt(a.channels),o.staleAfterHours=s("staleAfterHours"),o.retentionDays=s("retentionDays");let i={};if(typeof a.plansEnabled=="boolean"&&(i.enabled=a.plansEnabled),i.stallMinutes=s("stallMinutes"),a.maxNudges!==void 0){if(typeof a.maxNudges!="number"||!Number.isInteger(a.maxNudges)||a.maxNudges<0)throw new Error("maxNudges must be a whole number, 0 or more");i.maxNudges=a.maxNudges}i.approveKinds=Vt(a.approveKinds),i.disabledAgents=Vt(a.plansOffFor),Object.values(i).some(c=>c!==void 0)&&(o.plans=i);let l=await cr(o,{configPath:n.configPath,reload:n.reload});return l.success?{status:200,body:{ok:!0,settings:_t(n.configPath)}}:{status:400,body:{error:l.error}}}return{status:404,body:{error:"Not found"}}}var lu=["yes","no","later"];function te(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Yt(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 cu(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 Ts(t,e,a){t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(_s({peers:e,localToken:a}))}async function As(t,e,a,n,r={}){if(!a.startsWith("/api/admin/approvals"))return!1;let o=(t.method||"GET").toUpperCase(),s=r.ctx??{root:process.cwd(),configPath:r.configPath,reload:r.reload};if(o!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return te(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;try{if(a.startsWith(Me)){let i=await Es(o,a,o==="POST"?await Yt(t):{},s);return te(e,i.status,i.body),!0}if(o==="GET"&&a==="/api/admin/approvals"){let i=Et(s,{includeSnoozed:n.searchParams.get("all")==="1"});return te(e,200,{...i,settings:Ae(s.configPath)}),!0}if(o==="POST"&&a==="/api/admin/approvals/decide"){let i=await Yt(t),l=typeof i.key=="string"?i.key:"",c=i.action;if(!l||!lu.includes(c))return te(e,400,{error:"send { key, action: yes | no | later }"}),!0;let d=Ae(s.configPath),p=await Tt(s,l,c,{note:typeof i.note=="string"?i.note:void 0,force:i.force===!0,laterHours:d.laterHours,by:"operator (dashboard)",...cu(i)});return p.ok?(te(e,200,{ok:!0,message:p.message}),!0):(te(e,409,{error:p.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/popup"){let i=await Yt(t),l=fr(s,typeof i.key=="string"?i.key:"",!!Ae(s.configPath).popup?.enabled);return l.ok?(te(e,200,{ok:!0,message:l.message}),!0):(te(e,409,{error:l.error}),!0)}if(o==="POST"&&a==="/api/admin/approvals/settings"){let i=await Yt(t),l={},c=p=>{let m=i[p];if(m!==void 0){if(typeof m!="number"||!(m>0))throw new Error(`${p} must be a positive number`);return m}};if(l.defaultExpiryDays=c("defaultExpiryDays"),l.maxExpiryDays=c("maxExpiryDays"),l.laterHours=c("laterHours"),typeof i.notifyAgent=="boolean"&&(l.notifyAgent=i.notifyAgent),typeof i.digestEnabled=="boolean"&&(l.digestEnabled=i.digestEnabled),typeof i.digestTime=="string"&&(l.digestTime=i.digestTime),typeof i.destination=="string"){let p=i.destination.trim();if(!p)l.destination=null;else{let m=qr(p);if(!m)throw new Error("digest destination takes channel:chat id, for example telegram:123456");l.destination=m}}let d=await Fr(l,{configPath:s.configPath,reload:s.reload});return d.success?(te(e,200,{ok:!0,settings:Ae(s.configPath)}),!0):(te(e,400,{error:d.error}),!0)}}catch(i){return te(e,400,{error:String(i?.message??i).slice(0,300)}),!0}return te(e,404,{error:"Not found"}),!0}va();function Cs(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=de({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."})+`
|
|
6401
6435
|
<div class="pp">
|
|
6402
6436
|
<div id="pp-msg" class="pp-msg" role="status" aria-live="polite"></div>
|
|
6403
6437
|
<section id="pp-none" class="pp-none" hidden aria-labelledby="pp-none-title">
|
|
@@ -6410,7 +6444,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6410
6444
|
</ol>
|
|
6411
6445
|
</section>
|
|
6412
6446
|
<ol id="pp-list" class="pp-list" aria-label="People"><li class="pp-empty">Loading\u2026</li></ol>
|
|
6413
|
-
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:
|
|
6447
|
+
</div>`;return I({title:"AgentX \xB7 People",activeTab:"people",subtitle:"People",peers:t.peers,body:a,css:du,scripts:`${e}<script>${pu}</script>`})}var du=`
|
|
6414
6448
|
.pp { max-width: 1040px; margin: 0 auto; padding: 0 24px 64px; }
|
|
6415
6449
|
.pp-msg { min-height: 1.4em; margin: 4px 0 8px; font-size: var(--ax-fs-sm); }
|
|
6416
6450
|
.pp-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -6451,7 +6485,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6451
6485
|
.pp-text { overflow-wrap: anywhere; }
|
|
6452
6486
|
.pp-meta { margin-top: 2px; display: flex; flex-wrap: wrap; gap: 2px 12px; font-size: var(--ax-fs-xs); color: var(--ax-text-2); }
|
|
6453
6487
|
@media (prefers-reduced-motion: reduce) { .pp-caret { transition: none; } }
|
|
6454
|
-
`,
|
|
6488
|
+
`,pu=`
|
|
6455
6489
|
(function () {
|
|
6456
6490
|
var list = document.getElementById('pp-list');
|
|
6457
6491
|
var msg = document.getElementById('pp-msg');
|
|
@@ -6589,7 +6623,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6589
6623
|
load();
|
|
6590
6624
|
setInterval(load, 30000);
|
|
6591
6625
|
})();
|
|
6592
|
-
`;var
|
|
6626
|
+
`;var Wa="/api/admin/people";function uu(t,e){let a=Xr(t,e);return a?{...e,answer:a}:e}function mu(t){return t.state!=="pending"||!t.answer?t.state:t.answer==="yes"?"active":"removed"}function ge(t,e,a){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a))}function fu(t,e){let a=(o,s)=>e.filter(i=>i.personId===o&&mu(i)===s).length,n=o=>({id:o.id,name:o.name,role:o.role,identities:o.identities,agents:o.agents??[],machines:{active:a(o.id,"active"),pending:a(o.id,"pending")}}),r=t.map(n);return t.some(o=>o.role==="owner")||r.unshift({...n({id:mt,name:"Owner of this machine",role:"owner",identities:[]}),builtIn:!0}),r}var hu=(t,e)=>e.createdAt.localeCompare(t.createdAt);async function Is(t,e,a,n){if(a!=="/people"&&a!==Wa&&!a.startsWith(`${Wa}/`))return!1;let r=(t.method||"GET").toUpperCase();if(a==="/people")return r!=="GET"?(ge(e,405,{error:"GET only"}),!0):(e.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Cache-Control":"no-store"}),e.end(Cs({peers:n.peers,localToken:n.localToken})),!0);if(r!=="GET"&&t.headers["x-requested-with"]!=="agentx-board")return ge(e,400,{error:"missing X-Requested-With: agentx-board"}),!0;let o=c=>n.members.devices(c).map(d=>uu(n.root,d)),s=()=>fu(n.people(),o());if(r==="GET"&&a===Wa){let c=s();return ge(e,200,{people:c,paired:c.reduce((d,p)=>d+p.machines.active+p.machines.pending,0)}),!0}let i=a.match(/^\/api\/admin\/people\/([a-z0-9][a-z0-9_-]{0,39})$/);if(r==="GET"&&i){let c=s().find(f=>f.id===i[1]);if(!c)return ge(e,404,{error:`no person "${i[1]}"`}),!0;let d=n.db(),p=[],m=[];try{d&&(p=Ur(d,c.id))}catch{}try{d&&(m=jt(d,c.id,20))}catch{}return ge(e,200,{person:c,devices:o(c.id).sort(hu),requests:p,runs:m,database:!!d}),!0}let l=a.match(/^\/api\/admin\/people\/([a-z0-9][a-z0-9_-]{0,39})\/devices\/([A-Za-z0-9_-]{1,80})\/end$/);if(r==="POST"&&l){let[,c,d]=l,p=n.members.byToken(d);if(!p||p.personId!==c)return ge(e,404,{error:"no such machine for this person"}),!0;if(p.state==="removed")return ge(e,409,{error:"this machine's access has already ended"}),!0;let m=Jr({tokens:n.tokens??new G,members:n.members,now:n.now},d,"removed by the owner (dashboard)");return ge(e,200,{ok:!0,device:m}),!0}return ge(e,404,{error:"not found"}),!0}import{resolve as yu}from"path";import{existsSync as wu}from"fs";import ku from"better-sqlite3";var Ms=new WeakSet;function gu(t,e,a={}){if(Ms.has(t))return;Ms.add(t);let n=a.thresholdMs??200,r=a.now??(()=>performance.now()),o=t.prepare.bind(t);t.prepare=s=>{let i=o(s);for(let l of["all","get","run"]){let c=i[l].bind(i);i[l]=(...d)=>{let p=r();try{return c(...d)}finally{let m=r()-p;m>=n&&e({sql:s,ms:m})}}}return i}}function xu(t,e=160){let a=t.replace(/\s+/g," ").trim();return a.length>e?`${a.slice(0,e-1)}\u2026`:a}function ke(t,e){gu(t,({sql:a,ms:n})=>console.error(`[${e}] slow query, ${Math.round(n)} ms: ${xu(a)}`))}function Ls(t={}){let e=`<div class="ax-obs">
|
|
6593
6627
|
<header class="ax-obs__head">
|
|
6594
6628
|
<h1>Health</h1>
|
|
6595
6629
|
<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>
|
|
@@ -6711,7 +6745,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
6711
6745
|
</div>
|
|
6712
6746
|
<div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
|
|
6713
6747
|
</section>
|
|
6714
|
-
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
6748
|
+
</div>`;return I({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:vu,scripts:`<script>${bu}</script>`})}var vu=`
|
|
6715
6749
|
.ax-obs { padding: 16px 24px; }
|
|
6716
6750
|
.ax-obs__head { margin-bottom: 16px; }
|
|
6717
6751
|
.ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
|
|
@@ -7212,7 +7246,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7212
7246
|
|
|
7213
7247
|
load(current);
|
|
7214
7248
|
})();
|
|
7215
|
-
`;var
|
|
7249
|
+
`;var $s={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 js(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function Ga(t){let e=$s[js(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 _u(){let t=yu(process.cwd(),".agentx/db.sqlite");if(!wu(t))return null;try{let e=new ku(t,{readonly:!0,fileMustExist:!0});return ke(e,"health"),{db:e,close:()=>e.close()}}catch{return null}}function Os(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ls({peers:a}))}function Su(t){let e=new URL(t.url||"/","http://_"),a=parseInt(e.searchParams.get("limit")||"50",10),n=Number.isFinite(a)?Math.max(1,Math.min(500,a)):50,r=e.searchParams.get("agent")||void 0;return{limit:n,agent:r&&r.length>0?r:void 0}}function xe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function Ns(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=_u();if(!r)return xe(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=Su(t);if(n==="routing"){let i=[],l={limit:o};s&&(i.push("agent_id = @agent"),l.agent=s);let c=`
|
|
7216
7250
|
SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
|
|
7217
7251
|
FROM route_traces
|
|
7218
7252
|
${i.length?"WHERE "+i.join(" AND "):""}
|
|
@@ -7227,8 +7261,8 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7227
7261
|
FROM task_history
|
|
7228
7262
|
WHERE ${i.join(" AND ")}
|
|
7229
7263
|
ORDER BY started_at DESC LIMIT @limit
|
|
7230
|
-
`,p=r.db.prepare(c).all(l).map(m=>({...m,plain:
|
|
7231
|
-
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function
|
|
7264
|
+
`,p=r.db.prepare(c).all(l).map(m=>({...m,plain:Ds(m.error)}));return xe(e,200,{rows:p}),!0}if(n==="summary"||n==="overview")return xe(e,200,Eu(r.db)),!0;if(n==="activity")return xe(e,200,Tu(r.db,{agent:s})),!0;if(n==="cost"){let i=new URL(t.url||"/","http://_"),l=Rs(i.searchParams.get("range"));return xe(e,200,Ps(r.db,l)),!0}if(n==="cost.csv"){let i=new URL(t.url||"/","http://_"),l=Rs(i.searchParams.get("range")),c=Ps(r.db,l),d=Au(c.days);return e.writeHead(200,{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="agentx-cost-${l||"all"}d-${Date.now()}.csv"`}),e.end(d),!0}return xe(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return xe(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Ds(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(`
|
|
7265
|
+
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function Eu(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,i=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE status='error' AND started_at >= ?").get(a).n,c=t.prepare("SELECT AVG(duration_ms) AS d FROM task_history WHERE status='ok' AND started_at >= ?").get(a).d??0,d=t.prepare("SELECT duration_ms FROM task_history WHERE status='ok' AND started_at >= ? AND duration_ms IS NOT NULL ORDER BY duration_ms ASC").all(a),p=b=>d.length?d[Math.min(d.length-1,Math.floor(d.length*b))].duration_ms:0,m=p(.5),f=p(.95),v=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((b,A)=>b+Ga(A),0),E=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((b,A)=>b+Ga(A),0),x=t.prepare(`
|
|
7232
7266
|
SELECT agent_id,
|
|
7233
7267
|
COUNT(*) AS tasks,
|
|
7234
7268
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
|
|
@@ -7246,12 +7280,12 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7246
7280
|
WHERE started_at >= ?
|
|
7247
7281
|
GROUP BY channel
|
|
7248
7282
|
ORDER BY tasks DESC
|
|
7249
|
-
`).all(a),u=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(
|
|
7283
|
+
`).all(a),u=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(b=>b.agent_id),h=new Set(t.prepare("SELECT DISTINCT agent_id FROM task_history WHERE started_at >= ?").all(o).map(b=>b.agent_id)),w=u.filter(b=>!h.has(b)),T=t.prepare(`
|
|
7250
7284
|
SELECT started_at, agent_id, channel, message_preview, error
|
|
7251
7285
|
FROM task_history
|
|
7252
7286
|
WHERE status='error' AND started_at >= ?
|
|
7253
7287
|
ORDER BY started_at DESC LIMIT 5
|
|
7254
|
-
`).all(o).map(
|
|
7288
|
+
`).all(o).map(b=>({...b,plain:Ds(b.error)}));return{kpis:{tasksToday:s,tasksDelta:s-i,errorsToday:l,errorRate:s>0?l/s:0,avgDurationMs:Math.round(c),p50DurationMs:m,p95DurationMs:f,spendToday:v,spendDelta:v-E,idleAgentCount:w.length},perAgent:x,perChannel:g,idleAgents:w,recentErrors:T}}function Tu(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(`
|
|
7255
7289
|
SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
|
|
7256
7290
|
COUNT(*) AS tasks,
|
|
7257
7291
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
|
|
@@ -7278,7 +7312,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7278
7312
|
WHERE started_at >= @since
|
|
7279
7313
|
GROUP BY agent_id
|
|
7280
7314
|
ORDER BY tasks_24h DESC, tasks_7d DESC
|
|
7281
|
-
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function
|
|
7315
|
+
`).all({since:n,last24:a});return{hourly:s,daily:i,perAgent:l}}function Rs(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 Ps(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
|
|
7282
7316
|
SELECT day, agent_id, model,
|
|
7283
7317
|
input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
|
|
7284
7318
|
tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
|
|
@@ -7286,15 +7320,15 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7286
7320
|
FROM usage_daily
|
|
7287
7321
|
${a}
|
|
7288
7322
|
ORDER BY day
|
|
7289
|
-
`).all(),r=new Date().toISOString().slice(0,10),o=new Date(Date.now()-864e5).toISOString().slice(0,10),s=new Date(Date.now()-7*864e5).toISOString().slice(0,10),i=new Date(Date.now()-14*864e5).toISOString().slice(0,10),l=0,c=0,d=0,p=0,m=0,f=0,_=0,
|
|
7323
|
+
`).all(),r=new Date().toISOString().slice(0,10),o=new Date(Date.now()-864e5).toISOString().slice(0,10),s=new Date(Date.now()-7*864e5).toISOString().slice(0,10),i=new Date(Date.now()-14*864e5).toISOString().slice(0,10),l=0,c=0,d=0,p=0,m=0,f=0,_=0,v=0,E=0,x={},g={};for(let S of n){let L=Ga(S),j=js(S.model),$=$s[j],O=(S.tier2_input_tokens||0)/1e6*$.input*.5+(S.tier2_output_tokens||0)/1e6*$.output*.5+(S.tier2_cache_read_tokens||0)/1e6*$.cacheRead*.5+(S.tier2_cache_create_tokens||0)/1e6*$.cacheCreate*.5,W=(S.input_tokens||0)+(S.tier2_input_tokens||0),le=(S.output_tokens||0)+(S.tier2_output_tokens||0),Q=(S.cache_read_tokens||0)+(S.tier2_cache_read_tokens||0),re=(S.cache_create_tokens||0)+(S.tier2_cache_create_tokens||0);p+=L,S.day>=s&&(d+=L,_+=S.tasks||0),S.day>=i&&S.day<s&&(E+=L,v+=S.tasks||0),S.day===r&&(l+=L),S.day===o&&(c+=L),S.day===r&&(m+=O),S.day>=s&&(f+=O);let Z=x[S.day]||(x[S.day]={date:S.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});Z.tasks+=S.tasks||0,Z.input+=W,Z.output+=le,Z.cacheRead+=Q,Z.cacheCreate+=re,Z.cost+=L,Z.tier2+=O;let F=Z.agents[S.agent_id]||(Z.agents[S.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:S.model});F.tasks+=S.tasks||0,F.cost+=L,F.tier2+=O,F.input+=W,F.output+=le,F.cacheRead+=Q,F.cacheCreate+=re,S.model&&(F.model=S.model);let N=g[S.agent_id]||(g[S.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:S.model});N.tasks+=S.tasks||0,N.cost+=L,N.tier2+=O,N.input+=W,N.output+=le,N.cacheRead+=Q,N.cacheCreate+=re,S.model&&(N.model=S.model)}let u=Object.values(x).sort((S,L)=>S.date<L.date?-1:1),h=0,w=0,y=0,T=0,b=0,A=0;for(let S of u)h+=S.tasks,w+=S.input,y+=S.output,T+=S.cacheRead,b+=S.cacheCreate,A+=S.cost;let R=Object.entries(g).map(([S,L])=>({agent_id:S,...L,tokens:L.input+L.output+L.cacheRead+L.cacheCreate})).sort((S,L)=>L.cost-S.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:l,spendYesterday:c,spend7d:d,spend30d:p,tier2Today:m,tier2_7d:f,tier2PctToday:l>0?m/l:0,spendRange:A,avgDailyRange:u.length?A/u.length:0,tasksRange:h,tokensRange:w+y+T+b,cacheHitRange:T+w>0?T/(T+w):0,costPerTaskRange:h>0?A/h:0,spendDeltaWoW:E>0?(d-E)/E:0,tasksDeltaWoW:v>0?(_-v)/v:0},days:u,perAgent:R}}function Au(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+`
|
|
7290
7324
|
`+a.join(`
|
|
7291
7325
|
`)+`
|
|
7292
|
-
`}import{resolve as
|
|
7326
|
+
`}import{resolve as Cu}from"path";import{existsSync as Iu}from"fs";import Mu from"better-sqlite3";function Lu(){let t=Cu(process.cwd(),".agentx/intent/ledger.sqlite");if(!Iu(t))return null;try{let e=new Mu(t,{readonly:!0,fileMustExist:!0});return ke(e,"ledger-panel"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-Bs>6e4&&(Bs=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var Bs=0;function Le(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Ru(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 Hs(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=Lu();if(!r)return Le(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=Ru(o.searchParams.get("since")),i=o.searchParams.get("source")||"",l=o.searchParams.get("project")||"",c=parseInt(o.searchParams.get("limit")||"50",10),d=Number.isFinite(c)?Math.max(1,Math.min(500,c)):50;if(n==="stats"){let p=s!==void 0?"WHERE ts >= @since":"",m=s!==void 0?"WHERE decided_at >= @since":"",f=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${p} GROUP BY source ORDER BY n DESC`).all({since:s}),_=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${m}`).get({since:s}).n,v=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${m} GROUP BY outcome ORDER BY n DESC`).all({since:s}),E=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${p}`).get({since:s}).n,x=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${p} GROUP BY source ORDER BY n DESC`).all({since:s}),g=r.db.prepare(`
|
|
7293
7327
|
SELECT COUNT(*) AS n FROM intent_decisions d
|
|
7294
7328
|
LEFT JOIN intent_resolutions r
|
|
7295
7329
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7296
7330
|
WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
|
|
7297
|
-
`).get().n;return Le(e,200,{since:s??null,eventsBySource:f,totalDecisions:_,decisionsByOutcome:
|
|
7331
|
+
`).get().n;return Le(e,200,{since:s??null,eventsBySource:f,totalDecisions:_,decisionsByOutcome:v,totalDivergences:E,divergencesBySource:x,inFlight:g}),!0}if(n==="events"){let p=[],m={limit:d};s!==void 0&&(p.push("ts >= @since"),m.since=s),i&&(p.push("source = @source"),m.source=i),l&&(p.push("project = @project"),m.project=l);let f=`
|
|
7298
7332
|
SELECT id, ts, source, source_event_id, project, subject, intent
|
|
7299
7333
|
FROM intent_events
|
|
7300
7334
|
${p.length?"WHERE "+p.join(" AND "):""}
|
|
@@ -7316,7 +7350,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7316
7350
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
7317
7351
|
WHERE ${p.join(" AND ")}
|
|
7318
7352
|
ORDER BY d.decided_at DESC LIMIT @limit
|
|
7319
|
-
`;return Le(e,200,{rows:r.db.prepare(f).all(m)}),!0}return Le(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Le(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function
|
|
7353
|
+
`;return Le(e,200,{rows:r.db.prepare(f).all(m)}),!0}return Le(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return Le(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function zs(t={}){return I({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
|
|
7320
7354
|
<header class="ax-led__head">
|
|
7321
7355
|
<h1>Intent ledger</h1>
|
|
7322
7356
|
<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>
|
|
@@ -7521,7 +7555,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
7521
7555
|
}
|
|
7522
7556
|
load();
|
|
7523
7557
|
})();
|
|
7524
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
7558
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function qs(t={}){return I({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
|
|
7525
7559
|
<header class="ax-cost__head">
|
|
7526
7560
|
<div>
|
|
7527
7561
|
<h1>Cost</h1>
|
|
@@ -8094,7 +8128,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8094
8128
|
load();
|
|
8095
8129
|
setInterval(load, 30000);
|
|
8096
8130
|
})();
|
|
8097
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
8131
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Fs(t={}){let e=`<div class="ax-pj__root">
|
|
8098
8132
|
<aside class="ax-pj__list">
|
|
8099
8133
|
<header>
|
|
8100
8134
|
<h2>Projects</h2>
|
|
@@ -8121,7 +8155,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8121
8155
|
</header>
|
|
8122
8156
|
<div id="pj-detail-body" class="ax-pj__detail-body"></div>
|
|
8123
8157
|
</section>
|
|
8124
|
-
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
8158
|
+
</div>`;return I({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Pu,scripts:`<script>${$u}</script>`})}var Pu=`
|
|
8125
8159
|
.ax-pj__root {
|
|
8126
8160
|
display: grid;
|
|
8127
8161
|
grid-template-columns: 360px 1fr;
|
|
@@ -8308,7 +8342,7 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8308
8342
|
}
|
|
8309
8343
|
.ax-pj__warn { color: var(--ax-warn, #facc15); border-top: 1px solid var(--ax-border); }
|
|
8310
8344
|
.ax-pj__hint { font-size: 11px; color: var(--ax-fg-muted, var(--ax-text)); margin-top: 4px; }
|
|
8311
|
-
|
|
8345
|
+
`,$u=`
|
|
8312
8346
|
(function(){
|
|
8313
8347
|
const $ = (sel) => document.querySelector(sel);
|
|
8314
8348
|
const esc = (s) => String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({"&":"&","<":"<",">":">","\\"":"""}[c]));
|
|
@@ -8958,22 +8992,22 @@ setInterval(function(){ if (document.visibilityState === 'visible' && !document.
|
|
|
8958
8992
|
load();
|
|
8959
8993
|
});
|
|
8960
8994
|
})();
|
|
8961
|
-
`;import{resolve as Va,join as Ju}from"path";import{existsSync as Ya,readdirSync as Vu,readFileSync as Yu}from"fs";import Qu from"better-sqlite3";var Us=String.raw`[\w.-]+(?:/[\w.-]+)+`,$u=new RegExp(`^(?:chat:)?(${Us}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),ju=new RegExp(`^\\[(?:GitLab|GitHub) (${Us}) `);function Fs(t){if(!t)return null;let e=t.match($u);return e?e[1]:null}function Ga(t){if(!t)return null;let e=t.trimStart().match(ju);return e?e[1]:null}function Yt(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Fs(typeof n?.chatId=="string"?n.chatId:null)??Fs(e)??Ga(a)}function Ou(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function Qt(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Nu=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Du=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Bu=t=>/^issue/i.test(t)?"issue":"mr";function Hu(t){let e=t.subject.match(Nu)??t.inputPreview.trimStart().match(Du);return e?{kind:Bu(e[1]),n:Number(e[2])}:null}function zu(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 Ws(t){if(!Ou(t.projectId))return[];let e=Hu(t);return e?[e]:zu(t.inputPreview)}var qu=6e4,Fu=5*6e4,Uu=40,Gs=6,Xs=new Map;function Ks(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 Ws(n)){let s=Qt(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Uu)return[...e.values()]}}return[...e.values()]}async function Js(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=Qt(s.project,s.ref),l=Xs.get(i);l&&n-l.at<(s.github?Fu:qu)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Gs)await Promise.all(o.slice(s,s+Gs).map(async i=>{let l=Qt(i.project,i.ref),c=null;try{c=i.github?await Gu(i,e,a):await Wu(i,e,a)}catch{}Xs.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function Vs(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 Wu(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 Vs(`${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 Gu(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 Vs(`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}Rn();var Xa=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function Ys(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=pt(e);n&&(a.root={kind:n.kind,channel:n.channel},n.sender&&(a.root.sender=n.sender),n.agentId&&(a.root.agentId=n.agentId));let r=e.delegation;if(r&&typeof r=="object"){let o=r,s=Xa(o.from,80);if(s){a.callback={from:s,status:Xa(o.status,20)??"done"};let i=Xa(o.peer,80);i&&(a.callback.peer=i)}}return a}Rn();xa();var Qs={kind:"agentx",id:"agentx",name:"AgentX"},Ka={kind:"person",id:"unknown",name:"Unknown"},Xu=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),Zs=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),Re=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function Ku(t,e,a){let n=t==="workflow"?a?.event?.payload:a,r=n?.issueEvent||n?.webhookEvent,o=n?.sender??r?.sender??n?.message?.from??n?.user??r?.user,s=Re(o?.id)??(e==="whatsapp"?Re(n?.from):void 0),i=Re(o?.username)??Re(o?.login);return s||i?{id:s,username:i,name:Re(o?.name)}:null}function ei(t){let e=s=>({kind:"person",id:`person:${s}`,name:Nn(t.people,s)}),a=(s,i)=>i||Xu.has(s)?Qs:{kind:"external",id:`ext:${s}`,name:t.channelLabel(s)},n=t.raw&&typeof t.raw=="object"?t.raw:{};if(t.source==="mesh"){let s=n.context&&typeof n.context=="object"?n.context:void 0,i=Re(n.person)??Bn(t.people,s)?.id;if(i)return e(i);let l=pt(s),c=l?.channel??t.channel;if(Ln(s)==="human")return Zs(s?.senderUsername)?a(c,!1):Ka;let d=!!Re(n.senderAgentId)||ma(l?l.sender:s?.sender);return c==="desktop"&&!d?Ka:a(c,d)}let r=Ku(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Dn(t.people,t.channel,r);return o?e(o.id):ma(r.name)?Qs:Mn.has(t.channel)&&!Zs(r.username)?Ka:a(t.channel,!1)}function Qa(){let t=Va(process.cwd(),".agentx/intent/ledger.sqlite");if(!Ya(t))return null;try{let e=new Qu(t,{readonly:!0,fileMustExist:!0});return ke(e,"activity-graph"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-ti>6e4&&(ti=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var ti=0;function be(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var Pe={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"Web API",color:"#3a7bd5"},mcp:{label:"Agent tools (MCP)",color:"#bf8700"},voice:{label:"Voice",color:"#e5534b"},desktop:{label:"Desktop assistant",color:"#8957e5"},app:{label:"Phone app",color:"#0f9d8a"},opencode:{label:"OpenCode",color:"#57606a"}};function Zu(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in Pe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in Pe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in Pe)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in Pe)return s}return"workflow"}return t}function ri(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 em(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 Yn(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 tm(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&&!Ja(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!Ja(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:nm(e,n)}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,c=i||(s.id!=null?String(s.id):null)||l;if(c&&!Ja(i||l||"")){let d=typeof n.channel=="string"?n.channel:"",p=ai(d);return{id:c,name:l||i||c,avatar:J(l||i||c),kind:p}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,c=s.name||s.username;return{id:l,name:c,avatar:J(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:J(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:J(i),kind:ai(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 am={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function nm(t,e){let a=am[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function ai(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Ja(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 si(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}
|
|
8995
|
+
`;import{resolve as Ya,join as Vu}from"path";import{existsSync as Qa,readdirSync as Yu,readFileSync as Qu}from"fs";import Zu from"better-sqlite3";var Ws=String.raw`[\w.-]+(?:/[\w.-]+)+`,ju=new RegExp(`^(?:chat:)?(${Ws}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),Ou=new RegExp(`^\\[(?:GitLab|GitHub) (${Ws}) `);function Us(t){if(!t)return null;let e=t.match(ju);return e?e[1]:null}function Xa(t){if(!t)return null;let e=t.trimStart().match(Ou);return e?e[1]:null}function Qt(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Us(typeof n?.chatId=="string"?n.chatId:null)??Us(e)??Xa(a)}function Nu(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function Zt(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Du=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Bu=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,Hu=t=>/^issue/i.test(t)?"issue":"mr";function zu(t){let e=t.subject.match(Du)??t.inputPreview.trimStart().match(Bu);return e?{kind:Hu(e[1]),n:Number(e[2])}:null}function qu(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 Gs(t){if(!Nu(t.projectId))return[];let e=zu(t);return e?[e]:qu(t.inputPreview)}var Fu=6e4,Uu=5*6e4,Wu=40,Xs=6,Ks=new Map;function Js(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 Gs(n)){let s=Zt(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Wu)return[...e.values()]}}return[...e.values()]}async function Vs(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let i=Zt(s.project,s.ref),l=Ks.get(i);l&&n-l.at<(s.github?Uu:Fu)?l.item&&(r[i]=l.item):o.push(s)}for(let s=0;s<o.length;s+=Xs)await Promise.all(o.slice(s,s+Xs).map(async i=>{let l=Zt(i.project,i.ref),c=null;try{c=i.github?await Xu(i,e,a):await Gu(i,e,a)}catch{}Ks.set(l,{at:n,item:c}),c&&(r[l]=c)}));return r}async function Ys(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 Gu(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 Ys(`${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 Xu(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 Ys(`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}Pn();var Ka=(t,e)=>typeof t=="string"&&t.trim()?t.trim().slice(0,e):void 0;function Qs(t){let e=t&&typeof t=="object"?t.context:void 0;if(!e||typeof e!="object")return{};let a={},n=pt(e);n&&(a.root={kind:n.kind,channel:n.channel},n.sender&&(a.root.sender=n.sender),n.agentId&&(a.root.agentId=n.agentId));let r=e.delegation;if(r&&typeof r=="object"){let o=r,s=Ka(o.from,80);if(s){a.callback={from:s,status:Ka(o.status,20)??"done"};let i=Ka(o.peer,80);i&&(a.callback.peer=i)}}return a}Pn();va();var Zs={kind:"agentx",id:"agentx",name:"AgentX"},Ja={kind:"person",id:"unknown",name:"Unknown"},Ku=new Set(["cron","workflow","a2a","mcp","mesh","events","reminder","heartbeat","system","internal","business"]),ei=t=>typeof t=="string"&&/\[bot\]$|^(project|group)_\d+_bot/i.test(t),Re=t=>typeof t=="string"&&t?t:typeof t=="number"?String(t):void 0;function Ju(t,e,a){let n=t==="workflow"?a?.event?.payload:a,r=n?.issueEvent||n?.webhookEvent,o=n?.sender??r?.sender??n?.message?.from??n?.user??r?.user,s=Re(o?.id)??(e==="whatsapp"?Re(n?.from):void 0),i=Re(o?.username)??Re(o?.login);return s||i?{id:s,username:i,name:Re(o?.name)}:null}function ti(t){let e=s=>({kind:"person",id:`person:${s}`,name:Dn(t.people,s)}),a=(s,i)=>i||Ku.has(s)?Zs:{kind:"external",id:`ext:${s}`,name:t.channelLabel(s)},n=t.raw&&typeof t.raw=="object"?t.raw:{};if(t.source==="mesh"){let s=n.context&&typeof n.context=="object"?n.context:void 0,i=Re(n.person)??Hn(t.people,s)?.id;if(i)return e(i);let l=pt(s),c=l?.channel??t.channel;if(Rn(s)==="human")return ei(s?.senderUsername)?a(c,!1):Ja;let d=!!Re(n.senderAgentId)||fa(l?l.sender:s?.sender);return c==="desktop"&&!d?Ja:a(c,d)}let r=Ju(t.source,t.channel,n);if(!r)return a(t.channel,!1);let o=Bn(t.people,t.channel,r);return o?e(o.id):fa(r.name)?Zs:Ln.has(t.channel)&&!ei(r.username)?Ja:a(t.channel,!1)}function Za(){let t=Ya(process.cwd(),".agentx/intent/ledger.sqlite");if(!Qa(t))return null;try{let e=new Zu(t,{readonly:!0,fileMustExist:!0});return ke(e,"activity-graph"),{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-ai>6e4&&(ai=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var ai=0;function ve(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var Pe={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"Web API",color:"#3a7bd5"},mcp:{label:"Agent tools (MCP)",color:"#bf8700"},voice:{label:"Voice",color:"#e5534b"},desktop:{label:"Desktop assistant",color:"#8957e5"},app:{label:"Phone app",color:"#0f9d8a"},opencode:{label:"OpenCode",color:"#57606a"}};function em(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in Pe)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in Pe)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in Pe)return r;let o=n?.issueEvent||n?.webhookEvent;if(o){if(o.user?.username||o.project?.path_with_namespace)return"gitlab";if(o.sender?.login)return"github"}if(e.startsWith("workflow.")){let s=e.slice(9).split("-")[0];if(s in Pe)return s}return"workflow"}return t}function oi(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 tm(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 si(t,e,a){return Qn(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 am(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&&!Va(l))return{id:l,name:l,avatar:J(l),kind:"a2a"}}let i=o||r||s;if(i&&!Va(r||o||"")){let l=r||o||s;return{id:l,name:o||r||l,avatar:J(i),kind:rm(e,n)}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,i=typeof s.username=="string"?s.username:null,l=typeof s.name=="string"?s.name:null,c=i||(s.id!=null?String(s.id):null)||l;if(c&&!Va(i||l||"")){let d=typeof n.channel=="string"?n.channel:"",p=ni(d);return{id:c,name:l||i||c,avatar:J(l||i||c),kind:p}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let l=s.username||s.name,c=s.name||s.username;return{id:l,name:c,avatar:J(c),kind:"gitlab"}}let i=o.sender;if(i?.login)return{id:i.login,name:i.login,avatar:J(i.login),kind:"github"}}}let r=typeof a.workflowId=="string"&&a.workflowId||typeof a.runId=="string"&&a.runId||typeof a.workflow=="string"&&a.workflow||typeof a.event?.id=="string"&&a.event.id.split(":")[0];if(r)return{id:`workflow:${r}`,name:`Workflow: ${r}`,avatar:"\u25B6",kind:"workflow"}}if(a.sender&&typeof a.sender=="object"){let n=a.sender,r=typeof n.username=="string"?n.username:null,o=typeof n.name=="string"?n.name:null,s=r||(n.id!=null?String(n.id):null)||o;if(s){let i=o||r||s;return{id:s,name:i,avatar:J(i),kind:ni(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 nm={github:"github",gitlab:"gitlab",a2a:"a2a",voice:"voice",desktop:"desktop",app:"app"};function rm(t,e){let a=nm[t.startsWith("mesh.")?t.slice(5):""]??"mesh";return a!=="a2a"&&e.via==="voice"?"voice":a}function ni(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function Va(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 ii(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}
|
|
8962
8996
|
${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
|
|
8963
|
-
${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
|
|
8997
|
+
${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 om(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 li(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
|
|
8964
8998
|
SELECT id, ts, source, project, subject, intent, raw_json
|
|
8965
8999
|
FROM intent_events WHERE ts >= ? ORDER BY ts ASC
|
|
8966
|
-
`).all(r),s=new Map,i=new Map;if(o.length>0){let
|
|
9000
|
+
`).all(r),s=new Map,i=new Map;if(o.length>0){let b=o.map(j=>j.id),A=b.map((j,$)=>`@id${$}`).join(","),R=Object.fromEntries(b.map((j,$)=>[`id${$}`,j])),S=t.prepare(`
|
|
8967
9001
|
SELECT event_id, decided_at, decided_by, agent_id, outcome, reason
|
|
8968
9002
|
FROM intent_decisions WHERE event_id IN (${A}) ORDER BY decided_at ASC
|
|
8969
9003
|
`).all(R);for(let j of S)s.has(j.event_id)||s.set(j.event_id,[]),s.get(j.event_id).push(j);let L=t.prepare(`
|
|
8970
9004
|
SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
|
|
8971
9005
|
FROM intent_resolutions WHERE decision_event_id IN (${A})
|
|
8972
|
-
`).all(R);for(let j of L)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,c=new Map,d=new Map,p=new Map,m=[],f=e?.business?.projects??[],_=e?.business?.contactMap??[],
|
|
9006
|
+
`).all(R);for(let j of L)i.set(`${j.decision_event_id}|${j.decision_decided_by}`,j)}let l=new Map,c=new Map,d=new Map,p=new Map,m=[],f=e?.business?.projects??[],_=e?.business?.contactMap??[],v=wa(e?.business??{}),E=e?.people??[];for(let b of o){let A=null;try{A=JSON.parse(b.raw_json)}catch{}let R=si(b.source,A,_),S=ii(b.source,A),L=Qs(A),j=b.project??Qt(A,b.subject,S),$=null,O=null;R?($=R.client,O=R.project||`${R.client}/_chat`):j&&($=vt(j,f),O=j);let W=em(b.source,b.intent||"",A),le=Pe[W]||{label:W,color:"#6b7280"};d.has(W)||d.set(W,{id:W,label:le.label,color:le.color});let Q=ti({source:b.source,channel:W,raw:A,people:E,channelLabel:N=>Pe[N]?.label??N}),re="__system",Z,F=am(b.source,b.intent||"",A);if(F){re=F.id,Z=F.kind;let N=R?.displayName||F.name;(!p.has(F.id)||R?.displayName)&&p.set(F.id,{id:F.id,name:N,avatar:J(N),kind:F.kind})}else p.has("__system")||p.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});for(let N of s.get(b.id)??[]){if(N.outcome!=="dispatched"||!N.agent_id)continue;let Fc=`${b.id}|${N.decided_by}`,ct=i.get(Fc),An=N.decided_at,Cn=ct?.resolved_at??null,ua=Cn===null,Uc=ct?.duration_ms??(ua?n-An:0),Wc=ua?"active":ct?.status==="error"||ct?.status==="fail"?"error":"completed",ee,Ye;if($)ee=$,Ye=O;else{let ma=v.get(N.agent_id);ma?(ee=ma,Ye=`${ma}/_${b.source}`):(ee="unmapped",Ye=`unmapped/_${b.source}`)}l.has(ee)||l.set(ee,{id:ee,name:ee,color:oi(ee),projects:[]}),c.has(ee)||c.set(ee,new Set),c.get(ee).add(Ye),m.push({id:`${b.id}|${N.decided_by}`,agentId:N.agent_id,clientId:ee,projectId:Ye,channelId:W,initiatorId:re,initiatorKind:Z,subject:om(b.subject),intent:b.intent||"",startedAt:An,resolvedAt:Cn,duration:Uc,active:ua,outcome:Wc,tokens:0,inputPreview:S,system:tm(N.agent_id,e),...L,starter:Q})}}let x=[...l.values()].map(b=>({...b,projects:[...c.get(b.id)||[]].sort()})).sort((b,A)=>b.id.localeCompare(A.id)),g=[],u=new Set;if(e){let b=e.business??{},A=R=>{let S=b.orgChart?.[R]?.role,L=S?b.roles?.[S]?.title:void 0;return typeof L=="string"&&L.trim()?L.trim():void 0};for(let[R,S]of Object.entries(e.agents||{})){let L={id:R,name:S.name||R,tier:S.tier==="claude-code"?"lead":"worker",model:S.model||"",role:S.systemPrompt?S.systemPrompt.split(/[.\n]/)[0].slice(0,60):S.tier||"",title:A(R)};g.push(L),u.add(R)}}for(let b of m)u.has(b.agentId)||(g.push({id:b.agentId,name:b.agentId,tier:"worker",model:"",role:""}),u.add(b.agentId));g.sort((b,A)=>b.id.localeCompare(A.id));let h=[],w=new Set;for(let[b,A]of Object.entries(Pe))h.push({id:b,label:A.label,color:A.color}),w.add(b);for(let b of d.values())w.has(b.id)||h.push(b);let y=[...p.values()];y.find(b=>b.id==="__system")||y.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let T=e?.channels?.gitlab?.host;return{now:n,windowH:a,clients:x,agents:g,channels:h,initiators:y,dispatches:m,forges:{gitlab:typeof T=="string"?T:void 0,github:"https://github.com"}}}function en(t){let e=Za();if(!e)return null;try{return li(e.db,di(),t)}finally{e.close()}}function ci(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,i=0,l={};for(let{nodeId:c,snap:d}of t){l.gitlab??=d.forges?.gitlab,l.github??=d.forges?.github,d.now>s&&(s=d.now),d.windowH>i&&(i=d.windowH);for(let p of d.clients){let m=e.get(p.id);if(!m)e.set(p.id,{...p,projects:[...p.projects]});else{let f=Array.from(new Set([...m.projects,...p.projects])).sort();e.set(p.id,{...m,projects:f})}}for(let p of d.agents)a.has(p.id)||a.set(p.id,p);for(let p of d.channels)n.has(p.id)||n.set(p.id,p);for(let p of d.initiators)r.has(p.id)||r.set(p.id,p);for(let p of d.dispatches){let m=sm(p);if(m.clientId!==p.clientId&&!e.has(m.clientId)&&e.set(m.clientId,{id:m.clientId,name:m.clientId,color:oi(m.clientId),projects:[]}),m.projectId!==p.projectId){let f=e.get(m.clientId);f.projects.includes(m.projectId)||e.set(m.clientId,{...f,projects:[...f.projects,m.projectId].sort()})}o.push({...m,nodeId:c,id:`${c}::${m.id}`})}}return{now:s||Date.now(),windowH:i||6,localNodeId:t[0]?.nodeId,forges:l,clients:[...e.values()].sort((c,d)=>c.id.localeCompare(d.id)),agents:[...a.values()].sort((c,d)=>c.id.localeCompare(d.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((c,d)=>d.startedAt-c.startedAt)}}function sm(t){if(t.clientId!=="unmapped")return t;let e=Xa(t.inputPreview);if(!e)return t;let a=be?.business?.projects??[];return{...t,projectId:e,clientId:vt(e,a)}}async function ea(t){let e=be?.channels?.gitlab,a=await Vs(Js(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 be=null;function di(){return be&&{...be,people:et(be.people)}}function pi(t){be=t}async function ui(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=Za();if(!n)return ve(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=mi(parseInt(r.searchParams.get("hours")||"6",10));ve(e,200,await ea(li(n.db,di(),o)))}catch(r){ve(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var im=5e3;async function tn(t,e,a,n=en){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
|
|
8973
9007
|
|
|
8974
|
-
`);let r=new URL(t.url||"/","http://_"),o=
|
|
9008
|
+
`);let r=new URL(t.url||"/","http://_"),o=mi(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
|
|
8975
9009
|
|
|
8976
|
-
`)}catch{i()}},25e3);try{for(;!s;){try{let d=await n(o),p=d&&await
|
|
9010
|
+
`)}catch{i()}},25e3);try{for(;!s;){try{let d=await n(o),p=d&&await ea(d);if(s)break;p?(e.write(`event: snapshot
|
|
8977
9011
|
`),e.write(`data: ${JSON.stringify(p)}
|
|
8978
9012
|
|
|
8979
9013
|
`)):e.write(`event: error
|
|
@@ -8982,7 +9016,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
|
|
|
8982
9016
|
`)}catch(d){e.write(`event: error
|
|
8983
9017
|
data: ${JSON.stringify({error:d?.message??String(d)})}
|
|
8984
9018
|
|
|
8985
|
-
`)}let c=Date.now();for(;!s&&Date.now()-c<
|
|
9019
|
+
`)}let c=Date.now();for(;!s&&Date.now()-c<im;)await new Promise(d=>setTimeout(d,200))}}finally{clearInterval(l);try{e.end()}catch{}}return!0}function mi(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function lm(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=Ya(process.cwd(),".agentx/task-history",t,n);if(!Qa(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=Ya(process.cwd(),".agentx/task-history",t,o);return Qa(s)?ri(s,e,a):null}return ri(r,e,a)}function ri(t,e,a){let n=null,r=1/0;for(let o of Yu(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(Qu(Vu(t,o),"utf-8"))}catch{continue}let i=s.startedAt,l;if(typeof i=="number")l=i;else if(typeof i=="string"){let d=Date.parse(i);if(!Number.isFinite(d))continue;l=d}else continue;let c=Math.abs(l-e);c<r&&c<=a&&(n=s,r=c)}return n}async function fi(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 ve(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),i=r.slice(o+1),l=Za();if(!l)return ve(e,503,{error:"ledger not available"}),!0;try{let c=l.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!c)return ve(e,404,{error:"event not found"}),!0;let d=l.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,i);if(!d)return ve(e,404,{error:"decision not found"}),!0;let p=l.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,i),m=null;try{m=JSON.parse(c.raw_json)}catch{}let f=ii(c.source,m),_=m&&typeof m=="object"&&(m.text||m.message?.text||m.message?.caption||m.object_attributes?.note||m.object_attributes?.description||m.comment?.body||m.issue?.body||(typeof m.message=="string"?m.message:null)||(typeof m.prompt=="string"?m.prompt:null)||null)||f,v=null,E=null;if(d.agent_id){let y=lm(d.agent_id,d.decided_at);if(y){typeof y.responseText=="string"&&(v=y.responseText);let T=y.transcript;Array.isArray(T)&&(E=T.length)}}let x=be?.business?.projects??[],g=be?.business?.contactMap??[],u=wa(be?.business??{}),h={client:"unmapped",project:`unmapped/_${c.source}`,via:"fallback"},w=si(c.source,m,g);if(w)h={client:w.client,project:w.project||`${w.client}/_chat`,via:`contactMap (channel=${w.channel??"*"}${w.username?` username=${w.username}`:""}${w.chatId?` chatId=${w.chatId}`:""})`};else if(c.project||Qt(m,c.subject,f)){let y=c.project||Qt(m,c.subject,f);h={client:vt(y,x),project:y,via:c.project?`project namespace prefix (${y})`:`forge path in chat id / message (${y})`}}else if(d.agent_id){let y=u.get(d.agent_id);y&&(h={client:y,project:`${y}/_${c.source}`,via:`orgChart fallback (agent ${d.agent_id} reports up to a PM whose project belongs to ${y})`})}ve(e,200,{id:r,eventId:s,source:c.source,subject:c.subject,intent:c.intent,project:c.project,decidedBy:d.decided_by,agentId:d.agent_id,outcome:d.outcome,reason:d.reason,startedAt:d.decided_at,resolvedAt:p?.resolved_at??null,durationMs:p?.duration_ms??null,input:_,response:v,transcriptLen:E,resolutionStatus:p?.status??null,resultSummary:p?.result_summary??null,attribution:h})}catch(c){ve(e,500,{error:c?.message??String(c)})}finally{l.close()}return!0}import{existsSync as um,readFileSync as mm}from"fs";import{resolve as gi}from"path";ft();function hi(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=cm.replace(/__AGENT_ID__/g,B(e));return I({title:`AgentX \xB7 ${B(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${B(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:dm,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>${pm}</script>`})}var cm=`
|
|
8986
9020
|
<!-- Breadcrumb -->
|
|
8987
9021
|
<div class="ax-crumb">
|
|
8988
9022
|
<a href="/admin">Settings</a>
|
|
@@ -9571,7 +9605,7 @@ data: ${JSON.stringify({error:d?.message??String(d)})}
|
|
|
9571
9605
|
</div>
|
|
9572
9606
|
</div>
|
|
9573
9607
|
</div>
|
|
9574
|
-
`,
|
|
9608
|
+
`,dm=`
|
|
9575
9609
|
/* Agent-specific layout + legacy styles for bits the migration left in
|
|
9576
9610
|
* place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
|
|
9577
9611
|
* primitives live in components.css.ts. */
|
|
@@ -9690,7 +9724,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
|
|
|
9690
9724
|
|
|
9691
9725
|
/* Agent-specific button variant used in rail context (no ax-btn wrapper) */
|
|
9692
9726
|
.ax-btn.lg { padding: 9px 16px; font-size: 13px; }
|
|
9693
|
-
`,
|
|
9727
|
+
`,pm=`
|
|
9694
9728
|
const $ = (id) => document.getElementById(id);
|
|
9695
9729
|
const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
|
|
9696
9730
|
|
|
@@ -10546,15 +10580,15 @@ document.addEventListener('keydown', (e) => {
|
|
|
10546
10580
|
/* ===== Boot ===== */
|
|
10547
10581
|
initOptsToggles();
|
|
10548
10582
|
loadAgent();
|
|
10549
|
-
`;function
|
|
10550
|
-
`);return
|
|
10551
|
-
`);return
|
|
10583
|
+
`;function xi(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(hi({agentId:a,peers:n,localToken:r}))}async function vi(t,e,a){try{let n=t.method==="GET"?void 0:await jm(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){ta(e,404,{error:`unknown agent endpoint: ${a}`});return}let i=s[1],l=s[2]||"",c=`${t.method} ${l}`,p={"GET ":()=>nt(i),"PATCH ":()=>fm(i,n),"PATCH capability":()=>xm(i,n),"POST mcp":()=>hm(i,n),"DELETE mcp":()=>gm(i,n),"GET identity":()=>vm(i),"GET identity/file":()=>bm(i,String(o.path||"")),"PUT identity/file":()=>ym(i,n),"GET skills":()=>wm(i),"POST skills":()=>km(i,n),"DELETE skills":()=>_m(i,n),"GET skills/tree":()=>Sm(i,String(o.slug||"")),"GET skills/file":()=>Em(i,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>Tm(i,n),"GET skills/deps":()=>Am(i,String(o.slug||"")),"POST skills/install":()=>Cm(i,n,t),"POST skills/deps":()=>Im(i,n,t),"GET channels":()=>Mm(i),"GET activity":()=>Lm(i,t),"GET handovers":()=>Rm(i),"POST handovers":()=>Pm(i,n),"DELETE handovers":()=>$m(n)}[c];if(!p){ta(e,404,{error:`unknown agent sub-endpoint: ${c}`});return}let m=await p();ta(e,200,m)}catch(n){ta(e,400,{error:n?.message||"agent op failed"})}}function bi(){let t=gi(process.cwd(),"agentx.json");return um(t)?JSON.parse(mm(t,"utf-8")):null}function V(t){let e=bi();if(!e)throw new Error("agentx.json not found");let a=e.agents?.[t];if(!a)throw new Error(`Agent "${t}" not found`);return{def:a,cfg:e}}function nt(t){let{def:e,cfg:a}=V(t),n=e.workspace?He(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",intents:Array.isArray(e.intents)?e.intents:[],maxDelegationDepth:e.maxDelegationDepth??5,contextReferences:!!e.contextReferences,contextStrategy:e.contextStrategy||"",mcp:e.mcp&&typeof e.mcp=="object"?e.mcp:{},overview:n,defaultWorker:a.node?.defaultAgent,draftAgent:a.dashboard?.draftAgent}}function fm(t,e){let a={};for(let r of["name","tier","model","systemPrompt","mentions","access","maxConcurrent","maxExecutionMinutes","permissionMode"])e?.[r]!==void 0&&(a[r]=e[r]);let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);return r.agents[t]={...r.agents[t],...a},`agent "${t}" updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:nt(t)}}function hm(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(i=>String(i)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[i,l]of Object.entries(e.env))typeof l=="string"&&(o[i]=l);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=C(i=>{if(!i.agents?.[t])throw new Error(`Agent "${t}" not found`);return i.agents[t].mcp=i.agents[t].mcp||{},i.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:nt(t)}}function gm(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);if(!r.agents[t].mcp||!(a in r.agents[t].mcp))throw new Error(`no mcp.${a} on "${t}"`);return delete r.agents[t].mcp[a],Object.keys(r.agents[t].mcp).length===0&&delete r.agents[t].mcp,`agent "${t}" mcp.${a} removed`});return{summary:n,agent:nt(t)}}function xm(t,e){let a={};if(Array.isArray(e?.intents)&&(a.intents=e.intents.map(r=>String(r)).filter(Boolean)),e?.maxDelegationDepth!==void 0){let r=Number(e.maxDelegationDepth);if(!Number.isFinite(r)||r<0||r>50)throw new Error("maxDelegationDepth must be 0..50");a.maxDelegationDepth=r}if(e?.contextReferences!==void 0&&(a.contextReferences=!!e.contextReferences),e?.contextStrategy!==void 0){if(e.contextStrategy&&!["layered","planner"].includes(e.contextStrategy))throw new Error("contextStrategy must be layered|planner|empty");e.contextStrategy?a.contextStrategy=e.contextStrategy:a.contextStrategy=void 0}if(e?.maxExecutionMinutes!==void 0){let r=Number(e.maxExecutionMinutes);if(!Number.isFinite(r)||r<1||r>240)throw new Error("maxExecutionMinutes must be 1..240");a.maxExecutionMinutes=r}if(Object.keys(a).length===0)throw new Error("nothing to update");let{summary:n}=C(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,i]of Object.entries(a))i===void 0?delete o[s]:o[s]=i;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:nt(t)}}function vm(t){let{def:e}=V(t);return He(e.workspace)}function bm(t,e){if(!e)throw new Error("path query param required");let{def:a}=V(t);return Ct(a.workspace,e)}function ym(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=V(t);return It(n.workspace,a,String(e?.content??""))}function wm(t){let{def:e}=V(t),a=He(e.workspace);return{skills:a.skills,workspace:a.workspace}}function km(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return Mt(n.workspace,a,{title:e?.title,content:e?.content})}function _m(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=V(t);return Lt(n.workspace,a)}function Sm(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t),n=Cr(a.workspace,e),r=Rt(a.workspace,e);return{slug:e,tree:n,deps:r}}function Em(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=V(t);return Ir(n.workspace,e,a)}function Tm(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 Mr(r.workspace,a,n,String(e?.content??""))}function Am(t,e){if(!e)throw new Error("slug query param required");let{def:a}=V(t);return Rt(a.workspace,e)}async function Cm(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=yi(e?.worker),{def:o}=V(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
|
|
10584
|
+
`);return wi(a,r,s,`install-${n}:${Date.now()}`)}async function Im(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=yi(e?.worker),{def:o}=V(t),s=Rt(o.workspace,n);if(!s.manager)throw new Error(`No dependency manifest detected in .claude/skills/${n}. Expected one of: package.json, requirements.txt, Gemfile.`);let i=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(`
|
|
10585
|
+
`);return wi(a,r,l,`deps-${t}-${n}:${Date.now()}`)}function yi(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 wi(t,e,a,n){let r=X(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},i=t.headers.authorization;i?s.Authorization=String(i):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let l=await fetch(`${o}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"admin",sender:"admin-ui",chatId:n}})}),c=await l.text(),d;try{d=JSON.parse(c)}catch{d={content:c}}if(!l.ok)throw new Error(d?.error||`daemon /task HTTP ${l.status}`);return{worker:e,taskId:d?.taskId,content:d?.content,duration:d?.duration,error:d?.error}}function Mm(t){let e=bi(),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 Lm(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 an(){return new qn}function Rm(t){let e=an(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function Pm(t,e){let a=String(e?.channel||"").trim(),n=String(e?.chatId||"").trim(),r=String(e?.toAgent||"").trim();if(!a||!n||!r)throw new Error("channel, chatId, toAgent required");let o=String(e?.fromAgent||t||"").trim()||t,s=e?.accountId?String(e.accountId):void 0,i=e?.summary?String(e.summary):void 0,l=e?.expiresAt?String(e.expiresAt):void 0,c=an().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:i,expiresAt:l,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:c}}function $m(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:an().remove(e,a,n)?"Released":"No active handover for that chat"}}function ta(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function jm(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var $e={brand:"AgentX",subtitle:"Team AI ops",nodes:"machines",agentsCount:"agents",activeNow:"handling now",errorsCount:"failed",stats:{active:"Handling",total:"Today",errors:"Failed"},idle:"idle",runningNoPreview:"working \xB7 preparing reply",recentActivities:"Recent activities \u2192",noAgentsOnNode:"No agents set up on this machine.",unreachable:"This machine is unreachable.",neverRan:"not used yet",tierLabels:{"claude-code":"Claude Code","codex-cli":"Codex CLI",opencode:"OpenCode",sdk:"SDK",orchestrator:"Orchestrator"},taskModalTitle:"Task activity",taskModalConnecting:"connecting\u2026",taskModalLive:"live",taskModalFinished:"finished",taskModalArchived:"archived",taskModalLoadFailed:"couldn't load",taskModalFinalResponse:"Final reply",historyPanelTitle:"Recent activities",historyEmpty:"No activity yet.",historyLoading:"loading\u2026"};var ki=[{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 nn(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify($e)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
|
|
10552
10586
|
<span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
|
|
10553
10587
|
<span id="conn-label">live</span>`,n=`<div class="ax-app-live">
|
|
10554
10588
|
<section id="statstrip" class="ax-statstrip"></section>
|
|
10555
10589
|
<main id="grid" class="ax-live__body"></main>
|
|
10556
10590
|
</div>
|
|
10557
|
-
`;return I({title:`${$e.brand} \xB7 ${$e.subtitle}`,activeTab:"live",subtitle:$e.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:
|
|
10591
|
+
`;return I({title:`${$e.brand} \xB7 ${$e.subtitle}`,activeTab:"live",subtitle:$e.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:Om,scripts:e+`<script>${Nm}</script>`,headExtras:`<script>
|
|
10558
10592
|
// rightExtras for the topbar are injected at runtime \u2014 they reference
|
|
10559
10593
|
// IDs (#ts, #conn-dot) that the script below addresses directly.
|
|
10560
10594
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -10565,7 +10599,7 @@ loadAgent();
|
|
|
10565
10599
|
extras.innerHTML = ${JSON.stringify(a)};
|
|
10566
10600
|
right.insertBefore(extras, right.firstChild);
|
|
10567
10601
|
});
|
|
10568
|
-
</script>`})}var
|
|
10602
|
+
</script>`})}var Om=`
|
|
10569
10603
|
/* --- Page frame --- */
|
|
10570
10604
|
.ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
|
|
10571
10605
|
|
|
@@ -10772,7 +10806,7 @@ loadAgent();
|
|
|
10772
10806
|
border-top-color: var(--ax-accent); border-radius: 50%;
|
|
10773
10807
|
animation: ax-spin 800ms linear infinite; display: inline-block;
|
|
10774
10808
|
}
|
|
10775
|
-
@keyframes ax-spin { to { transform: rotate(360deg); } }`,
|
|
10809
|
+
@keyframes ax-spin { to { transform: rotate(360deg); } }`,Nm=`
|
|
10776
10810
|
'use strict';
|
|
10777
10811
|
|
|
10778
10812
|
const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
|
|
@@ -11343,7 +11377,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11343
11377
|
});
|
|
11344
11378
|
}
|
|
11345
11379
|
|
|
11346
|
-
`;var
|
|
11380
|
+
`;var _i=`
|
|
11347
11381
|
.mx-content{max-width:1180px;margin:0 auto;padding:0 24px 56px}
|
|
11348
11382
|
.mx-updated{margin:0;color:var(--ax-muted);font-size:11px;font-family:var(--ax-mono)}
|
|
11349
11383
|
.mx-section{margin-bottom:28px}.mx-section .ax-section-head{margin-bottom:14px}
|
|
@@ -11517,7 +11551,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
11517
11551
|
.mx-summary{max-width:56vw}
|
|
11518
11552
|
}
|
|
11519
11553
|
@media(prefers-reduced-motion:reduce){.mx-drawer{transition:none}}
|
|
11520
|
-
`;var
|
|
11554
|
+
`;var Si=`<script>
|
|
11521
11555
|
window.MX=(function(){
|
|
11522
11556
|
var ENT={'&':'&','<':'<','>':'>','"':'"',"'":'''};
|
|
11523
11557
|
function esc(v){return String(v==null?'':v).replace(/[&<>"']/g,function(c){return ENT[c]})}
|
|
@@ -11626,7 +11660,7 @@ window.MX=(function(){
|
|
|
11626
11660
|
verdict:verdict,verdictChip:verdictChip,mark:mark,causeLabel:causeLabel,
|
|
11627
11661
|
setHealth:setHealth,get:get};
|
|
11628
11662
|
})();
|
|
11629
|
-
</script>`;var
|
|
11663
|
+
</script>`;var Ei=`<script>
|
|
11630
11664
|
window.MXD=(function(){
|
|
11631
11665
|
function el(id){return document.getElementById(id)}
|
|
11632
11666
|
function tz(){return -new Date().getTimezoneOffset()}
|
|
@@ -11840,7 +11874,7 @@ window.MXD=(function(){
|
|
|
11840
11874
|
|
|
11841
11875
|
return {openDay:openDay,openJob:openJob,openConversation:openConversation};
|
|
11842
11876
|
})();
|
|
11843
|
-
</script>`;var
|
|
11877
|
+
</script>`;var Ti=`<script>
|
|
11844
11878
|
(function(){
|
|
11845
11879
|
var LANES=[
|
|
11846
11880
|
{id:'cron',name:'Scheduled',hint:'cron jobs'},
|
|
@@ -12156,7 +12190,7 @@ window.MXD=(function(){
|
|
|
12156
12190
|
window.addEventListener('scroll',hideTip,{passive:true});
|
|
12157
12191
|
load();
|
|
12158
12192
|
})();
|
|
12159
|
-
</script>`;var
|
|
12193
|
+
</script>`;var Ai=`<script>
|
|
12160
12194
|
(function(){
|
|
12161
12195
|
var showAll=document.getElementById('mx-show-all'),expanded=false;
|
|
12162
12196
|
var esc=MX.esc;
|
|
@@ -12334,7 +12368,7 @@ window.MXD=(function(){
|
|
|
12334
12368
|
}
|
|
12335
12369
|
load();setInterval(load,5000);
|
|
12336
12370
|
})();
|
|
12337
|
-
</script>`;var
|
|
12371
|
+
</script>`;var Ci=`
|
|
12338
12372
|
.mx-rt-bar{display:flex;flex-wrap:wrap;align-items:center;gap:6px;margin-bottom:12px}
|
|
12339
12373
|
.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}
|
|
12340
12374
|
.mx-rt-wrap > .mx-empty{border:0}
|
|
@@ -12375,7 +12409,7 @@ window.MXD=(function(){
|
|
|
12375
12409
|
.mx-rt-msg td{display:block}.mx-rt-msg td::before{content:none}
|
|
12376
12410
|
.mx-rt-name{max-width:100%}
|
|
12377
12411
|
}
|
|
12378
|
-
`,
|
|
12412
|
+
`,Ii=`<script>
|
|
12379
12413
|
(function(){
|
|
12380
12414
|
var root=document.getElementById('mx-routines');
|
|
12381
12415
|
var bar=document.getElementById('mx-rt-filter');
|
|
@@ -12502,7 +12536,7 @@ window.MXD=(function(){
|
|
|
12502
12536
|
syncBar();
|
|
12503
12537
|
document.addEventListener('mx:snapshot',function(e){render(e.detail||{})});
|
|
12504
12538
|
})();
|
|
12505
|
-
</script>`;var
|
|
12539
|
+
</script>`;var Mi=[{id:"all",label:"All"},{id:"peers",label:"Other machines"},{id:"announce",label:"Announcements"},{id:"problems",label:"Problems"}],Li=`<script>
|
|
12506
12540
|
(function(){
|
|
12507
12541
|
var root=document.getElementById('mx-feed');
|
|
12508
12542
|
if(!root)return;
|
|
@@ -12577,12 +12611,12 @@ window.MXD=(function(){
|
|
|
12577
12611
|
}
|
|
12578
12612
|
load();setInterval(load,5000);
|
|
12579
12613
|
})();
|
|
12580
|
-
</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
|
|
12614
|
+
</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 Dm=[{id:"all",label:"All"},{id:"attention",label:"Flagged"},{id:"schedule",label:"Schedules"},{id:"event",label:"Events"}],Bm=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],Hm=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function Ri(t){let e=de({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+Pt([{kind:"off",num:"-",label:"Nodes online"},{kind:"off",num:"-",label:"Tasks running"},{kind:"off",num:"-",label:"Failed today"},{kind:"off",num:"-",label:"Jobs needing review"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="mx-health">'),a=`<div class="mx-toolbar">
|
|
12581
12615
|
<div class="mx-tabs" role="tablist" aria-label="Mesh views">
|
|
12582
|
-
${
|
|
12616
|
+
${Bm.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("")}
|
|
12583
12617
|
</div>
|
|
12584
12618
|
<div class="mx-range" id="mx-range" role="group" aria-label="History window">
|
|
12585
|
-
${
|
|
12619
|
+
${Hm.map(i=>`<button type="button" data-days="${i.days}" aria-pressed="${i.days===30}">${i.label}</button>`).join("")}
|
|
12586
12620
|
</div>
|
|
12587
12621
|
</div>
|
|
12588
12622
|
<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">
|
|
@@ -12635,7 +12669,7 @@ window.MXD=(function(){
|
|
|
12635
12669
|
<section class="mx-section" aria-labelledby="mx-routines-title">
|
|
12636
12670
|
${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>')}
|
|
12637
12671
|
<div class="mx-rt-bar" id="mx-rt-filter" role="group" aria-label="Filter routines">
|
|
12638
|
-
${
|
|
12672
|
+
${Dm.map(i=>`<button class="mx-chip" type="button" data-rt-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12639
12673
|
</div>
|
|
12640
12674
|
<div class="mx-rt-wrap" id="mx-routines"><div class="mx-empty">Loading routines...</div></div>
|
|
12641
12675
|
</section>
|
|
@@ -12643,7 +12677,7 @@ window.MXD=(function(){
|
|
|
12643
12677
|
<section class="mx-section" aria-labelledby="mx-feed-title">
|
|
12644
12678
|
${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>')}
|
|
12645
12679
|
<div class="mx-rt-bar" role="group" aria-label="Filter the mesh feed">
|
|
12646
|
-
${
|
|
12680
|
+
${Mi.map(i=>`<button class="mx-chip" type="button" data-feed-filter="${i.id}" aria-pressed="${i.id==="all"}">${i.label}</button>`).join("")}
|
|
12647
12681
|
</div>
|
|
12648
12682
|
<div class="ax-stack" id="mx-feed" aria-live="polite"><div class="mx-empty">Loading the mesh feed...</div></div>
|
|
12649
12683
|
</section>
|
|
@@ -12676,7 +12710,7 @@ window.MXD=(function(){
|
|
|
12676
12710
|
<button class="ax-btn ax-btn--ghost" id="mx-close" type="button" aria-label="Close details">Close</button>
|
|
12677
12711
|
</header>
|
|
12678
12712
|
<div class="mx-drawer__body" id="mx-drawer-body"></div>
|
|
12679
|
-
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:
|
|
12713
|
+
</aside>`;return I({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:_i+Ci,scripts:Si+zm+Ei+Ti+Ii+Ai+Li})}var zm=`<script>
|
|
12680
12714
|
(function(){
|
|
12681
12715
|
var tabs=Array.prototype.slice.call(document.querySelectorAll('.mx-tab'));
|
|
12682
12716
|
var range=document.getElementById('mx-range');
|
|
@@ -12704,10 +12738,10 @@ window.MXD=(function(){
|
|
|
12704
12738
|
var saved=null;try{saved=localStorage.getItem('mx-view')}catch(e){}
|
|
12705
12739
|
select(tabs.some(function(t){return t.dataset.view===saved})?saved:'activity');
|
|
12706
12740
|
})();
|
|
12707
|
-
</script>`;function
|
|
12741
|
+
</script>`;function Pi(t){let e=de({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."})+`
|
|
12708
12742
|
<div id="gm-msg" class="gm-msg" role="status" aria-live="polite"></div>
|
|
12709
12743
|
<ol id="gm-list" class="gm-list" aria-label="Grants"><li class="gm-empty">Loading\u2026</li></ol>
|
|
12710
|
-
<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:
|
|
12744
|
+
<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:qm,scripts:`<script>${Fm}</script>`})}var qm=`
|
|
12711
12745
|
.gm-list { list-style: none; margin: 16px 0; padding: 0; display: grid; gap: 12px; }
|
|
12712
12746
|
.gm-empty { color: var(--ax-text-2); }
|
|
12713
12747
|
.gm-item { padding: 14px 16px; border: var(--ax-border-w) solid var(--ax-border); border-radius: var(--ax-radius); background: var(--ax-surface); }
|
|
@@ -12725,7 +12759,7 @@ window.MXD=(function(){
|
|
|
12725
12759
|
.gm-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
12726
12760
|
.gm-msg.is-bad { color: var(--ax-red-ink); }
|
|
12727
12761
|
.gm-note { color: var(--ax-text-2); font-size: var(--ax-fs-sm); }
|
|
12728
|
-
`,
|
|
12762
|
+
`,Fm=`
|
|
12729
12763
|
(function () {
|
|
12730
12764
|
var list = document.getElementById('gm-list');
|
|
12731
12765
|
var msg = document.getElementById('gm-msg');
|
|
@@ -12772,7 +12806,7 @@ window.MXD=(function(){
|
|
|
12772
12806
|
load();
|
|
12773
12807
|
setInterval(load, 30000);
|
|
12774
12808
|
})();
|
|
12775
|
-
`;async function
|
|
12809
|
+
`;async function $i(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?days=${e.days}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/mesh"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return Um(s,e.days)}function Um(t,e){let a={runs:0,errors:0,hours:0,agents:0,threads:0},n=new Map,r=new Map,o=new Map,s=new Map,i=[],l=[],c=0,d=0,p=0,m=0,f=0,_=0;for(let{node:E,data:x}of t)if(x){a.runs+=x.totals.runs,a.errors+=x.totals.errors,a.hours+=x.totals.hours,a.agents+=x.totals.agents,a.threads+=x.totals.threads;for(let g of x.days){let u=n.get(g.day)||{day:g.day,cron:[0,0],workflow:[0,0],direct:[0,0]};for(let h of["cron","workflow","direct"])u[h][0]+=g[h]?.[0]||0,u[h][1]+=g[h]?.[1]||0;n.set(g.day,u)}for(let g of x.origins){let u=r.get(g.channel)||{channel:g.channel,runs:0,errors:0,hours:0};u.runs+=g.runs,u.errors+=g.errors,u.hours+=g.hours,r.set(g.channel,u)}for(let g of x.causes){let u=o.get(g.cause)||{cause:g.cause,count:0,agents:[],example:""};u.count+=g.count;for(let h of g.agents)u.agents.includes(h)||u.agents.push(h);u.example||(u.example=g.example),o.set(g.cause,u)}for(let g of x.rotations.byReason)s.set(g.reason,(s.get(g.reason)||0)+g.count);c+=x.rotations.total,d+=x.rotations.tokenSum||0,p+=x.rotations.tokenSamples||0,m=Math.max(m,x.rotations.maxTokens),f+=x.retention.traces,_+=x.retention.tracesWithSteps;for(let g of x.jobs)i.push({...g,node:E.name,nodeUrl:E.url});for(let g of x.threads)l.push({...g,node:E.name,nodeUrl:E.url})}let v=t.filter(E=>E.data).map(E=>E.data.since).filter(E=>Number.isFinite(E));return{generatedAt:Date.now(),windowDays:e,since:v.length?Math.min(...v):Date.now()-e*864e5,nodes:t.map(E=>({name:E.node.name,url:E.node.url,ok:!!E.data,error:E.error,runs:E.data?.totals.runs||0})),totals:{...a,hours:Math.round(a.hours*100)/100},days:[...n.values()].sort((E,x)=>E.day.localeCompare(x.day)),origins:[...r.values()].map(E=>({...E,hours:Math.round(E.hours*100)/100})).sort((E,x)=>x.runs-E.runs),causes:[...o.values()].sort((E,x)=>x.count-E.count),jobs:i.sort((E,x)=>x.hours-E.hours),threads:l.sort((E,x)=>x.lastAt-x.firstAt-(E.lastAt-E.firstAt)||x.runs-E.runs),rotations:{total:c,byReason:[...s.entries()].map(([E,x])=>({reason:E,count:x})).sort((E,x)=>x.count-E.count),tokenSum:d,tokenSamples:p,maxTokens:m},retention:{traces:f,tracesWithSteps:_}}}async function ji(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 Oi(t,e,a=6e3){let n=new AbortController,r=setTimeout(()=>n.abort(),a),o=`?day=${encodeURIComponent(e.day)}&tzOffset=${e.tzOffsetMinutes}&limit=${e.limit}`,s;try{s=await Promise.all(t.map(async i=>{let l={Accept:"application/json"};i.token&&(l.Authorization=`Bearer ${i.token}`);try{let c=await fetch(i.url+"/analytics/day"+o,{headers:l,signal:n.signal});return c.ok?{node:i,data:await c.json()}:{node:i,error:`HTTP ${c.status}`}}catch(c){return{node:i,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return Wm(s,e.day)}function Wm(t,e){let a={runs:0,errors:0,ms:0,inputTokens:0,outputTokens:0},n=new Map,r=new Map,o=[];for(let{node:s,data:i}of t)if(i){a.runs+=i.totals.runs,a.errors+=i.totals.errors,a.ms+=i.totals.ms,a.inputTokens+=i.totals.inputTokens,a.outputTokens+=i.totals.outputTokens;for(let l of i.origins){let c=n.get(l.channel)||{channel:l.channel,runs:0,errors:0,ms:0};c.runs+=l.runs,c.errors+=l.errors,c.ms+=l.ms,n.set(l.channel,c)}for(let l of i.causes)r.set(l.cause,(r.get(l.cause)||0)+l.count);for(let l of i.conversations)o.push({...l,node:s.name,nodeUrl:s.url})}return{day:e,nodes:t.map(s=>({name:s.node.name,url:s.node.url,ok:!!s.data,error:s.error,runs:s.data?.totals.runs||0})),totals:a,origins:[...n.values()].sort((s,i)=>i.runs-s.runs),causes:[...r.entries()].map(([s,i])=>({cause:s,count:i})).sort((s,i)=>i.count-s.count),conversations:o.sort((s,i)=>i.ms-s.ms||i.turns-s.turns)}}function Ni(t={}){let e=`
|
|
12776
12810
|
<select id="boardPicker" title="Switch board"></select>
|
|
12777
12811
|
<div class="search">
|
|
12778
12812
|
<span class="icon">\u2315</span>
|
|
@@ -12873,7 +12907,7 @@ window.MXD=(function(){
|
|
|
12873
12907
|
</footer>
|
|
12874
12908
|
</div>
|
|
12875
12909
|
</div>
|
|
12876
|
-
<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:
|
|
12910
|
+
<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:Gm,scripts:`<script>${Xm}</script>`,headExtras:`<script>
|
|
12877
12911
|
// The boards page has its own connection dot + wants body height:100%
|
|
12878
12912
|
// for the full-viewport kanban layout. Inject the dot into the topbar
|
|
12879
12913
|
// and override body height at runtime so the shared shell doesn't
|
|
@@ -12889,7 +12923,7 @@ window.MXD=(function(){
|
|
|
12889
12923
|
right.insertBefore(dot, right.firstChild);
|
|
12890
12924
|
}
|
|
12891
12925
|
});
|
|
12892
|
-
</script>`})}var
|
|
12926
|
+
</script>`})}var Gm=`
|
|
12893
12927
|
/* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
|
|
12894
12928
|
.ax-subheader select, .ax-subheader input, .ax-subheader button {
|
|
12895
12929
|
background: var(--col); color: var(--text); border: 1px solid var(--border);
|
|
@@ -13142,7 +13176,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
|
|
|
13142
13176
|
.draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
|
|
13143
13177
|
.draft-box .draft-row .hint.err { color: var(--red); }
|
|
13144
13178
|
.draft-box .draft-row .hint.ok { color: var(--green); }
|
|
13145
|
-
`,
|
|
13179
|
+
`,Xm=`
|
|
13146
13180
|
'use strict';
|
|
13147
13181
|
const state = {
|
|
13148
13182
|
boards: [], current: null, items: {},
|
|
@@ -14195,9 +14229,9 @@ function appendEvents(events) {
|
|
|
14195
14229
|
}
|
|
14196
14230
|
|
|
14197
14231
|
loadBoards().catch(e => toast('Init failed: ' + e.message));
|
|
14198
|
-
`;function
|
|
14232
|
+
`;function Di(t={}){let a=`<h1>Plain-English glossary</h1>
|
|
14199
14233
|
<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>
|
|
14200
|
-
${
|
|
14234
|
+
${ki.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${B(n.alias)}</span>`:"";return`<article class="term"><h3>${B(n.term)}${r}</h3><p>${B(n.definition)}</p></article>`}).join("")}`;return I({title:`${$e.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Km})}var Km=`
|
|
14201
14235
|
main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
|
|
14202
14236
|
h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
|
|
14203
14237
|
.lead {
|
|
@@ -14227,7 +14261,7 @@ article.term .alias {
|
|
|
14227
14261
|
}
|
|
14228
14262
|
article.term p {
|
|
14229
14263
|
margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
|
|
14230
|
-
}`;function
|
|
14264
|
+
}`;function Bi(t={}){let e=`<div class="ax-wf__root">
|
|
14231
14265
|
<aside class="ax-wf__list">
|
|
14232
14266
|
<header>
|
|
14233
14267
|
<h2>Workflows</h2>
|
|
@@ -14304,7 +14338,7 @@ article.term p {
|
|
|
14304
14338
|
</aside>
|
|
14305
14339
|
</div>
|
|
14306
14340
|
|
|
14307
|
-
<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:
|
|
14341
|
+
<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:Jm,scripts:`<script>${q({workflowHealth:Yn})}${Vm}</script>`})}var Jm=`
|
|
14308
14342
|
.ax-wf__root {
|
|
14309
14343
|
display: grid;
|
|
14310
14344
|
grid-template-columns: 340px 1fr;
|
|
@@ -14688,7 +14722,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14688
14722
|
font-size: 12px; z-index: 50;
|
|
14689
14723
|
}
|
|
14690
14724
|
.hint { color: var(--ax-muted); font-size: 11px; }
|
|
14691
|
-
`,
|
|
14725
|
+
`,Vm=`
|
|
14692
14726
|
(() => {
|
|
14693
14727
|
const $ = (sel) => document.querySelector(sel)
|
|
14694
14728
|
const $$ = (sel) => Array.from(document.querySelectorAll(sel))
|
|
@@ -15477,7 +15511,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15477
15511
|
setInterval(refresh, 15000)
|
|
15478
15512
|
})
|
|
15479
15513
|
})();
|
|
15480
|
-
`;function
|
|
15514
|
+
`;function Hi(t={}){let e=`<div class="ax-proc__root">
|
|
15481
15515
|
<header class="ax-proc__header">
|
|
15482
15516
|
<h1>Procedures</h1>
|
|
15483
15517
|
<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>
|
|
@@ -15521,7 +15555,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15521
15555
|
<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>
|
|
15522
15556
|
<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>
|
|
15523
15557
|
</section>
|
|
15524
|
-
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:
|
|
15558
|
+
</div>`;return I({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Ym,scripts:`<script>${Qm}</script>`})}var Ym=`
|
|
15525
15559
|
.ax-proc__root { padding: 18px 24px 40px; max-width: 1100px; margin: 0 auto; color: var(--ax-text); }
|
|
15526
15560
|
.ax-proc__header h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
15527
15561
|
.ax-proc__header .hint { color: var(--ax-muted); font-size: 12px; margin: 0 0 18px; }
|
|
@@ -15547,7 +15581,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15547
15581
|
.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); }
|
|
15548
15582
|
.ax-proc__link { color: var(--ax-accent, #6366f1); text-decoration: none; font-size: 11px; }
|
|
15549
15583
|
.ax-proc__link:hover { text-decoration: underline; }
|
|
15550
|
-
`,
|
|
15584
|
+
`,Qm=`
|
|
15551
15585
|
(function(){
|
|
15552
15586
|
function $(sel){ return document.querySelector(sel) }
|
|
15553
15587
|
function esc(s){ return String(s||"").replace(/[&<>"']/g, function(c){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c] }) }
|
|
@@ -15647,7 +15681,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15647
15681
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootAll)
|
|
15648
15682
|
else bootAll()
|
|
15649
15683
|
})();
|
|
15650
|
-
`;function
|
|
15684
|
+
`;function zi(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
|
|
15651
15685
|
data-task-id="${B(t.taskId)}"
|
|
15652
15686
|
data-agent-id="${B(t.agentId)}"
|
|
15653
15687
|
data-node-url="${B(t.nodeUrl)}"
|
|
@@ -15690,7 +15724,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15690
15724
|
<button type="button" id="task-send" class="ax-btn ax-btn--primary">send \u2192</button>
|
|
15691
15725
|
</div>
|
|
15692
15726
|
</footer>
|
|
15693
|
-
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
15727
|
+
</div>`;return I({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Zm,scripts:`<script>${ef}</script>`})}var Zm=`
|
|
15694
15728
|
/* The shell gives <main> no padding, so page content butted straight against
|
|
15695
15729
|
the sticky topbar. Breathe. */
|
|
15696
15730
|
.ax-task-page {
|
|
@@ -15832,7 +15866,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
15832
15866
|
line-height: 1.55; text-wrap: pretty; white-space: pre-wrap; word-break: break-word;
|
|
15833
15867
|
}
|
|
15834
15868
|
|
|
15835
|
-
`,
|
|
15869
|
+
`,ef=`
|
|
15836
15870
|
(function () {
|
|
15837
15871
|
var root = document.querySelector('.ax-task-page');
|
|
15838
15872
|
if (!root) return;
|
|
@@ -16217,7 +16251,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16217
16251
|
});
|
|
16218
16252
|
|
|
16219
16253
|
})();
|
|
16220
|
-
`;function
|
|
16254
|
+
`;function qi(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
|
|
16221
16255
|
data-agent-id="${B(t.agentId)}"
|
|
16222
16256
|
data-agent-name="${B(e)}"
|
|
16223
16257
|
data-node-url="${B(t.nodeUrl)}">
|
|
@@ -16246,7 +16280,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16246
16280
|
<div class="ax-history__list" id="hist-list">
|
|
16247
16281
|
<div class="ax-history__empty">loading\u2026</div>
|
|
16248
16282
|
</div>
|
|
16249
|
-
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:
|
|
16283
|
+
</div>`;return I({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:tf,scripts:`<script>${af}</script>`})}var tf=`
|
|
16250
16284
|
/* <main> carries no padding in the shell \u2014 without this the breadcrumb sits
|
|
16251
16285
|
flush against the sticky topbar. */
|
|
16252
16286
|
.ax-history {
|
|
@@ -16298,7 +16332,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16298
16332
|
-webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
|
16299
16333
|
}
|
|
16300
16334
|
.ax-history__foot { margin-top: 6px; font-size: var(--ax-fs-xs); color: var(--ax-muted); font-family: var(--ax-mono); }
|
|
16301
|
-
`,
|
|
16335
|
+
`,af=`
|
|
16302
16336
|
(function () {
|
|
16303
16337
|
var root = document.querySelector('.ax-history');
|
|
16304
16338
|
if (!root) return;
|
|
@@ -16398,31 +16432,31 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
16398
16432
|
listEl.innerHTML = '<div class="ax-history__empty" style="color:var(--ax-err)">' + esc(e.message) + '</div>';
|
|
16399
16433
|
});
|
|
16400
16434
|
})();
|
|
16401
|
-
`;function
|
|
16435
|
+
`;function Ui(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 Ge(t,e,l=>Fi(e,a,l,{mode:"create",convertFromYaml:i}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:rf(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?Ge(t,e,i=>{let l=i,c=a.dispatcher.emitSignal({name:s,scope:l?.scope,workflowId:l?.workflowId,payload:l?.payload});return P(e,200,{ok:!0,emission:c})}):P(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),i=o[2];if(i==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?P(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?Ge(t,e,l=>{try{let c=a.layouts.save(s,l);return P(e,200,{layout:c})}catch(c){return P(e,400,{error:"invalid layout",message:c.message})}}):!0}if(i==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?Ge(t,e,l=>{let c=ba.safeParse(l);if(!c.success)return P(e,200,{ok:!1,issues:c.error.issues.map(p=>({path:p.path.join("."),message:p.message}))});let d=ya(c.data).map(p=>({path:"",message:p}));return P(e,200,{ok:d.length===0,issues:d,workflow:c.data})}):!0;if(!i){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let l=a.store.get(s);return l?P(e,200,{workflow:l}):P(e,404,{error:"workflow not found"})}if(r==="PUT"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=new URL(n,"http://_").searchParams,c=l.get("convertFromYaml")==="true"||l.get("convertFromYaml")==="1";return Ge(t,e,d=>Fi(e,a,d,{mode:"update",id:s,convertFromYaml:c}))}if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let l=a.store.delete(s);return a.layouts.delete(s),P(e,l?200:404,l?{ok:!0}:{error:"workflow not found"})}}}return P(e,404,{error:"unknown workflows endpoint",path:n})}var nf=["mesh"];function Fi(t,e,a,n){let r=ba.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=ya(o);if(s.length>0)return P(t,400,{error:"lint errors",issues:s.map(l=>({path:"",message:l}))});if(n.mode==="update"&&o.id!==n.id)return P(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return P(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let l=a,c=e.store.get(n.id);if(c)for(let d of nf)!(d in l)&&d in c&&(o[d]=c[d])}let i;try{i=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(l){let c=l?.message||String(l),d=l?.yamlPath,p=!!d||/yaml round-trip failed/.test(c);return P(t,p?409:500,{error:p?"couldn't preserve comments while saving back to the YAML file. Re-submit with ?convertFromYaml=true to convert this workflow to JSON (comments will be lost).":c,kind:p?"yaml-authored":"save-failed",...d?{path:d}:{}})}return e.layouts.sync(i.id,i.nodes.map(l=>l.id)),P(t,200,{workflow:i})}function rf(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let l=Math.max(1,Math.min(500,Number(r.get("limit")||50))),c=r.get("workflowId")||void 0,d=r.get("summary")==="1"||r.get("summary")==="true",p=a.runs.list({workflowId:c,limit:l});if(!d)return P(e,200,{runs:p});let m=p.map(f=>({id:f.id,workflowId:f.workflowId,workflowVersion:f.workflowVersion,homeNode:f.homeNode,status:f.status,pending:f.pending,entityRef:f.entityRef,history:(f.history||[]).slice(-5),parentRunId:f.parentRunId,parentNodeId:f.parentNodeId,rootRunId:f.rootRunId,depth:f.depth,createdAt:f.createdAt,updatedAt:f.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 Ge(t,e,c=>{let d=c?.status;return d!=="paused"&&d!=="running"&&d!=="canceled"?P(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(l,d)?P(e,200,{ok:!0,runId:l,status:d}):P(e,404,{error:"run not found"})})}let i=o.match(/^\/([^\/?]+)(\/stream)?$/);if(i){let l=decodeURIComponent(i[1]);if(i[2])return of(t,e,a,l);let c=a.runs.get(l);return c?P(e,200,{run:c}):P(e,404,{error:"run not found"})}return P(e,404,{error:"unknown runs endpoint"})}function of(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)}
|
|
16402
16436
|
|
|
16403
16437
|
`);let o=!1,s=()=>{o=!0,l?.(),clearInterval(d);try{e.end()}catch{}};t.on("close",s);let i=p=>{if(!o)try{e.write(`data: ${JSON.stringify(p)}
|
|
16404
16438
|
|
|
16405
|
-
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,d=setInterval(()=>{if(o)return;let p=a.runs.get(n);p&&p.updatedAt!==c&&(c=p.updatedAt,i(p))},2e3);return!0}function Ge(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
|
|
16439
|
+
`)}catch{s()}},l=a.runEvents?.subscribe(n,i),c=r.updatedAt,d=setInterval(()=>{if(o)return;let p=a.runs.get(n);p&&p.updatedAt!==c&&(c=p.updatedAt,i(p))},2e3);return!0}function Ge(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 Qf}from"fs";import{createRequire as Zf}from"module";jn();var Gi=50,sf=280;async function Xi(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=lf(await o.recent(Gi))}catch(c){l=String(c?.message||"unreachable").slice(0,200)}return Wi(e,200,{items:i,error:l,notify:s?s.on(r.id,"announce"):!1,notifyAvailable:!!s})}return Wi(e,404,{error:"not found"})}function Ki(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=process.env.MESH_TOKEN||U(t.dashboard,e),n=t.channels.push;return{async recent(r){let o=await fetch(`${e}/events/recent?kind=announce&limit=${r}`,{headers:a?{Authorization:`Bearer ${a}`}:{},signal:AbortSignal.timeout(5e3)});if(!o.ok)throw new Error(`the daemon answered ${o.status}`);return(await o.json()).events??[]},prefs:()=>{if(!n.enabled)return null;if(n.relayTo)return wt();let r=ut();return r?new nr(r):null}}}function lf(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:rn(typeof n.summary=="string"?n.summary:"",sf),by:typeof n.agentId=="string"?rn(n.agentId,100):null,node:rn(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,Gi)}function rn(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}function Wi(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var cf="operator",df=50,Ji=4,Vi=500;function pf(t){let e={channel:"app",chatId:t.chatId,sender:cf,...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 Yi(t,e,a,n){let{path:r,body:o}=pf(e),s="",i=!1,l=[],c=new Map,d=(p,m,f)=>{let _=p!=="done",v=i?{text:xt(m,_),artifacts:[]}:gt(m,ce.perMessage,_),{cleanText:E,ui:x}=p==="done"?bt(v.text):{cleanText:v.text,ui:void 0},g=i?void 0:on(x);return{status:p,text:E,tools:l,files:v.artifacts,...g?{ui:g}:{},...f?{error:f}:{}}};try{let p=await fetch(t.url.replace(/\/+$/,"")+r,{method:"POST",headers:{"Content-Type":"application/json",Accept:"text/event-stream",...t.token?{Authorization:`Bearer ${t.token}`}:{},...t.operatorKey?{"X-AgentX-Operator":t.operatorKey}:{}},body:JSON.stringify(o),signal:a});if(!p.ok||!p.body){let m=await p.json().then(f=>f?.error).catch(()=>"");return d("error",s,m||`AgentX answered HTTP ${p.status}.`)}for await(let m of mf(p.body)){n(m.event,m.data);let f=m.data??{};if(m.event==="start")i=f.rich===!1;else if(m.event==="text"&&typeof f.text=="string")s+=f.text;else if(m.event==="tool"&&f.status==="start"&&l.length<df){let _={name:String(f.name||"tool").slice(0,80),...f.arg?{arg:String(f.arg).slice(0,80)}:{}};l.push(_),f.id&&c.set(String(f.id),_)}else if(m.event==="tool"&&f.status==="result"&&f.error===!0&&c.has(String(f.id)))c.get(String(f.id)).error=!0;else{if(m.event==="done")return d("done",typeof f.content=="string"&&f.content?f.content:s);if(m.event==="error")return d("error",s,uf(f.error))}}return a.aborted?d("stopped",s):d("error",s,"The connection to the agent closed before it answered.")}catch(p){return a.aborted?d("stopped",s):d("error",s,`Could not reach AgentX: ${p?.message||p}`)}}function uf(t){let e=String(t||"The agent could not answer.");return Fn(e)?"The agent is busy with other work. Send the message again when it is free.":e.slice(0,500)}function on(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,Ji).map(s=>s.slice(0,Vi));r.length&&(a.quickReplies=r);let o=(t.replies??[]).slice(0,Ji).map(s=>({label:s.label.slice(0,80),reply:s.reply.slice(0,Vi)}));return o.length&&(a.replies=o),Object.keys(a).length?a:void 0}async function*mf(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,`
|
|
16406
16440
|
`);let s;for(;(s=n.indexOf(`
|
|
16407
16441
|
|
|
16408
16442
|
`))!==-1;){let i=n.slice(0,s);n=n.slice(s+2);let l="message",c=[];for(let d of i.split(`
|
|
16409
16443
|
`))d.startsWith("event:")?l=d.slice(6).trim():d.startsWith("data:")&&c.push(d.slice(5).replace(/^ /,""));if(c.length)try{yield{event:l,data:JSON.parse(c.join(`
|
|
16410
|
-
`))}}catch{}}}}finally{e.releaseLock()}}var
|
|
16444
|
+
`))}}catch{}}}}finally{e.releaseLock()}}var aa=class{constructor(e){this.orphanLimitMs=e}ac=new AbortController;text="";tools=[];plain=!1;orphaned=!1;startedAt=Date.now();listeners=new Map;orphanTimer=null;done=!1;broadcast(e,a){e==="start"&&(this.plain=a?.rich===!1),e==="text"&&typeof a?.text=="string"&&(this.text+=a.text),e==="tool"&&a?.status==="start"&&this.tools.length<50&&this.tools.push({name:String(a.name||"tool"),...a.arg?{arg:String(a.arg)}:{}});for(let n of this.listeners.keys())n(e,a)}watched(){return this.listeners.size>0}attach(e){let a=()=>!e.writableEnded&&!e.destroyed,n=(o,s)=>{a()&&e.write(`event: ${o}
|
|
16411
16445
|
data: ${JSON.stringify(s)}
|
|
16412
16446
|
|
|
16413
16447
|
`)},r=setInterval(()=>{a()&&e.write(`: ping
|
|
16414
16448
|
|
|
16415
|
-
`)},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
|
|
16416
|
-
`)){let n=
|
|
16417
|
-
`).map(
|
|
16449
|
+
`)},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 Zi(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=ff(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:sn(i.answer)||(i.status==="done"?"Answered.":i.status==="stopped"?"Stopped.":"The agent could not answer."),updatedAt:i.at}))}return r}function sn(t,e=120){for(let a of t.split(`
|
|
16450
|
+
`)){let n=el(a);if(n)return ln(n,e)}return""}function ff(t,e=120){let a=t.split(`
|
|
16451
|
+
`).map(el).filter(Boolean);return a.length?ln(a[a.length-1],e):""}function el(t){return t.replace(/^\s*(?:[#>]+|[-*+]\s|\d+\.\s)\s*/,"").replace(/[*_`]+/g,"").replace(/\s+/g," ").trim()}function ln(t,e){let a=[...t];return a.length>e?a.slice(0,e-1).join("")+"\u2026":t}var na=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 ra(t){return t.enabled&&!t.attached&&!t.appOpen&&t.status!=="stopped"}var Qi=140;function oa(t,e,a,n,r){let o=a==="error"?`Could not answer: ${sn(r||"",Qi-18)||"something went wrong."}`:sn(n,Qi)||"Answered.";return{deviceId:t,title:ln(e.agentName||e.agent,80),body:o,url:`/app#chat=${e.id}`}}var al=8e3,gf=/^[A-Za-z0-9_.:-]{1,64}$/,je=new Map,cn=new Map,un=new na;function nl(){return un}async function rl(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??un;if(n==="GET"&&a==="/api/app/agents")return H(e,200,{nodes:await ol(o)});let i=o.store();if(!i)return H(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),H(e,200,{conversations:Zi(r.id,bf(),i.unread(r.id,12))});if(n==="POST"&&a==="/api/app/chat/away")return s.away(r.id),H(e,200,{ok:!0});if(n==="GET"&&a==="/api/app/conversations")return H(e,200,{conversations:i.list(r.id)});let l=n==="GET"?/^\/api\/app\/conversations\/([^/]+)$/.exec(a):null;if(l){let d=i.get(r.id,decodeURIComponent(l[1]));if(!d)return H(e,404,{error:"no such conversation"});new URL(t.url||a,"http://x").searchParams.get("peek")!=="1"&&i.markRead(r.id,d.id);let p=je.get(d.id);return H(e,200,{...d,running:!!p,...p?{partial:{text:p.text,tools:p.tools,...p.plain?{plain:!0}:{}}}:{}})}if(n==="GET"&&a==="/api/app/chat/attach"){let d=i.get(r.id,new URL(t.url||a,"http://x").searchParams.get("conversationId")||""),p=d&&je.get(d.id);if(!d||!p)return H(e,404,{error:"nothing is running in this conversation"});i.markRead(r.id,d.id),sl(e);let{id:m,title:f,node:_,nodeName:v,agent:E,agentName:x}=d;return e.write(dn("conversation",{id:m,title:f,node:_,nodeName:v,agent:E,agentName:x})),e.write(dn("resume",{text:p.text,tools:p.tools,...p.plain?{plain:!0}:{}})),p.attach(e),!0}if(n!=="POST"||a!=="/api/app/chat"&&a!=="/api/app/chat/stop")return H(e,404,{error:"not found"});let c;try{c=await yt(t,64*1024)}catch(d){return H(e,400,{error:d.message})}if(a==="/api/app/chat/stop"){let d=i.get(r.id,String(c.conversationId??""));if(!d)return H(e,404,{error:"no such conversation"});let p=je.get(d.id);return p?(p.ac.abort(),pn(d,o,r.name),H(e,200,{stopped:!0})):await pn(d,o,r.name)?H(e,200,{stopped:!0}):H(e,404,{error:"nothing is running in this conversation"})}return await vf(e,c,r,i,o),!0}function xf(t,e,a){let n=Xe(e.url),r=new Set,o=[];for(let s of t){let i=Xe(s.url),l=a.find(p=>Xe(p.peerUrl)===i);l&&r.add(l.peer);let c=i===n,d=s.agents.length?s.agents:l?.skills??[];o.push({target:c?"local":l?l.peer:null,name:s.reachable?s.name:(c?e.name:l?.peer)||s.name,online:c?s.reachable:l?l.healthy:!1,agents:d.map(p=>{let m=Array.isArray(p.runningTasks)?p.runningTasks.length:0;return{id:p.id,name:p.name||p.id,busy:m>0||(p.active??0)>0,running:m,...p.color?{color:p.color}:{}}})})}for(let s of a)r.has(s.peer)||o.push({target:s.peer,name:s.peer,online:s.healthy,agents:(s.skills??[]).map(i=>({id:i.id,name:i.name||i.id,busy:!1,running:0}))});return o}async function ol(t){let[e,a]=await Promise.all([t.snapshot().catch(()=>({nodes:[]})),t.meshPeers().catch(()=>[])]);return xf(e.nodes,t.daemon,a)}async function vf(t,e,a,n,r){let o=typeof e.message=="string"?e.message.trim():"";if(!o||o.length>al){H(t,400,{error:`message must be 1\u2013${al} characters`});return}let s;if(e.conversationId!=null){if(s=n.get(a.id,String(e.conversationId)),!s){H(t,404,{error:"no such conversation"});return}}else{let _=typeof e.node=="string"?e.node:"",v=typeof e.agent=="string"?e.agent:"";if(!gf.test(v)){H(t,400,{error:"pick an agent"});return}let E=(await ol(r)).find(g=>g.target===_);if(!E){H(t,400,{error:`unknown node "${_}"`});return}if(!E.online){H(t,409,{error:`${E.name} is offline`});return}let x=E.agents.find(g=>g.id===v);if(!x){H(t,400,{error:`no agent "${v}" on ${E.name}`});return}s=n.create(a.id,{node:_,nodeName:E.name,agent:v,agentName:x.name,...x.color?{color:x.color}:{}},o)}if(je.has(s.id)){H(t,409,{error:"The agent is still answering in this conversation."});return}let i=new aa(r.orphanLimitMs??18e5);je.set(s.id,i);let{id:l,title:c,node:d,nodeName:p,agent:m,agentName:f}=s;cn.set(l,{id:l,deviceId:a.id,title:c,agent:m,...f?{agentName:f}:{},...s.color?{color:s.color}:{}}),n.append(a.id,s.id,{role:"user",content:o,at:Date.now()}),sl(t),t.write(dn("conversation",{id:l,title:c,node:d,nodeName:p,agent:m,agentName:f})),i.attach(t);try{let _=e.spoken===!0,v=await Yi(r.daemon,{node:d,agent:m,message:o,chatId:`app:${l}`,spoken:_},i.ac.signal,(u,h)=>i.broadcast(u,h));i.orphaned&&(v.error=`Stopped: the phone was away for more than ${Math.round((r.orphanLimitMs??18e5)/6e4)} minutes.`,pn(s,r,a.name));let E=n.appendWithFiles(a.id,l,{role:"assistant",content:v.text,status:v.status,at:Date.now(),...v.error?{error:v.error}:{},...v.ui?{ui:v.ui}:{},...v.tools.length?{tools:v.tools}:{}},v.files)??[];i.broadcast("final",{status:v.status,content:v.text,...v.error?{error:v.error}:{},...v.ui?{ui:v.ui}:{},...E.length?{files:E}:{}});let x=i.watched();x&&n.markRead(a.id,l);let g={status:v.status,attached:x,appOpen:(r.presence??un).open(a.id),enabled:!!r.finishAlerts?.(a.id)};r.notifyFinish&&ra(g)&&r.notifyFinish(oa(a.id,s,v.status,v.text,v.error)).catch(()=>{})}finally{je.delete(l),cn.delete(l),i.finish()}}function bf(){let t=[];for(let[e,a]of cn){let n=je.get(e);n&&t.push({...a,text:n.text,startedAt:n.startedAt})}return t}function sl(t){t.writeHead(200,{"Content-Type":"text/event-stream; charset=utf-8","Cache-Control":"no-cache, no-store","X-Accel-Buffering":"no"})}function dn(t,e){return`event: ${t}
|
|
16418
16452
|
data: ${JSON.stringify(e)}
|
|
16419
16453
|
|
|
16420
|
-
`}async function dn(t,e,a){try{let n=Xe(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(c=>c.peer===t.node);if(!l)return 0;n=Xe(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Xe(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 Xe(t){return t.replace(/\/+$/,"")}function H(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{Readable as vf}from"stream";var yf=/^\/api\/app\/files\/([^/]+)$/,wf=15e3;async function il(t,e,a,n,r,o){let s=yf.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return Oe(e,405,{error:"GET only"});let i=o.store();if(!i)return Oe(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let c=i.getFile(r.id,l);if(!c)return Oe(e,404,{error:"no such file"});let d=await kf(c.node,o);if(!d)return Oe(e,502,{error:`${c.node} is not linked to this computer's mesh any more.`});let p=new AbortController;e.on("close",()=>p.abort());let m=setTimeout(()=>p.abort(),wf),f;try{let g=new URLSearchParams({agent:c.agent,file:c.path});f=await fetch(`${d.url}${mr}?${g}`,{method:n,headers:{...d.token?{Authorization:`Bearer ${d.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:p.signal})}catch{return Oe(e,502,{error:"The computer that made this file did not answer."})}finally{clearTimeout(m)}if(f.status!==200&&f.status!==206){let g=await f.json().then(h=>h?.error).catch(()=>""),u=[403,404,413,415,416].includes(f.status)?f.status:502;return Oe(e,u,{error:g||`The computer that made this file answered HTTP ${f.status}.`})}let _=Number(f.headers.get("content-length")||0);if(_>ce.bytes)return p.abort(),Oe(e,413,{error:"the file is too large"});let b=f.headers.get("content-range");if(e.writeHead(f.status,{...fr(c.mime,c.name,c.kind),...f.headers.get("content-length")?{"Content-Length":String(_)}:{},...f.status===206&&b?{"Content-Range":b}:{}}),n==="HEAD"||!f.body)return e.end(),!0;let E=0,x=vf.fromWeb(f.body);return x.on("data",g=>{E+=g.length,E>ce.bytes&&(x.destroy(),e.destroy())}),x.on("error",()=>e.destroy()),x.pipe(e),!0}async function kf(t,e){if(t==="local")return{url:sl(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=sl(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function sl(t){return t.replace(/\/+$/,"")}function Oe(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),t.end(JSON.stringify(a)),!0}var cl=8e3;async function dl(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 f=String(t.headers["content-type"]||"");if(!_r(f))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let _=kr(t.headers["x-audio-duration-ms"]);if(_)return t.resume(),Y(e,_.status,{error:_.error});let b=await Te(t,wr.bytes);if(!b)return Y(e,413,{error:Sr()});if(!b.length)return Y(e,400,{error:"The recording is empty."});let E={"Content-Type":f,"X-Audio-Duration-Ms":String(t.headers["x-audio-duration-ms"]).trim()};return ll(e,o.daemon,"/voice/transcribe",b,E,18e4)}let s,i=await Te(t,64*1024);if(!i)return Y(e,413,{error:"request too large"});try{s=JSON.parse(i.toString("utf8")||"{}")}catch{return Y(e,400,{error:"expected JSON"})}let l=o.store();if(!l)return Y(e,503,{error:"The database on this computer is unavailable."});let c=l.get(r.id,String(s?.conversationId??""));if(!c)return Y(e,404,{error:"no such conversation"});let d=typeof s?.text=="string"?s.text.slice(0,cl):"";if(!d.trim())return Y(e,400,{error:"text is required"});if(!Sf(c.messages,d))return Y(e,404,{error:"no such answer in this conversation"});let p=s?.announce===!0?`${c.agentName||c.agent}: ${d}`:d,m={agent:c.agent,text:p,...c.node!=="local"?{peer:c.node}:{}};return ll(e,o.daemon,"/voice/speak",Buffer.from(JSON.stringify(m)),{"Content-Type":"application/json"},9e4)}async function ll(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(_f(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 _f(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function Sf(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===cl&&a.content.startsWith(e)))}var Ef=new Set(["ring","offer","answer","ice","hangup"]),Ke=/^[A-Za-z0-9_-]{4,64}$/,Tf=128*1024,Af=24,Cf=2*1024*1024,Ne=new Map;async function ul(t,e,a,n,r){if(!a.startsWith("/api/app/camera/"))return!1;let o=r.daemon.url.replace(/\/+$/,""),s=r.daemon.token?{Authorization:`Bearer ${r.daemon.token}`}:{};if(a==="/api/app/camera/config"){if(n!=="GET")return M(e,405,{error:"GET"});try{let l=await fetch(`${o}/webrtc/config`,{headers:s,signal:AbortSignal.timeout(1e4)});if(l.status===404)return M(e,503,{error:"Calls are off on this computer. Set channels.webrtc.enabled to true in agentx.json."});if(!l.ok)return M(e,502,{error:`AgentX answered HTTP ${l.status}.`});let c=await l.json(),d=Qe(r.nodeName),p=(Array.isArray(c.peers)?c.peers:[]).filter(f=>Qe(String(f?.name??""))!==d),m=(Array.isArray(c.agents)?c.agents:[]).filter(f=>f&&typeof f.id=="string").map(f=>({id:f.id,name:typeof f.name=="string"&&f.name?f.name:f.id}));return M(e,200,{node:r.nodeName,iceServers:c.iceServers??[],peers:p,agents:m,camera:c.camera??null})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/signal"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,Tf);if(!l)return M(e,413,{error:"signal too large"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=Mf(c,r.nodeName);if(typeof d=="string")return M(e,400,{error:d});let p=ml(d.to);if(p&&d.kind==="ring"){let m=await De(o,s,"POST","/webrtc/camera/watch",{callId:d.callId,agentId:p});return M(e,m.status,m.status<300?{ok:!0,watch:m.body.watch}:{error:m.body.error})}try{let m=await fetch(`${o}/webrtc/signal/out`,{method:"POST",headers:{"Content-Type":"application/json",...s},body:JSON.stringify(d),signal:AbortSignal.timeout(15e3)}),f=await m.json().catch(()=>({}));return M(e,m.ok?200:502,m.ok?{ok:!0}:{error:f?.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 Ke.test(l)?Lf(t,e,`${o}/webrtc/events?callId=${encodeURIComponent(l)}&as=${encodeURIComponent(r.nodeName)}`,s):M(e,400,{error:"callId is required"})}if(a==="/api/app/camera/look"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,4096);if(!l)return M(e,413,{error:"note too long"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=String(c?.callId??"");if(!Ke.test(d))return M(e,400,{error:"callId is required"});let p=typeof c?.note=="string"?c.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/look`,{note:p},18e4);return M(e,m.status,m.status<300?{reply:m.body.reply,frame:m.body.frame}:{error:m.body.error})}if(a==="/api/app/camera/stream"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await pl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Ke.test(c))return M(e,400,{error:"callId is required"});let d=Number(l.seconds??0);if(!Number.isFinite(d)||d<0)return M(e,400,{error:"seconds must be 0 or more"});let p=typeof l.note=="string"?l.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(c)}/stream`,{seconds:d,note:p});return M(e,m.status,m.status<300?{watch:m.body.watch}:{error:m.body.error})}if(a==="/api/app/camera/speak"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await pl(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Ke.test(c))return M(e,400,{error:"callId is required"});let d=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(c)}`);if(d.status>=300)return M(e,d.status,{error:d.body.error});let p=(Array.isArray(d.body.watch?.replies)?d.body.watch.replies:[]).find(b=>b&&b.at===l.at);if(!p||typeof p.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(d.body.watch.agentId??""),f=JSON.stringify([c,p.at,m,p.text]),_=Ne.get(f);return _?(Ne.delete(f),Ne.set(f,_),fl(e,_.type,_.bytes)):If(e,o,s,{agent:m,text:p.text},(b,E)=>{if(!(E.length>Cf))for(Ne.set(f,{type:b,bytes:E});Ne.size>Af;)Ne.delete(Ne.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await De(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let c=(Array.isArray(l.body.calls)?l.body.calls:[]).map(d=>({id:d.id,agentId:d.agentId,reason:d.reason,createdAt:d.createdAt}));return M(e,200,{asks:c,ringSeconds:l.body.ringSeconds??null})}let i=/^\/api\/app\/camera\/asks\/([A-Za-z0-9_-]{4,64})\/(answer|decline)$/.exec(a);if(i){if(n!=="POST")return M(e,405,{error:"POST"});let l=await De(o,s,"POST",`/calls/${i[1]}/${i[2]}`,{});return M(e,l.status,l.status<300?{call:l.body.call}:{error:l.body.error})}if(a==="/api/app/camera/watch"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";if(!Ke.test(l))return M(e,400,{error:"callId is required"});let c=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,c.status,c.status<300?{watch:c.body.watch}:{error:c.body.error})}return M(e,404,{error:"not found"})}function ml(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function De(t,e,a,n,r,o=15e3){try{let s=await fetch(`${t}${n}`,{method:a,headers:{"Content-Type":"application/json",...e},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(o)}),i=await s.json().catch(()=>({}));return s.status===404&&typeof i?.error=="string"&&/channels\.webrtc\.enabled/.test(i.error)?{status:503,body:i}:{status:s.ok?s.status:s.status>=500?502:s.status,body:s.ok?i:{error:i?.error||`AgentX answered HTTP ${s.status}.`}}}catch{return{status:502,body:{error:"Could not reach AgentX on this computer."}}}}async function pl(t,e){let a=await Te(t,e);if(!a)return null;try{let n=JSON.parse(a.toString("utf8")||"{}");return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}async function If(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),fl(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 fl(t,e,a){return t.writeHead(200,{"Content-Type":e,"Content-Length":String(a.length),"Cache-Control":"no-store"}),t.end(a),!0}function Mf(t,e){let a=String(t?.kind??"");if(!Ef.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!Ke.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:")&&!ml(r))return"to must be bot:<agent id> for an agent";if(Qe(r)===Qe(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 Lf(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 Rf,readFileSync as Pf,renameSync as $f,writeFileSync as jf}from"fs";import{dirname as Of,isAbsolute as Nf,resolve as Df}from"path";import{randomBytes as Bf}from"crypto";var hl=60,gl=500,Hf=200,vl=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,zf=/^[A-Za-z0-9_-]{8,64}$/,qf=/^[A-Za-z0-9._-]{1,64}$/;function yl(t,e){return Nf(e)?e:Df(t,e)}function xl(t){return`${t}_${Bf(6).toString("hex")}`}function bl(){return{places:[],rules:[],seen:[]}}function wl(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>hl)return{ok:!1,error:`Keep the name under ${hl} 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 kl(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>gl)return{ok:!1,error:`Keep it under ${gl} characters.`};let o=typeof t.agent=="string"?t.agent.trim():"";return o&&(!qf.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 _l(t){let e=typeof t.id=="string"?t.id:"";if(!zf.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 oa=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse(Pf(this.path,"utf-8"));return!e||typeof e!="object"?bl():{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 bl()}}write(e){Rf(Of(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;jf(a,JSON.stringify(e,null,2)+`
|
|
16421
|
-
`,{mode:384})
|
|
16422
|
-
`)}async function
|
|
16454
|
+
`}async function pn(t,e,a){try{let n=Xe(e.daemon.url);if(t.node!=="local"){let l=(await e.meshPeers()).find(c=>c.peer===t.node);if(!l)return 0;n=Xe(l.peerUrl)}let s=(await e.snapshot()).nodes.find(l=>Xe(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 Xe(t){return t.replace(/\/+$/,"")}function H(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}import{Readable as yf}from"stream";var wf=/^\/api\/app\/files\/([^/]+)$/,kf=15e3;async function ll(t,e,a,n,r,o){let s=wf.exec(a);if(!s)return!1;if(n!=="GET"&&n!=="HEAD")return Oe(e,405,{error:"GET only"});let i=o.store();if(!i)return Oe(e,503,{error:"The database on this computer is unavailable."});let l="";try{l=decodeURIComponent(s[1])}catch{}let c=i.getFile(r.id,l);if(!c)return Oe(e,404,{error:"no such file"});let d=await _f(c.node,o);if(!d)return Oe(e,502,{error:`${c.node} is not linked to this computer's mesh any more.`});let p=new AbortController;e.on("close",()=>p.abort());let m=setTimeout(()=>p.abort(),kf),f;try{let g=new URLSearchParams({agent:c.agent,file:c.path});f=await fetch(`${d.url}${hr}?${g}`,{method:n,headers:{...d.token?{Authorization:`Bearer ${d.token}`}:{},...typeof t.headers.range=="string"?{Range:t.headers.range}:{}},signal:p.signal})}catch{return Oe(e,502,{error:"The computer that made this file did not answer."})}finally{clearTimeout(m)}if(f.status!==200&&f.status!==206){let g=await f.json().then(h=>h?.error).catch(()=>""),u=[403,404,413,415,416].includes(f.status)?f.status:502;return Oe(e,u,{error:g||`The computer that made this file answered HTTP ${f.status}.`})}let _=Number(f.headers.get("content-length")||0);if(_>ce.bytes)return p.abort(),Oe(e,413,{error:"the file is too large"});let v=f.headers.get("content-range");if(e.writeHead(f.status,{...gr(c.mime,c.name,c.kind),...f.headers.get("content-length")?{"Content-Length":String(_)}:{},...f.status===206&&v?{"Content-Range":v}:{}}),n==="HEAD"||!f.body)return e.end(),!0;let E=0,x=yf.fromWeb(f.body);return x.on("data",g=>{E+=g.length,E>ce.bytes&&(x.destroy(),e.destroy())}),x.on("error",()=>e.destroy()),x.pipe(e),!0}async function _f(t,e){if(t==="local")return{url:il(e.daemon.url),token:e.daemon.token};let a=(await e.meshPeers().catch(()=>[])).find(r=>r.peer===t);if(!a)return null;let n=il(a.peerUrl);return{url:n,token:e.tokenFor?.(n)}}function il(t){return t.replace(/\/+$/,"")}function Oe(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),t.end(JSON.stringify(a)),!0}var dl=8e3;async function pl(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 f=String(t.headers["content-type"]||"");if(!Er(f))return Y(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let _=Sr(t.headers["x-audio-duration-ms"]);if(_)return t.resume(),Y(e,_.status,{error:_.error});let v=await Te(t,_r.bytes);if(!v)return Y(e,413,{error:Tr()});if(!v.length)return Y(e,400,{error:"The recording is empty."});let E={"Content-Type":f,"X-Audio-Duration-Ms":String(t.headers["x-audio-duration-ms"]).trim()};return cl(e,o.daemon,"/voice/transcribe",v,E,18e4)}let s,i=await Te(t,64*1024);if(!i)return Y(e,413,{error:"request too large"});try{s=JSON.parse(i.toString("utf8")||"{}")}catch{return Y(e,400,{error:"expected JSON"})}let l=o.store();if(!l)return Y(e,503,{error:"The database on this computer is unavailable."});let c=l.get(r.id,String(s?.conversationId??""));if(!c)return Y(e,404,{error:"no such conversation"});let d=typeof s?.text=="string"?s.text.slice(0,dl):"";if(!d.trim())return Y(e,400,{error:"text is required"});if(!Ef(c.messages,d))return Y(e,404,{error:"no such answer in this conversation"});let p=s?.announce===!0?`${c.agentName||c.agent}: ${d}`:d,m={agent:c.agent,text:p,...c.node!=="local"?{peer:c.node}:{}};return cl(e,o.daemon,"/voice/speak",Buffer.from(JSON.stringify(m)),{"Content-Type":"application/json"},9e4)}async function cl(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(Sf(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 Sf(t){try{return JSON.parse(t.toString("utf8"))}catch{return null}}function Ef(t,e){return t.some(a=>a.role==="assistant"&&(a.content===e||e.length===dl&&a.content.startsWith(e)))}var Tf=new Set(["ring","offer","answer","ice","hangup"]),Ke=/^[A-Za-z0-9_-]{4,64}$/,Af=128*1024,Cf=24,If=2*1024*1024,Ne=new Map;async function ml(t,e,a,n,r){if(!a.startsWith("/api/app/camera/"))return!1;let o=r.daemon.url.replace(/\/+$/,""),s=r.daemon.token?{Authorization:`Bearer ${r.daemon.token}`}:{};if(a==="/api/app/camera/config"){if(n!=="GET")return M(e,405,{error:"GET"});try{let l=await fetch(`${o}/webrtc/config`,{headers:s,signal:AbortSignal.timeout(1e4)});if(l.status===404)return M(e,503,{error:"Calls are off on this computer. Set channels.webrtc.enabled to true in agentx.json."});if(!l.ok)return M(e,502,{error:`AgentX answered HTTP ${l.status}.`});let c=await l.json(),d=Qe(r.nodeName),p=(Array.isArray(c.peers)?c.peers:[]).filter(f=>Qe(String(f?.name??""))!==d),m=(Array.isArray(c.agents)?c.agents:[]).filter(f=>f&&typeof f.id=="string").map(f=>({id:f.id,name:typeof f.name=="string"&&f.name?f.name:f.id}));return M(e,200,{node:r.nodeName,iceServers:c.iceServers??[],peers:p,agents:m,camera:c.camera??null})}catch{return M(e,502,{error:"Could not reach AgentX on this computer."})}}if(a==="/api/app/camera/signal"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,Af);if(!l)return M(e,413,{error:"signal too large"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=Lf(c,r.nodeName);if(typeof d=="string")return M(e,400,{error:d});let p=fl(d.to);if(p&&d.kind==="ring"){let m=await De(o,s,"POST","/webrtc/camera/watch",{callId:d.callId,agentId:p});return M(e,m.status,m.status<300?{ok:!0,watch:m.body.watch}:{error:m.body.error})}try{let m=await fetch(`${o}/webrtc/signal/out`,{method:"POST",headers:{"Content-Type":"application/json",...s},body:JSON.stringify(d),signal:AbortSignal.timeout(15e3)}),f=await m.json().catch(()=>({}));return M(e,m.ok?200:502,m.ok?{ok:!0}:{error:f?.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 Ke.test(l)?Rf(t,e,`${o}/webrtc/events?callId=${encodeURIComponent(l)}&as=${encodeURIComponent(r.nodeName)}`,s):M(e,400,{error:"callId is required"})}if(a==="/api/app/camera/look"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await Te(t,4096);if(!l)return M(e,413,{error:"note too long"});let c;try{c=JSON.parse(l.toString("utf8")||"{}")}catch{return M(e,400,{error:"expected JSON"})}let d=String(c?.callId??"");if(!Ke.test(d))return M(e,400,{error:"callId is required"});let p=typeof c?.note=="string"?c.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(d)}/look`,{note:p},18e4);return M(e,m.status,m.status<300?{reply:m.body.reply,frame:m.body.frame}:{error:m.body.error})}if(a==="/api/app/camera/stream"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await ul(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Ke.test(c))return M(e,400,{error:"callId is required"});let d=Number(l.seconds??0);if(!Number.isFinite(d)||d<0)return M(e,400,{error:"seconds must be 0 or more"});let p=typeof l.note=="string"?l.note:"",m=await De(o,s,"POST",`/webrtc/camera/watch/${encodeURIComponent(c)}/stream`,{seconds:d,note:p});return M(e,m.status,m.status<300?{watch:m.body.watch}:{error:m.body.error})}if(a==="/api/app/camera/speak"){if(n!=="POST")return M(e,405,{error:"POST"});let l=await ul(t,4096);if(!l)return M(e,400,{error:"expected JSON"});let c=String(l.callId??"");if(!Ke.test(c))return M(e,400,{error:"callId is required"});let d=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(c)}`);if(d.status>=300)return M(e,d.status,{error:d.body.error});let p=(Array.isArray(d.body.watch?.replies)?d.body.watch.replies:[]).find(v=>v&&v.at===l.at);if(!p||typeof p.text!="string")return M(e,404,{error:"no such answer on this share"});let m=String(d.body.watch.agentId??""),f=JSON.stringify([c,p.at,m,p.text]),_=Ne.get(f);return _?(Ne.delete(f),Ne.set(f,_),hl(e,_.type,_.bytes)):Mf(e,o,s,{agent:m,text:p.text},(v,E)=>{if(!(E.length>If))for(Ne.set(f,{type:v,bytes:E});Ne.size>Cf;)Ne.delete(Ne.keys().next().value)})}if(a==="/api/app/camera/asks"){if(n!=="GET")return M(e,405,{error:"GET"});let l=await De(o,s,"GET","/calls/asking");if(l.status>=300)return M(e,l.status,{error:l.body.error});let c=(Array.isArray(l.body.calls)?l.body.calls:[]).map(d=>({id:d.id,agentId:d.agentId,reason:d.reason,createdAt:d.createdAt}));return M(e,200,{asks:c,ringSeconds:l.body.ringSeconds??null})}let i=/^\/api\/app\/camera\/asks\/([A-Za-z0-9_-]{4,64})\/(answer|decline)$/.exec(a);if(i){if(n!=="POST")return M(e,405,{error:"POST"});let l=await De(o,s,"POST",`/calls/${i[1]}/${i[2]}`,{});return M(e,l.status,l.status<300?{call:l.body.call}:{error:l.body.error})}if(a==="/api/app/camera/watch"){if(n!=="GET")return M(e,405,{error:"GET"});let l=new URL(t.url||"/","http://x").searchParams.get("callId")||"";if(!Ke.test(l))return M(e,400,{error:"callId is required"});let c=await De(o,s,"GET",`/webrtc/camera/watch/${encodeURIComponent(l)}`);return M(e,c.status,c.status<300?{watch:c.body.watch}:{error:c.body.error})}return M(e,404,{error:"not found"})}function fl(t){let e=/^bot:([A-Za-z0-9_.-]{1,80})$/.exec(t);return e?e[1]:null}async function De(t,e,a,n,r,o=15e3){try{let s=await fetch(`${t}${n}`,{method:a,headers:{"Content-Type":"application/json",...e},body:r===void 0?void 0:JSON.stringify(r),signal:AbortSignal.timeout(o)}),i=await s.json().catch(()=>({}));return s.status===404&&typeof i?.error=="string"&&/channels\.webrtc\.enabled/.test(i.error)?{status:503,body:i}:{status:s.ok?s.status:s.status>=500?502:s.status,body:s.ok?i:{error:i?.error||`AgentX answered HTTP ${s.status}.`}}}catch{return{status:502,body:{error:"Could not reach AgentX on this computer."}}}}async function ul(t,e){let a=await Te(t,e);if(!a)return null;try{let n=JSON.parse(a.toString("utf8")||"{}");return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}async function Mf(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),hl(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 hl(t,e,a){return t.writeHead(200,{"Content-Type":e,"Content-Length":String(a.length),"Cache-Control":"no-store"}),t.end(a),!0}function Lf(t,e){let a=String(t?.kind??"");if(!Tf.has(a))return"kind must be ring, offer, answer, ice or hangup";let n=String(t?.callId??"");if(!Ke.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:")&&!fl(r))return"to must be bot:<agent id> for an agent";if(Qe(r)===Qe(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 Rf(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 Pf,readFileSync as $f,renameSync as jf,writeFileSync as Of}from"fs";import{dirname as Nf,isAbsolute as Df,resolve as Bf}from"path";import{randomBytes as Hf}from"crypto";var gl=60,xl=500,zf=200,yl=/^[a-z]{2,5}_[a-z0-9]{6,32}$/,qf=/^[A-Za-z0-9_-]{8,64}$/,Ff=/^[A-Za-z0-9._-]{1,64}$/;function wl(t,e){return Df(e)?e:Bf(t,e)}function vl(t){return`${t}_${Hf(6).toString("hex")}`}function bl(){return{places:[],rules:[],seen:[]}}function kl(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 _l(t,e){let a=typeof t.placeId=="string"?t.placeId:"";if(!yl.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&&(!Ff.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 Sl(t){let e=typeof t.id=="string"?t.id:"";if(!qf.test(e))return{ok:!1,error:"id must be 8 to 64 letters, digits, - or _"};let a=typeof t.place=="string"?t.place:"";if(!yl.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 sa=class{constructor(e,a=Date.now){this.path=e;this.now=a}read(){try{let e=JSON.parse($f(this.path,"utf-8"));return!e||typeof e!="object"?bl():{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 bl()}}write(e){Pf(Nf(this.path),{recursive:!0});let a=`${this.path}.${process.pid}.tmp`;Of(a,JSON.stringify(e,null,2)+`
|
|
16455
|
+
`,{mode:384}),jf(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(-zf);let r=this.now(),o=n.places.find(i=>i.id===e.place),s;if(!o)s={status:"unknown-place"};else if(e.time<r-a.maxEventAgeMinutes*6e4)s={status:"too-old"};else{let i=a.cooldownMinutes*6e4,l=n.rules.filter(c=>c.placeId===o.id&&c.on===e.transition&&c.enabled&&!(c.lastFiredAt&&Date.parse(c.lastFiredAt)>r-i));for(let c of l)c.lastFiredAt=new Date(r).toISOString(),c.repeat||(c.enabled=!1);s=l.length?{status:"fired",place:o,rules:l.map(c=>({...c}))}:{status:"no-rules"}}return this.write(n),s}};Nn();function Uf(t,e){return e==="enter"?`Arrived at ${t.name}`:`Left ${t.name}`}function Wf(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(`
|
|
16456
|
+
`)}async function El(t,e,a,n,r){await Promise.all(a.map(async o=>{let s=Uf(e,o.on),i=o.text;if(o.agent)try{i=(await r.task(o.agent,Wf(e,o,n),o.id)).trim()||`${o.agent} had nothing to add.`}catch(l){i=`${o.text}
|
|
16423
16457
|
|
|
16424
|
-
(${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
|
|
16425
|
-
${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?{[
|
|
16458
|
+
(${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 Tl(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}
|
|
16459
|
+
${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?{[On]: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 Al(t,e,a,n,r,o){return a!=="/api/app/places"&&!a.startsWith("/api/app/places/")?!1:Il(t,e,a.slice(15),n,o,r)}async function Cl(t,e,a,n,r){return a!=="/api/places"&&!a.startsWith("/api/places/")?!1:Il(t,e,a.slice(11),n,r,null)}async function Il(t,e,a,n,r,o){if(n==="GET"&&a===""){let i=r.enabled?r.store.read():{places:[],rules:[]};return z(e,200,{enabled:r.enabled,reason:r.enabled?null:"Place reminders are off on this computer (app.places.enabled).",pushAvailable:!!r.fire,pushReason:r.fire?null:r.pushReason??null,limits:{defaultRadiusMeters:r.limits.defaultRadiusMeters,minRadiusMeters:r.limits.minRadiusMeters,maxRadiusMeters:r.limits.maxRadiusMeters,maxPlaces:r.limits.maxPlaces},syncMinutes:r.syncMinutes,android:{packageName:r.androidPackage},places:i.places,rules:i.rules,agents:r.agents()})}if(n!=="POST")return z(e,404,{error:"not found"});if(!r.enabled)return z(e,403,{error:"Place reminders are off on this computer (app.places.enabled)."});let s;try{s=await yt(t,4096)}catch(i){return z(e,400,{error:i.message})}if(a==="/event"){if(!o)return z(e,404,{error:"not found"});let i=Sl(s);if(!i.ok)return z(e,400,{error:i.error});let l=r.store.accept(i.value,r.limits);return r.log(`[places] ${o.id} ${i.value.transition} ${i.value.place}: ${l.status}${l.status==="fired"?` (${l.rules.length})`:""}`),l.status==="fired"&&(r.fire?El(o.id,l.place,l.rules,i.value.time,r.fire).catch(c=>r.log(`[places] delivery failed: ${c?.message||c}`)):r.log(`[places] ${l.rules.length} reminder(s) not sent: ${r.pushReason??"this computer doesn't send pushes"}`)),z(e,202,{ok:!0,status:l.status,fired:l.status==="fired"?l.rules.length:0})}if(a==="/add"){let i=kl(s,r.limits);if(!i.ok)return z(e,400,{error:i.error});let l=r.store.addPlace(i.value,r.limits);return l.ok?z(e,200,{ok:!0,place:l.place}):z(e,409,{error:l.error})}if(a==="/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removePlace(i)?z(e,200,{ok:!0}):z(e,404,{error:"No such place."})}if(a==="/rules/add"){let i=new Set(r.agents()),l=_l(s,d=>i.has(d));if(!l.ok)return z(e,400,{error:l.error});let c=r.store.addRule(l.value,r.limits);return c.ok?z(e,200,{ok:!0,rule:c.rule}):z(e,409,{error:c.error})}if(a==="/rules/enable"){if(typeof s.enabled!="boolean")return z(e,400,{error:"enabled must be true or false"});let i=r.store.setRuleEnabled(typeof s.id=="string"?s.id:"",s.enabled);return i?z(e,200,{ok:!0,rule:i}):z(e,404,{error:"No such reminder."})}if(a==="/rules/remove"){let i=typeof s.id=="string"?s.id:"";return r.store.removeRule(i)?z(e,200,{ok:!0}):z(e,404,{error:"No such reminder."})}return z(e,404,{error:"not found"})}function Ml(t,e,a,n){let r=t.app.places;return{enabled:r.enabled,limits:r,syncMinutes:r.syncMinutes,store:new sa(wl(e,r.file)),agents:()=>Object.keys(t.agents||{}).sort(),fire:a,pushReason:n,androidPackage:t.app.android.packageName,log:o=>console.error(o)}}function Ll(t){let e=t.app.android;return e.certFingerprints.length?[{relation:["delegate_permission/common.handle_all_urls"],target:{namespace:"android_app",package_name:e.packageName,sha256_cert_fingerprints:e.certFingerprints.map(a=>a.toUpperCase())}}]:null}function z(t,e,a){return t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(a)),!0}var Rl=`
|
|
16426
16460
|
:root {
|
|
16427
16461
|
--ax-bg: #fff; --ax-surface: #fff; --ax-surface-2: #f4f5f7; --ax-surface-3: #f6f7f9;
|
|
16428
16462
|
--ax-text: #0b0d10; --ax-text-2: #5a616c; --ax-border: #e5e7eb;
|
|
@@ -16436,7 +16470,7 @@ ${s}`,buttons:[{label:"Open",url:"/app#alerts"}]}),signal:AbortSignal.timeout(15
|
|
|
16436
16470
|
--ax-accent: #6aa0ff; --ax-accent-2: #6aa0ff; --ax-accent-t: #1c2b47;
|
|
16437
16471
|
--phone-bubble: #1d2f52; --phone-green: #3dbe74;
|
|
16438
16472
|
}
|
|
16439
|
-
`,
|
|
16473
|
+
`,Pl=`
|
|
16440
16474
|
[hidden] { display: none !important; }
|
|
16441
16475
|
main > .sw-peek[hidden] { display: block !important; }
|
|
16442
16476
|
main > #panel-chat.sw-peek[hidden] { display: flex !important; }
|
|
@@ -16542,7 +16576,7 @@ main > #panel-chat.sw-peek { height: 100%; padding-top: 8px; }
|
|
|
16542
16576
|
@media (max-width: 360px) { #cam-btn span { display: none; } .bar { padding-left: 12px; } .bar-btns { gap: 4px; } .vx-row { gap: 24px; } }
|
|
16543
16577
|
@media (max-height: 540px) { .vx { gap: 4px; padding-top: 4px; } .cx-top { padding-bottom: 4px; } }
|
|
16544
16578
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { scroll-behavior: auto !important; transition: none !important; animation: none !important; } }
|
|
16545
|
-
`;var
|
|
16579
|
+
`;var $l=`
|
|
16546
16580
|
window.AXSheet = function (sheet, onClose) {
|
|
16547
16581
|
var handle = document.createElement('button');
|
|
16548
16582
|
handle.type = 'button'; handle.className = 'sheet-handle';
|
|
@@ -16571,7 +16605,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
16571
16605
|
handle.addEventListener('pointercancel', reset);
|
|
16572
16606
|
sheet.addEventListener('close', function () { reset(); if (onClose) onClose(); });
|
|
16573
16607
|
};
|
|
16574
|
-
`;var
|
|
16608
|
+
`;var jl=`
|
|
16575
16609
|
(function () {
|
|
16576
16610
|
var fleetPanel = document.getElementById('panel-fleet');
|
|
16577
16611
|
var activityPanel = document.getElementById('panel-activity');
|
|
@@ -16862,7 +16896,7 @@ window.AXSheet = function (sheet, onClose) {
|
|
|
16862
16896
|
setInterval(refresh, 15000);
|
|
16863
16897
|
refresh();
|
|
16864
16898
|
})();
|
|
16865
|
-
`;var
|
|
16899
|
+
`;var Ol=`
|
|
16866
16900
|
.fx-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
|
|
16867
16901
|
.fx-head h2 { margin: 4px 0 0; }
|
|
16868
16902
|
.fx-sub { font-size: 15px; margin: 18px 0 8px; color: var(--ax-text-2); }
|
|
@@ -16927,7 +16961,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
16927
16961
|
.fx-opt em { font-style: normal; font-size: 12px; color: var(--ax-ok); white-space: nowrap; }
|
|
16928
16962
|
.fx-error:empty { display: none; }
|
|
16929
16963
|
.fx-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }
|
|
16930
|
-
`;var
|
|
16964
|
+
`;var Nl=`
|
|
16931
16965
|
(function () {
|
|
16932
16966
|
var panel = document.getElementById('panel-alerts');
|
|
16933
16967
|
if (!panel) return;
|
|
@@ -17138,7 +17172,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17138
17172
|
refresh();
|
|
17139
17173
|
loadRecent();
|
|
17140
17174
|
})();
|
|
17141
|
-
`;var
|
|
17175
|
+
`;var Dl=`
|
|
17142
17176
|
(function () {
|
|
17143
17177
|
var panel = document.getElementById('panel-alerts');
|
|
17144
17178
|
if (!panel) return;
|
|
@@ -17290,7 +17324,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17290
17324
|
document.addEventListener('visibilitychange', function () { if (!document.hidden && state) load(); });
|
|
17291
17325
|
load();
|
|
17292
17326
|
})();
|
|
17293
|
-
`,
|
|
17327
|
+
`,Bl=`
|
|
17294
17328
|
.pl-card { margin-top: 12px; }
|
|
17295
17329
|
.pl-list { margin-top: 8px; }
|
|
17296
17330
|
.pl-rules { list-style: none; margin: 6px 0 0; padding: 0; }
|
|
@@ -17309,7 +17343,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17309
17343
|
.pl-check { display: flex; align-items: center; gap: 8px; font-size: var(--ax-fs-sm); }
|
|
17310
17344
|
.pl-check input { width: 20px; height: 20px; }
|
|
17311
17345
|
#pl-here { justify-self: start; }
|
|
17312
|
-
`;function
|
|
17346
|
+
`;function Hl(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 zl=`
|
|
17313
17347
|
(function () {
|
|
17314
17348
|
var panel = document.getElementById('panel-alerts');
|
|
17315
17349
|
if (!panel) return;
|
|
@@ -17422,7 +17456,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17422
17456
|
}
|
|
17423
17457
|
load();
|
|
17424
17458
|
})();
|
|
17425
|
-
`;var
|
|
17459
|
+
`;var ql=`
|
|
17426
17460
|
(function () {
|
|
17427
17461
|
var panel = document.getElementById('panel-chat');
|
|
17428
17462
|
var V = window.AXChatView;
|
|
@@ -17705,7 +17739,7 @@ details[open] > summary::before { transform: rotate(90deg); }
|
|
|
17705
17739
|
var last = recall('ax-chat-conv');
|
|
17706
17740
|
if (!fromHash() && last) openConversation(last);
|
|
17707
17741
|
})();
|
|
17708
|
-
`;var
|
|
17742
|
+
`;var Fl=`
|
|
17709
17743
|
window.AXChatView = (function () {
|
|
17710
17744
|
var NL = String.fromCharCode(10), TAB = String.fromCharCode(9), FENCE = String.fromCharCode(96, 96, 96);
|
|
17711
17745
|
// Cut a half-written agentx:ui block from a streaming reply so its raw
|
|
@@ -17986,7 +18020,7 @@ window.AXChatView = (function () {
|
|
|
17986
18020
|
openViewer: openViewer, closeViewer: closeViewer, readStream: readStream,
|
|
17987
18021
|
cachePut: cachePut, cacheGet: cacheGet, cacheAll: cacheAll, cacheDrop: cacheDrop };
|
|
17988
18022
|
})();
|
|
17989
|
-
`;var
|
|
18023
|
+
`;var Ul=`
|
|
17990
18024
|
window.AXChatSheets = function (o) {
|
|
17991
18025
|
var V = o.V, picker = o.picker, hist = o.hist;
|
|
17992
18026
|
function loadPicker() {
|
|
@@ -18032,7 +18066,7 @@ window.AXChatSheets = function (o) {
|
|
|
18032
18066
|
});
|
|
18033
18067
|
return { loadPicker: loadPicker, loadHistory: loadHistory };
|
|
18034
18068
|
};
|
|
18035
|
-
`;var
|
|
18069
|
+
`;var Wl=`
|
|
18036
18070
|
window.AXChatLog = function (o) {
|
|
18037
18071
|
var V = o.V, log = o.log, empty = o.empty, NOTES = o.notes;
|
|
18038
18072
|
function scrollDown() { var m = log; if (m) m.scrollTop = m.scrollHeight; }
|
|
@@ -18095,7 +18129,7 @@ window.AXChatLog = function (o) {
|
|
|
18095
18129
|
return { scrollDown: scrollDown, clear: clear, userMsg: userMsg, queuedMsg: queuedMsg, agentMsg: agentMsg, setBody: setBody,
|
|
18096
18130
|
setNote: setNote, renderUi: renderUi, renderFiles: renderFiles, renderConversation: renderConversation, flash: flash };
|
|
18097
18131
|
};
|
|
18098
|
-
`;var
|
|
18132
|
+
`;var Gl=`
|
|
18099
18133
|
(function () {
|
|
18100
18134
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, V = window.AXChatView, O = window.AXOrb;
|
|
18101
18135
|
var top = panel && panel.querySelector('.cx-top');
|
|
@@ -18245,7 +18279,7 @@ window.AXChatLog = function (o) {
|
|
|
18245
18279
|
window.AXStrip = { poll: poll, update: update, banner: banner };
|
|
18246
18280
|
poll();
|
|
18247
18281
|
})();
|
|
18248
|
-
`;var
|
|
18282
|
+
`;var Xl=`
|
|
18249
18283
|
.cs { margin: 0 -2px; }
|
|
18250
18284
|
.cs[hidden] { display: none; }
|
|
18251
18285
|
.cs-list {
|
|
@@ -18301,7 +18335,7 @@ window.AXChatLog = function (o) {
|
|
|
18301
18335
|
@media (prefers-reduced-motion: reduce) {
|
|
18302
18336
|
.cs-thinking .cs-dot, .cs-answering .cs-dot, .cs-banner { animation: none; }
|
|
18303
18337
|
}
|
|
18304
|
-
`;function
|
|
18338
|
+
`;function Kl(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 Jl(t,e){return e||!t.length?{item:null,queue:t.slice()}:{item:t[0],queue:t.slice(1)}}var Vl=`
|
|
18305
18339
|
body { height: 100dvh; }
|
|
18306
18340
|
main { min-height: 0; }
|
|
18307
18341
|
#panel-chat:not([hidden]) { display: flex; flex-direction: column; min-height: 100%; }
|
|
@@ -18411,7 +18445,7 @@ main { min-height: 0; }
|
|
|
18411
18445
|
background: color-mix(in oklch, var(--ax-accent) 15%, var(--ax-surface)); color: var(--ax-accent);
|
|
18412
18446
|
}
|
|
18413
18447
|
.cx-composer .fx-btn { border-radius: var(--ax-radius); }
|
|
18414
|
-
`;var
|
|
18448
|
+
`;var Yl=`
|
|
18415
18449
|
window.AXOrb = (function () {
|
|
18416
18450
|
// Same list, order and hash as presenceLook (src/voice/presence.ts) and
|
|
18417
18451
|
// OrbMath.colorHex, for an agent whose colour did not come with it.
|
|
@@ -18528,7 +18562,7 @@ window.AXOrb = (function () {
|
|
|
18528
18562
|
}
|
|
18529
18563
|
return { create: create, colorFor: colorFor, levelFromRms: levelFromRms, speakingEnvelope: speakingEnvelope };
|
|
18530
18564
|
})();
|
|
18531
|
-
`;var
|
|
18565
|
+
`;var Ql=`
|
|
18532
18566
|
window.AXVoiceIO = (function () {
|
|
18533
18567
|
var TYPES = ['audio/webm;codecs=opus', 'audio/mp4', 'audio/webm', 'audio/ogg;codecs=opus', 'audio/aac'];
|
|
18534
18568
|
var ac = null, playing = null;
|
|
@@ -18646,7 +18680,7 @@ window.AXVoiceIO = (function () {
|
|
|
18646
18680
|
|
|
18647
18681
|
return { canRecord: canRecord, mimeType: mimeType, unlock: unlock, record: record, playAudio: playAudio, speakText: speakText, stop: stopPlaying };
|
|
18648
18682
|
})();
|
|
18649
|
-
`;var
|
|
18683
|
+
`;var Zl=`
|
|
18650
18684
|
(function () {
|
|
18651
18685
|
var panel = document.getElementById('panel-chat'), C = window.AXChat, IO = window.AXVoiceIO, O = window.AXOrb;
|
|
18652
18686
|
if (!panel || !C || !IO || !O) return;
|
|
@@ -18859,7 +18893,7 @@ window.AXVoiceIO = (function () {
|
|
|
18859
18893
|
idle();
|
|
18860
18894
|
window.AXVoice = { show: show, orb: orb, state: function () { return v.state; }, queued: function () { return speech.length; } };
|
|
18861
18895
|
})();
|
|
18862
|
-
`;var
|
|
18896
|
+
`;var ec=`
|
|
18863
18897
|
.vx {
|
|
18864
18898
|
position: sticky; bottom: -16px; z-index: 1; display: grid; justify-items: center; gap: 4px;
|
|
18865
18899
|
margin: 0 0 -16px; padding: 8px 0 12px; background: var(--ax-bg);
|
|
@@ -18895,7 +18929,7 @@ window.AXVoiceIO = (function () {
|
|
|
18895
18929
|
.cx-typing-on .vx-orb { width: 88px; height: 88px; }
|
|
18896
18930
|
.cx-typing-on .vx-row { gap: 16px; }
|
|
18897
18931
|
@media (prefers-reduced-motion: reduce) { .vx-orb { transition: none; } }
|
|
18898
|
-
`;var
|
|
18932
|
+
`;var tc=`
|
|
18899
18933
|
<main class="card">
|
|
18900
18934
|
<h1>This phone isn't paired</h1>
|
|
18901
18935
|
<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>
|
|
@@ -18909,7 +18943,7 @@ window.AXVoiceIO = (function () {
|
|
|
18909
18943
|
<p id="pair-msg" class="pair-msg" role="status" aria-live="polite"></p>
|
|
18910
18944
|
</form>
|
|
18911
18945
|
<p class="muted">If this phone was paired before, it may have been removed with <code>agentx app revoke</code>.</p>
|
|
18912
|
-
</main>`,
|
|
18946
|
+
</main>`,ac=`
|
|
18913
18947
|
.pair-form { display: grid; gap: 10px; margin: 20px 0 24px; }
|
|
18914
18948
|
.pair-form label { font-weight: 600; }
|
|
18915
18949
|
.pair-form input {
|
|
@@ -18931,7 +18965,7 @@ window.AXVoiceIO = (function () {
|
|
|
18931
18965
|
margin: 0; padding: 8px 12px; border-radius: var(--ax-radius-sm); font-size: var(--ax-fs-sm);
|
|
18932
18966
|
background: var(--ax-amber-t); color: var(--ax-amber-ink); border: 1px solid var(--ax-amber-e);
|
|
18933
18967
|
}
|
|
18934
|
-
`,
|
|
18968
|
+
`,nc=`
|
|
18935
18969
|
(function () {
|
|
18936
18970
|
var form = document.getElementById('pair-form');
|
|
18937
18971
|
var input = document.getElementById('pair-code');
|
|
@@ -19023,7 +19057,7 @@ window.AXVoiceIO = (function () {
|
|
|
19023
19057
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
19024
19058
|
}
|
|
19025
19059
|
})();
|
|
19026
|
-
`;var
|
|
19060
|
+
`;var rc=`
|
|
19027
19061
|
<div id="scan" class="scan" role="dialog" aria-modal="true" aria-labelledby="scan-title" hidden>
|
|
19028
19062
|
<video id="scan-video" playsinline muted autoplay></video>
|
|
19029
19063
|
<div class="scan-frame" aria-hidden="true"></div>
|
|
@@ -19032,7 +19066,7 @@ window.AXVoiceIO = (function () {
|
|
|
19032
19066
|
<button type="button" id="scan-close" class="scan-close">Close</button>
|
|
19033
19067
|
</div>
|
|
19034
19068
|
<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>
|
|
19035
|
-
</div>`,
|
|
19069
|
+
</div>`,oc=`
|
|
19036
19070
|
.pair-form .scan-btn {
|
|
19037
19071
|
color: var(--ax-accent-2, var(--ax-accent)); background: transparent; border: 2px solid var(--ax-accent);
|
|
19038
19072
|
}
|
|
@@ -19061,7 +19095,7 @@ window.AXVoiceIO = (function () {
|
|
|
19061
19095
|
}
|
|
19062
19096
|
.scan-msg.bad { color: #ffd0cc; font-weight: 600; }
|
|
19063
19097
|
body.scanning { overflow: hidden; }
|
|
19064
|
-
`,
|
|
19098
|
+
`,sc=`
|
|
19065
19099
|
(function () {
|
|
19066
19100
|
var openBtn = document.getElementById('scan-btn');
|
|
19067
19101
|
var box = document.getElementById('scan');
|
|
@@ -19227,7 +19261,7 @@ body.scanning { overflow: hidden; }
|
|
|
19227
19261
|
document.addEventListener('visibilitychange', function () { if (document.hidden) close(); });
|
|
19228
19262
|
window.addEventListener('pagehide', close);
|
|
19229
19263
|
})();
|
|
19230
|
-
`;var
|
|
19264
|
+
`;var mn=`
|
|
19231
19265
|
.cam { position: fixed; inset: 0; z-index: 50; display: flex; flex-direction: column; background: var(--ax-bg); }
|
|
19232
19266
|
.cam[hidden] { display: none; }
|
|
19233
19267
|
.cam-live {
|
|
@@ -19286,7 +19320,7 @@ body.scanning { overflow: hidden; }
|
|
|
19286
19320
|
@keyframes cam-pulse { 50% { opacity: .3; } }
|
|
19287
19321
|
@media (prefers-reduced-motion: reduce) { .cam-live.is-stream .cam-dot { animation: none; } }
|
|
19288
19322
|
#cam-stream[aria-pressed="true"] { border-color: var(--ax-red); color: var(--ax-red-ink); }
|
|
19289
|
-
`;var
|
|
19323
|
+
`;var ic='<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>',lc=`
|
|
19290
19324
|
<div id="cam" class="cam" role="dialog" aria-modal="true" aria-labelledby="cam-title" hidden>
|
|
19291
19325
|
<div class="cam-live" id="cam-live" role="status" aria-live="polite" hidden>
|
|
19292
19326
|
<span class="cam-dot" aria-hidden="true"></span>
|
|
@@ -19315,7 +19349,7 @@ body.scanning { overflow: hidden; }
|
|
|
19315
19349
|
<button type="button" id="cam-close" class="cam-secondary">Close</button>
|
|
19316
19350
|
</div>
|
|
19317
19351
|
</div>
|
|
19318
|
-
</div>`,
|
|
19352
|
+
</div>`,cc=`
|
|
19319
19353
|
(function () {
|
|
19320
19354
|
var btn = document.getElementById('cam-btn');
|
|
19321
19355
|
var sheet = document.getElementById('cam');
|
|
@@ -19789,7 +19823,7 @@ body.scanning { overflow: hidden; }
|
|
|
19789
19823
|
});
|
|
19790
19824
|
window.addEventListener('pagehide', function () { stop(); });
|
|
19791
19825
|
})();
|
|
19792
|
-
`;var
|
|
19826
|
+
`;var dc=`
|
|
19793
19827
|
<div id="cam-ask-bar" class="cam-askbar" role="alert" hidden>
|
|
19794
19828
|
<div class="cam-askbar-text">
|
|
19795
19829
|
<strong id="cam-ask-who">An agent</strong> wants to see through your camera
|
|
@@ -19799,7 +19833,7 @@ body.scanning { overflow: hidden; }
|
|
|
19799
19833
|
<button type="button" id="cam-ask-show" class="cam-askbar-show">Show</button>
|
|
19800
19834
|
<button type="button" id="cam-ask-no" class="cam-askbar-no">Decline</button>
|
|
19801
19835
|
</div>
|
|
19802
|
-
</div>`,
|
|
19836
|
+
</div>`,pc=`
|
|
19803
19837
|
.cam-askbar[hidden] { display: none; }
|
|
19804
19838
|
.cam-askbar {
|
|
19805
19839
|
display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
|
|
@@ -19814,7 +19848,7 @@ body.scanning { overflow: hidden; }
|
|
|
19814
19848
|
border: 2px solid #fff; background: #fff; color: var(--ax-accent);
|
|
19815
19849
|
}
|
|
19816
19850
|
.cam-askbar-no { background: transparent; color: #fff; }
|
|
19817
|
-
`,
|
|
19851
|
+
`,uc=`
|
|
19818
19852
|
(function () {
|
|
19819
19853
|
var bar = document.getElementById('cam-ask-bar');
|
|
19820
19854
|
if (!bar) return;
|
|
@@ -19884,7 +19918,7 @@ body.scanning { overflow: hidden; }
|
|
|
19884
19918
|
setInterval(poll, 5000);
|
|
19885
19919
|
document.addEventListener('visibilitychange', function () { if (document.visibilityState === 'visible') poll(); });
|
|
19886
19920
|
})();
|
|
19887
|
-
`;function
|
|
19921
|
+
`;function mc(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 fc(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 hc(t){return t>=400?"send":"listen"}function gc(t){let e=Math.max(1,Math.round(t||60));return"Keep watching "+(e%60===0?e/60+" min":e+" s")}var xc=`
|
|
19888
19922
|
(function () {
|
|
19889
19923
|
var main = document.querySelector('main');
|
|
19890
19924
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
@@ -20003,7 +20037,7 @@ body.scanning { overflow: hidden; }
|
|
|
20003
20037
|
main.addEventListener('touchend', function () { end(false); });
|
|
20004
20038
|
main.addEventListener('touchcancel', function () { end(true); });
|
|
20005
20039
|
})();
|
|
20006
|
-
`,
|
|
20040
|
+
`,vc=`
|
|
20007
20041
|
main { position: relative; }
|
|
20008
20042
|
main.sw-on { overflow: hidden; }
|
|
20009
20043
|
.sw-on > [role=tabpanel] { will-change: transform; }
|
|
@@ -20014,8 +20048,8 @@ main > .sw-peek {
|
|
|
20014
20048
|
}
|
|
20015
20049
|
main > #panel-chat.sw-peek { display: flex; flex-direction: column; }
|
|
20016
20050
|
@media (prefers-reduced-motion: reduce) { .sw-slide > [role=tabpanel] { transition: none; } }
|
|
20017
|
-
`;function bc(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
|
|
20018
|
-
${q({afterUnauthorized:
|
|
20051
|
+
`;function bc(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 yc(t,e){let a=Math.abs(t),n=Math.abs(e);return a<10&&n<10?"":a>n*1.5?"x":"y"}function wc(t,e,a){return a>0&&t===0||a<0&&t===e-1?a/4:a}function kc(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 fn=`
|
|
20052
|
+
${q({afterUnauthorized:Ao})}
|
|
20019
20053
|
var CACHE = 'agentx-app-v3';
|
|
20020
20054
|
var STATIC = ['/app/manifest.webmanifest', '/app/icon-192.png', '/app/icon-512.png'];
|
|
20021
20055
|
self.addEventListener('install', function (e) {
|
|
@@ -20106,7 +20140,7 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20106
20140
|
return self.clients.openWindow(target);
|
|
20107
20141
|
}));
|
|
20108
20142
|
});
|
|
20109
|
-
`;var
|
|
20143
|
+
`;var Gf="<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 hn(t){return`<meta charset="utf-8">
|
|
20110
20144
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
|
20111
20145
|
<meta name="theme-color" content="#2979FF">
|
|
20112
20146
|
<meta name="referrer" content="no-referrer">
|
|
@@ -20117,58 +20151,58 @@ self.addEventListener('notificationclick', function (e) {
|
|
|
20117
20151
|
<link rel="icon" type="image/png" href="/app/icon-192.png">
|
|
20118
20152
|
<link rel="apple-touch-icon" href="/app/icon-192.png">
|
|
20119
20153
|
<title>${t}</title>
|
|
20120
|
-
${
|
|
20121
|
-
<style>${ze}${
|
|
20154
|
+
${Gf}
|
|
20155
|
+
<style>${ze}${Rl}${Vf}</style>`}var Xf={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"},_c=[{id:"chat",label:"Chat",soon:"Loading your conversations\u2026"},{id:"fleet",label:"Fleet",soon:"Loading your machines\u2026"},{id:"activity",label:"Activity",soon:"Loading what your agents are doing\u2026"},{id:"alerts",label:"Alerts",soon:"Loading notifications\u2026"}];function Sc(){let t=_c.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="${Xf[a.id]}"/></svg></span><span>${a.label}</span></button>`).join(""),e=_c.map((a,n)=>`<section role="tabpanel" id="panel-${a.id}" aria-labelledby="tab-${a.id}" tabindex="0"${n===0?"":" hidden"}>
|
|
20122
20156
|
<h2>${a.label}</h2>
|
|
20123
20157
|
<p class="soon">${a.soon}</p>
|
|
20124
20158
|
</section>`).join("");return`<!doctype html>
|
|
20125
20159
|
<html lang="en">
|
|
20126
|
-
<head>${
|
|
20160
|
+
<head>${hn("AgentX")}<style>${Yf}${Ol}${Vl}${Xl}${ec}${mn}${pc}${vc}${Bl}${Pl}</style></head>
|
|
20127
20161
|
<body>
|
|
20128
20162
|
<header class="bar">
|
|
20129
20163
|
<div>
|
|
20130
20164
|
<h1>AgentX</h1>
|
|
20131
20165
|
<p id="who" class="who">Connecting\u2026</p>
|
|
20132
20166
|
</div>
|
|
20133
|
-
<div class="bar-btns">${
|
|
20167
|
+
<div class="bar-btns">${ic}<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>
|
|
20134
20168
|
</header>
|
|
20135
20169
|
<p id="offline" class="offline" role="status" hidden>Offline. Showing the saved app; live data needs a connection.</p>
|
|
20136
|
-
${
|
|
20170
|
+
${dc}
|
|
20137
20171
|
<main>${e}</main>
|
|
20138
20172
|
<nav class="tabs" role="tablist" aria-label="Sections">${t}</nav>
|
|
20139
|
-
${
|
|
20140
|
-
<script>${
|
|
20141
|
-
<script>${q({swipeMayStart:bc,swipeAxis:
|
|
20142
|
-
<script>${Pl}</script>
|
|
20173
|
+
${lc}
|
|
20174
|
+
<script>${Kf}</script>
|
|
20175
|
+
<script>${q({swipeMayStart:bc,swipeAxis:yc,swipeOffset:wc,swipeLanding:kc})}${xc}</script>
|
|
20143
20176
|
<script>${$l}</script>
|
|
20144
|
-
<script>${
|
|
20145
|
-
<script>${
|
|
20146
|
-
<script>${Hl}</script>
|
|
20147
|
-
<script>${
|
|
20148
|
-
<script>${q({
|
|
20149
|
-
<script>${
|
|
20150
|
-
<script>${
|
|
20151
|
-
<script>${
|
|
20177
|
+
<script>${jl}</script>
|
|
20178
|
+
<script>${Nl}</script>
|
|
20179
|
+
<script>${q({locationErrorText:Hl})}${Dl}</script>
|
|
20180
|
+
<script>${zl}</script>
|
|
20181
|
+
<script>${q({markdownToHtml:ur})}${Fl}${Wl}${Ul}${ql}</script>
|
|
20182
|
+
<script>${q({queueSpeech:Kl,nextSpeech:Jl})}${Yl}${Ql}${Zl}</script>
|
|
20183
|
+
<script>${Gl}</script>
|
|
20184
|
+
<script>${q({cameraConstraints:mc,shareClock:fc,streamLabel:gc,talkRelease:hc})}${cc}</script>
|
|
20185
|
+
<script>${uc}</script>
|
|
20152
20186
|
</body>
|
|
20153
|
-
</html>`}function
|
|
20187
|
+
</html>`}function Ec(){return`<!doctype html>
|
|
20154
20188
|
<html lang="en">
|
|
20155
|
-
<head>${
|
|
20189
|
+
<head>${hn("Pair \xB7 AgentX")}</head>
|
|
20156
20190
|
<body>
|
|
20157
20191
|
<main class="card">
|
|
20158
20192
|
<h1>Pairing this phone\u2026</h1>
|
|
20159
20193
|
<p id="msg" role="status">One moment.</p>
|
|
20160
20194
|
</main>
|
|
20161
|
-
<script>${
|
|
20195
|
+
<script>${Jf}</script>
|
|
20162
20196
|
</body>
|
|
20163
|
-
</html>`}function
|
|
20197
|
+
</html>`}function Tc(){return`<!doctype html>
|
|
20164
20198
|
<html lang="en">
|
|
20165
|
-
<head>${
|
|
20166
|
-
<body>${
|
|
20167
|
-
<script>${q({mayBounce:
|
|
20168
|
-
<script>${
|
|
20169
|
-
<script>${
|
|
20199
|
+
<head>${hn("Not paired \xB7 AgentX")}<style>${ac}${oc}</style></head>
|
|
20200
|
+
<body>${tc}${rc}
|
|
20201
|
+
<script>${q({mayBounce:Co,formatPairInput:qt,parsePairScan:Io})}</script>
|
|
20202
|
+
<script>${nc}</script>
|
|
20203
|
+
<script>${sc}</script>
|
|
20170
20204
|
</body>
|
|
20171
|
-
</html>`}function
|
|
20205
|
+
</html>`}function Ac(){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 Kf=`
|
|
20172
20206
|
(function () {
|
|
20173
20207
|
var tabs = Array.prototype.slice.call(document.querySelectorAll('[role=tab]'));
|
|
20174
20208
|
function select(tab, focus, keepHash) {
|
|
@@ -20240,7 +20274,7 @@ ${ic}
|
|
|
20240
20274
|
navigator.serviceWorker.register('/app/sw.js', { scope: '/app' }).catch(function () {});
|
|
20241
20275
|
}
|
|
20242
20276
|
})();
|
|
20243
|
-
`,
|
|
20277
|
+
`,Jf=`
|
|
20244
20278
|
(function () {
|
|
20245
20279
|
var msg = document.getElementById('msg');
|
|
20246
20280
|
var m = /(?:^#|&)token=([^&]+)/.exec(location.hash);
|
|
@@ -20257,7 +20291,7 @@ ${ic}
|
|
|
20257
20291
|
: 'Pairing failed (HTTP ' + r.status + '). Try again.';
|
|
20258
20292
|
}).catch(function () { msg.textContent = 'Could not reach AgentX. Check this phone is on your tailnet, then try again.'; });
|
|
20259
20293
|
})();
|
|
20260
|
-
`,
|
|
20294
|
+
`,Vf=`
|
|
20261
20295
|
html, body { margin: 0; background: var(--ax-bg); color: var(--ax-text); font-family: var(--ax-font); }
|
|
20262
20296
|
body { min-height: 100dvh; -webkit-text-size-adjust: 100%; }
|
|
20263
20297
|
code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surface-3); padding: 1px 6px; border-radius: 6px; }
|
|
@@ -20269,7 +20303,7 @@ code { font-family: var(--ax-mono); font-size: 0.92em; background: var(--ax-surf
|
|
|
20269
20303
|
.card h1 { font-size: 22px; margin: 0 0 12px; }
|
|
20270
20304
|
.muted { color: var(--ax-text-2); }
|
|
20271
20305
|
:focus-visible { outline: 3px solid var(--ax-accent); outline-offset: 2px; }
|
|
20272
|
-
`,
|
|
20306
|
+
`,Yf=`
|
|
20273
20307
|
body { display: flex; flex-direction: column; }
|
|
20274
20308
|
.bar {
|
|
20275
20309
|
display: flex; align-items: center; justify-content: space-between; gap: 12px;
|
|
@@ -20307,8 +20341,8 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20307
20341
|
}
|
|
20308
20342
|
.tabs [role=tab][aria-selected=true] { background: var(--ax-accent-t); color: var(--ax-accent-2); }
|
|
20309
20343
|
[data-theme="dark"] .tabs [role=tab][aria-selected=true] { color: var(--ax-text); }
|
|
20310
|
-
`;var
|
|
20311
|
-
`;rt=Buffer.concat([Buffer.from(a),
|
|
20344
|
+
`;var ia="agentx_app",eh=400*86400,th=new At,ah=new Ie;async function Cc(t,e,a,n,r={}){if(a==="/.well-known/assetlinks.json"&&n==="GET"){let i=r.assetLinks?.()??null;return i?ue(e,200,"application/json",JSON.stringify(i),"public, max-age=300"):_e(e,404,{error:"not found"})}if(a!=="/app"&&!a.startsWith("/app/")&&!a.startsWith("/api/app/"))return!1;let o=r.tokens??new G;if(n==="GET"){if(a==="/app/manifest.webmanifest")return ue(e,200,"application/manifest+json",Ac());if(a==="/app/sw.js")return e.setHeader("Service-Worker-Allowed","/app"),ue(e,200,"text/javascript; charset=utf-8",fn);if(a==="/app/icon-192.png")return ue(e,200,"image/png",Fe(192),"public, max-age=86400");if(a==="/app/icon-512.png")return ue(e,200,"image/png",Fe(512),"public, max-age=86400");if(a==="/app/pair")return ue(e,200,"text/html; charset=utf-8",Ec());if(a==="/app/qr.js"){let i=nh();return i?ue(e,200,"text/javascript; charset=utf-8",i,"public, max-age=2592000"):_e(e,404,{error:"not found"})}}if(n==="POST"&&a==="/api/app/session"){let i=gn(ot(t),o);return i?(e.setHeader("Set-Cookie",xn(ot(t))),_e(e,200,{device:i.name})):_e(e,401,{error:"invalid or revoked device token"})}if(n==="POST"&&a==="/api/app/pair-code"){let i=await pr(t,{codes:r.pairCodes??new kt,limiter:r.pairLimiter??th,verify:l=>gn(l,o)?.name??null,minMs:r.pairMinMs});return i.status===200&&e.setHeader("Set-Cookie",xn(i.token)),i.status===429&&e.setHeader("Retry-After",String(i.retryAfter)),_e(e,i.status,i.body)}let s=gn(rh(t),o);if(!s){let i=ot(t);return(r.rejectLog??ah).record(a.slice(0,120),Bt(t,qe(vn(t,ia),o),i?qe(i,o):null)),a==="/app"?ue(e,401,"text/html; charset=utf-8",Tc()):_e(e,401,{error:"this device is not paired",hint:"run: agentx app pair"})}if(n==="GET"&&a==="/app"){let i=vn(t,ia);return i&&!ot(t)&&e.setHeader("Set-Cookie",xn(i)),ue(e,200,"text/html; charset=utf-8",Sc())}return n==="GET"&&a==="/api/app/me"?_e(e,200,{id:s.id,device:s.name,node:r.nodeName??null}):r.fleet&&await rr(t,e,a,n,s.name,r.fleet)||r.push&&await or(t,e,a,n,s,r.push)||r.announce&&await Xi(t,e,a,n,s,r.announce)||r.chat&&await rl(t,e,a,n,s,r.chat)||r.chat&&await ll(t,e,a,n,s,r.chat)||r.voice&&await pl(t,e,a,n,s,r.voice)||r.camera&&await ml(t,e,a,n,r.camera)||r.places&&await Al(t,e,a,n,s,r.places)?!0:_e(e,404,{error:"not found"})}var rt;function nh(){if(rt!==void 0)return rt;try{let t=Zf(import.meta.url),{version:e}=t("jsqr/package.json"),a=`/*! jsQR ${e} | Apache-2.0 | https://github.com/cozmo/jsQR */
|
|
20345
|
+
`;rt=Buffer.concat([Buffer.from(a),Qf(t.resolve("jsqr"))])}catch(t){console.error(`[app] QR decoder unavailable (install the jsqr package): ${t.message}`),rt=null}return rt}function gn(t,e){if(!t)return null;let a=e.verify(t);return a&&Ee(a,"app")?a:null}function xn(t){return`${ia}=${t}; Path=/; Max-Age=${eh}; HttpOnly; Secure; SameSite=Lax`}function rh(t){return ot(t)??vn(t,ia)}function ot(t){let e=t.headers.authorization||"";return e.toLowerCase().startsWith("bearer ")&&e.slice(7).trim()||null}function vn(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 ue(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 ue(t,e,"application/json",JSON.stringify(a))}function Ic(t){let e=de({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."})+`
|
|
20312
20346
|
<div class="pl-wrap">
|
|
20313
20347
|
<div id="pl-msg" class="pl-msg" role="status" aria-live="polite"></div>
|
|
20314
20348
|
<form id="pl-add" class="pl-form" autocomplete="off">
|
|
@@ -20320,7 +20354,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20320
20354
|
<button type="submit" class="ax-btn ax-btn--primary">Add place</button>
|
|
20321
20355
|
</form>
|
|
20322
20356
|
<ol id="pl-list" class="pl-list" aria-label="Places"><li class="pl-empty">Loading\u2026</li></ol>
|
|
20323
|
-
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:
|
|
20357
|
+
</div>`;return I({title:"AgentX \xB7 Places",activeTab:"admin",subtitle:"Places",peers:t.peers,body:e,css:oh,scripts:`<script>${sh}</script>`})}var oh=`
|
|
20324
20358
|
.pl-wrap { max-width: 1040px; margin: 0 auto; padding: 0 24px 96px; box-sizing: border-box; }
|
|
20325
20359
|
.pl-msg { min-height: 1.4em; margin: 8px 0 0; }
|
|
20326
20360
|
.pl-msg.is-bad { color: var(--ax-red-ink); }
|
|
@@ -20343,7 +20377,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20343
20377
|
.pl-rule-form { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
|
|
20344
20378
|
.pl-rule-form input[name=text] { flex: 1 1 240px; }
|
|
20345
20379
|
.pl-btns { margin-left: auto; display: flex; gap: 8px; }
|
|
20346
|
-
`,
|
|
20380
|
+
`,sh=`
|
|
20347
20381
|
(function () {
|
|
20348
20382
|
var list = document.getElementById('pl-list');
|
|
20349
20383
|
var msg = document.getElementById('pl-msg');
|
|
@@ -20422,7 +20456,7 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20422
20456
|
});
|
|
20423
20457
|
load();
|
|
20424
20458
|
})();
|
|
20425
|
-
`;import{randomBytes as
|
|
20459
|
+
`;import{randomBytes as Mc}from"crypto";var Be={content:32e3,messagesPerConversation:200,conversationsPerDevice:100,toolsPerMessage:50,filesPerMessage:ce.perMessage},ih=/^[a-f0-9]{32}$/,lh=/^c[a-z0-9]{8,32}$/,ch=/^#[0-9a-fA-F]{6}$/;function bn(t){return lh.test(t)}var st=class{constructor(e){this.db=e;e.exec(`CREATE TABLE IF NOT EXISTS app_chat_conversations (
|
|
20426
20460
|
id TEXT PRIMARY KEY, device_id TEXT NOT NULL, title TEXT NOT NULL,
|
|
20427
20461
|
node TEXT NOT NULL, node_name TEXT NOT NULL, agent TEXT NOT NULL, agent_name TEXT,
|
|
20428
20462
|
created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL);
|
|
@@ -20435,39 +20469,39 @@ main h2 { font-size: 20px; margin: 4px 0 8px; }
|
|
|
20435
20469
|
id TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, message_id INTEGER NOT NULL,
|
|
20436
20470
|
path TEXT NOT NULL, name TEXT NOT NULL, mime TEXT NOT NULL, kind TEXT NOT NULL, created_at INTEGER NOT NULL);
|
|
20437
20471
|
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 (
|
|
20438
|
-
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return bn(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)}${
|
|
20439
|
-
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,c.title,c.node,c.nodeName,c.agent,c.agentName??null,l??null,r,r,r),this.pruneDevice(e),c}get(e,a){if(!bn(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(
|
|
20472
|
+
key TEXT PRIMARY KEY, conversation_id TEXT NOT NULL, at INTEGER NOT NULL)`)}ownerOf(e){return bn(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)}${Mc(4).toString("hex")}`,{color:s,...i}=a,l=s&&ch.test(s)?s:void 0,c={id:o,title:ph(n),...i,...l?{color:l}:{},createdAt:r,updatedAt:r,messages:[]};return this.db.prepare(`INSERT INTO app_chat_conversations
|
|
20473
|
+
(id, device_id, title, node, node_name, agent, agent_name, color, created_at, updated_at, read_at) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(o,e,c.title,c.node,c.nodeName,c.agent,c.agentName??null,l??null,r,r,r),this.pruneDevice(e),c}get(e,a){if(!bn(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(dh);return{...Lc(n),messages:r}}list(e,a=Be.conversationsPerDevice){return this.db.prepare(`SELECT c.*,
|
|
20440
20474
|
(SELECT COUNT(*) FROM app_chat_messages m WHERE m.conversation_id = c.id) AS n,
|
|
20441
20475
|
(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
|
|
20442
|
-
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{...
|
|
20476
|
+
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{...Lc(r),messages:r.n,...o?{last:o}:{}}})}markRead(e,a,n=Date.now()){bn(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,
|
|
20443
20477
|
substr(m.content, 1, 240) AS answer, m.status, m.at
|
|
20444
20478
|
FROM app_chat_conversations c
|
|
20445
20479
|
JOIN app_chat_messages m ON m.id = (SELECT MAX(id) FROM app_chat_messages WHERE conversation_id = c.id)
|
|
20446
20480
|
WHERE c.device_id = ? AND m.role = 'assistant' AND m.at > COALESCE(c.read_at, 0)
|
|
20447
20481
|
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>Be.content?n.content.slice(0,Be.content)+`
|
|
20448
20482
|
|
|
20449
|
-
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,Be.toolsPerMessage),l=[];for(let m of r){if(l.length>=Be.filesPerMessage)break;let f=m.filename.trim(),_=
|
|
20483
|
+
[Cut here: the full answer is in the agent's task history.]`:n.content,i=n.tools?.slice(0,Be.toolsPerMessage),l=[];for(let m of r){if(l.length>=Be.filesPerMessage)break;let f=m.filename.trim(),_=Kn(f);if(!_||!f||f.length>ce.pathChars||f.includes("\0"))continue;let v=(f.split(/[\\/]/).pop()||f).slice(0,120);l.push({id:Mc(16).toString("hex"),name:v,mime:_.mime,kind:_.kind,path:f})}let c=l.map(m=>({id:m.id,name:m.name,mime:m.mime,kind:m.kind})),d=this.db.prepare(`INSERT INTO app_chat_messages (conversation_id, role, content, status, error, ui, tools, files, at)
|
|
20450
20484
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(a,n.role,s,n.status??null,n.error?.slice(0,500)??null,n.ui?JSON.stringify(n.ui):null,i?.length?JSON.stringify(i):null,c.length?JSON.stringify(c):null,n.at),p=this.db.prepare(`INSERT INTO app_chat_files (id, conversation_id, message_id, path, name, mime, kind, created_at)
|
|
20451
20485
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);for(let m of l)p.run(m.id,a,Number(d.lastInsertRowid),m.path,m.name,m.mime,m.kind,n.at);return this.db.prepare(`DELETE FROM app_chat_messages WHERE conversation_id = ? AND id NOT IN
|
|
20452
20486
|
(SELECT id FROM app_chat_messages WHERE conversation_id = ? ORDER BY id DESC LIMIT ?)`).run(a,a,Be.messagesPerConversation),this.db.prepare(`DELETE FROM app_chat_files WHERE conversation_id = ? AND message_id NOT IN
|
|
20453
|
-
(SELECT id FROM app_chat_messages WHERE conversation_id = ?)`).run(a,a),this.db.prepare("UPDATE app_chat_conversations SET updated_at = ? WHERE id = ?").run(n.at,a),c}getFile(e,a){if(!
|
|
20487
|
+
(SELECT id FROM app_chat_messages WHERE conversation_id = ?)`).run(a,a),this.db.prepare("UPDATE app_chat_conversations SET updated_at = ? WHERE id = ?").run(n.at,a),c}getFile(e,a){if(!ih.test(a))return null;let n=this.db.prepare(`SELECT f.*, c.node, c.agent FROM app_chat_files f
|
|
20454
20488
|
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 = ?
|
|
20455
|
-
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,Be.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
|
|
20489
|
+
ORDER BY updated_at DESC, rowid DESC LIMIT -1 OFFSET ?`).all(e,Be.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 Lc(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 dh(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 ph(t){let e=t.replace(/\s+/g," ").trim();return(e.length>60?e.slice(0,59)+"\u2026":e)||"Untitled"}var uh=4e3,yn=100,mh=15,Rc=t=>t.replace(/\/+$/,""),la=class{constructor(e){this.deps=e}cursor;retry=new Map;timer;running=!1;start(e=uh){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,yn);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??mh)-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>=yn&&n?.(`[app] warning: one poll returned ${e} delegation events, the most it reads (${yn}); 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||Rc(l)!==Rc(n)||i.agent!==r.agent)return this.deps.log?.(`[app] callback reply ${r.taskId} from ${e.node} does not match conversation ${o}; ignored`),"skip";let c=fh(r,this.deps.now?.()??Date.now());if(a.appendOnce(s,o,`dlg:${e.node}:${r.taskId}`,c.row,c.declared)===null)return"skip";let p=c.row.status,m=!!this.deps.finishAlerts?.(s),f={status:p,attached:!1,appOpen:this.deps.presence.open(s),enabled:m};return this.deps.notifyFinish&&ra(f)&&this.deps.notifyFinish(oa(s,i,p,c.row.content,c.row.error)).catch(()=>{}),"filed"}};function fh(t,e){let a=t.plain?{text:xt(t.text,!1),artifacts:[]}:gt(t.text,ce.perMessage,!1),{cleanText:n,ui:r}=bt(a.text),o=t.plain?void 0:on(r),s=t.status==="error"?"error":"done";return{row:{role:"assistant",content:n,status:s,...s==="error"?{error:hh(n)}:{},...o?{ui:o}:{},at:e},declared:a.artifacts}}function hh(t){return t.replace(/\s+/g," ").trim().slice(0,300)}jn();function Je(){let t=ut();return t&&ke(t,"dashboard"),t}function I0(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let f of a)try{s.set(f.id,Ah(f,t))}catch(_){console.error(` Board "${f.id}" failed to initialize: ${_.message}`)}let i=t.node?.id||"local",l=t.workflows?.dir?it(process.cwd(),t.workflows.dir):void 0,c=new Un(l?{baseDir:l}:void 0),d=new Wn(l?{baseDir:l,nodeId:i}:{nodeId:i}),p=new Gn(l?{baseDir:l}:void 0);pi(t),Je(),br({business:t.business?.enabled===!0});let m=gh(async(f,_)=>{try{await _h(f,_,{boards:a,sources:s,token:o,config:t,workflowStore:c,workflowRuns:d,workflowLayouts:p})}catch(v){k(_,500,{error:v.message||"internal error"})}});Uh(t).start(),m.listen(n,r,()=>{let f=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
|
|
20456
20490
|
Live dashboard: http://${f}:${n}
|
|
20457
20491
|
`),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
|
|
20458
20492
|
Kanban dashboard: http://${f}:${n}
|
|
20459
|
-
`),console.log(` Boards: ${a.map(_=>_.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}var wh=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 kh(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if((t.url||"/").split(/[?#]/)[0]!==r){k(e,404,{error:"not found"});return}if(hr(t.headers)==="foreign"&&gr(o)){k(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(await Yo(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>et(a.config.people),members:Pc(a.config.members.logRetentionDays),db:()=>Je(),linkFor:(u,h)=>vo(u,h,{gitlab:a.config.channels.gitlab?.host})})||await Ac(t,e,r,o,{nodeName:a.config.node?.name,fleet:Dc(a.config),push:En(a.config),announce:Xi(a.config),chat:Bc(a.config),voice:Uh(a.config),camera:Wh(a.config),places:Rc(a.config),assetLinks:()=>Ml(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"&&wh.has(r)&&Vr("page",r),o==="GET"&&r==="/"){let u=Or();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(an({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Oi({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(an({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Se(a.config);if(!u){k(e,503,{error:"no node available"});return}let h=await new Promise(y=>{let T="";t.on("data",v=>T+=v),t.on("end",()=>y(T)),t.on("error",()=>y(""))}),w=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:h||"{}"});e.writeHead(w.status,{"Content-Type":"application/json"}),e.end(await w.text())}catch(u){k(e,502,{error:"could not reach the node",message:String(u?.message||u)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let u=await Se(a.config),h=o==="POST"?void 0:n.searchParams.get("node"),w=o==="POST"?await me(t):void 0,y=w?.node??h,T=y?u.find(R=>R.url===y):u[0];if(!T){k(e,400,{error:"unknown node"});return}let v=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",A=await fetch(T.url+r+v,{method:o,headers:{"Content-Type":"application/json",...T.token?{Authorization:`Bearer ${T.token}`}:{}},...o==="POST"?{body:JSON.stringify({...w,node:void 0})}:{}});k(e,A.status,await A.json().catch(()=>({error:`HTTP ${A.status}`})))}catch(u){k(e,502,{error:"could not reach the node",message:u?.message||String(u)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let u=await me(t),h={"Content-Type":"application/json"};a.config.dashboard.token&&(h.Authorization=`Bearer ${a.config.dashboard.token}`);let w=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${w}/api/workflows/editor/chat`,{method:"POST",headers:h,body:JSON.stringify(u??{})}),T=await y.json().catch(()=>({error:`HTTP ${y.status}`}));k(e,y.status,T)}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[u]=await Se(a.config);if(!u){k(e,200,{configured:!1,workflows:[]});return}let h=await fetch(u.url+"/api/n8n/workflows",{headers:u.token?{Authorization:`Bearer ${u.token}`}:{}});k(e,h.status,await h.json().catch(()=>({configured:!1,workflows:[]})))}catch{k(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(so({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(to({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let u=new AbortController,h=setTimeout(()=>u.abort(),8e3);try{let w=Jn(await Se(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let R=await Promise.all(w.map(async S=>{try{let L=await fetch(S.url+"/monitor",{headers:S.token?{Authorization:`Bearer ${S.token}`}:{},signal:u.signal});if(!L.ok)throw new Error(`HTTP ${L.status}`);return{name:S.name,url:S.url,ok:!0,data:await L.json()}}catch(L){return{name:S.name,url:S.url,ok:!1,error:L.message}}}));k(e,200,{nodes:R});return}let y=w.find(R=>R.url===n.searchParams.get("node"));if(!y){k(e,400,{error:"Select a known node"});return}let T=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(T)||o==="POST"&&["register","ended","action","retry","clear"].includes(T))){k(e,405,{error:"Unknown monitor operation"});return}let v=o==="POST"?JSON.stringify(await Kn(t)):void 0,A=await fetch(y.url+"/monitor/"+T+(T==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):T==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:v,signal:u.signal,headers:{"Content-Type":"application/json",...y.token?{Authorization:`Bearer ${y.token}`}:{}}});k(e,A.status,await A.json())}catch(w){k(e,502,{error:w.message})}finally{clearTimeout(h)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Li({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(Ri({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 h=a.config.dashboard.daemonUrl.replace(/\/+$/,""),w=o==="POST"?await me(t).catch(()=>({})):void 0,y=await fetch(`${h}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...w!==void 0?{body:JSON.stringify(w??{})}:{}});k(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ni({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Di({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Bi({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(jr({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let u=n.searchParams.get("agent")||"",h=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(Hi({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:h,peers:D(a.config)}));return}let c=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(c){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(zi({agentId:decodeURIComponent(c[1]),agentName:n.searchParams.get("name")||void 0,nodeUrl:n.searchParams.get("node")||a.config.dashboard.daemonUrl,peers:D(a.config)}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){Nr(t,e);return}if(o==="POST"&&r==="/api/setup"){await Dr(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Br(t,e);return}if(o==="GET"&&r==="/admin"){ls(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){Es(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){hs(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}js(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 Yh(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await en(t,e,r,w=>zc(w,a.config));return}let h=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(h){let w=decodeURIComponent(h[1]),y=w.indexOf("::");if(y>0){let T=w.slice(0,y),v=w.slice(y+2),A=a.config.node?.id||a.config.node?.name||"local";if(T===A)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(v)}`;else{let R=(a.config.dashboard?.daemons||[]).find(S=>(S.name||S.url)===T);if(R){let S=lt(R.url.replace(/\/+$/,""),a.config);if(S){await jc(t,e,S,`/api/admin/activity-graph/dispatch/${encodeURIComponent(v)}`);return}}k(e,404,{error:`unknown node "${T}" in fleet dispatch id`});return}}}}else if(u&&u!=="primary"){let h=lt(u,a.config);if(!h){k(e,404,{error:`unknown peer: ${u}`});return}let w=(n.search||"").replace(/[?&]peer=[^&]*/g,T=>T.startsWith("?")?"?":"");await jc(t,e,h,r+(w==="?"?"":w));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Os(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Qh(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-LRTOOCM6.js"),w=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",y=await u({running:w});k(e,200,y)}catch(u){k(e,500,{error:u?.message||String(u)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Hs({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Bs(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(zs({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(qs({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 Ih(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 pi(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await en(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await mi(t,e,r))return;let d=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(d){gi(t,e,d[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let u=t.headers.authorization||"",h=u.startsWith("Bearer ")?u.slice(7):"";if(h!==a.token){let w=new G,y=h?w.verify(h):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await cs(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){k(e,200,yr()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await Ts(t,e,r,n);return}if(await Cs(t,e,r,{people:()=>et(a.config.people),members:Pc(a.config.members.logRetentionDays),root:process.cwd(),db:()=>Je(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await gs(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await xi(t,e,r);return}if(r.startsWith("/api/admin/")){await ds(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(Qo);return}if(o==="GET"&&r.startsWith("/assets/")){let u=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(u)){k(e,400,{error:"invalid asset name"});return}let h=Jh("web/"+u);try{let w=await Vh(h),y=u.endsWith(".map")?"application/json; charset=utf-8":u.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",T=n.searchParams.has("v");e.writeHead(200,{"Content-Type":y,"Cache-Control":T?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(w)}catch{k(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let u=await Ve(a.config);k(e,200,u)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let u=n.searchParams.get("date")||new Date().toISOString().slice(0,10),h=n.searchParams.get("timezone")||"UTC",w=await Ve(a.config,{date:u,timezone:h});k(e,200,w)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(h,w,y,T)=>{let v=parseInt(n.searchParams.get(h)||"",10);return Number.isFinite(v)?Math.max(y,Math.min(T,v)):w};try{let h=await Se(a.config);k(e,200,await Pi(h,{days:u("days",30,0,180),tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",60,1,200)}))}catch(h){k(e,502,{error:h.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let u=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(u)){k(e,400,{error:"day=YYYY-MM-DD query param required"});return}let h=(w,y,T,v)=>{let A=parseInt(n.searchParams.get(w)||"",10);return Number.isFinite(A)?Math.max(T,Math.min(v,A)):y};try{let w=await Se(a.config);k(e,200,await ji(w,{day:u,tzOffsetMinutes:h("tzOffset",0,-840,840),limit:h("limit",40,1,200)}))}catch(w){k(e,502,{error:w.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}let h=n.searchParams,w;if(r==="/api/mesh/thread"){let[y,T,v]=[h.get("agent"),h.get("channel"),h.get("chat")];if(!y||!T||!v){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/thread?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(v)}&limit=${encodeURIComponent(h.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[y,T]=[h.get("kind"),h.get("key")];if(!y||!T){k(e,400,{error:"kind and key required"});return}w=`/analytics/job?kind=${encodeURIComponent(y)}&key=${encodeURIComponent(T)}&limit=${encodeURIComponent(h.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[y,T,v]=[h.get("agent"),h.get("channel"),h.get("chat")];if(!y||!T||!v){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/conversation?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(v)}&tzOffset=${encodeURIComponent(h.get("tzOffset")||"0")}`}else{let y=h.get("task");if(!y){k(e,400,{error:"task required"});return}w=`/analytics/run/${encodeURIComponent(y)}`}try{await $i(e,await Se(a.config),u,w)}catch(y){k(e,502,{error:y.message})}return}if(o==="GET"&&r==="/api/live/stream"){Oh(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task");if(!h||!w||!y){k(e,400,{error:"node, agent, task query params required"});return}await Nh(t,e,a,h,w,y);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task"),T=u.searchParams.get("limit")||"50";if(!h||!w){k(e,400,{error:"node and agent query params required"});return}await Hh(e,a,h,w,y,T);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("task"),y=u.searchParams.get("kind");if(!h||!w||y!=="cancel"&&y!=="followup"){k(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await zh(t,e,a,h,w,y);return}if(o==="POST"&&r==="/api/voice/stop"){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await Sn(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 h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:u});if(!h.ok)throw new Error(`HTTP ${h.status}`);let w=await h.json();k(e,200,w)}catch(u){k(e,502,{error:u.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:u});if(!h.ok){k(e,h.status,{error:`HTTP ${h.status}`});return}k(e,200,await h.json())}catch(u){k(e,502,{error:u.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let u=await me(t);try{let h=await Xh(a.config,u);k(e,200,h)}catch(h){k(e,502,{error:h.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let u=p[1];if(!Dh(t,e,[`agent:${u}`]))return;await Bh(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 h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/health",{headers:u,signal:AbortSignal.timeout(3e3)});if(!h.ok)throw new Error(`HTTP ${h.status}`);k(e,200,vr(await h.json()))}catch(u){k(e,502,{error:u.message||"daemon not reachable"})}return}if(r.startsWith("/api/")&&a.token){let u=t.headers.authorization||"",h=u.startsWith("Bearer ")?u.slice(7):"";if(h!==a.token){let w=new G,y=h?w.verify(h):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Mh(e,a.config,n.searchParams);return}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){k(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(await Al(t,e,r,o,Rc(a.config)))return;if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await Sn(t,e,a,u,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let h=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let w=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(A=>({name:A.name,url:A.url,token:A.token}))],y={flag:!1},T=[];t.on("close",()=>{y.flag=!0;for(let A of T)try{A.abort()}catch{}});let v=setInterval(()=>{if(!y.flag)try{e.write(`: ping
|
|
20493
|
+
`),console.log(` Boards: ${a.map(_=>_.id).join(", ")}`)),r==="127.0.0.1"&&!o?console.log(" (bound to localhost; no auth token \u2014 safe default)"):r!=="127.0.0.1"&&!o&&console.log(" \u26A0 bound to a non-loopback address without a token \u2014 writes are UNAUTHENTICATED")})}var kh=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 _h(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if((t.url||"/").split(/[?#]/)[0]!==r){k(e,404,{error:"not found"});return}if(xr(t.headers)==="foreign"&&vr(o)){k(e,403,{error:"Forbidden: request from a page on another origin"});return}if(o==="OPTIONS"){e.writeHead(204),e.end();return}if(await Zo(t,e,r,o,{nodeName:a.config.node?.name,root:process.cwd(),people:()=>et(a.config.people),members:$c(a.config.members.logRetentionDays),db:()=>Je(),linkFor:(u,h)=>wo(u,h,{gitlab:a.config.channels.gitlab?.host})})||await Cc(t,e,r,o,{nodeName:a.config.node?.name,fleet:Bc(a.config),push:Tn(a.config),announce:Ki(a.config),chat:Hc(a.config),voice:Wh(a.config),camera:Gh(a.config),places:Pc(a.config),assetLinks:()=>Ll(a.config)}))return;let s=o==="GET"?vo(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"&&kh.has(r)&&Qr("page",r),o==="GET"&&r==="/"){let u=Dr();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(nn({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ni({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(nn({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[u]=await Se(a.config);if(!u){k(e,503,{error:"no node available"});return}let h=await new Promise(y=>{let T="";t.on("data",b=>T+=b),t.on("end",()=>y(T)),t.on("error",()=>y(""))}),w=await fetch(u.url+r,{method:"POST",headers:{"Content-Type":"application/json",...u.token?{Authorization:`Bearer ${u.token}`}:{}},body:h||"{}"});e.writeHead(w.status,{"Content-Type":"application/json"}),e.end(await w.text())}catch(u){k(e,502,{error:"could not reach the node",message:String(u?.message||u)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let u=await Se(a.config),h=o==="POST"?void 0:n.searchParams.get("node"),w=o==="POST"?await me(t):void 0,y=w?.node??h,T=y?u.find(R=>R.url===y):u[0];if(!T){k(e,400,{error:"unknown node"});return}let b=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",A=await fetch(T.url+r+b,{method:o,headers:{"Content-Type":"application/json",...T.token?{Authorization:`Bearer ${T.token}`}:{}},...o==="POST"?{body:JSON.stringify({...w,node:void 0})}:{}});k(e,A.status,await A.json().catch(()=>({error:`HTTP ${A.status}`})))}catch(u){k(e,502,{error:"could not reach the node",message:u?.message||String(u)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let u=await me(t),h={"Content-Type":"application/json"};a.config.dashboard.token&&(h.Authorization=`Bearer ${a.config.dashboard.token}`);let w=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${w}/api/workflows/editor/chat`,{method:"POST",headers:h,body:JSON.stringify(u??{})}),T=await y.json().catch(()=>({error:`HTTP ${y.status}`}));k(e,y.status,T)}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[u]=await Se(a.config);if(!u){k(e,200,{configured:!1,workflows:[]});return}let h=await fetch(u.url+"/api/n8n/workflows",{headers:u.token?{Authorization:`Bearer ${u.token}`}:{}});k(e,h.status,await h.json().catch(()=>({configured:!1,workflows:[]})))}catch{k(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(lo({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(io({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(no({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let u=new AbortController,h=setTimeout(()=>u.abort(),8e3);try{let w=Vn(await Se(a.config,u.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let R=await Promise.all(w.map(async S=>{try{let L=await fetch(S.url+"/monitor",{headers:S.token?{Authorization:`Bearer ${S.token}`}:{},signal:u.signal});if(!L.ok)throw new Error(`HTTP ${L.status}`);return{name:S.name,url:S.url,ok:!0,data:await L.json()}}catch(L){return{name:S.name,url:S.url,ok:!1,error:L.message}}}));k(e,200,{nodes:R});return}let y=w.find(R=>R.url===n.searchParams.get("node"));if(!y){k(e,400,{error:"Select a known node"});return}let T=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(T)||o==="POST"&&["register","ended","action","retry","clear"].includes(T))){k(e,405,{error:"Unknown monitor operation"});return}let b=o==="POST"?JSON.stringify(await Jn(t)):void 0,A=await fetch(y.url+"/monitor/"+T+(T==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):T==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:b,signal:u.signal,headers:{"Content-Type":"application/json",...y.token?{Authorization:`Bearer ${y.token}`}:{}}});k(e,A.status,await A.json())}catch(w){k(e,502,{error:w.message})}finally{clearTimeout(h)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ri({peers:D(a.config)}));return}if(o==="GET"&&r==="/places"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ic({peers:D(a.config)}));return}if(o==="GET"&&r==="/guests"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Pi({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 h=a.config.dashboard.daemonUrl.replace(/\/+$/,""),w=o==="POST"?await me(t).catch(()=>({})):void 0,y=await fetch(`${h}${r.replace(/^\/api\/guests/,"/mesh/guests")}`,{method:o,headers:u,...w!==void 0?{body:JSON.stringify(w??{})}:{}});k(e,y.status,await y.json().catch(()=>({error:`HTTP ${y.status}`})))}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Di({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Bi({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Hi({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Nr({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let u=n.searchParams.get("agent")||"",h=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(zi({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:h,peers:D(a.config)}));return}let c=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(c){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(qi({agentId:decodeURIComponent(c[1]),agentName:n.searchParams.get("name")||void 0,nodeUrl:n.searchParams.get("node")||a.config.dashboard.daemonUrl,peers:D(a.config)}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){Br(t,e);return}if(o==="POST"&&r==="/api/setup"){await Hr(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await zr(t,e);return}if(o==="GET"&&r==="/admin"){ds(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/approvals"){Ts(e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){xs(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}Os(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 Qh(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await tn(t,e,r,w=>qc(w,a.config));return}let h=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(h){let w=decodeURIComponent(h[1]),y=w.indexOf("::");if(y>0){let T=w.slice(0,y),b=w.slice(y+2),A=a.config.node?.id||a.config.node?.name||"local";if(T===A)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(b)}`;else{let R=(a.config.dashboard?.daemons||[]).find(S=>(S.name||S.url)===T);if(R){let S=lt(R.url.replace(/\/+$/,""),a.config);if(S){await Oc(t,e,S,`/api/admin/activity-graph/dispatch/${encodeURIComponent(b)}`);return}}k(e,404,{error:`unknown node "${T}" in fleet dispatch id`});return}}}}else if(u&&u!=="primary"){let h=lt(u,a.config);if(!h){k(e,404,{error:`unknown peer: ${u}`});return}let w=(n.search||"").replace(/[?&]peer=[^&]*/g,T=>T.startsWith("?")?"?":"");await Oc(t,e,h,r+(w==="?"?"":w));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await Ns(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Zh(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:u}=await import("./doctor-G5TM5GVF.js"),w=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",y=await u({running:w});k(e,200,y)}catch(u){k(e,500,{error:u?.message||String(u)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(zs({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await Hs(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(qs({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Fs({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 Mh(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 ui(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await tn(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await fi(t,e,r))return;let d=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(d){xi(t,e,d[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let u=t.headers.authorization||"",h=u.startsWith("Bearer ")?u.slice(7):"";if(h!==a.token){let w=new G,y=h?w.verify(h):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await ps(t,e);return}if(o==="GET"&&r==="/api/admin/voice-health"){k(e,200,kr()??{checkedAt:null,missing:[]});return}if(r.startsWith("/api/admin/approvals")){await As(t,e,r,n);return}if(await Is(t,e,r,{people:()=>et(a.config.people),members:$c(a.config.members.logRetentionDays),root:process.cwd(),db:()=>Je(),peers:D(a.config),localToken:a.token}))return;if(r.startsWith("/api/admin/graph/")){await vs(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await vi(t,e,r);return}if(r.startsWith("/api/admin/")){await us(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(es);return}if(o==="GET"&&r.startsWith("/assets/")){let u=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(u)){k(e,400,{error:"invalid asset name"});return}let h=Vh("web/"+u);try{let w=await Yh(h),y=u.endsWith(".map")?"application/json; charset=utf-8":u.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",T=n.searchParams.has("v");e.writeHead(200,{"Content-Type":y,"Cache-Control":T?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(w)}catch{k(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let u=await Ve(a.config);k(e,200,u)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let u=n.searchParams.get("date")||new Date().toISOString().slice(0,10),h=n.searchParams.get("timezone")||"UTC",w=await Ve(a.config,{date:u,timezone:h});k(e,200,w)}catch(u){k(e,502,{error:u.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let u=(h,w,y,T)=>{let b=parseInt(n.searchParams.get(h)||"",10);return Number.isFinite(b)?Math.max(y,Math.min(T,b)):w};try{let h=await Se(a.config);k(e,200,await $i(h,{days:u("days",30,0,180),tzOffsetMinutes:u("tzOffset",0,-840,840),limit:u("limit",60,1,200)}))}catch(h){k(e,502,{error:h.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let u=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(u)){k(e,400,{error:"day=YYYY-MM-DD query param required"});return}let h=(w,y,T,b)=>{let A=parseInt(n.searchParams.get(w)||"",10);return Number.isFinite(A)?Math.max(T,Math.min(b,A)):y};try{let w=await Se(a.config);k(e,200,await Oi(w,{day:u,tzOffsetMinutes:h("tzOffset",0,-840,840),limit:h("limit",40,1,200)}))}catch(w){k(e,502,{error:w.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}let h=n.searchParams,w;if(r==="/api/mesh/thread"){let[y,T,b]=[h.get("agent"),h.get("channel"),h.get("chat")];if(!y||!T||!b){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/thread?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(b)}&limit=${encodeURIComponent(h.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[y,T]=[h.get("kind"),h.get("key")];if(!y||!T){k(e,400,{error:"kind and key required"});return}w=`/analytics/job?kind=${encodeURIComponent(y)}&key=${encodeURIComponent(T)}&limit=${encodeURIComponent(h.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[y,T,b]=[h.get("agent"),h.get("channel"),h.get("chat")];if(!y||!T||!b){k(e,400,{error:"agent, channel, chat required"});return}w=`/analytics/conversation?agent=${encodeURIComponent(y)}&channel=${encodeURIComponent(T)}&chat=${encodeURIComponent(b)}&tzOffset=${encodeURIComponent(h.get("tzOffset")||"0")}`}else{let y=h.get("task");if(!y){k(e,400,{error:"task required"});return}w=`/analytics/run/${encodeURIComponent(y)}`}try{await ji(e,await Se(a.config),u,w)}catch(y){k(e,502,{error:y.message})}return}if(o==="GET"&&r==="/api/live/stream"){Nh(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task");if(!h||!w||!y){k(e,400,{error:"node, agent, task query params required"});return}await Dh(t,e,a,h,w,y);return}if(o==="GET"&&r==="/api/task/history"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("agent"),y=u.searchParams.get("task"),T=u.searchParams.get("limit")||"50";if(!h||!w){k(e,400,{error:"node and agent query params required"});return}await zh(e,a,h,w,y,T);return}if(o==="POST"&&r==="/api/task/action"){let u=new URL(t.url||"/","http://localhost"),h=u.searchParams.get("node"),w=u.searchParams.get("task"),y=u.searchParams.get("kind");if(!h||!w||y!=="cancel"&&y!=="followup"){k(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await qh(t,e,a,h,w,y);return}if(o==="POST"&&r==="/api/voice/stop"){let u=new URL(t.url||"/","http://localhost").searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await En(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 h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:u});if(!h.ok)throw new Error(`HTTP ${h.status}`);let w=await h.json();k(e,200,w)}catch(u){k(e,502,{error:u.message||"agents fetch failed"})}return}if(o==="GET"&&r==="/api/business/status"){try{let u={};a.config.dashboard.token&&(u.Authorization=`Bearer ${a.config.dashboard.token}`);let h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/business/status",{headers:u});if(!h.ok){k(e,h.status,{error:`HTTP ${h.status}`});return}k(e,200,await h.json())}catch(u){k(e,502,{error:u.message||"business status fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let u=await me(t);try{let h=await Kh(a.config,u);k(e,200,h)}catch(h){k(e,502,{error:h.message||"draft failed"})}return}let p=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(p&&o==="POST"){let u=p[1];if(!Bh(t,e,[`agent:${u}`]))return;await Hh(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 h=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/health",{headers:u,signal:AbortSignal.timeout(3e3)});if(!h.ok)throw new Error(`HTTP ${h.status}`);k(e,200,wr(await h.json()))}catch(u){k(e,502,{error:u.message||"daemon not reachable"})}return}if(r.startsWith("/api/")&&a.token){let u=t.headers.authorization||"",h=u.startsWith("Bearer ")?u.slice(7):"";if(h!==a.token){let w=new G,y=h?w.verify(h):null;if(!y||!Ee(y,"dashboard:write")){k(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/mesh/feed"){await Lh(e,a.config,n.searchParams);return}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){k(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(await Cl(t,e,r,o,Pc(a.config)))return;if(o==="POST"&&(r==="/api/node/restart"||r==="/api/node/restart/cancel")){let u=n.searchParams.get("node");if(!u){k(e,400,{error:"node query param required"});return}await En(t,e,a,u,r==="/api/node/restart"?"/daemon/restart":"/daemon/restart/cancel");return}if(o==="GET"&&r==="/events"){let h=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let w=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(A=>({name:A.name,url:A.url,token:A.token}))],y={flag:!1},T=[];t.on("close",()=>{y.flag=!0;for(let A of T)try{A.abort()}catch{}});let b=setInterval(()=>{if(!y.flag)try{e.write(`: ping
|
|
20460
20494
|
|
|
20461
|
-
`)}catch{}},15e3);t.on("close",()=>clearInterval(
|
|
20495
|
+
`)}catch{}},15e3);t.on("close",()=>clearInterval(b));for(let A of w)(async()=>{let R={Accept:"text/event-stream"};A.token&&(R.Authorization=`Bearer ${A.token}`);let S=new AbortController;T.push(S);try{let L=await fetch(`${A.url.replace(/\/+$/,"")}/events${h?`?${h}`:""}`,{headers:R,signal:S.signal});if(!L.ok||!L.body)return;let j=L.body.getReader(),$=new TextDecoder,O="";for(;!y.flag;){let{done:W,value:le}=await j.read();if(W)break;O+=$.decode(le,{stream:!0});let Q;for(;(Q=O.indexOf(`
|
|
20462
20496
|
|
|
20463
20497
|
`))>=0;){let re=O.slice(0,Q);if(O=O.slice(Q+2),y.flag)break;try{e.write(re+`
|
|
20464
20498
|
|
|
20465
|
-
`)}catch{y.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let u=new URL(t.url||"/","http://localhost"),h=Math.max(1,Math.min(500,Number(u.searchParams.get("limit")||50))),w=u.searchParams.get("workflowId")||void 0,y=u.searchParams.get("summary")==="1"||u.searchParams.get("summary")==="true",T=a.workflowRuns.list({limit:h,workflowId:w}),
|
|
20466
|
-
`;
|
|
20499
|
+
`)}catch{y.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let u=new URL(t.url||"/","http://localhost"),h=Math.max(1,Math.min(500,Number(u.searchParams.get("limit")||50))),w=u.searchParams.get("workflowId")||void 0,y=u.searchParams.get("summary")==="1"||u.searchParams.get("summary")==="true",T=a.workflowRuns.list({limit:h,workflowId:w}),b=`?limit=${h}${w?`&workflowId=${encodeURIComponent(w)}`:""}${y?"&summary=1":""}`,A=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map($=>({url:$.url,token:$.token}))],R=await Promise.all(A.map(async $=>{let O={};$.token&&(O.Authorization=`Bearer ${$.token}`);try{let W=new AbortController,le=setTimeout(()=>W.abort(),5e3);try{let Q=await fetch(`${$.url.replace(/\/+$/,"")}/api/workflows/runs${b}`,{headers:O,signal:W.signal});if(!Q.ok)return[];let re=await Q.json();return Array.isArray(re.runs)?re.runs:[]}finally{clearTimeout(le)}}catch{return[]}})),S=new Map;for(let $ of T)S.set($.id,$);for(let $ of R)for(let O of $)S.set(O.id,O);let L=Array.from(S.values()).sort(($,O)=>$.updatedAt<O.updatedAt?1:-1).slice(0,h),j=y?L.map($=>Th($)):L;k(e,200,{runs:j})}catch(u){k(e,502,{error:"runs fetch failed",message:u.message||String(u)})}return}let f=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(f){let u=decodeURIComponent(f[1]),h=a.workflowRuns.get(u);if(h){k(e,200,{run:h});return}let w=[{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 w)try{let T={};y.token&&(T.Authorization=`Bearer ${y.token}`);let b=await fetch(`${y.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(u)}`,{headers:T});if(b.ok){k(e,200,await b.json());return}}catch{}k(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 h=a.config.dashboard.daemonUrl.replace(/\/+$/,""),w=await fetch(`${h}/api/actions/builtin`,{headers:u}),y=await w.json().catch(()=>({error:`HTTP ${w.status}`}));k(e,w.status,y)}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}let _=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(_){try{let u=await me(t).catch(()=>({})),h={"Content-Type":"application/json"};a.config.dashboard.token&&(h.Authorization=`Bearer ${a.config.dashboard.token}`);let w=a.config.dashboard.daemonUrl.replace(/\/+$/,""),y=await fetch(`${w}/workflows/${encodeURIComponent(_[1])}/run`,{method:"POST",headers:h,body:JSON.stringify(u??{})}),T=await y.json().catch(()=>({error:`HTTP ${y.status}`}));k(e,y.status,T)}catch(u){k(e,502,{error:"daemon unreachable",message:u.message||String(u)})}return}if(r.startsWith("/api/workflows")&&Ui(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(h,w,y)=>{if(a.token)return!0;let T=ka(h);if(!T)return!0;let b=new G().verify(T);if(!b)return k(w,401,{error:"invalid or revoked token"}),!1;for(let A of y)if(!Ee(b,A))return k(w,403,{error:`token missing scope: ${A}`,scopes:b.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){k(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 v=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(v&&o==="GET"){let u=a.sources.get(v[1]);if(!u){k(e,404,{error:"unknown board"});return}try{let h=typeof u.listMembers=="function"?await u.listMembers():[];k(e,200,h)}catch(h){k(e,502,{error:h.message})}return}let E=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(E&&o==="GET"){let u=a.sources.get(E[1]);if(!u){k(e,404,{error:"unknown board"});return}try{let h=typeof u.listMilestones=="function"?await u.listMilestones():[];k(e,200,h)}catch(h){k(e,502,{error:h.message})}return}let x=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),g=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(x&&o==="PATCH"){let[,u,h]=x,w=decodeURIComponent(h),y=a.boards.find(S=>S.id===u);if(!y){k(e,404,{error:`unknown board: ${u}`});return}let T=a.sources.get(u);if(!T){k(e,503,{error:`board "${u}" source unavailable`});return}let b=await me(t),A=y.columns.find(S=>S.id===b.to),R=y.columns.find(S=>S.id===b.from);if(!A){k(e,400,{error:`unknown 'to' column: ${b.to}`});return}try{await Eh(T,w,R,A),wn({actor:kn(t),action:"move",boardId:u,itemId:w,payload:{from:b.from,to:b.to}}),k(e,200,{ok:!0})}catch(S){k(e,502,{error:S.message||"transition failed"})}return}if(g){let[,u,h]=g,w=h?decodeURIComponent(h):void 0,y=a.boards.find(b=>b.id===u);if(!y){k(e,404,{error:`unknown board: ${u}`});return}let T=a.sources.get(u);if(!T){k(e,503,{error:`board "${u}" source unavailable`});return}if(o==="GET"&&!w){let{columns:b,totals:A}=await Sh(y,T,n.searchParams);k(e,200,{columns:b,totals:A});return}if(o==="GET"&&w){try{let b=typeof T.getItem=="function"?await T.getItem(w):null;if(!b){k(e,404,{error:"not found"});return}k(e,200,b)}catch(b){k(e,502,{error:b.message})}return}if(o==="PATCH"&&w){let b=await me(t);try{let A=typeof T.updateItem=="function"?await T.updateItem(w,b):null;if(!A){k(e,501,{error:"update unsupported"});return}wn({actor:kn(t),action:"update",boardId:u,itemId:w,payload:b}),k(e,200,A)}catch(A){k(e,502,{error:A.message})}return}if(o==="POST"&&!w){let b=await me(t);if(!b.title){k(e,400,{error:"title required"});return}if(!T.capabilities.create||!T.create){k(e,400,{error:`source ${T.type} does not support create`});return}try{let A=await T.create({title:b.title,description:b.description,labels:b.labels,assigneeUsernames:b.assigneeUsernames,milestoneTitle:b.milestoneTitle,projectHint:b.projectHint});wn({actor:kn(t),action:"create",boardId:u,itemId:A.id,payload:{title:b.title}}),k(e,201,A)}catch(A){k(e,502,{error:A.message})}return}}if(o==="GET"&&/^\/[a-z][a-z-]*\/?$/.test(r)){let u=r.replace(/^\/+|\/+$/g,""),w={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[u];if(w){e.writeHead(302,{Location:w}),e.end();return}}k(e,404,{error:"not found",path:r})}async function Sh(t,e,a){if(!e.capabilities.listAll||!e.listAll){let g={};for(let u of t.columns)g[u.id]=[];return{columns:g,totals:Object.fromEntries(t.columns.map(u=>[u.id,0]))}}let n=[];t.primaryToolLabel&&n.push(t.primaryToolLabel);let r=a.get("label")||void 0;r&&n.push(r);let o=a.get("q")||void 0,s=a.get("milestone")||void 0,i=a.get("assignee")||void 0,l=parseInt(a.get("days")||String(t.timeRangeDays),10),c=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),d=t.columns.some(g=>g.kind!=="closed"),p=t.columns.some(g=>g.kind==="closed"),m=d?await e.listAll({sinceDays:l,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],f=p?await e.listAll({sinceDays:c,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],_={};for(let g of t.columns)_[g.id]=[];let v=t.columns.find(g=>g.kind==="closed");for(let g of f)v&&_[v.id].push({...g,stage:v.id});let E=t.columns.filter(g=>g.kind!=="closed");for(let g of m){let u=In(g,E);if(!u)continue;let h=_[u];h&&h.push({...g,stage:u})}if(i)for(let g of Object.keys(_))_[g]=_[g].filter(u=>u.assignee===i);for(let g of Object.keys(_))_[g].sort((u,h)=>{let w=(u.priority??99)-(h.priority??99);return w!==0?w:(h.updatedAt||"").localeCompare(u.updatedAt||"")});let x=Object.fromEntries(Object.entries(_).map(([g,u])=>[g,u.length]));return{columns:_,totals:x}}async function Eh(t,e,a,n){let r=Mn(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 Th(t){return{id:t.id,workflowId:t.workflowId,workflowVersion:t.workflowVersion,homeNode:t.homeNode,status:t.status,pending:t.pending,entityRef:t.entityRef,history:(t.history||[]).slice(-5),parentRunId:t.parentRunId,parentNodeId:t.parentNodeId,rootRunId:t.rootRunId,depth:t.depth,createdAt:t.createdAt,updatedAt:t.updatedAt}}function Ah(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 Ar(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function wn(t){try{let e=it(process.cwd(),".agentx");Nc(e)||vh(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
|
|
20500
|
+
`;xh(it(e,"board-audit.jsonl"),a)}catch{}}function kn(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}var Ch=2e3;async function Ih(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=x=>{let g=new AbortController,u=setTimeout(()=>g.abort(),Ch),h=()=>g.abort();return a?.addEventListener("abort",h,{once:!0}),fetch(t+x,{headers:r,signal:g.signal}).then(async w=>{let y=w.ok?await w.json().catch(()=>{}):void 0;return{ok:y!==void 0,json:async()=>y}}).catch(()=>null).finally(()=>{clearTimeout(u),a?.removeEventListener("abort",h)})},[l,c,d,p,m,f,_,v]=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")]);if(!c||!c.ok)return o.error=c?`HTTP ${c.status}`:"unreachable",o;let E=await c.json();if(o.agents=E.map(x=>({id:x.id,name:x.name,tier:x.tier,model:x.model,...typeof x.color=="string"&&/^#[0-9a-fA-F]{6}$/.test(x.color)?{color:x.color}:{},skillCount:Number.isFinite(x.skillCount)?x.skillCount:void 0,active:x.active||0,total:x.total||0,errors:x.errors||0,lastActive:x.lastActive,lastSummary:x.lastSummary,hourlyTasks:Array.isArray(x.hourlyTasks)?x.hourlyTasks:void 0,runningTasks:Array.isArray(x.runningTasks)?x.runningTasks:[]})),l&&l.ok){let x=await l.json().catch(()=>({}));o.uptimeSec=x.uptime,typeof x.inflight?.total=="number"&&(o.inflight=x.inflight.total),x.restart&&typeof x.restart.state=="string"&&(o.restart=x.restart),o.name=x.node?.name||x.node?.id||t,o.id=x.node?.id||t,x.usage&&(o.usage=x.usage)}if(p&&p.ok){let x=await p.json().then(g=>Array.isArray(g)?g:[],()=>[]);o.crons=x.map(g=>({id:g.id,enabled:g.enabled===!0,schedule:String(g.schedule||""),timezone:g.timezone,agent:String(g.agent||""),kind:typeof g.command=="string"&&g.command.trim()?"command":"agent",model:g.model,nextRun:g.nextRun,retryPending:g.retryPending===!0,consecutiveErrors:Number(g.consecutiveErrors)||0}))}if(m&&m.ok){let x=await m.json().catch(()=>({}));o.cronRuns=Array.isArray(x.runs)?x.runs:[]}if(_&&_.ok){let x=await _.json().catch(()=>null);x&&Array.isArray(x.routines)&&(o.routines=x.routines.slice(0,Zn.routines))}if(f&&f.ok){let x=await f.json().catch(()=>null);x?.active&&x.kind==="lesson"&&(o.lesson={agentId:x.agentId??null,mode:String(x.mode||"teach"),goal:String(x.goal||""),step:Number(x.step)||0,saying:String(x.saying||""),startedAt:String(x.startedAt||"")})}if(v&&v.ok){let x=await v.json().catch(()=>null);x&&Array.isArray(x.sessions)&&Oh(o,x.sessions,x.saved??{})}o.reachable=!0,o._peers=Array.isArray(d?.ok?await d.json():null)?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var ca=null;function Mh(t){if(ca)return ca;let e=it(process.cwd(),".agentx/wiki");return ca=to({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),ca}async function pa(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 Lh(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){k(t,502,{error:`daemon answered ${s.status}`});return}let i=await s.json();k(t,200,{node:e.node.name||e.node.id,events:i.events??[]})}catch(s){k(t,502,{error:s.message||"daemon unreachable"})}}async function Se(t,e){let a=t.dashboard,n=a.daemonUrl.replace(/\/+$/,""),r=U(a,n),o=new Map;o.set(n,{name:"primary",url:n,token:r});for(let i of a.daemons){let l=i.url.replace(/\/+$/,"");o.has(l)||o.set(l,{name:i.name,url:l,token:U(a,l)})}let s=await pa(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 Rh=3e3,Ph=6e3,$h=5*6e4,Sn=new Map,da=new Map;function Ve(t,e){let a=e?`${e.date}|${e.timezone}`:"live",n=da.get(a);if(n)return n;let r=(async()=>{let o=await Se(t,AbortSignal.timeout(Rh)),s=await Promise.all(o.map(async i=>{let l=await Ih(i.url,i.token,AbortSignal.timeout(Ph),e);return e?l:jh(i.url,l)}));return{ts:new Date().toISOString(),nodes:s}})().finally(()=>da.delete(a));return da.set(a,r),r}function jh(t,e,a=Date.now()){if(e.reachable&&!e.error)return Sn.set(t,{node:e,at:a}),e;let n=Sn.get(t);return!n||a-n.at>$h?e:{...n.node,stale:!0,staleSince:new Date(n.at).toISOString(),error:e.error}}function M0(){Sn.clear(),da.clear()}function Oh(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 Nh(t,e,a){e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let n=!1,r=(l,c)=>{n||e.write(`event: ${l}
|
|
20467
20501
|
data: ${JSON.stringify(c)}
|
|
20468
20502
|
|
|
20469
|
-
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await Ve(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
|
|
20470
|
-
${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
|
|
20503
|
+
`)},o=!1,s=async()=>{if(!o){o=!0;try{let l=await Ve(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 Dh(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),i=new Set;i.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let _ of a.config.dashboard.daemons)i.add(_.url.replace(/\/+$/,""));try{let _=await pa(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let v of _)i.add(v.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){k(e,403,{error:"node not in dashboard allowlist",target:s});return}let l=U(a.config.dashboard,s),c={Accept:"text/event-stream"};l&&(c.Authorization=`Bearer ${l}`);let d=new AbortController,p;try{p=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:c,signal:d.signal})}catch(_){k(e,502,{error:_.message||"upstream connect failed"});return}if(!p.ok||!p.body){k(e,p.status||502,{error:`upstream HTTP ${p.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","X-Accel-Buffering":"no"});let m=p.body.getReader();(async()=>{try{for(;;){let{value:_,done:v}=await m.read();if(v)break;_&&e.write(_)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{d.abort();try{e.end()}catch{}})}function Bh(t,e,a){let n=ka(t);if(!n)return k(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new G().verify(n);if(!r)return k(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!Ee(r,o))return k(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function Hh(t,e,a,n){let r=a.agents?.[n];if(!r){k(e,404,{error:"unknown agent"});return}if(r.access!=="public"){k(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await me(t)}catch{k(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){k(e,400,{error:"required: { message: string, context?: {...} }"});return}let i=a.dashboard.daemonUrl.replace(/\/+$/,""),l={"Content-Type":"application/json"};a.dashboard.token&&(l.Authorization=`Bearer ${a.dashboard.token}`);try{let c=await fetch(`${i}/task`,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),d=await c.text();e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8"}),e.end(d)}catch(c){k(e,502,{error:c.message||"upstream call failed"})}}async function zh(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),i=new Set;i.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let p of e.config.dashboard.daemons)i.add(p.url.replace(/\/+$/,""));try{let p=await pa(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let m of p)i.add(m.url.replace(/\/+$/,""))}catch{}if(!i.has(s)){k(t,403,{error:"node not in dashboard allowlist",target:s});return}let l=U(e.config.dashboard,s),c={Accept:"application/json"};l&&(c.Authorization=`Bearer ${l}`);let d=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let p=await fetch(`${s}${d}`,{headers:c}),m=await p.text();t.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json; charset=utf-8"}),t.end(m)}catch(p){k(t,502,{error:p.message||"upstream fetch failed"})}}async function qh(t,e,a,n,r,o){await En(t,e,a,n,`/api/tasks/${encodeURIComponent(r)}/${o}`)}async function En(t,e,a,n,r){let o={};try{o=await me(t)??{}}catch{}let s=await Dc(a.config,n,r,o);e.writeHead(s.status,{"Content-Type":s.contentType}),e.end(s.text)}async function Dc(t,e,a,n){let r=(c,d)=>({status:c,text:JSON.stringify(d),contentType:"application/json"}),o=e.replace(/\/+$/,""),s=new Set;s.add(t.dashboard.daemonUrl.replace(/\/+$/,""));for(let c of t.dashboard.daemons)s.add(c.url.replace(/\/+$/,""));try{let c=await pa(t.dashboard.daemonUrl.replace(/\/+$/,""),t.dashboard.token);for(let d of c)s.add(d.url.replace(/\/+$/,""))}catch{}if(!s.has(o))return r(403,{error:"node not in dashboard allowlist",target:o});let i=U(t.dashboard,o),l={"Content-Type":"application/json",Accept:"application/json"};i&&(l.Authorization=`Bearer ${i}`);try{let c=await fetch(`${o}${a}`,{method:"POST",headers:l,body:JSON.stringify(n??{})});return{status:c.status,text:await c.text(),contentType:c.headers.get("content-type")||"application/json; charset=utf-8"}}catch(c){return r(502,{error:c.message||"upstream fetch failed"})}}function Tn(t){let e=t.channels.push,a=r=>({store:()=>null,publicKey:()=>null,keepRecent:0,allowedHosts:[],reason:r});if(!e.enabled)return a("Notifications are off. On the computer, run: agentx notifications push --enable");if(e.relayTo){let r=t.dashboard.daemonUrl.replace(/\/+$/,""),o=process.env.MESH_TOKEN||U(t.dashboard,r);return wt(),{...a(`Can't reach ${e.relayTo}, the computer that sends notifications`),async forward(s){let i=await fetch(`${r}/push/app`,{method:"POST",headers:{"Content-Type":"application/json",...o?{Authorization:`Bearer ${o}`}:{}},body:JSON.stringify({op:"app",call:s}),signal:AbortSignal.timeout(2e4)}),l=await i.json().catch(()=>({}));if(!i.ok||typeof l.status!="number")throw new Error(l.error||`the daemon answered ${i.status}`);return{status:l.status,body:l.body??{}}}}}let n=ir(e.keysFile);return{store:()=>{let r=Je();return r?new Pr(r):null},publicKey:()=>lr(n)?.publicKey??null,keepRecent:e.keepRecent,allowedHosts:e.allowedHosts,reason:"The database on this computer is unavailable, so notifications can't be saved."}}function Pc(t){let e=t.channels.push,a=t.dashboard.daemonUrl.replace(/\/+$/,""),n=e.enabled&&!e.relayTo?Tl({url:a,token:U(t.dashboard,a),operatorKey:xa(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}.`:Tn(t).reason;return Ml(t,process.cwd(),n,r)}function Bc(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=n=>{try{return JSON.parse(n)}catch{return{error:n.slice(0,200)}}};return{snapshot:n=>Ve(t,n),async nodePost(n,r,o){let s=await Dc(t,n,r,o);return{status:s.status,body:a(s.text)}},async approvals(){let n={node:e,nodeName:t.node?.name||"this computer",items:[]};try{n.items=Et({root:process.cwd()}).items.map(jc)}catch(o){n.error=o.message}let r=await Promise.all(t.dashboard.daemons.map(async o=>{let s={node:o.url.replace(/\/+$/,""),nodeName:o.name,items:[]},i=lt(o.url,t);if(!i)return s;try{let l=await fetch(`${i.url}/api/admin/approvals`,{headers:{"X-Agentx-Peer":"primary",...i.token?{Authorization:`Bearer ${i.token}`}:{}},signal:AbortSignal.timeout(4e3)});if(!l.ok)return s.error=`HTTP ${l.status}`,s;let c=await l.json();s.items=(c.items??[]).map(jc)}catch(l){s.error=l.message||"unreachable"}return s}));return[n,...r]},async decide(n,r,o,s,i={}){let l=n.replace(/\/+$/,"");if(l===e){let d=Ae(),p=await Tt({root:process.cwd()},r,o,{laterHours:d.laterHours,by:s,...i});return p.ok?{status:200,body:{ok:!0,message:p.message}}:{status:409,body:{error:p.error}}}let c=lt(l,t);if(!c)return{status:403,body:{error:"node not in dashboard allowlist",target:l}};try{let d=await fetch(`${c.url}/api/admin/approvals/decide`,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"agentx-board","X-Agentx-Peer":"primary",...c.token?{Authorization:`Bearer ${c.token}`}:{}},body:JSON.stringify({key:r,action:o,...i}),signal:AbortSignal.timeout(1e4)});return{status:d.status,body:a(await d.text())}}catch(d){return{status:502,body:{error:d.message||"peer dashboard unreachable"}}}}}}var _n=null;function $c(t){return _n?.days!==t&&(_n={days:t,store:new ht(process.cwd(),Date.now,t)}),_n.store}function Hc(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,""),a=U(t.dashboard,e),n=Bc(t);return{store:()=>{let r=Je();return r?new st(r):null},daemon:{url:e,token:a,name:t.node?.name,operatorKey:xa(process.cwd())??void 0},snapshot:()=>Ve(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(/\/+$/,"")),...Fh(t,e,a)}}function Fh(t,e,a){let n=Tn(t);return{finishAlerts:r=>{if(n.forward)return sr.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}
|
|
20504
|
+
${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 Uh(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=Hc(t);return new la({recent:async(o,s)=>{let i=new URLSearchParams({kind:"delegation",limit:String(s)});o&&i.set("since",o);let l=await fetch(`${e}/events/recent?${i}`,{headers:n(e),signal:AbortSignal.timeout(5e3)});if(!l.ok)throw new Error(`the daemon answered ${l.status}`);let c=await l.json();return{events:Array.isArray(c.events)?c.events:[],gap:c.gap===!0}},nodeUrl:async o=>{let i=(await Ve(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:nl(),finishAlerts:r.finishAlerts,notifyFinish:r.notifyFinish,log:o=>console.log(o),warn:o=>console.warn(o)})}function Wh(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{store:()=>{let a=Je();return a?new st(a):null},daemon:{url:e,token:U(t.dashboard,e)}}}function Gh(t){let e=t.dashboard.daemonUrl.replace(/\/+$/,"");return{daemon:{url:e,token:U(t.dashboard,e)},nodeName:t.node.name}}function jc(t){return{key:t.key,title:t.title,ask:t.ask,recommend:t.recommend,yes:t.yes,no:t.no,raisedBy:t.raised_by,expires:t.expires,...t.choices?{choices:t.choices}:{},...t.draft?{draft:t.draft}:{}}}var Xh=`
|
|
20471
20505
|
You are helping draft a new GitLab issue. Follow these conventions strictly.
|
|
20472
20506
|
|
|
20473
20507
|
Title pattern:
|
|
@@ -20499,10 +20533,10 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
|
|
|
20499
20533
|
Shape:
|
|
20500
20534
|
{ "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
|
|
20501
20535
|
If you don't have enough information to pick a label confidently, omit it rather than guessing.
|
|
20502
|
-
`;async function
|
|
20536
|
+
`;async function Kh(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):
|
|
20503
20537
|
- ${r.knownLabels.slice(0,60).join(`
|
|
20504
20538
|
- `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
|
|
20505
|
-
`),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:
|
|
20539
|
+
`),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:Xh}})});if(!l.ok)throw new Error(`daemon /task HTTP ${l.status}: ${await l.text().catch(()=>"")}`);let c=await l.json();if(c.error)throw new Error(String(c.error));let d=(c.content||"").toString(),p=Jh(d);if(!p||typeof p.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+d.slice(0,400));let m=Array.isArray(p.labels)?p.labels.filter(f=>typeof f=="string"):[];return r.primaryLabel&&!m.includes(r.primaryLabel)&&m.unshift(r.primaryLabel),r.columnLabel&&!m.includes(r.columnLabel)&&m.unshift(r.columnLabel),{title:p.title.trim(),description:(p.description||"").toString(),labels:m,assigneeUsername:typeof p.assigneeUsername=="string"?p.assigneeUsername:void 0,kind:typeof p.kind=="string"?p.kind:void 0,raw:d}}function Jh(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 Vh(t){let e=wh(yh(import.meta.url));return it(e,t)}async function Yh(t){return bh(t)}function k(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function me(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 zc(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:zc(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 Qh(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;k(e,200,await ea(await qc(r,a.config)))}async function qc(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=en(t);r&&n.push({nodeId:a,snap:r});let o=(e.dashboard?.daemons||[]).filter(i=>i.url),s=await Promise.all(o.map(async i=>{let l=lt(i.url.replace(/\/+$/,""),e);if(!l)return null;try{let c=new AbortController,d=setTimeout(()=>c.abort(),8e3);try{let p=await fetch(`${l.url}/api/admin/activity-graph?hours=${t}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...l.token?{Authorization:`Bearer ${l.token}`}:{}},signal:c.signal});return p.ok?{nodeId:i.name||i.url,snap:await p.json()}:null}finally{clearTimeout(d)}}catch{return null}}));for(let i of s)i&&n.push(i);return ci(n)}async function Zh(t,e){let{spawn:a,execSync:n}=await import("child_process"),r,o;try{n("which journalctl",{stdio:"pipe"}),r="journalctl",o=["-u","agentx","--no-pager","-n","200","-f","-o","cat"]}catch{let p=process.env.HOME||"",m=[p&&`${p}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),f=m.find(_=>Nc(_));if(!f){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",f]}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}
|
|
20506
20540
|
|
|
20507
20541
|
`);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),i="",l=p=>{i+=p.toString("utf8");let m;for(;(m=i.indexOf(`
|
|
20508
20542
|
`))>=0;){let f=i.slice(0,m).replace(/\r$/,"");i=i.slice(m+1);try{e.write(`event: line
|
|
@@ -20510,5 +20544,5 @@ data: ${f.replace(/\n/g," ")}
|
|
|
20510
20544
|
|
|
20511
20545
|
`)}catch{}}};s.stdout?.on("data",l),s.stderr?.on("data",l);let c=setInterval(()=>{try{e.write(`: hb
|
|
20512
20546
|
|
|
20513
|
-
`)}catch{}},15e3),d=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",d),s.on("exit",d),s.on("error",d)}async function
|
|
20514
|
-
//# sourceMappingURL=board-dashboard-
|
|
20547
|
+
`)}catch{}},15e3),d=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",d),s.on("exit",d),s.on("error",d)}async function Oc(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),i=o!=="GET"&&o!=="HEAD"?await new Promise((p,m)=>{let f=[];t.on("data",_=>f.push(_)),t.on("end",()=>p(Buffer.concat(f))),t.on("error",m)}):void 0,l={},c=t.headers["content-type"];c&&(l["Content-Type"]=Array.isArray(c)?c[0]:c);let d=t.headers["x-requested-with"];d&&(l["X-Requested-With"]=Array.isArray(d)?d[0]:d),a.token&&(l.Authorization=`Bearer ${a.token}`),l["X-Agentx-Peer"]="primary";try{let p=await fetch(r,{method:o,headers:l,body:i&&i.length>0?i:void 0}),m=Buffer.from(await p.arrayBuffer());e.writeHead(p.status,{"Content-Type":p.headers.get("content-type")||"application/json","Cache-Control":"no-store"}),e.end(m)}catch(p){k(e,502,{error:`proxy to peer failed: ${p?.message||p}`,target:r})}}function lt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:zc(n),token:n.dashboardToken||n.token}:null}export{Oh as applyAttachSessions,Ih as fetchDaemonAgents,_h as handleBoardRequest,M0 as resetLiveCaches,Se as resolveNodeTargets,I0 as startBoardDashboard,jh as withLastGood};
|
|
20548
|
+
//# sourceMappingURL=board-dashboard-ZDJ4UDW4.js.map
|