agentix-cli 0.30.0 → 0.31.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-IEQXWJ7B.js → App-6TP7YMQ3.js} +2 -2
- package/dist/{ChatApp-NWOSAP5U.js → ChatApp-G2MQUBR3.js} +2 -2
- package/dist/{agent-SPE7Q7MD.js → agent-A5G4DGVU.js} +2 -2
- package/dist/{board-dashboard-K4DM32SO.js → board-dashboard-BU6QJK6X.js} +192 -171
- package/dist/board-dashboard-BU6QJK6X.js.map +1 -0
- package/dist/{chunk-DI7FMCDK.js → chunk-2J3NV6RZ.js} +2 -2
- package/dist/{chunk-UCQ2N3KO.js → chunk-2TJ5L7CB.js} +2 -2
- package/dist/{chunk-FKBGJYWQ.js → chunk-3RHPZXCR.js} +2 -2
- package/dist/{chunk-AUNDQPDR.js → chunk-6DD4DA2L.js} +2 -2
- package/dist/{chunk-52ZPELD2.js → chunk-7CVJ4JOE.js} +2 -2
- package/dist/{chunk-IVQO43U2.js → chunk-7JWYLSFF.js} +2 -2
- package/dist/{chunk-GUBMLV34.js → chunk-7MNXKITO.js} +8 -8
- package/dist/chunk-7MNXKITO.js.map +1 -0
- package/dist/{chunk-45BLFNDG.js → chunk-COOJI5SR.js} +37 -37
- package/dist/chunk-COOJI5SR.js.map +1 -0
- package/dist/{chunk-JKYMXLYL.js → chunk-DLOYTMYZ.js} +2 -2
- package/dist/{chunk-SC5DIKBB.js → chunk-FFDXDUVQ.js} +2 -2
- package/dist/{chunk-MGNJWBVP.js → chunk-JC6ZHSTY.js} +2 -2
- package/dist/{chunk-MGNJWBVP.js.map → chunk-JC6ZHSTY.js.map} +1 -1
- package/dist/{chunk-UU4WOZNR.js → chunk-JJIYFBDH.js} +2 -2
- package/dist/{chunk-EL3J74N2.js → chunk-JV52UMCI.js} +2 -2
- package/dist/{chunk-Q7CZIRBB.js → chunk-NZ346QCV.js} +2 -2
- package/dist/{chunk-M4AMWP3H.js → chunk-QLTM3F7M.js} +17 -8
- package/dist/{chunk-M4AMWP3H.js.map → chunk-QLTM3F7M.js.map} +1 -1
- package/dist/{chunk-4KXBUORV.js → chunk-R7WLFEW3.js} +2 -2
- package/dist/{chunk-GK7XAM3D.js → chunk-UOGDSRG3.js} +2 -2
- package/dist/{chunk-IWMW5432.js → chunk-V7FYSZSV.js} +1 -1
- package/dist/{chunk-IWMW5432.js.map → chunk-V7FYSZSV.js.map} +1 -1
- package/dist/chunk-VMDA2SX2.js +43 -0
- package/dist/chunk-VMDA2SX2.js.map +1 -0
- package/dist/{chunk-V4HURNMX.js → chunk-W6HKWISZ.js} +2 -2
- package/dist/{chunk-GMNKJXTR.js → chunk-Z3RKXKE2.js} +2 -2
- package/dist/{chunk-GMNKJXTR.js.map → chunk-Z3RKXKE2.js.map} +1 -1
- package/dist/{chunk-42DCRKUD.js → chunk-ZZQMR526.js} +12 -12
- package/dist/cli.js +1 -1
- package/dist/client-QALLJG62.js +2 -0
- package/dist/config-TNNODULV.js +2 -0
- package/dist/config-mutator-RI77M5YT.js +2 -0
- package/dist/doctor-DW27MR2T.js +2 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +1 -1
- package/dist/processes-I3XAPHG7.js +2 -0
- package/dist/program-WZ3GEOXO.js +2 -0
- package/dist/query-7X6VO5VU.js +2 -0
- package/dist/{registry-EJRWAJYG.js → registry-LUMYXZ6F.js} +2 -2
- package/dist/request-planner-RNQB4L6F.js +2 -0
- package/dist/request-planner-RNQB4L6F.js.map +1 -0
- package/dist/{review-candidates-O2PS7L3B.js → review-candidates-ZX4JBWQL.js} +2 -2
- package/dist/{routing-5K7PGHPL.js → routing-5VGXQ4VG.js} +2 -2
- package/dist/scheduler-W5C43ZTE.js +2 -0
- package/dist/{seat-FZRNRAHQ.js → seat-SXPFROXT.js} +2 -2
- package/dist/{select-SOJYFAMI.js → select-GJ47QACY.js} +2 -2
- package/dist/{surface-usage-NS74AXSE.js → surface-usage-UREILT2E.js} +2 -2
- package/dist/web/activity-graph.global.js +901 -368
- package/dist/web/activity-graph.global.js.map +1 -1
- package/dist/wiki-SRH3JKI4.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-K4DM32SO.js.map +0 -1
- package/dist/chunk-45BLFNDG.js.map +0 -1
- package/dist/chunk-4BR7D2OU.js +0 -36
- package/dist/chunk-4BR7D2OU.js.map +0 -1
- package/dist/chunk-GUBMLV34.js.map +0 -1
- package/dist/client-5Z3URGPY.js +0 -2
- package/dist/config-ORSGLVRW.js +0 -2
- package/dist/config-mutator-JB3S2E7H.js +0 -2
- package/dist/doctor-FS2BX6H4.js +0 -2
- package/dist/processes-WU23U2OJ.js +0 -2
- package/dist/program-DWZAI4GY.js +0 -2
- package/dist/query-3HXGBKGM.js +0 -2
- package/dist/request-planner-BCOXUAPA.js +0 -2
- package/dist/request-planner-BCOXUAPA.js.map +0 -1
- package/dist/scheduler-DSAOMV4O.js +0 -2
- package/dist/wiki-34XVI32N.js +0 -2
- /package/dist/{App-IEQXWJ7B.js.map → App-6TP7YMQ3.js.map} +0 -0
- /package/dist/{ChatApp-NWOSAP5U.js.map → ChatApp-G2MQUBR3.js.map} +0 -0
- /package/dist/{agent-SPE7Q7MD.js.map → agent-A5G4DGVU.js.map} +0 -0
- /package/dist/{chunk-DI7FMCDK.js.map → chunk-2J3NV6RZ.js.map} +0 -0
- /package/dist/{chunk-UCQ2N3KO.js.map → chunk-2TJ5L7CB.js.map} +0 -0
- /package/dist/{chunk-FKBGJYWQ.js.map → chunk-3RHPZXCR.js.map} +0 -0
- /package/dist/{chunk-AUNDQPDR.js.map → chunk-6DD4DA2L.js.map} +0 -0
- /package/dist/{chunk-52ZPELD2.js.map → chunk-7CVJ4JOE.js.map} +0 -0
- /package/dist/{chunk-IVQO43U2.js.map → chunk-7JWYLSFF.js.map} +0 -0
- /package/dist/{chunk-JKYMXLYL.js.map → chunk-DLOYTMYZ.js.map} +0 -0
- /package/dist/{chunk-SC5DIKBB.js.map → chunk-FFDXDUVQ.js.map} +0 -0
- /package/dist/{chunk-UU4WOZNR.js.map → chunk-JJIYFBDH.js.map} +0 -0
- /package/dist/{chunk-EL3J74N2.js.map → chunk-JV52UMCI.js.map} +0 -0
- /package/dist/{chunk-Q7CZIRBB.js.map → chunk-NZ346QCV.js.map} +0 -0
- /package/dist/{chunk-4KXBUORV.js.map → chunk-R7WLFEW3.js.map} +0 -0
- /package/dist/{chunk-GK7XAM3D.js.map → chunk-UOGDSRG3.js.map} +0 -0
- /package/dist/{chunk-V4HURNMX.js.map → chunk-W6HKWISZ.js.map} +0 -0
- /package/dist/{chunk-42DCRKUD.js.map → chunk-ZZQMR526.js.map} +0 -0
- /package/dist/{client-5Z3URGPY.js.map → client-QALLJG62.js.map} +0 -0
- /package/dist/{config-ORSGLVRW.js.map → config-TNNODULV.js.map} +0 -0
- /package/dist/{config-mutator-JB3S2E7H.js.map → config-mutator-RI77M5YT.js.map} +0 -0
- /package/dist/{doctor-FS2BX6H4.js.map → doctor-DW27MR2T.js.map} +0 -0
- /package/dist/{processes-WU23U2OJ.js.map → processes-I3XAPHG7.js.map} +0 -0
- /package/dist/{program-DWZAI4GY.js.map → program-WZ3GEOXO.js.map} +0 -0
- /package/dist/{query-3HXGBKGM.js.map → query-7X6VO5VU.js.map} +0 -0
- /package/dist/{registry-EJRWAJYG.js.map → registry-LUMYXZ6F.js.map} +0 -0
- /package/dist/{review-candidates-O2PS7L3B.js.map → review-candidates-ZX4JBWQL.js.map} +0 -0
- /package/dist/{routing-5K7PGHPL.js.map → routing-5VGXQ4VG.js.map} +0 -0
- /package/dist/{scheduler-DSAOMV4O.js.map → scheduler-W5C43ZTE.js.map} +0 -0
- /package/dist/{seat-FZRNRAHQ.js.map → seat-SXPFROXT.js.map} +0 -0
- /package/dist/{select-SOJYFAMI.js.map → select-GJ47QACY.js.map} +0 -0
- /package/dist/{surface-usage-NS74AXSE.js.map → surface-usage-UREILT2E.js.map} +0 -0
- /package/dist/{wiki-34XVI32N.js.map → wiki-SRH3JKI4.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as Bt}from"./chunk-3RHPZXCR.js";import{a as T,b as zt,c as qt,d as Ft,e as Ut,f as ae,g as ve,h as Ke,i as Gt}from"./chunk-NZ346QCV.js";import{a as Wt}from"./chunk-2TJ5L7CB.js";import{a as me,c as M,d as P,i as Me,j as Ie,k as J,l as q,m as $e,n as Ot,o as Ht,p as Nt}from"./chunk-7CVJ4JOE.js";import{a as Mt,c as _e,d as Xe,e as It,m as Lt,o as ue,p as Ee,q as Se,r as Te,s as Ce,t as Rt,u as Pt,v as Dt,w as Ae}from"./chunk-F6CNF7V3.js";import{g as Ct,h as At}from"./chunk-JV52UMCI.js";import{a as $t,b as jt}from"./chunk-V7FYSZSV.js";import{a as _t,b as We,c as Ge,g as Et,h as St,i as Tt}from"./chunk-7JWYLSFF.js";import"./chunk-VMDA2SX2.js";import"./chunk-QLTM3F7M.js";import"./chunk-R7WLFEW3.js";import"./chunk-AFRHKA7B.js";import"./chunk-FFDXDUVQ.js";import{b as kt}from"./chunk-6DD4DA2L.js";import"./chunk-PNWNVOEZ.js";import"./chunk-64P4QHSZ.js";import"./chunk-AJ5RMU7X.js";import"./chunk-EVWEG3VD.js";import"./chunk-JC6ZHSTY.js";import"./chunk-ZTEU5JVQ.js";import"./chunk-AJONZWLT.js";import"./chunk-F4HZTZHW.js";import"./chunk-QOYAX2FT.js";import"./chunk-LCIREYTD.js";import"./chunk-L2WSPY6S.js";import{a as yt,b as wt,c as Sn,g as K,j as Ue}from"./chunk-Z3RKXKE2.js";import"./chunk-BH3GTCZ6.js";import"./chunk-FIOB3MEX.js";function Je(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 Xt(t,e,a=Date.now()){return t.map((n,r)=>({i:r,s:Je(n,e,a).score})).sort((n,r)=>r.s-n.s||n.i-r.i).map(n=>n.i)}var V={refresh:'<path d="M21 2v6h-6"/><path d="M3 12a9 9 0 0 1 15-6.7L21 8"/><path d="M3 22v-6h6"/><path d="M21 12a9 9 0 0 1-15 6.7L3 16"/>',clock:'<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>',alert:'<path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z"/><path d="M12 9v4"/><path d="M12 17h.01"/>',gavel:'<path d="M12 3 6 9"/><path d="m9 6 6 6"/><path d="M15 9 9 15"/><path d="m12 12 6 6"/><path d="M4 21h10"/>',loop:'<path d="M17 2l4 4-4 4"/><path d="M3 11V9a4 4 0 0 1 4-4h14"/><path d="M7 22l-4-4 4-4"/><path d="M21 13v2a4 4 0 0 1-4 4H3"/>',broom:'<path d="M3 21h18"/><path d="M12 3v9"/><path d="m7 12 5-3 5 3-1.5 6h-7Z"/>',server:'<rect x="2" y="3" width="20" height="7" rx="2"/><rect x="2" y="14" width="20" height="7" rx="2"/><path d="M6 6.5h.01"/><path d="M6 17.5h.01"/>',inbox:'<path d="M21 12h-6l-2 3h-2l-2-3H3"/><path d="M5 5h14l2 7v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-5Z"/>',cross:'<circle cx="12" cy="12" r="9"/><path d="m15 9-6 6"/><path d="m9 9 6 6"/>',file:'<path d="M14 2H7a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7Z"/><path d="M14 2v5h5"/>',search:'<circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/>',chev:'<path d="m6 9 6 6 6-6"/>',chevr:'<path d="m9 6 6 6-6 6"/>',ext:'<path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/>',pulse:'<path d="M3 12h4l3-8 4 16 3-8h4"/>',plug:'<path d="M9 2v6"/><path d="M15 2v6"/><path d="M6 8h12v3a6 6 0 0 1-12 0Z"/><path d="M12 17v5"/>',check:'<path d="M20 6 9 17l-5-5"/>',route:'<circle cx="6" cy="19" r="3"/><circle cx="18" cy="5" r="3"/><path d="M9 19h6a4 4 0 0 0 0-8H9a4 4 0 0 1 0-8h6"/>',branch:'<circle cx="6" cy="6" r="3"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="8" r="3"/><path d="M18 11v1a3 3 0 0 1-3 3H9"/><path d="M6 9v6"/>',send:'<path d="M22 2 11 13"/><path d="M22 2l-7 20-4-9-9-4Z"/>',msg:'<path d="M21 11.5a8.4 8.4 0 0 1-12.9 7.5L3 21l2-5.1A8.4 8.4 0 1 1 21 11.5Z"/>',code:'<path d="m9 18-6-6 6-6"/><path d="m15 6 6 6-6 6"/>',hash:'<path d="M4 9h16"/><path d="M4 15h16"/><path d="M10 3 8 21"/><path d="M16 3l-2 18"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',trace:'<path d="M4 4v16h16"/><path d="m7 15 4-4 3 3 5-6"/>'},de=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",je=(t,e,a,n="")=>'<div class="ax-sec-label"><h3>'+de(t,13)+e+(a?'<span class="ax-sec-label__n" id="'+a+'"></span>':"")+"</h3>"+n+"</div>";function Kt(t={}){return M({title:"AgentX \xB7 Monitor",activeTab:"monitor",subtitle:"Monitor",peers:t.peers,body:`<div class="bf">
|
|
2
2
|
|
|
3
3
|
<div class="bf-head">
|
|
4
4
|
<div>
|
|
@@ -7,8 +7,8 @@ import{a as Lt}from"./chunk-FKBGJYWQ.js";import{a as T,b as Rt,c as Pt,d as Dt,e
|
|
|
7
7
|
</div>
|
|
8
8
|
<div class="bf-sync">
|
|
9
9
|
<span class="bf-sync__t" id="synced">Gathering…</span>
|
|
10
|
-
<a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${
|
|
11
|
-
<button class="ax-btn" id="refresh" title="Refresh now">${
|
|
10
|
+
<a class="ax-btn ax-btn--sm" href="/activity" title="What ran, and when">${de(V.pulse,13)} Activity</a>
|
|
11
|
+
<button class="ax-btn" id="refresh" title="Refresh now">${de(V.refresh)} Refresh</button>
|
|
12
12
|
</div>
|
|
13
13
|
</div>
|
|
14
14
|
|
|
@@ -21,24 +21,24 @@ import{a as Lt}from"./chunk-FKBGJYWQ.js";import{a as T,b as Rt,c as Pt,d as Dt,e
|
|
|
21
21
|
|
|
22
22
|
<div class="bf-grid">
|
|
23
23
|
<section class="bf-col">
|
|
24
|
-
${
|
|
24
|
+
${je(V.alert,"Only you","you-count",'<span class="bf-why">needs your authority, your relationship, or something the system cannot know</span><button class="ax-btn ax-btn--sm" id="clear-actions" title="Mark every open action done on every node">Clear all</button>')}
|
|
25
25
|
<div id="you" class="bf-col"></div>
|
|
26
26
|
|
|
27
|
-
${
|
|
27
|
+
${je(V.plug,"Agents can handle","agents-count",'<span class="bf-why">no human needed — not yet automatic</span>')}
|
|
28
28
|
<div id="agents" class="bf-col"></div>
|
|
29
29
|
<button class="ax-btn ax-btn--sm" id="more-actions" hidden></button>
|
|
30
30
|
|
|
31
31
|
<div id="handled"></div>
|
|
32
32
|
</section>
|
|
33
33
|
<aside class="bf-col">
|
|
34
|
-
${
|
|
34
|
+
${je(V.pulse,"In motion","run-count")}
|
|
35
35
|
<div id="running" class="bf-col"></div>
|
|
36
36
|
</aside>
|
|
37
37
|
</div>
|
|
38
38
|
|
|
39
|
-
${
|
|
39
|
+
${je(V.file,"Session briefings","brief-count")}
|
|
40
40
|
<div class="bf-toolbar">
|
|
41
|
-
<div class="bf-search">${
|
|
41
|
+
<div class="bf-search">${de(V.search)}
|
|
42
42
|
<input id="search" type="search" placeholder="Search sessions…" aria-label="Search sessions">
|
|
43
43
|
</div>
|
|
44
44
|
<div class="bf-filters" id="filters" role="group" aria-label="Filter briefings"></div>
|
|
@@ -46,15 +46,15 @@ ${$e(K.file,"Session briefings","brief-count")}
|
|
|
46
46
|
<div id="reviews" class="bf-col"></div>
|
|
47
47
|
|
|
48
48
|
<section class="ax-panel bf-connect">
|
|
49
|
-
<div class="bf-connect__head">${
|
|
49
|
+
<div class="bf-connect__head">${de(V.plug,17)}<h2>Connect a CLI session</h2>
|
|
50
50
|
<span class="bf-connect__note">Daemon-owned processes only</span></div>
|
|
51
51
|
<div class="bf-discover">
|
|
52
52
|
<div class="ax-field"><label for="node">Node</label><select id="node"></select></div>
|
|
53
|
-
<button class="ax-btn" id="discover">${
|
|
53
|
+
<button class="ax-btn" id="discover">${de(V.search)} Discover CLIs</button>
|
|
54
54
|
</div>
|
|
55
55
|
<div class="bf-cli" id="discovered"></div>
|
|
56
56
|
<details class="bf-manual">
|
|
57
|
-
<summary>${
|
|
57
|
+
<summary>${de(V.chev,12)} Register manually</summary>
|
|
58
58
|
<div class="bf-forms">
|
|
59
59
|
<form id="register" class="bf-form">
|
|
60
60
|
<div class="ax-sec-label"><h3>Register a session</h3></div>
|
|
@@ -85,7 +85,7 @@ ${$e(K.file,"Session briefings","brief-count")}
|
|
|
85
85
|
</div>
|
|
86
86
|
</details>
|
|
87
87
|
</section>
|
|
88
|
-
</div>`,css:
|
|
88
|
+
</div>`,css:Tn,scripts:`<script>${me({decayOf:Je,rankByDecay:Xt})}const ICON = ${JSON.stringify(V)};${Cn}</script>`})}var Tn=`
|
|
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
|
+
}`,Cn=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,41 +776,50 @@ 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 Ve(t,e=20*6e4,a=6){let n=[...t].sort((i,c)=>i.startedAt-c.startedAt);if(!n.length)return{bands:[],gaps:[]};let r=[];for(let i of n){let c=i.startedAt+Math.max(i.durationMs||0,0),m=r[r.length-1];m&&i.startedAt-m.to<=e?(m.to=Math.max(m.to,c),m.runs++):r.push({from:i.startedAt,to:c,runs:1})}for(;r.length>a;){let i=0,c=1/0;for(let m=1;m<r.length;m++){let u=r[m].from-r[m-1].to;u<c&&(c=u,i=m)}r[i-1].to=r[i].to,r[i-1].runs+=r[i].runs,r.splice(i,1)}let o=r.reduce((i,c)=>i+c.runs,0)||1,s=r.map(i=>({from:i.from,to:Math.max(i.to,i.from+1),weight:i.runs/o,runs:i.runs})),l=r.slice(1).map((i,c)=>i.from-r[c].to);return{bands:s,gaps:l}}function Ye(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 Jt(t,e=[],a){let{bands:n,gaps:r}=Ve(t,a);if(!n.length)return{bands:[],gaps:[],lanes:[],from:0,to:0};let o=new Map;for(let i of e){let c=o.get(i.runId);c?c.push(i):o.set(i.runId,[i])}let s=new Map;for(let i of t){let c=n.findIndex(I=>i.startedAt>=I.from&&i.startedAt<=I.to);if(c===-1)continue;let m=n[c],u=m.to-m.from||1,g=(i.startedAt-m.from)/u*100,b=Math.min(Math.max((i.durationMs||0)/u*100,1.2),100-g),_=s.get(i.laneKey)??{key:i.laneKey,label:i.laneLabel,sub:i.laneSub,tracks:1,runs:[]};_.runs.push({...i,band:c,track:0,left:g,width:b,marks:o.get(i.id)??[]}),s.set(i.laneKey,_)}let l=[...s.values()];for(let i of l)i.tracks=Math.max(...n.map((c,m)=>Ye(i.runs.filter(u=>u.band===m))),1);return l.sort((i,c)=>c.runs.length-i.runs.length||i.label.localeCompare(c.label)),{bands:n,gaps:r,lanes:l,from:n[0].from,to:n[n.length-1].to}}import{createHash as An}from"crypto";import{readFileSync as Mn,statSync as In}from"fs";import{resolve as $n,dirname as jn}from"path";import{fileURLToPath as Ln}from"url";var Vt=new Map;function Le(t){let e=Vt.get(t);if(e)return e;let a=`/assets/${t}`;try{let n=jn(Ln(import.meta.url)),r=$n(n,"web",t),o=In(r),s=o.size<8e6?An("sha1").update(Mn(r)).digest("hex").slice(0,10):`${o.size}-${Math.floor(o.mtimeMs)}`;a=`/assets/${t}?v=${s}`}catch{}return Vt.set(t,a),a}var Q={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"/>'},Re=(t,e=14)=>'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" width="'+e+'" height="'+e+'" aria-hidden="true">'+t+"</svg>",Rn=[["agent","Agent",Q.bot],["client","Client",Q.user],["project","Project",Q.folder],["channel","Channel",Q.route],["node","Node",Q.mesh]],Yt={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 Qt(t={}){let e=t.view==="map"?"map":"timeline",a=e==="map";return M({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"
|
|
785
|
+
<p class="ac-sub" id="sub">${Yt[e]}</p>
|
|
786
786
|
</div>
|
|
787
787
|
<div class="ac-tools">
|
|
788
|
+
<div class="ac-seg" id="view" role="radiogroup" aria-label="View">
|
|
789
|
+
${[["timeline","Timeline",Q.timeline],["map","Map",Q.map]].map(([n,r,o])=>`<button type="button" role="radio" data-value="${n}" aria-checked="${n===e}"${n===e?' class="is-on"':""}>${Re(o,13)}${r}</button>`).join("")}
|
|
790
|
+
</div>
|
|
788
791
|
<div class="ac-seg" id="hours" role="radiogroup" aria-label="Window">
|
|
789
|
-
${[["6","6h"],["24","24h"],["72","3d"],["168","7d"]].map(([
|
|
792
|
+
${[["6","6h"],["24","24h"],["72","3d"],["168","7d"]].map(([n,r],o)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${o===1}"${o===1?' class="is-on"':""}>${r}</button>`).join("")}
|
|
790
793
|
</div>
|
|
791
|
-
<button class="ax-btn ax-btn--sm" id="refresh">${
|
|
794
|
+
<button class="ax-btn ax-btn--sm" id="refresh"${a?" hidden":""}>${Re(Q.refresh,13)} Refresh</button>
|
|
792
795
|
</div>
|
|
793
796
|
</div>
|
|
794
797
|
|
|
798
|
+
<div id="view-timeline"${a?" hidden":""}>
|
|
795
799
|
<div class="ac-bar">
|
|
796
800
|
<span class="ac-lbl">Lanes by</span>
|
|
797
801
|
<div class="ac-seg" id="persp" role="radiogroup" aria-label="Perspective">
|
|
798
|
-
${
|
|
802
|
+
${Rn.map(([n,r,o],s)=>`<button type="button" role="radio" data-value="${n}" aria-checked="${s===0}"${s===0?' class="is-on"':""}>${Re(o,13)}${r}</button>`).join("")}
|
|
799
803
|
</div>
|
|
800
804
|
<div class="ac-key">
|
|
801
805
|
<span class="ac-k"><i class="ac-d ac-d--decision"></i>decision</span>
|
|
802
806
|
<span class="ac-k"><i class="ac-d ac-d--warning"></i>warning</span>
|
|
803
807
|
<span class="ac-k"><i class="ac-d ac-d--recommendation"></i>friction</span>
|
|
804
808
|
<span class="ac-k"><i class="ac-d ac-d--later"></i>do later</span>
|
|
805
|
-
<span class="ac-k">${
|
|
809
|
+
<span class="ac-k">${Re(Q.x,11)}canceled</span>
|
|
806
810
|
</div>
|
|
807
811
|
</div>
|
|
808
812
|
|
|
809
813
|
<p id="notice" role="status" aria-live="polite"></p>
|
|
810
814
|
<div id="tl" class="ac-tl"></div>
|
|
811
815
|
<div id="detail"></div>
|
|
816
|
+
</div>
|
|
812
817
|
|
|
813
|
-
|
|
818
|
+
<div id="view-map" class="ac-map"${a?"":" hidden"}>
|
|
819
|
+
<div id="ax-fleet-root" data-hours="24" data-src="${Le("activity-graph.global.js")}"></div>
|
|
820
|
+
</div>
|
|
821
|
+
|
|
822
|
+
</div>`,css:Pn,scripts:`<script>${me({computeBands:Ve,packTracks:Ye,buildTimeline:Jt})}const ICON = ${JSON.stringify(Q)};const SUB = ${JSON.stringify(Yt)};${Dn}</script>`})}var Pn=`
|
|
814
823
|
.ac{max-width:1440px;margin:0 auto;padding:22px 24px 48px}
|
|
815
824
|
.ac :focus-visible{outline:2px solid var(--ax-accent);outline-offset:2px;border-radius:4px}
|
|
816
825
|
.ac-head{display:flex;align-items:flex-start;justify-content:space-between;gap:24px;margin-bottom:14px}
|
|
@@ -882,15 +891,26 @@ refresh();
|
|
|
882
891
|
.ac-chip{display:inline-flex;align-items:center;gap:5px;border-radius:var(--ax-radius-pill);padding:2px 9px;
|
|
883
892
|
font-size:11.5px;font-weight:600;border:1px solid var(--ax-border-2);background:var(--ax-surface-2);
|
|
884
893
|
color:var(--ax-text-2)}
|
|
894
|
+
.ac-map{height:calc(100vh - 190px);min-height:480px;background:var(--ax-surface);
|
|
895
|
+
border:var(--ax-border-w) solid var(--ax-border);border-radius:var(--ax-radius-lg);
|
|
896
|
+
box-shadow:var(--ax-shadow);overflow:hidden}
|
|
897
|
+
#ax-fleet-root{height:100%}
|
|
898
|
+
#ax-fleet-root:empty::before{content:"Loading fleet map\u2026";display:block;padding:40px 24px;
|
|
899
|
+
color:var(--ax-text-2);font-size:13px;text-align:center}
|
|
900
|
+
[hidden]{display:none!important}
|
|
885
901
|
#notice{margin:0 0 12px;font-size:12.5px;color:var(--ax-text-2)}
|
|
886
902
|
#notice:not(:empty){padding:9px 13px;border-radius:var(--ax-radius-sm);background:var(--ax-surface-2);
|
|
887
903
|
border:var(--ax-border-w) solid var(--ax-border)}
|
|
888
904
|
@media (max-width:900px){.ac-gut{width:120px}.ac-key{display:none}}
|
|
889
|
-
|
|
905
|
+
@media (max-width:640px){.ac{padding:16px 16px 32px}.ac-head{flex-direction:column;gap:10px}
|
|
906
|
+
.ac-tools{flex-wrap:wrap;padding-top:0}.ac-map{height:calc(100vh - 250px);margin:0 -16px;
|
|
907
|
+
border-left:none;border-right:none;border-radius:0}}
|
|
908
|
+
`,Dn=String.raw`
|
|
890
909
|
const $=id=>document.getElementById(id);
|
|
891
910
|
const esc=s=>String(s==null?'':s).replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
|
892
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>';
|
|
893
|
-
let runs=[],marks=[],persp='agent',hours='24',selected=null,busy=false
|
|
912
|
+
let runs=[],marks=[],persp='agent',hours='24',selected=null,busy=false,loaded=false,
|
|
913
|
+
view=$('view').querySelector('[aria-checked="true"]').dataset.value;
|
|
894
914
|
|
|
895
915
|
function fmtDur(ms){if(!ms)return '0s';if(ms<1000)return ms+'ms';const s=Math.round(ms/1000);
|
|
896
916
|
if(s<60)return s+'s';const m=Math.floor(s/60);return m+'m '+(s%60)+'s';}
|
|
@@ -986,10 +1006,23 @@ b.classList.toggle('is-on',on);b.setAttribute('aria-checked',String(on));}}
|
|
|
986
1006
|
$('persp').addEventListener('click',e=>{const b=e.target.closest('button[data-value]');if(!b)return;
|
|
987
1007
|
persp=b.dataset.value;paint('persp',persp);selected=null;render();});
|
|
988
1008
|
$('hours').addEventListener('click',e=>{const b=e.target.closest('button[data-value]');if(!b)return;
|
|
989
|
-
hours=b.dataset.value;paint('hours',hours)
|
|
1009
|
+
hours=b.dataset.value;paint('hours',hours);$('ax-fleet-root').dataset.hours=hours;
|
|
1010
|
+
window.dispatchEvent(new CustomEvent('ax:activity-hours',{detail:Number(hours)}));
|
|
1011
|
+
loaded=false;if(view==='timeline'){loaded=true;load();}});
|
|
990
1012
|
$('refresh').onclick=load;
|
|
991
|
-
|
|
992
|
-
|
|
1013
|
+
|
|
1014
|
+
/* The map bundle is heavy (React + xyflow); fetch it only when asked for. */
|
|
1015
|
+
function ensureMap(){const root=$('ax-fleet-root');if(root.dataset.loaded)return;root.dataset.loaded='1';
|
|
1016
|
+
const sc=document.createElement('script');sc.src=root.dataset.src;document.body.appendChild(sc);}
|
|
1017
|
+
function show(v){view=v;paint('view',v);
|
|
1018
|
+
$('view-timeline').hidden=v!=='timeline';$('view-map').hidden=v!=='map';$('refresh').hidden=v!=='timeline';
|
|
1019
|
+
$('sub').innerHTML=SUB[v];
|
|
1020
|
+
const u=new URL(location.href);if(v==='map')u.searchParams.set('view','map');else u.searchParams.delete('view');
|
|
1021
|
+
history.replaceState(null,'',u);
|
|
1022
|
+
if(v==='map')ensureMap();else if(!loaded){loaded=true;load();}}
|
|
1023
|
+
$('view').addEventListener('click',e=>{const b=e.target.closest('button[data-value]');if(!b||b.dataset.value===view)return;show(b.dataset.value);});
|
|
1024
|
+
show(view);
|
|
1025
|
+
`;function Zt(t={}){let e='<div id="wfe-root" style="height:100%"></div>';return M({title:"AgentX \xB7 Workflow editor",activeTab:"workflows",subtitle:"Workflow editor",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:On,scripts:`<script src="${Le("workflow-editor.global.js")}" defer></script>`,noMain:!0})}var On=`
|
|
993
1026
|
/* Preload the fonts the redesign's CSS references. Placed in the shell so
|
|
994
1027
|
* they start fetching while the React bundle is still parsing. */
|
|
995
1028
|
@import url("https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&family=Instrument+Serif&display=swap");
|
|
@@ -1010,10 +1043,10 @@ body { margin: 0; overflow: hidden; }
|
|
|
1010
1043
|
font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
|
|
1011
1044
|
text-align: center;
|
|
1012
1045
|
}
|
|
1013
|
-
`;cn();import{createServer as xs}from"http";import{appendFileSync as vs,existsSync as on,mkdirSync as bs}from"fs";import{readFile as ys}from"fs/promises";import{fileURLToPath as ws}from"url";import{dirname as ks,resolve as ke}from"path";var Gt='/*! 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 Le,readFileSync as Kt,writeFileSync as Jt,rmSync as hi,mkdirSync as An,copyFileSync as Mn,readdirSync as In}from"fs";import{resolve as he}from"path";Ne();var V={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 Xt(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=Ae({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.`})+Me([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return C({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+En()+It,css:Tn,scripts:`${e}<script>${$t}
|
|
1014
|
-
${
|
|
1015
|
-
${
|
|
1016
|
-
${
|
|
1046
|
+
`;Sn();import{createServer as Us}from"http";import{appendFileSync as Ws,existsSync as yn,mkdirSync as Gs}from"fs";import{readFile as Xs}from"fs/promises";import{fileURLToPath as Ks}from"url";import{dirname as Js,resolve as ke}from"path";var ea='/*! 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 Pe,readFileSync as aa,writeFileSync as na,rmSync as qi,mkdirSync as Fn,copyFileSync as Un,readdirSync as Wn}from"fs";import{resolve as he}from"path";Ue();var Z={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 ta(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=Me({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.`})+Ie([{kind:"off",num:"\u2014",label:"Agents online"},{kind:"off",num:"\u2014",label:"Channels connected"},{kind:"off",num:"0",label:"Needs attention"},{kind:"off",num:"\u2014",label:"Active tokens"}]).replace('<div class="ax-health-strip">','<div class="ax-health-strip" id="ax-health">');return M({title:"AgentX \xB7 Settings",activeTab:"admin",subtitle:"Settings",peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a+Nn()+Ot,css:zn,scripts:`${e}<script>${Ht}
|
|
1047
|
+
${Nt}
|
|
1048
|
+
${Hn}
|
|
1049
|
+
${qn}</script>`})}var Hn=`
|
|
1017
1050
|
(function(){
|
|
1018
1051
|
function fmt(n) { return n == null ? '\u2014' : String(n); }
|
|
1019
1052
|
async function refresh() {
|
|
@@ -1074,8 +1107,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1074
1107
|
refresh();
|
|
1075
1108
|
// Refresh again after the main admin script has had a chance to mutate config.
|
|
1076
1109
|
document.addEventListener('ax-config-saved', refresh);
|
|
1077
|
-
})();`;function
|
|
1078
|
-
`:"";return
|
|
1110
|
+
})();`;function Nn(){let t=jt().business?`<button data-tab="business">Business</button>
|
|
1111
|
+
`:"";return Bn.replace("__BUSINESS_TABS__",t)}var Bn=`
|
|
1079
1112
|
<div id="peer-banner" class="peer-banner">
|
|
1080
1113
|
<span class="label">Managing</span>
|
|
1081
1114
|
<span class="name" id="peer-banner-name">\u2014</span>
|
|
@@ -1218,8 +1251,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1218
1251
|
<div id="global-msg" class="msg"></div>
|
|
1219
1252
|
|
|
1220
1253
|
<section id="tab-agents" class="tab active">
|
|
1221
|
-
${
|
|
1222
|
-
${
|
|
1254
|
+
${q({icon:Z.agents,title:"Your agents",lead:"Each agent is a role with its own trigger words and workspace. Delete removes the config only \u2014 the folder on disk stays."})}
|
|
1255
|
+
${J({persistKey:"agents",bodyHtml:`<b>What's an agent, exactly?</b> Think of it as a specialised teammate. A sales agent handles pricing questions, a support agent answers tickets, a reports agent sends a weekly summary. You decide what they do and what to say to wake them up (their "trigger words", like <code>@support</code>).`})}
|
|
1223
1256
|
<div id="agent-list" class="ax-stack"></div>
|
|
1224
1257
|
<div class="add-form">
|
|
1225
1258
|
<h3>Add a new agent</h3>
|
|
@@ -1241,8 +1274,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1241
1274
|
</section>
|
|
1242
1275
|
|
|
1243
1276
|
<section id="tab-channels" class="tab">
|
|
1244
|
-
${
|
|
1245
|
-
${
|
|
1277
|
+
${q({icon:Z.channels,title:"Where your agents show up",lead:"Connect a chat app, and your agents can answer from there. Set up once \u2014 they'll keep working in the background."})}
|
|
1278
|
+
${J({persistKey:"channels",bodyHtml:"<b>How does this work?</b> Connect Telegram with a bot token or pair WhatsApp with a QR code. For webhook sources (GitHub, GitLab), use the URL shown in setup. Slack and Discord adapters are not supported in this build."})}
|
|
1246
1279
|
|
|
1247
1280
|
<details class="add-form" style="margin-top:14px;margin-bottom:18px" id="notif-section">
|
|
1248
1281
|
<summary class="primary">\u2699 Notifications routing</summary>
|
|
@@ -1271,10 +1304,10 @@ ${Cn}</script>`})}var _n=`
|
|
|
1271
1304
|
</div>
|
|
1272
1305
|
</details>
|
|
1273
1306
|
|
|
1274
|
-
<div id="ch-chatapps-label">${
|
|
1307
|
+
<div id="ch-chatapps-label">${$e({label:"Chat apps"})}</div>
|
|
1275
1308
|
<div class="ax-connectors" id="ch-chatapps"></div>
|
|
1276
1309
|
|
|
1277
|
-
<div id="ch-devtools-label">${
|
|
1310
|
+
<div id="ch-devtools-label">${$e({label:"Developer tools",rightHtml:'<span class="ax-pill">Send events from GitHub, GitLab, Sentry, etc.</span>'})}</div>
|
|
1278
1311
|
<div class="ax-connectors" id="ch-devtools"></div>
|
|
1279
1312
|
|
|
1280
1313
|
<!-- Active-channel configuration panes. One shows at a time; clicking
|
|
@@ -1292,8 +1325,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1292
1325
|
</section>
|
|
1293
1326
|
|
|
1294
1327
|
<section id="tab-crons" class="tab">
|
|
1295
|
-
${
|
|
1296
|
-
${
|
|
1328
|
+
${q({icon:Z.schedules,title:"Schedules",lead:"Make an agent do something on a timer \u2014 no one has to ask. Daily summaries, weekly reports, hourly health checks."})}
|
|
1329
|
+
${J({persistKey:"crons",bodyHtml:"<b>What's a good schedule?</b> Anything recurring. A <i>Reports agent</i> sending Monday-morning numbers, a <i>Health agent</i> pinging you at 3am if a server's down, a <i>Standup agent</i> reminding the team. Pick a time below."})}
|
|
1297
1330
|
<div id="cron-list" class="ax-stack" style="margin-bottom:22px"></div>
|
|
1298
1331
|
|
|
1299
1332
|
<div class="ax-builder">
|
|
@@ -1390,8 +1423,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1390
1423
|
</section>
|
|
1391
1424
|
|
|
1392
1425
|
<section id="tab-webhooks" class="tab">
|
|
1393
|
-
${
|
|
1394
|
-
${
|
|
1426
|
+
${q({icon:Z.webhooks,title:"Webhooks",lead:"A URL you give to another service. When something happens there \u2014 a PR is merged, an error fires \u2014 they POST to that URL, and we forward it to your agent as a readable message."})}
|
|
1427
|
+
${J({persistKey:"webhooks",bodyHtml:`<b>Not sure you need this?</b> If a service you use has a "webhooks" setting (GitHub, Stripe, Sentry, Typeform\u2026), you probably do. It's how those services tell AgentX when something's worth looking at.`})}
|
|
1395
1428
|
<div id="webhook-list" class="ax-stack"></div>
|
|
1396
1429
|
<div class="add-form">
|
|
1397
1430
|
<h3>Add a webhook</h3>
|
|
@@ -1410,10 +1443,10 @@ ${Cn}</script>`})}var _n=`
|
|
|
1410
1443
|
</section>
|
|
1411
1444
|
|
|
1412
1445
|
<section id="tab-mesh" class="tab">
|
|
1413
|
-
${
|
|
1446
|
+
${q({icon:Z.mesh,title:"Mesh",lead:"Link this AgentX to other machines so they share work. Good for teams running AgentX on multiple laptops or a mix of laptop + server."})}
|
|
1414
1447
|
<div id="mesh-hero" class="ax-mesh-hero"></div>
|
|
1415
|
-
${
|
|
1416
|
-
${
|
|
1448
|
+
${J({persistKey:"mesh",bodyHtml:"<b>Do I need mesh?</b> Only if you're running AgentX in more than one place. Solo users on one laptop can skip this entirely."})}
|
|
1449
|
+
${$e({label:"Connected peers"})}
|
|
1417
1450
|
<div id="mesh-peers" class="ax-stack"></div>
|
|
1418
1451
|
<div class="add-form">
|
|
1419
1452
|
<h3>Add a peer</h3>
|
|
@@ -1440,8 +1473,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1440
1473
|
</section>
|
|
1441
1474
|
|
|
1442
1475
|
<section id="tab-business" class="tab">
|
|
1443
|
-
${
|
|
1444
|
-
${
|
|
1476
|
+
${q({icon:Z.tokens,title:"Business layer",lead:"Org chart, projects, and contact map \u2014 the data that drives PM gating and activity-graph attribution. Mirrors <code>agentx business</code>."})}
|
|
1477
|
+
${J({persistKey:"business",bodyHtml:'<b>Three concepts.</b> The <b>org chart</b> is who reports to whom (<code>reportsTo</code>). <b>Projects</b> map an id to a PM and client (drives the PM gate and lets the activity graph attribute work to the right client). The <b>contact map</b> tells the activity graph which client a Telegram/WhatsApp chat belongs to \u2014 without it, free-text channels fall into the catch-all "internal" bucket. Editing here writes to <code>agentx.json</code>; restart the daemon (or POST /reload) for the change to take effect.'})}
|
|
1445
1478
|
|
|
1446
1479
|
<div class="ax-stack" style="margin-top:14px">
|
|
1447
1480
|
<h3 style="margin:0 0 6px;font-size:13px">Org chart</h3>
|
|
@@ -1528,8 +1561,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1528
1561
|
</section>
|
|
1529
1562
|
|
|
1530
1563
|
<section id="tab-boards-cfg" class="tab">
|
|
1531
|
-
${
|
|
1532
|
-
${
|
|
1564
|
+
${q({icon:Z.tokens,title:"Kanban boards",lead:"Configure the boards rendered on the home page. Mirrors <code>agentx board add/edit/remove</code> + <code>agentx board column</code>. Source is GitLab today; backlog/wiki sources land when the schema unlocks them."})}
|
|
1565
|
+
${J({persistKey:"boards-cfg",bodyHtml:'<b>Two layers.</b> A board points to one or more GitLab projects (<code>source.projects</code>) and optionally filters by a primary tool label. Inside each board, <b>columns</b> map drag-drop actions to scoped-labels (e.g. dropping a card on "Doing" adds <code>Status::Doing</code>). The default flow is Open \u2192 To Do \u2192 Doing \u2192 On Hold \u2192 Review \u2192 Closed; override per-board with the column controls below.'})}
|
|
1533
1566
|
|
|
1534
1567
|
<div class="ax-stack" style="margin-top:14px">
|
|
1535
1568
|
<h3 style="margin:0 0 6px;font-size:13px">Boards</h3>
|
|
@@ -1553,8 +1586,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1553
1586
|
</section>
|
|
1554
1587
|
|
|
1555
1588
|
<section id="tab-actions" class="tab">
|
|
1556
|
-
${
|
|
1557
|
-
${
|
|
1589
|
+
${q({icon:Z.actions,title:"Action registry",lead:"Reusable shell commands and HTTP calls. Workflows invoke them by id; the dashboard runs them on demand for smoke-tests. Mirrors <code>agentx actions</code>."})}
|
|
1590
|
+
${J({persistKey:"actions",bodyHtml:"<b>Two flavors.</b> <code>shell</code> runs a templated command on the daemon host (cwd + extra env vars supported). <code>http</code> calls a URL with templated method/headers/body. Inputs are typed (string / number / boolean) and fill <code>{{name}}</code> markers; <code>$VAR</code> resolves against the daemon's process env. Output capped at 32KB."})}
|
|
1558
1591
|
|
|
1559
1592
|
<div class="ax-stack" style="margin-top:14px">
|
|
1560
1593
|
<h3 style="margin:0 0 6px;font-size:13px">Registered actions</h3>
|
|
@@ -1609,8 +1642,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1609
1642
|
</section>
|
|
1610
1643
|
|
|
1611
1644
|
<section id="tab-tokens" class="tab">
|
|
1612
|
-
${
|
|
1613
|
-
${
|
|
1645
|
+
${q({icon:Z.tokens,title:"Access tokens",lead:"Passwords, but for software. Anything that wants to talk to AgentX from outside (a Slack bridge, another AgentX machine, a script) uses one."})}
|
|
1646
|
+
${J({persistKey:"tokens",bodyHtml:"<b>Tokens get scopes.</b> A scope is what the token is allowed to do. Give the narrowest one that works \u2014 a Slack bridge only needs to send messages, it doesn't need to edit settings. You can't recover a token after you close this page, so copy it immediately."})}
|
|
1614
1647
|
<div id="token-list" class="ax-stack"></div>
|
|
1615
1648
|
<div class="add-form">
|
|
1616
1649
|
<h3>Mint a new token</h3>
|
|
@@ -1629,8 +1662,8 @@ ${Cn}</script>`})}var _n=`
|
|
|
1629
1662
|
</section>
|
|
1630
1663
|
|
|
1631
1664
|
<section id="tab-advanced" class="tab">
|
|
1632
|
-
${
|
|
1633
|
-
${
|
|
1665
|
+
${q({icon:Z.advanced,title:"Raw configuration",lead:"Everything on the other tabs writes to this file. Edit here for bulk changes, diffs, or fields we haven't put in the UI yet. Saving creates a timestamped backup."})}
|
|
1666
|
+
${J({persistKey:"advanced",bodyHtml:`<b>Safe to look, careful editing.</b> We've pretty-printed and annotated each section so you can read it. Click any <span class="mono" style="color:var(--ax-muted)">\u25B8</span> to fold. Switch to <b>Edit</b> to change values \u2014 invalid JSON is refused before saving.`})}
|
|
1634
1667
|
|
|
1635
1668
|
<div class="ax-jv-toolbar">
|
|
1636
1669
|
<input class="ax-jv-search" id="jv-search" placeholder="Search keys & values\u2026" />
|
|
@@ -1656,7 +1689,7 @@ ${Cn}</script>`})}var _n=`
|
|
|
1656
1689
|
<div class="hint-block">The schema is documented at <code>docs/reference/config-schema.md</code>. Invalid JSON is refused; schema-level errors only surface after the daemon tries to use the new config.</div>
|
|
1657
1690
|
</section>
|
|
1658
1691
|
</main>
|
|
1659
|
-
`,
|
|
1692
|
+
`,zn=`
|
|
1660
1693
|
|
|
1661
1694
|
/* --- Inner tabs (Agents / Channels / Schedules / \u2026) --- */
|
|
1662
1695
|
nav.tabs{display:flex;gap:4px;padding:14px 24px 0;background:var(--ax-bg-elev);
|
|
@@ -1864,7 +1897,7 @@ textarea.raw{min-height:480px;font-family:var(--ax-mono);font-size:12px;line-hei
|
|
|
1864
1897
|
.peer-banner button{background:transparent;border:1px solid currentColor;color:var(--ax-accent);
|
|
1865
1898
|
padding:4px 10px;border-radius:4px;font:inherit;font-size:11px;cursor:pointer}
|
|
1866
1899
|
.peer-banner button:hover{background:color-mix(in oklch,var(--ax-accent) 12%,transparent)}
|
|
1867
|
-
`,
|
|
1900
|
+
`,qn=`
|
|
1868
1901
|
const $ = (id) => document.getElementById(id);
|
|
1869
1902
|
let state = null;
|
|
1870
1903
|
|
|
@@ -4586,11 +4619,11 @@ for (const btn of document.querySelectorAll('nav.tabs button')) {
|
|
|
4586
4619
|
})();
|
|
4587
4620
|
|
|
4588
4621
|
refresh();
|
|
4589
|
-
`;function Vt(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xt({peers:a,localToken:n}))}async function Yt(t,e){let a=Ye();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function Qt(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await Fn(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await $n(t),r={"GET /api/admin/state":()=>Ln(),"POST /api/admin/agents":()=>Nn(n),"PATCH /api/admin/agents":()=>Bn(n),"DELETE /api/admin/agents":()=>zn(n),"POST /api/admin/agents/access":()=>Rn(n),"POST /api/admin/channels/telegram":()=>qn(n),"DELETE /api/admin/channels/telegram":()=>ur(n),"POST /api/admin/channels/telegram/toggle":()=>mr(n),"POST /api/admin/crons":()=>hr(n),"DELETE /api/admin/crons":()=>gr(n),"POST /api/admin/config/raw":()=>fr(n),"GET /api/admin/tokens":()=>Pn(),"POST /api/admin/tokens":()=>Dn(n),"DELETE /api/admin/tokens":()=>On(n),"POST /api/admin/agents/test":()=>Hn(n),"POST /api/admin/agents/integrations":()=>Vn(n),"DELETE /api/admin/agents/integrations":()=>Yn(n),"PATCH /api/admin/agents/integrations":()=>Qn(n),"PATCH /api/admin/channels/telegram":()=>Un(n),"POST /api/admin/channels/slack":()=>or(n),"POST /api/admin/channels/slack/toggle":()=>sr(n),"POST /api/admin/channels/discord":()=>ir(n),"POST /api/admin/channels/discord/toggle":()=>lr(n),"POST /api/admin/channels/gitlab":()=>dr(n),"POST /api/admin/channels/gitlab/toggle":()=>cr(n),"GET /api/admin/channels/whatsapp/state":()=>be("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>be("/webrtc/history"),"POST /api/admin/actions":()=>Mr(n),"DELETE /api/admin/actions":()=>Ir(n),"POST /api/admin/actions/run":()=>$r(n),"GET /api/admin/channels/whatsapp/chats":()=>be("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>be("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>te("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>pr(n),"POST /api/admin/webhooks":()=>Zn(n),"PATCH /api/admin/webhooks":()=>er(n),"DELETE /api/admin/webhooks":()=>rr(n),"POST /api/admin/mesh/peers":()=>tr(n),"DELETE /api/admin/mesh/peers":()=>ar(n),"POST /api/admin/mesh/toggle":()=>nr(n),"GET /api/admin/files":()=>Wn(t),"GET /api/admin/files/read":()=>Gn(t),"PUT /api/admin/files":()=>Xn(n),"POST /api/admin/files/skill":()=>Kn(n),"DELETE /api/admin/files/skill":()=>Jn(n),"POST /api/admin/business/orgchart":()=>xr(n),"DELETE /api/admin/business/orgchart":()=>vr(n),"POST /api/admin/business/project":()=>br(n),"DELETE /api/admin/business/project":()=>kr(n),"POST /api/admin/business/client":()=>yr(n),"DELETE /api/admin/business/client":()=>wr(n),"POST /api/admin/business/contact":()=>_r(n),"DELETE /api/admin/business/contact":()=>Er(n),"POST /api/admin/boards":()=>Sr(n),"DELETE /api/admin/boards":()=>Tr(n),"POST /api/admin/boards/columns":()=>Cr(n),"DELETE /api/admin/boards/columns":()=>Ar(n),"POST /api/admin/notifications":()=>Lr(n),"POST /api/admin/webhooks/triggers":()=>Rr(n),"POST /api/admin/mesh/health":()=>jr(n),"GET /api/admin/projects":()=>be("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>te("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>te("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>te("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>te("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>te("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>te("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>te("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>te("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Je(e,404,{error:`unknown admin endpoint: ${o}`});return}let l=await s();Je(e,200,l)}catch(n){Je(e,400,{error:n.message||"admin op failed"})}}function Je(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function $n(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 jn(t){let e=he(process.cwd(),t);if(!Le(e))return[];let a=[];for(let n of In(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(Kt(he(e,n.name),"utf-8")))}catch{}return a}function Ye(){let t=he(process.cwd(),"agentx.json");return Le(t)?JSON.parse(Kt(t,"utf-8")):null}function Ln(){let t=Ye();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([d,p])=>({id:d,name:p.name,tier:p.tier,model:p.model,mentions:p.mentions||[],workspace:p.workspace,access:p.access||"private",systemPrompt:p.systemPrompt||"",maxConcurrent:p.maxConcurrent??1,maxExecutionMinutes:p.maxExecutionMinutes??20,permissionMode:p.permissionMode||"default",integrations:(Array.isArray(p.integrations)?p.integrations:[]).map(g=>{let f=g.credentials||{},h={};for(let[y,k]of Object.entries(f))typeof k=="string"&&/^[A-Z][A-Z0-9_]*$/.test(k)?h[y]=process.env[k]?"set":"unset":typeof k=="string"&&(h[y]="literal");return{kind:g.kind,label:g.label,enabled:g.enabled!==!1,credentials:f,credStatus:h,metadata:g.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([d,p])=>({id:d,botUsername:p.botUsername||"",agentBinding:p.agentBinding||"",botTokenRef:p.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},l={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},i=Object.entries(t.crons||{}).map(([d,p])=>({id:d,schedule:p.schedule,agent:p.agent,prompt:(p.prompt||"").slice(0,200),enabled:p.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(d=>({id:d.id,source:d.source,agentId:d.agentId,secretEnv:d.secretEnv||"",description:d.description||"",enabled:d.enabled!==!1,triggers:d.triggers&&typeof d.triggers=="object"?d.triggers:{},defaultWorkflow:d.defaultWorkflow||""})):[],u={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(d=>({url:d.url,name:d.name,hasToken:!!d.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},m=t.dashboard?.daemonUrl||"http://localhost:18800",x=t.business||{},b={enabled:!!x.enabled,timezone:x.timezone||"UTC",orgChart:x.orgChart||{},projects:Array.isArray(x.projects)?x.projects:[],contactMap:Array.isArray(x.contactMap)?x.contactMap:[],clients:x.clients&&typeof x.clients=="object"?x.clients:{}},_=t.notifications||{},M={longTaskThreshold:_.longTaskThreshold??30,destination:_.destination||null,on:{taskComplete:_.on?.taskComplete!==!1,taskError:_.on?.taskError!==!1,taskQueued:!!_.on?.taskQueued}},E=[];try{E=jn(".agentx/actions").filter(p=>p&&typeof p=="object"&&p.id).map(p=>({id:p.id,title:p.title,kind:p.kind,description:p.description||"",inputs:Array.isArray(p.inputs)?p.inputs:[],timeoutMs:p.timeoutMs??3e4,command:p.kind==="shell"?p.command:void 0,url:p.kind==="http"?p.url:void 0,method:p.kind==="http"?p.method:void 0})).sort((p,g)=>p.id.localeCompare(g.id))}catch{}let S=(Array.isArray(t.boards)?t.boards:[]).map(d=>({id:d.id,name:d.name,source:d.source||{type:"gitlab",projects:[]},primaryToolLabel:d.primaryToolLabel||"",timeRangeDays:d.timeRangeDays??30,closedWindowDays:d.closedWindowDays??30,columns:Array.isArray(d.columns)?d.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:l,crons:i,webhooks:c,mesh:u,daemonUrl:m,nodeName:t.node?.name,business:b,boards:S,notifications:M,actions:E}}function Rn(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}=T(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 Pn(){return new ee().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 Dn(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 ee().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function On(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new ee().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function Hn(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 u=G();r=u.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=u.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let l=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),i=await l.text(),c;try{c=JSON.parse(i)}catch{c={content:i}}if(!l.ok)throw new Error(c?.error||`daemon HTTP ${l.status}`);return{chatId:n,response:c}}function Nn(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(t?.tier)?t.tier:"claude-code",r=ea(t?.triggerWords),o=t?.model?String(t.model).trim():void 0,s=t?.personality?String(t.personality).trim():void 0;if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Agent id must be lowercase (letters, digits, -, _).");if(!a)throw new Error("Agent name is required.");if(r.length===0)throw new Error("At least one trigger word is required.");let l=he(process.cwd(),"agents",e),{summary:i}=T(u=>{if(u.agents=u.agents||{},u.agents[e])throw new Error(`Agent "${e}" already exists.`);let m={name:a,workspace:l,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(m.model=o),s&&(m.systemPrompt=s.slice(0,400)),u.agents[e]=m,`added agent "${e}"`}),c=he(l,"CLAUDE.md");if(!Le(c))try{An(l,{recursive:!0}),Jt(c,`# ${a}
|
|
4622
|
+
`;function ra(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ta({peers:a,localToken:n}))}async function oa(t,e){let a=et();e.writeHead(200,{"Content-Type":"application/json"}),e.end(JSON.stringify(a))}async function sa(t,e,a){try{if(t.method==="GET"&&a==="/api/admin/channels/whatsapp/qr.svg"){await or(e,"/whatsapp/qr.svg");return}let n=t.method==="GET"?void 0:await Gn(t),r={"GET /api/admin/state":()=>Kn(),"POST /api/admin/agents":()=>er(n),"PATCH /api/admin/agents":()=>tr(n),"DELETE /api/admin/agents":()=>ar(n),"POST /api/admin/agents/access":()=>Jn(n),"POST /api/admin/channels/telegram":()=>nr(n),"DELETE /api/admin/channels/telegram":()=>Cr(n),"POST /api/admin/channels/telegram/toggle":()=>Ar(n),"POST /api/admin/crons":()=>Mr(n),"DELETE /api/admin/crons":()=>Ir(n),"POST /api/admin/config/raw":()=>$r(n),"GET /api/admin/tokens":()=>Vn(),"POST /api/admin/tokens":()=>Yn(n),"DELETE /api/admin/tokens":()=>Qn(n),"POST /api/admin/agents/test":()=>Zn(n),"POST /api/admin/agents/integrations":()=>pr(n),"DELETE /api/admin/agents/integrations":()=>ur(n),"PATCH /api/admin/agents/integrations":()=>mr(n),"PATCH /api/admin/channels/telegram":()=>rr(n),"POST /api/admin/channels/slack":()=>yr(n),"POST /api/admin/channels/slack/toggle":()=>wr(n),"POST /api/admin/channels/discord":()=>kr(n),"POST /api/admin/channels/discord/toggle":()=>_r(n),"POST /api/admin/channels/gitlab":()=>Er(n),"POST /api/admin/channels/gitlab/toggle":()=>Sr(n),"GET /api/admin/channels/whatsapp/state":()=>be("/whatsapp/state"),"GET /api/admin/channels/webrtc/history":()=>be("/webrtc/history"),"POST /api/admin/actions":()=>Ur(n),"DELETE /api/admin/actions":()=>Wr(n),"POST /api/admin/actions/run":()=>Gr(n),"GET /api/admin/channels/whatsapp/chats":()=>be("/whatsapp/chats"),"GET /api/admin/channels/whatsapp/contacts":()=>be("/whatsapp/contacts"),"POST /api/admin/channels/whatsapp/ingest":()=>ne("/whatsapp/ingest",n),"POST /api/admin/crons/preview":()=>Tr(n),"POST /api/admin/webhooks":()=>hr(n),"PATCH /api/admin/webhooks":()=>gr(n),"DELETE /api/admin/webhooks":()=>br(n),"POST /api/admin/mesh/peers":()=>fr(n),"DELETE /api/admin/mesh/peers":()=>xr(n),"POST /api/admin/mesh/toggle":()=>vr(n),"GET /api/admin/files":()=>sr(t),"GET /api/admin/files/read":()=>ir(t),"PUT /api/admin/files":()=>lr(n),"POST /api/admin/files/skill":()=>dr(n),"DELETE /api/admin/files/skill":()=>cr(n),"POST /api/admin/business/orgchart":()=>jr(n),"DELETE /api/admin/business/orgchart":()=>Lr(n),"POST /api/admin/business/project":()=>Rr(n),"DELETE /api/admin/business/project":()=>Or(n),"POST /api/admin/business/client":()=>Pr(n),"DELETE /api/admin/business/client":()=>Dr(n),"POST /api/admin/business/contact":()=>Hr(n),"DELETE /api/admin/business/contact":()=>Nr(n),"POST /api/admin/boards":()=>Br(n),"DELETE /api/admin/boards":()=>zr(n),"POST /api/admin/boards/columns":()=>qr(n),"DELETE /api/admin/boards/columns":()=>Fr(n),"POST /api/admin/notifications":()=>Kr(n),"POST /api/admin/webhooks/triggers":()=>Jr(n),"POST /api/admin/mesh/health":()=>Xr(n),"GET /api/admin/projects":()=>be("/api/admin/projects"),"POST /api/admin/projects/workflows/link":()=>ne("/api/admin/projects/workflows/link",n),"POST /api/admin/projects/workflows/unlink":()=>ne("/api/admin/projects/workflows/unlink",n),"POST /api/admin/projects/header":()=>ne("/api/admin/projects/header",n),"POST /api/admin/projects/clauses":()=>ne("/api/admin/projects/clauses",n),"POST /api/admin/projects/contacts/link":()=>ne("/api/admin/projects/contacts/link",n),"POST /api/admin/projects/contacts/unlink":()=>ne("/api/admin/projects/contacts/unlink",n),"POST /api/admin/projects/create":()=>ne("/api/admin/projects/create",n),"POST /api/admin/projects/delete":()=>ne("/api/admin/projects/delete",n)},o=`${t.method} ${a}`,s=r[o];if(!s){Qe(e,404,{error:`unknown admin endpoint: ${o}`});return}let l=await s();Qe(e,200,l)}catch(n){Qe(e,400,{error:n.message||"admin op failed"})}}function Qe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function Gn(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 Xn(t){let e=he(process.cwd(),t);if(!Pe(e))return[];let a=[];for(let n of Wn(e,{withFileTypes:!0}))if(!(!n.isFile()||!n.name.endsWith(".json")))try{a.push(JSON.parse(aa(he(e,n.name),"utf-8")))}catch{}return a}function et(){let t=he(process.cwd(),"agentx.json");return Pe(t)?JSON.parse(aa(t,"utf-8")):null}function Kn(){let t=et();if(!t)return{exists:!1};let e=Object.entries(t.agents||{}).map(([d,p])=>({id:d,name:p.name,tier:p.tier,model:p.model,mentions:p.mentions||[],workspace:p.workspace,access:p.access||"private",systemPrompt:p.systemPrompt||"",maxConcurrent:p.maxConcurrent??1,maxExecutionMinutes:p.maxExecutionMinutes??20,permissionMode:p.permissionMode||"default",integrations:(Array.isArray(p.integrations)?p.integrations:[]).map(h=>{let f=h.credentials||{},y={};for(let[x,w]of Object.entries(f))typeof w=="string"&&/^[A-Z][A-Z0-9_]*$/.test(w)?y[x]=process.env[w]?"set":"unset":typeof w=="string"&&(y[x]="literal");return{kind:h.kind,label:h.label,enabled:h.enabled!==!1,credentials:f,credStatus:y,metadata:h.metadata||{}}})})),a=t.channels?.telegram?.accounts||{},n={enabled:!!t.channels?.telegram?.enabled,accounts:Object.entries(a).map(([d,p])=>({id:d,botUsername:p.botUsername||"",agentBinding:p.agentBinding||"",botTokenRef:p.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},l={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},i=Object.entries(t.crons||{}).map(([d,p])=>({id:d,schedule:p.schedule,agent:p.agent,prompt:(p.prompt||"").slice(0,200),enabled:p.enabled!==!1})),c=Array.isArray(t.webhooks)?t.webhooks.map(d=>({id:d.id,source:d.source,agentId:d.agentId,secretEnv:d.secretEnv||"",description:d.description||"",enabled:d.enabled!==!1,triggers:d.triggers&&typeof d.triggers=="object"?d.triggers:{},defaultWorkflow:d.defaultWorkflow||""})):[],m={enabled:!!t.mesh?.enabled,discovery:t.mesh?.discovery||"static",peers:(t.mesh?.peers||[]).map(d=>({url:d.url,name:d.name,hasToken:!!d.token})),healthCheck:{interval:t.mesh?.healthCheck?.interval??60,timeout:t.mesh?.healthCheck?.timeout??10}},u=t.dashboard?.daemonUrl||"http://localhost:18800",g=t.business||{},b={enabled:!!g.enabled,timezone:g.timezone||"UTC",orgChart:g.orgChart||{},projects:Array.isArray(g.projects)?g.projects:[],contactMap:Array.isArray(g.contactMap)?g.contactMap:[],clients:g.clients&&typeof g.clients=="object"?g.clients:{}},_=t.notifications||{},I={longTaskThreshold:_.longTaskThreshold??30,destination:_.destination||null,on:{taskComplete:_.on?.taskComplete!==!1,taskError:_.on?.taskError!==!1,taskQueued:!!_.on?.taskQueued}},E=[];try{E=Xn(".agentx/actions").filter(p=>p&&typeof p=="object"&&p.id).map(p=>({id:p.id,title:p.title,kind:p.kind,description:p.description||"",inputs:Array.isArray(p.inputs)?p.inputs:[],timeoutMs:p.timeoutMs??3e4,command:p.kind==="shell"?p.command:void 0,url:p.kind==="http"?p.url:void 0,method:p.kind==="http"?p.method:void 0})).sort((p,h)=>p.id.localeCompare(h.id))}catch{}let S=(Array.isArray(t.boards)?t.boards:[]).map(d=>({id:d.id,name:d.name,source:d.source||{type:"gitlab",projects:[]},primaryToolLabel:d.primaryToolLabel||"",timeRangeDays:d.timeRangeDays??30,closedWindowDays:d.closedWindowDays??30,columns:Array.isArray(d.columns)?d.columns:[]}));return{exists:!0,agents:e,telegram:n,slack:r,discord:o,gitlab:s,whatsapp:l,crons:i,webhooks:c,mesh:m,daemonUrl:u,nodeName:t.node?.name,business:b,boards:S,notifications:I,actions:E}}function Jn(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}=T(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 Vn(){return new ae().list().map(t=>({id:t.id,name:t.name,prefix:t.prefix,scopes:t.scopes,createdAt:t.createdAt,expiresAt:t.expiresAt,revokedAt:t.revokedAt,lastUsedAt:t.lastUsedAt}))}function Yn(t){let e=String(t?.name||"").trim(),a=Array.isArray(t?.scopes)?t.scopes.map(String):[],n=t?.expiresInDays?Number(t.expiresInDays):void 0,{token:r,record:o}=new ae().create({name:e,scopes:a,expiresInDays:n});return{summary:`created token "${e}"`,token:r,record:o}}function Qn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Token id is required.");let a=new ae().revoke(e);if(!a)throw new Error(`Token "${e}" not found.`);return{summary:`revoked token ${e} (${a.name})`}}async function Zn(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 m=K();r=m.dashboard.daemonUrl.replace(/\/+$/,"")||r,o=m.dashboard.token}catch{}let s={"Content-Type":"application/json"};o&&(s.Authorization=`Bearer ${o}`);let l=await fetch(`${r}/task`,{method:"POST",headers:s,body:JSON.stringify({agent:e,message:a,context:{channel:"test-drive",sender:"admin",chatId:n}})}),i=await l.text(),c;try{c=JSON.parse(i)}catch{c={content:i}}if(!l.ok)throw new Error(c?.error||`daemon HTTP ${l.status}`);return{chatId:n,response:c}}function er(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=la(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 l=he(process.cwd(),"agents",e),{summary:i}=T(m=>{if(m.agents=m.agents||{},m.agents[e])throw new Error(`Agent "${e}" already exists.`);let u={name:a,workspace:l,tier:n,mentions:r,maxConcurrent:2,permissionMode:"default"};return o&&(u.model=o),s&&(u.systemPrompt=s.slice(0,400)),m.agents[e]=u,`added agent "${e}"`}),c=he(l,"CLAUDE.md");if(!Pe(c))try{Fn(l,{recursive:!0}),na(c,`# ${a}
|
|
4590
4623
|
|
|
4591
4624
|
${s||"You are "+a+"."}
|
|
4592
|
-
`)}catch{}return{summary:i}}function Bn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=T(r=>{if(!r.agents?.[e])throw new Error(`Agent "${e}" not found.`);let o=r.agents[e];return typeof a.name=="string"&&a.name.trim()&&(o.name=a.name.trim()),typeof a.model=="string"&&(o.model=a.model.trim()||void 0),typeof a.tier=="string"&&["claude-code","codex-cli","opencode","sdk","orchestrator"].includes(a.tier)&&(o.tier=a.tier),typeof a.systemPrompt=="string"&&(o.systemPrompt=a.systemPrompt.trim()||void 0),Array.isArray(a.mentions)?o.mentions=a.mentions.map(s=>String(s).trim()).filter(Boolean):typeof a.triggerWords=="string"&&(o.mentions=ea(a.triggerWords)),typeof a.maxConcurrent=="number"&&a.maxConcurrent>=1&&(o.maxConcurrent=a.maxConcurrent),typeof a.maxExecutionMinutes=="number"&&a.maxExecutionMinutes>=1&&a.maxExecutionMinutes<=240&&(o.maxExecutionMinutes=a.maxExecutionMinutes),typeof a.permissionMode=="string"&&(o.permissionMode=a.permissionMode),(a.access==="public"||a.access==="private")&&(o.access=a.access),`updated agent "${e}"`});return{summary:n}}function zn(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=T(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 qn(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}=T(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 Un(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=T(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 be(t){let{url:e,headers:a}=Qe(),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 te(t,e){let{url:a,headers:n}=Qe(),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 Fn(t,e){try{let{url:a,headers:n}=Qe(),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 Qe(){let t="http://127.0.0.1:18800",e={};try{let a=G();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function ye(t){let a=Ye()?.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 Ve(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function Wn(t){let e=Ve(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=ue(ye(e));return{agentId:e,...a}}function Gn(t){let e=Ve(t,"agent").trim(),a=Ve(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return _e(ye(e),a)}function Xn(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=Ee(ye(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function Kn(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=Se(ye(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function Jn(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=Te(ye(e),a);return{summary:`removed skill "${a}"`,...n}}function Vn(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 i of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[i];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${i} must be uppercase identifier (got "${c}")`);r[i]=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[i,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[i]=c);let{summary:l}=T(i=>{if(!i.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(i.agents[e].integrations=Array.isArray(i.agents[e].integrations)?i.agents[e].integrations:[],i.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return i.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:l}}function Yn(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}=T(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let l=s.integrations||[],i=l.findIndex(c=>c.kind===a&&c.label===n);if(i===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return l.splice(i,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function Qn(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}=T(s=>{let l=s.agents?.[e];if(!l)throw new Error(`Unknown agent "${e}"`);let c=(l.integrations||[]).find(u=>u.kind===a&&u.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 Zt=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function Zn(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(!Zt.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:l}=T(i=>{if(s){if(!(i.mesh?.peers||[]).find(m=>m.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!i.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(i.webhooks=Array.isArray(i.webhooks)?i.webhooks:[],i.webhooks.find(u=>u.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),i.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:l}}function er(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=T(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&Zt.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 tr(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}=T(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(l=>l.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 ar(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=T(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 nr(t){let e=!!t?.enabled,{summary:a}=T(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 rr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=T(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 or(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}=T(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 sr(t){let e=!!t?.enabled,{summary:a}=T(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 ir(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}=T(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 lr(t){let e=!!t?.enabled,{summary:a}=T(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 dr(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}=T(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 cr(t){let e=!!t?.enabled,{summary:a}=T(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 pr(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-DSAOMV4O.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(l){throw new Error(`Invalid cron: ${l.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let l=0;l<3;l++)s=a(e,s,r),o.push(s.toISOString())}catch(l){throw new Error(`Cron preview failed: ${l.message}`)}return{human:n,next:o,timezone:r}}function ur(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=T(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 mr(t){let e=!!t?.enabled,{summary:a}=T(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 hr(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}=T(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 gr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=T(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function fr(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=he(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Le(n))try{Mn(n,r)}catch{}Jt(n,JSON.stringify(a,null,2)+`
|
|
4593
|
-
`,"utf-8");try{let s=G().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function ea(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function xr(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():"",l=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:i}=T(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:l},`orgChart "${e}" upserted`));return{summary:i}}async function vr(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=T(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 br(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}=T(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(i=>i.id===e),l={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...l}:o.business.projects.push(l),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function yr(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}=T(s=>{s.business=s.business||{},s.business.clients=s.business.clients||{};let l=!!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},l?`client "${e}" updated`:`client "${e}" configured`});return{summary:o}}async function wr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let{summary:a}=T(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 kr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=T(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 _r(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}=T(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 Er(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}=T(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(l=>{for(let i of a)if(l[i]!==t[i])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 Sr(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(i=>i.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:l}=T(i=>{i.boards=Array.isArray(i.boards)?i.boards:[];let c=i.boards.findIndex(m=>m.id===e),u={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(u.primaryToolLabel=r),c>=0){let m=i.boards[c];return i.boards[c]={...m,...u,columns:m.columns,labels:m.labels},`board "${e}" updated`}return i.boards.push(u),`board "${e}" added`});return{summary:l}}async function Tr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=T(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 Cr(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}=T(s=>{let i=(Array.isArray(s.boards)?s.boards:[]).find(m=>m.id===e);if(!i)throw new Error(`board "${e}" not found`);i.columns=Array.isArray(i.columns)?i.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 u=i.columns.findIndex(m=>m.id===a);return u>=0?(i.columns[u]={...i.columns[u],...c},`column "${a}" updated`):(i.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Ar(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}=T(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(i=>i.id===e);if(!s)throw new Error(`board "${e}" not found`);let l=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(i=>i.id!==a),s.columns.length===l)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function Mr(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{actionSchema:a}=await import("./types-H5ENIUIT.js");if(!t||typeof t!="object")throw new Error("body required");let n=a.safeParse(t);if(!n.success){let o=n.error.issues[0];throw new Error(`${o.path.join(".")||"<root>"}: ${o.message}`)}let r=new e().save(n.data);return{summary:`action "${r.id}" saved (${r.kind})`,action:r}}async function Ir(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),a=String(t?.id||"").trim();if(!a)throw new Error("id required");if(!new e().delete(a))throw new Error(`action "${a}" not found`);return{summary:`action "${a}" removed`}}async function $r(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{runAction:a}=await import("./runner-YRBVNYTY.js"),n=String(t?.id||"").trim();if(!n)throw new Error("id required");let r=new e().get(n);if(!r)throw new Error(`action "${n}" not found`);let o=t?.inputs&&typeof t.inputs=="object"?t.inputs:{},s=await a(r,o);return{summary:`action "${n}" ${s.ok?"ok":"failed"} (${s.durationMs}ms)`,result:s}}async function jr(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}=T(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 Lr(t){let{summary:e}=T(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`)}}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function Rr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=T(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[l,i]of Object.entries(t.triggers))typeof i=="string"&&i.trim()&&(s[String(l)]=i.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}}Ne();import{resolve as Or}from"path";function ta(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
4625
|
+
`)}catch{}return{summary:i}}function tr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let a=t?.patch||{},{summary:n}=T(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=la(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 ar(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Agent id is required.");let{summary:a}=T(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 nr(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}=T(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 rr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let a=t?.patch||{},{summary:n}=T(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 be(t){let{url:e,headers:a}=tt(),n=await fetch(e+t,{headers:a}),r=await n.text();if(!n.ok)throw new Error(`daemon ${n.status}: ${r.slice(0,200)}`);try{return JSON.parse(r)}catch{return{raw:r}}}async function ne(t,e){let{url:a,headers:n}=tt(),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 or(t,e){try{let{url:a,headers:n}=tt(),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 tt(){let t="http://127.0.0.1:18800",e={};try{let a=K();t=a.dashboard.daemonUrl?.replace(/\/+$/,"")||t,a.dashboard.token&&(e.Authorization=`Bearer ${a.dashboard.token}`)}catch{}return{url:t,headers:e}}function ye(t){let a=et()?.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 Ze(t,e){try{return new URL(t.url||"/","http://localhost").searchParams.get(e)||""}catch{return""}}function sr(t){let e=Ze(t,"agent").trim();if(!e)throw new Error("agent= query param is required.");let a=ue(ye(e));return{agentId:e,...a}}function ir(t){let e=Ze(t,"agent").trim(),a=Ze(t,"path").trim();if(!e||!a)throw new Error("agent= and path= query params are required.");return Ee(ye(e),a)}function lr(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=Se(ye(e),a,n);return{summary:`saved ${a} (${r.bytes} bytes)`,...r}}function dr(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=Te(ye(e),a,{title:n,content:r});return{summary:`added skill "${a}"`,...o}}function cr(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=Ce(ye(e),a);return{summary:`removed skill "${a}"`,...n}}function pr(t){let e=String(t?.agentId||"").trim(),a=String(t?.kind||"").trim(),n=String(t?.label||"").trim();if(!e)throw new Error("agentId is required");if(!a)throw new Error("kind is required");if(!n)throw new Error("label is required");let r={},o=t?.credentials||{};for(let i of["tokenEnv","privateAppTokenEnv","apiKeyEnv","refreshTokenEnv","clientIdEnv","clientSecretEnv"]){let c=o[i];if(typeof c=="string"&&c.trim()){if(!/^[A-Z][A-Z0-9_]*$/.test(c.trim()))throw new Error(`${i} must be uppercase identifier (got "${c}")`);r[i]=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[i,c]of Object.entries(t?.metadata||{}))(typeof c=="string"||typeof c=="number"||typeof c=="boolean")&&(s[i]=c);let{summary:l}=T(i=>{if(!i.agents?.[e])throw new Error(`Unknown agent "${e}"`);if(i.agents[e].integrations=Array.isArray(i.agents[e].integrations)?i.agents[e].integrations:[],i.agents[e].integrations.find(c=>c.kind===a&&c.label===n))throw new Error(`integration (${a}, ${n}) already exists on ${e}`);return i.agents[e].integrations.push({kind:a,label:n,credentials:r,metadata:s,enabled:!0}),`added ${a} integration "${n}" to ${e}`});return{summary:l}}function ur(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}=T(o=>{let s=o.agents?.[e];if(!s)throw new Error(`Unknown agent "${e}"`);let l=s.integrations||[],i=l.findIndex(c=>c.kind===a&&c.label===n);if(i===-1)throw new Error(`integration (${a}, ${n}) not found on ${e}`);return l.splice(i,1),`removed ${a} integration "${n}" from ${e}`});return{summary:r}}function mr(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}=T(s=>{let l=s.agents?.[e];if(!l)throw new Error(`Unknown agent "${e}"`);let c=(l.integrations||[]).find(m=>m.kind===a&&m.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 ia=["gitlab","github","sentry","stripe","vercel","odoo","hubspot","discord","slack","custom"];function hr(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(!ia.includes(a))throw new Error(`Unknown source: ${a}`);if(!n)throw new Error("Pick an agent to bind the webhook to.");let{summary:l}=T(i=>{if(s){if(!(i.mesh?.peers||[]).find(u=>u.name===s))throw new Error(`Mesh peer "${s}" not found in mesh.peers. Add the peer first or remove the node field.`)}else if(!i.agents?.[n])throw new Error(`Unknown agent "${n}". Add it locally, or set --node <peer> to forward to a mesh peer.`);if(i.webhooks=Array.isArray(i.webhooks)?i.webhooks:[],i.webhooks.find(m=>m.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),i.webhooks.push(c),`added webhook "${e}" (${a} \u2192 ${n}${s?` @ ${s}`:""})`});return{summary:l}}function gr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let a=t?.patch||{},{summary:n}=T(r=>{let o=(r.webhooks||[]).find(s=>s.id===e);if(!o)throw new Error(`Webhook "${e}" not found.`);if(typeof a.source=="string"&&ia.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 fr(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}=T(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(l=>l.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 xr(t){let e=String(t?.url||"").trim().replace(/\/+$/,"");if(!e)throw new Error("Peer URL is required.");let{summary:a}=T(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 vr(t){let e=!!t?.enabled,{summary:a}=T(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 br(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Webhook id is required.");let{summary:a}=T(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 yr(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}=T(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 wr(t){let e=!!t?.enabled,{summary:a}=T(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 kr(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}=T(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 _r(t){let e=!!t?.enabled,{summary:a}=T(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 Er(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}=T(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 Sr(t){let e=!!t?.enabled,{summary:a}=T(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 Tr(t){let e=String(t?.schedule||"").trim();if(!e)throw new Error("schedule is required");let{getNextCronDate:a}=await import("./scheduler-W5C43ZTE.js"),n;try{n=(await import("cronstrue")).default.toString(e,{use24HourTimeFormat:!1})}catch(l){throw new Error(`Invalid cron: ${l.message||"unknown"}`)}let r=Intl.DateTimeFormat().resolvedOptions().timeZone||"UTC",o=[],s=new Date;try{for(let l=0;l<3;l++)s=a(e,s,r),o.push(s.toISOString())}catch(l){throw new Error(`Cron preview failed: ${l.message}`)}return{human:n,next:o,timezone:r}}function Cr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Account id is required.");let{summary:a}=T(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 Ar(t){let e=!!t?.enabled,{summary:a}=T(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 Mr(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}=T(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 Ir(t){let e=String(t?.id||"").trim();if(!e)throw new Error("Cron id is required.");let{summary:a}=T(n=>{if(!n.crons?.[e])throw new Error(`Cron "${e}" not found.`);return delete n.crons[e],`removed cron "${e}"`});return{summary:a}}function $r(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=he(process.cwd(),"agentx.json"),r=`${n}.bak.${Date.now()}`;if(Pe(n))try{Un(n,r)}catch{}na(n,JSON.stringify(a,null,2)+`
|
|
4626
|
+
`,"utf-8");try{let s=K().dashboard.daemonUrl?.replace(/\/+$/,"")||"http://127.0.0.1:18800";fetch(`${s}/reload`,{method:"POST"}).catch(()=>null)}catch{}return{summary:"agentx.json replaced",backupPath:r}}function la(t){return String(t||"").split(/[,\s]+/).map(e=>e.trim()).filter(Boolean).filter((e,a,n)=>n.indexOf(e)===a)}async function jr(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():"",l=typeof t?.utilizationTarget=="number"?t.utilizationTarget:.8,{summary:i}=T(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:l},`orgChart "${e}" upserted`));return{summary:i}}async function Lr(t){let e=String(t?.agentId||"").trim();if(!e)throw new Error("agentId required");let{summary:a}=T(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 Rr(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}=T(o=>{o.business=o.business||{},o.business.projects=o.business.projects||[];let s=o.business.projects.findIndex(i=>i.id===e),l={id:e,...a?{pm:a}:{},...n?{client:n}:{}};return s>=0?o.business.projects[s]={...o.business.projects[s],...l}:o.business.projects.push(l),s>=0?`project "${e}" updated`:`project "${e}" added`});return{summary:r}}async function Pr(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}=T(s=>{s.business=s.business||{},s.business.clients=s.business.clients||{};let l=!!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},l?`client "${e}" updated`:`client "${e}" configured`});return{summary:o}}async function Dr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("client id required");let{summary:a}=T(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 Or(t){let e=String(t?.id||"").trim();if(!e)throw new Error("project id required");let{summary:a}=T(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 Hr(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}=T(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 Nr(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}=T(r=>{let o=r.business?.contactMap||[],s=o.length;if(r.business.contactMap=o.filter(l=>{for(let i of a)if(l[i]!==t[i])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 Br(t){let e=String(t?.id||"").trim(),a=String(t?.name||"").trim(),n=String(t?.projects||"").split(/[,\n]/).map(i=>i.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:l}=T(i=>{i.boards=Array.isArray(i.boards)?i.boards:[];let c=i.boards.findIndex(u=>u.id===e),m={id:e,name:a,source:{type:"gitlab",projects:n},timeRangeDays:o,closedWindowDays:s};if(r&&(m.primaryToolLabel=r),c>=0){let u=i.boards[c];return i.boards[c]={...u,...m,columns:u.columns,labels:u.labels},`board "${e}" updated`}return i.boards.push(m),`board "${e}" added`});return{summary:l}}async function zr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("id required");let{summary:a}=T(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 qr(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}=T(s=>{let i=(Array.isArray(s.boards)?s.boards:[]).find(u=>u.id===e);if(!i)throw new Error(`board "${e}" not found`);i.columns=Array.isArray(i.columns)?i.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 m=i.columns.findIndex(u=>u.id===a);return m>=0?(i.columns[m]={...i.columns[m],...c},`column "${a}" updated`):(i.columns.push(c),`column "${a}" added to board "${e}"`)});return{summary:o}}async function Fr(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}=T(r=>{let s=(Array.isArray(r.boards)?r.boards:[]).find(i=>i.id===e);if(!s)throw new Error(`board "${e}" not found`);let l=(s.columns||[]).length;if(s.columns=(s.columns||[]).filter(i=>i.id!==a),s.columns.length===l)throw new Error(`column "${a}" not found`);return`column "${a}" removed from board "${e}"`});return{summary:n}}async function Ur(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{actionSchema:a}=await import("./types-H5ENIUIT.js");if(!t||typeof t!="object")throw new Error("body required");let n=a.safeParse(t);if(!n.success){let o=n.error.issues[0];throw new Error(`${o.path.join(".")||"<root>"}: ${o.message}`)}let r=new e().save(n.data);return{summary:`action "${r.id}" saved (${r.kind})`,action:r}}async function Wr(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),a=String(t?.id||"").trim();if(!a)throw new Error("id required");if(!new e().delete(a))throw new Error(`action "${a}" not found`);return{summary:`action "${a}" removed`}}async function Gr(t){let{ActionStore:e}=await import("./store-MCOA6N4F.js"),{runAction:a}=await import("./runner-YRBVNYTY.js"),n=String(t?.id||"").trim();if(!n)throw new Error("id required");let r=new e().get(n);if(!r)throw new Error(`action "${n}" not found`);let o=t?.inputs&&typeof t.inputs=="object"?t.inputs:{},s=await a(r,o);return{summary:`action "${n}" ${s.ok?"ok":"failed"} (${s.durationMs}ms)`,result:s}}async function Xr(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}=T(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 Kr(t){let{summary:e}=T(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`)}}if(n.length===0)throw new Error("nothing to update");return`notifications updated (${n.join(", ")})`});return{summary:e}}async function Jr(t){let e=String(t?.id||"").trim();if(!e)throw new Error("webhook id required");let{summary:a}=T(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[l,i]of Object.entries(t.triggers))typeof i=="string"&&i.trim()&&(s[String(l)]=i.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}}Ue();import{resolve as Qr}from"path";function da(t={}){let e=t.localToken?`<script>window.AX_LOCAL_TOKEN = ${JSON.stringify(t.localToken)};</script>`:"",a=`<div id="msg" class="msg"></div>
|
|
4594
4627
|
|
|
4595
4628
|
<div id="disabled-banner" class="banner warn" style="display:none">
|
|
4596
4629
|
<b>Graph is disabled.</b> Set <code class="mono">graph.enabled: true</code>
|
|
@@ -4645,7 +4678,7 @@ ${s||"You are "+a+"."}
|
|
|
4645
4678
|
<h2>Recent classifications</h2>
|
|
4646
4679
|
<p class="muted">Last 25 log rows, newest first \u2014 approved / pending / rejected.</p>
|
|
4647
4680
|
<div id="recent"></div>
|
|
4648
|
-
</section>`;return
|
|
4681
|
+
</section>`;return M({title:"AgentX \xB7 Intent Graph",activeTab:"graph",subtitle:"Intent Graph",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Vr,scripts:`${e}<script>${Yr}</script>`})}var Vr=`
|
|
4649
4682
|
main { max-width: 1200px; margin: 0 auto; padding: 24px 20px 60px; }
|
|
4650
4683
|
h2 { margin: 0 0 12px; font-size: 16px; font-weight: 600; letter-spacing: -0.01em; }
|
|
4651
4684
|
.grid { display: grid; gap: 20px; grid-template-columns: 1fr; }
|
|
@@ -4749,7 +4782,7 @@ details {
|
|
|
4749
4782
|
border-radius: 4px; padding: 8px 12px; margin-top: 8px;
|
|
4750
4783
|
}
|
|
4751
4784
|
details summary { cursor: pointer; font-size: 11px; color: var(--ax-muted); user-select: none; }
|
|
4752
|
-
details[open] summary { margin-bottom: 8px; }`,
|
|
4785
|
+
details[open] summary { margin-bottom: 8px; }`,Yr=`
|
|
4753
4786
|
const $ = (id) => document.getElementById(id);
|
|
4754
4787
|
const state = { schema: null, nodes: [], pending: [], recent: [] };
|
|
4755
4788
|
|
|
@@ -4969,7 +5002,7 @@ $('btn-save-schema').addEventListener('click', async () => {
|
|
|
4969
5002
|
$('btn-reload-schema').addEventListener('click', refresh);
|
|
4970
5003
|
|
|
4971
5004
|
refresh();
|
|
4972
|
-
`;function
|
|
5005
|
+
`;function pa(t,e,a=[],n){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(da({peers:a,localToken:n}))}async function ua(t,e,a){try{let n=t.method==="GET"?void 0:await io(t),r=Zr(),o={"GET /api/admin/graph/state":()=>eo(r),"POST /api/admin/graph/classifications/approve":()=>to(r,n),"POST /api/admin/graph/classifications/reject":()=>ao(r,n),"POST /api/admin/graph/nodes":()=>no(r,n),"PATCH /api/admin/graph/nodes":()=>ro(r,n),"DELETE /api/admin/graph/nodes":()=>oo(r,n),"PUT /api/admin/graph/schema":()=>so(r,n)},s=`${t.method} ${a}`,l=o[s];if(!l){at(e,404,{error:`unknown graph endpoint: ${s}`});return}let i=await l();at(e,200,i)}catch(n){at(e,400,{error:n?.message||"graph op failed"})}}function Zr(){let t=K(),e=Qr(process.cwd(),t.graph.baseDir);return new kt({baseDir:e})}function eo(t){let e=K(),a=t.loadSchema(),n=t.loadNodes().nodes,r=t.readRecentClassifications(100),o=t.loadIndex().entries,s=new Map;for(let i of r)s.has(i.msgHash)||s.set(i.msgHash,i);let l=[];for(let i of s.values())i.status==="pending"&&!o[i.msgHash]&&l.push(i);return{enabled:e.graph.enabled,schema:a,nodes:n,pending:l,recent:r.slice(0,25),counts:{nodes:n.length,pending:l.length,fingerprints:Object.keys(o).length}}}function to(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=ma(t,a);return Array.isArray(e?.path)&&e.path.length>0&&(n.path=e.path.map(r=>String(r))),e?.proposedAxes&&typeof e.proposedAxes=="object"&&(n.proposedAxes=nt(e.proposedAxes)),t.approveClassification(n),{summary:`Approved ${n.msgHash}`}}function ao(t,e){let a=String(e?.msgHash||"").trim();if(!a)throw new Error("msgHash is required");let n=ma(t,a);return t.rejectClassification(n),{summary:`Rejected ${n.msgHash}`}}function ma(t,e){let n=t.readRecentClassifications(500).find(r=>r.msgHash===e);if(!n)throw new Error(`No classification found for ${e}`);return n}function no(t,e){let a=ca(String(e?.id||"")),n=String(e?.level||"").trim(),r=e?.parentId?ca(String(e.parentId)):null,o=nt({[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 ro(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");let n=nt({[a]:e?.axes||{}})[a]||{};return{node:t.updateNodeAxes(a,n)}}function oo(t,e){let a=String(e?.id||"").trim();if(!a)throw new Error("id is required");return t.deleteNode(a),{summary:`Deleted ${a}`}}function so(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 nt(t){let e={};for(let[a,n]of Object.entries(t||{})){if(!n||typeof n!="object")continue;let r={};for(let[o,s]of Object.entries(n))typeof s=="string"&&(r[o]=s);e[a]=r}return e}function ca(t){return t.trim().toLowerCase().replace(/[^a-z0-9_-]+/g,"-").replace(/^-+|-+$/g,"")}function at(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function io(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)})}import{resolve as po}from"path";import{existsSync as uo}from"fs";import mo from"better-sqlite3";function ha(t={}){let e=`<div class="ax-obs">
|
|
4973
5006
|
<header class="ax-obs__head">
|
|
4974
5007
|
<h1>Health</h1>
|
|
4975
5008
|
<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>
|
|
@@ -5091,7 +5124,7 @@ refresh();
|
|
|
5091
5124
|
</div>
|
|
5092
5125
|
<div id="obs-doctor-body" class="ax-obs__doctor-body"></div>
|
|
5093
5126
|
</section>
|
|
5094
|
-
</div>`;return
|
|
5127
|
+
</div>`;return M({title:"AgentX \xB7 Health",activeTab:"health",subtitle:"Health",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:lo,scripts:`<script>${co}</script>`})}var lo=`
|
|
5095
5128
|
.ax-obs { padding: 16px 24px; }
|
|
5096
5129
|
.ax-obs__head { margin-bottom: 16px; }
|
|
5097
5130
|
.ax-obs__head h1 { margin: 0 0 4px; font-size: 18px; }
|
|
@@ -5208,7 +5241,7 @@ refresh();
|
|
|
5208
5241
|
.ax-obs__doctor-title { font-size: 12px; font-weight: 500; }
|
|
5209
5242
|
.ax-obs__doctor-detail { font-size: 11px; color: var(--ax-muted); margin-top: 2px; font-family: 'IBM Plex Mono', monospace; word-break: break-word; }
|
|
5210
5243
|
.ax-obs__doctor-fix { font-size: 11px; color: var(--ax-accent, #3a7bd5); margin-top: 2px; }
|
|
5211
|
-
`,
|
|
5244
|
+
`,co=`
|
|
5212
5245
|
(function(){
|
|
5213
5246
|
var panes = document.querySelectorAll('.ax-obs__pane');
|
|
5214
5247
|
var tabs = document.querySelectorAll('.ax-obs__tab');
|
|
@@ -5592,23 +5625,23 @@ refresh();
|
|
|
5592
5625
|
|
|
5593
5626
|
load(current);
|
|
5594
5627
|
})();
|
|
5595
|
-
`;var
|
|
5628
|
+
`;var xa={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 va(t){let e=(t||"").toLowerCase();return e.includes("opus")?"opus":e.includes("haiku")?"haiku":e.includes("sonnet")||e.includes("claude")?"sonnet":"external"}function rt(t){let e=xa[va(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 ho(){let t=po(process.cwd(),".agentx/db.sqlite");if(!uo(t))return null;try{let e=new mo(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch{return null}}function ba(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ha({peers:a}))}function go(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 re(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}async function ya(t,e,a){if(!a.startsWith("/api/admin/observability/"))return!1;let n=a.replace(/^\/api\/admin\/observability\//,"").split("?")[0],r=ho();if(!r)return re(e,503,{error:"operational SQLite not available",rows:[]}),!0;try{let{limit:o,agent:s}=go(t);if(n==="routing"){let l=[],i={limit:o};s&&(l.push("agent_id = @agent"),i.agent=s);let c=`
|
|
5596
5629
|
SELECT at, channel, chat_id, account_id, kind, deciding_stage, agent_id, reason
|
|
5597
5630
|
FROM route_traces
|
|
5598
5631
|
${l.length?"WHERE "+l.join(" AND "):""}
|
|
5599
5632
|
ORDER BY at DESC LIMIT @limit
|
|
5600
|
-
`,
|
|
5633
|
+
`,m=r.db.prepare(c).all(i);return re(e,200,{rows:m}),!0}if(n==="rotations"){let l=[],i={limit:o};s&&(l.push("agent_id = @agent"),i.agent=s);let c=`
|
|
5601
5634
|
SELECT rotated_at, agent_id, channel, reason, last_turn_input_tokens
|
|
5602
5635
|
FROM rotations
|
|
5603
5636
|
${l.length?"WHERE "+l.join(" AND "):""}
|
|
5604
5637
|
ORDER BY rotated_at DESC LIMIT @limit
|
|
5605
|
-
`,
|
|
5638
|
+
`,m=r.db.prepare(c).all(i);return re(e,200,{rows:m}),!0}if(n==="errors"){let l=["status = 'error'"],i={limit:o};s&&(l.push("agent_id = @agent"),i.agent=s);let c=`
|
|
5606
5639
|
SELECT started_at, agent_id, channel, message_preview, error
|
|
5607
5640
|
FROM task_history
|
|
5608
5641
|
WHERE ${l.join(" AND ")}
|
|
5609
5642
|
ORDER BY started_at DESC LIMIT @limit
|
|
5610
|
-
`,
|
|
5611
|
-
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function
|
|
5643
|
+
`,u=r.db.prepare(c).all(i).map(g=>({...g,plain:wa(g.error)}));return re(e,200,{rows:u}),!0}if(n==="summary"||n==="overview")return re(e,200,fo(r.db)),!0;if(n==="activity")return re(e,200,xo(r.db,{agent:s})),!0;if(n==="cost"){let l=new URL(t.url||"/","http://_"),i=ga(l.searchParams.get("range"));return re(e,200,fa(r.db,i)),!0}if(n==="cost.csv"){let l=new URL(t.url||"/","http://_"),i=ga(l.searchParams.get("range")),c=fa(r.db,i),m=vo(c.days);return e.writeHead(200,{"Content-Type":"text/csv; charset=utf-8","Content-Disposition":`attachment; filename="agentx-cost-${i||"all"}d-${Date.now()}.csv"`}),e.end(m),!0}return re(e,404,{error:"unknown observability slice",rows:[]}),!0}catch(o){return re(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function wa(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(`
|
|
5644
|
+
`)[0].slice(0,80)+(e.length>80?"\u2026":""):"unknown failure"}function fo(t){let e=new Date,a=new Date(e.getFullYear(),e.getMonth(),e.getDate()).toISOString(),n=new Date(e.getTime()-864e5),r=new Date(n.getFullYear(),n.getMonth(),n.getDate()).toISOString(),o=new Date(e.getTime()-864e5).toISOString(),s=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ?").get(a).n,l=t.prepare("SELECT COUNT(*) AS n FROM task_history WHERE started_at >= ? AND started_at < ?").get(r,a).n,i=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,m=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),u=w=>m.length?m[Math.min(m.length-1,Math.floor(m.length*w))].duration_ms:0,g=u(.5),b=u(.95),I=t.prepare("SELECT * FROM usage_daily WHERE day = date('now')").all().reduce((w,A)=>w+rt(A),0),E=t.prepare("SELECT * FROM usage_daily WHERE day = date('now', '-1 day')").all().reduce((w,A)=>w+rt(A),0),S=t.prepare(`
|
|
5612
5645
|
SELECT agent_id,
|
|
5613
5646
|
COUNT(*) AS tasks,
|
|
5614
5647
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors,
|
|
@@ -5626,12 +5659,12 @@ refresh();
|
|
|
5626
5659
|
WHERE started_at >= ?
|
|
5627
5660
|
GROUP BY channel
|
|
5628
5661
|
ORDER BY tasks DESC
|
|
5629
|
-
`).all(a),p=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(
|
|
5662
|
+
`).all(a),p=t.prepare("SELECT DISTINCT agent_id FROM usage_daily WHERE day >= date('now', '-7 day')").all().map(w=>w.agent_id),h=new Set(t.prepare("SELECT DISTINCT agent_id FROM task_history WHERE started_at >= ?").all(o).map(w=>w.agent_id)),f=p.filter(w=>!h.has(w)),x=t.prepare(`
|
|
5630
5663
|
SELECT started_at, agent_id, channel, message_preview, error
|
|
5631
5664
|
FROM task_history
|
|
5632
5665
|
WHERE status='error' AND started_at >= ?
|
|
5633
5666
|
ORDER BY started_at DESC LIMIT 5
|
|
5634
|
-
`).all(o).map(
|
|
5667
|
+
`).all(o).map(w=>({...w,plain:wa(w.error)}));return{kpis:{tasksToday:s,tasksDelta:s-l,errorsToday:i,errorRate:s>0?i/s:0,avgDurationMs:Math.round(c),p50DurationMs:g,p95DurationMs:b,spendToday:I,spendDelta:I-E,idleAgentCount:f.length},perAgent:S,perChannel:d,idleAgents:f,recentErrors:x}}function xo(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(`
|
|
5635
5668
|
SELECT strftime('%Y-%m-%dT%H:00', started_at) AS hour,
|
|
5636
5669
|
COUNT(*) AS tasks,
|
|
5637
5670
|
SUM(CASE WHEN status='error' THEN 1 ELSE 0 END) AS errors
|
|
@@ -5658,7 +5691,7 @@ refresh();
|
|
|
5658
5691
|
WHERE started_at >= @since
|
|
5659
5692
|
GROUP BY agent_id
|
|
5660
5693
|
ORDER BY tasks_24h DESC, tasks_7d DESC
|
|
5661
|
-
`).all({since:n,last24:a});return{hourly:s,daily:l,perAgent:i}}function
|
|
5694
|
+
`).all({since:n,last24:a});return{hourly:s,daily:l,perAgent:i}}function ga(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 fa(t,e){let a=e>0?`WHERE day >= date('now', '-${e} day')`:"",n=t.prepare(`
|
|
5662
5695
|
SELECT day, agent_id, model,
|
|
5663
5696
|
input_tokens, output_tokens, cache_read_tokens, cache_create_tokens,
|
|
5664
5697
|
tier2_input_tokens, tier2_output_tokens, tier2_cache_read_tokens, tier2_cache_create_tokens,
|
|
@@ -5666,37 +5699,37 @@ refresh();
|
|
|
5666
5699
|
FROM usage_daily
|
|
5667
5700
|
${a}
|
|
5668
5701
|
ORDER BY day
|
|
5669
|
-
`).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),l=new Date(Date.now()-14*864e5).toISOString().slice(0,10),i=0,c=0,
|
|
5702
|
+
`).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),l=new Date(Date.now()-14*864e5).toISOString().slice(0,10),i=0,c=0,m=0,u=0,g=0,b=0,_=0,I=0,E=0,S={},d={};for(let k of n){let C=rt(k),L=va(k.model),R=xa[L],N=(k.tier2_input_tokens||0)/1e6*R.input*.5+(k.tier2_output_tokens||0)/1e6*R.output*.5+(k.tier2_cache_read_tokens||0)/1e6*R.cacheRead*.5+(k.tier2_cache_create_tokens||0)/1e6*R.cacheCreate*.5,Y=(k.input_tokens||0)+(k.tier2_input_tokens||0),B=(k.output_tokens||0)+(k.tier2_output_tokens||0),O=(k.cache_read_tokens||0)+(k.tier2_cache_read_tokens||0),H=(k.cache_create_tokens||0)+(k.tier2_cache_create_tokens||0);u+=C,k.day>=s&&(m+=C,_+=k.tasks||0),k.day>=l&&k.day<s&&(E+=C,I+=k.tasks||0),k.day===r&&(i+=C),k.day===o&&(c+=C),k.day===r&&(g+=N),k.day>=s&&(b+=N);let G=S[k.day]||(S[k.day]={date:k.day,tasks:0,input:0,output:0,cacheRead:0,cacheCreate:0,cost:0,tier2:0,agents:{}});G.tasks+=k.tasks||0,G.input+=Y,G.output+=B,G.cacheRead+=O,G.cacheCreate+=H,G.cost+=C,G.tier2+=N;let z=G.agents[k.agent_id]||(G.agents[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});z.tasks+=k.tasks||0,z.cost+=C,z.tier2+=N,z.input+=Y,z.output+=B,z.cacheRead+=O,z.cacheCreate+=H,k.model&&(z.model=k.model);let X=d[k.agent_id]||(d[k.agent_id]={tasks:0,cost:0,input:0,output:0,cacheRead:0,cacheCreate:0,tier2:0,model:k.model});X.tasks+=k.tasks||0,X.cost+=C,X.tier2+=N,X.input+=Y,X.output+=B,X.cacheRead+=O,X.cacheCreate+=H,k.model&&(X.model=k.model)}let p=Object.values(S).sort((k,C)=>k.date<C.date?-1:1),h=0,f=0,y=0,x=0,w=0,A=0;for(let k of p)h+=k.tasks,f+=k.input,y+=k.output,x+=k.cacheRead,w+=k.cacheCreate,A+=k.cost;let $=Object.entries(d).map(([k,C])=>({agent_id:k,...C,tokens:C.input+C.output+C.cacheRead+C.cacheCreate})).sort((k,C)=>C.cost-k.cost);return{range:e,generatedAt:new Date().toISOString(),kpis:{spendToday:i,spendYesterday:c,spend7d:m,spend30d:u,tier2Today:g,tier2_7d:b,tier2PctToday:i>0?g/i:0,spendRange:A,avgDailyRange:p.length?A/p.length:0,tasksRange:h,tokensRange:f+y+x+w,cacheHitRange:x+f>0?x/(x+f):0,costPerTaskRange:h>0?A/h:0,spendDeltaWoW:E>0?(m-E)/E:0,tasksDeltaWoW:I>0?(_-I)/I:0},days:p,perAgent:$}}function vo(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+`
|
|
5670
5703
|
`+a.join(`
|
|
5671
5704
|
`)+`
|
|
5672
|
-
`}import{resolve as
|
|
5705
|
+
`}import{resolve as bo}from"path";import{existsSync as yo}from"fs";import wo from"better-sqlite3";function ko(){let t=bo(process.cwd(),".agentx/intent/ledger.sqlite");if(!yo(t))return null;try{let e=new wo(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-ka>6e4&&(ka=a,console.error(`[ledger-panel] openReadOnly failed: ${e?.message??e}`)),null}}var ka=0;function ce(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function _o(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 _a(t,e,a){if(!a.startsWith("/api/admin/ledger/"))return!1;let n=a.replace(/^\/api\/admin\/ledger\//,"").split("?")[0],r=ko();if(!r)return ce(e,503,{error:"intent ledger not available",rows:[]}),!0;try{let o=new URL(t.url||"/","http://_"),s=_o(o.searchParams.get("since")),l=o.searchParams.get("source")||"",i=o.searchParams.get("project")||"",c=parseInt(o.searchParams.get("limit")||"50",10),m=Number.isFinite(c)?Math.max(1,Math.min(500,c)):50;if(n==="stats"){let u=s!==void 0?"WHERE ts >= @since":"",g=s!==void 0?"WHERE decided_at >= @since":"",b=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_events ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),_=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_decisions ${g}`).get({since:s}).n,I=r.db.prepare(`SELECT outcome, COUNT(*) AS n FROM intent_decisions ${g} GROUP BY outcome ORDER BY n DESC`).all({since:s}),E=r.db.prepare(`SELECT COUNT(*) AS n FROM intent_divergences ${u}`).get({since:s}).n,S=r.db.prepare(`SELECT source, COUNT(*) AS n FROM intent_divergences ${u} GROUP BY source ORDER BY n DESC`).all({since:s}),d=r.db.prepare(`
|
|
5673
5706
|
SELECT COUNT(*) AS n FROM intent_decisions d
|
|
5674
5707
|
LEFT JOIN intent_resolutions r
|
|
5675
5708
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
5676
5709
|
WHERE d.outcome = 'dispatched' AND r.decision_event_id IS NULL
|
|
5677
|
-
`).get().n;return
|
|
5710
|
+
`).get().n;return ce(e,200,{since:s??null,eventsBySource:b,totalDecisions:_,decisionsByOutcome:I,totalDivergences:E,divergencesBySource:S,inFlight:d}),!0}if(n==="events"){let u=[],g={limit:m};s!==void 0&&(u.push("ts >= @since"),g.since=s),l&&(u.push("source = @source"),g.source=l),i&&(u.push("project = @project"),g.project=i);let b=`
|
|
5678
5711
|
SELECT id, ts, source, source_event_id, project, subject, intent
|
|
5679
5712
|
FROM intent_events
|
|
5680
|
-
${
|
|
5713
|
+
${u.length?"WHERE "+u.join(" AND "):""}
|
|
5681
5714
|
ORDER BY ts DESC LIMIT @limit
|
|
5682
|
-
`;return
|
|
5715
|
+
`;return ce(e,200,{rows:r.db.prepare(b).all(g)}),!0}if(n==="divergences"){let u=[],g={limit:m};s!==void 0&&(u.push("ts >= @since"),g.since=s),l&&(u.push("source = @source"),g.source=l);let b=`
|
|
5683
5716
|
SELECT ts, source, decided_by,
|
|
5684
5717
|
legacy_agent_id, legacy_outcome, legacy_reason,
|
|
5685
5718
|
ledger_agent_id, ledger_outcome, ledger_reason,
|
|
5686
5719
|
event_id
|
|
5687
5720
|
FROM intent_divergences
|
|
5688
|
-
${
|
|
5721
|
+
${u.length?"WHERE "+u.join(" AND "):""}
|
|
5689
5722
|
ORDER BY ts DESC LIMIT @limit
|
|
5690
|
-
`;return
|
|
5723
|
+
`;return ce(e,200,{rows:r.db.prepare(b).all(g)}),!0}if(n==="active"){let u=["d.outcome = 'dispatched'","r.decision_event_id IS NULL"],g={limit:m};l&&(u.push("e.source = @source"),g.source=l);let b=`
|
|
5691
5724
|
SELECT e.id AS event_id, e.ts, e.source, e.project, e.subject, e.intent,
|
|
5692
5725
|
d.decided_by, d.decided_at, d.agent_id, d.reason
|
|
5693
5726
|
FROM intent_decisions d
|
|
5694
5727
|
JOIN intent_events e ON e.id = d.event_id
|
|
5695
5728
|
LEFT JOIN intent_resolutions r
|
|
5696
5729
|
ON r.decision_event_id = d.event_id AND r.decision_decided_by = d.decided_by
|
|
5697
|
-
WHERE ${
|
|
5730
|
+
WHERE ${u.join(" AND ")}
|
|
5698
5731
|
ORDER BY d.decided_at DESC LIMIT @limit
|
|
5699
|
-
`;return
|
|
5732
|
+
`;return ce(e,200,{rows:r.db.prepare(b).all(g)}),!0}return ce(e,404,{error:"unknown ledger slice",rows:[]}),!0}catch(o){return ce(e,500,{error:o?.message??String(o),rows:[]}),!0}finally{r.close()}}function Ea(t={}){return M({title:"AgentX \xB7 Ledger",activeTab:"graph",subtitle:"Ledger",body:`<div class="ax-led">
|
|
5700
5733
|
<header class="ax-led__head">
|
|
5701
5734
|
<h1>Intent ledger</h1>
|
|
5702
5735
|
<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>
|
|
@@ -5901,7 +5934,7 @@ refresh();
|
|
|
5901
5934
|
}
|
|
5902
5935
|
load();
|
|
5903
5936
|
})();
|
|
5904
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
5937
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Sa(t={}){return M({title:"AgentX \xB7 Cost",activeTab:"cost",subtitle:"Cost",body:`<div class="ax-cost">
|
|
5905
5938
|
<header class="ax-cost__head">
|
|
5906
5939
|
<div>
|
|
5907
5940
|
<h1>Cost</h1>
|
|
@@ -6474,7 +6507,7 @@ refresh();
|
|
|
6474
6507
|
load();
|
|
6475
6508
|
setInterval(load, 30000);
|
|
6476
6509
|
})();
|
|
6477
|
-
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function
|
|
6510
|
+
</script>`,peers:t.peers,currentPeerId:t.currentPeerId})}function Ta(t={}){let e=`<div class="ax-pj__root">
|
|
6478
6511
|
<aside class="ax-pj__list">
|
|
6479
6512
|
<header>
|
|
6480
6513
|
<h2>Projects</h2>
|
|
@@ -6501,7 +6534,7 @@ refresh();
|
|
|
6501
6534
|
</header>
|
|
6502
6535
|
<div id="pj-detail-body" class="ax-pj__detail-body"></div>
|
|
6503
6536
|
</section>
|
|
6504
|
-
</div>`;return
|
|
6537
|
+
</div>`;return M({title:"AgentX \xB7 Projects",activeTab:"projects",subtitle:"Projects",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Eo,scripts:`<script>${So}</script>`})}var Eo=`
|
|
6505
6538
|
.ax-pj__root {
|
|
6506
6539
|
display: grid;
|
|
6507
6540
|
grid-template-columns: 360px 1fr;
|
|
@@ -6688,7 +6721,7 @@ refresh();
|
|
|
6688
6721
|
}
|
|
6689
6722
|
.ax-pj__warn { color: var(--ax-warn, #facc15); border-top: 1px solid var(--ax-border); }
|
|
6690
6723
|
.ax-pj__hint { font-size: 11px; color: var(--ax-fg-muted, var(--ax-text)); margin-top: 4px; }
|
|
6691
|
-
`,
|
|
6724
|
+
`,So=`
|
|
6692
6725
|
(function(){
|
|
6693
6726
|
const $ = (sel) => document.querySelector(sel);
|
|
6694
6727
|
const esc = (s) => String(s == null ? "" : s).replace(/[&<>"]/g, (c) => ({"&":"&","<":"<",">":">","\\"":"""}[c]));
|
|
@@ -7338,43 +7371,31 @@ refresh();
|
|
|
7338
7371
|
load();
|
|
7339
7372
|
});
|
|
7340
7373
|
})();
|
|
7341
|
-
`;import{resolve as
|
|
7342
|
-
html, body { height: 100%; }
|
|
7343
|
-
body { margin: 0; }
|
|
7344
|
-
#ax-fleet-root { height: calc(100vh - 48px); }
|
|
7345
|
-
#ax-fleet-root:empty::before {
|
|
7346
|
-
content: "Loading fleet snapshot\u2026";
|
|
7347
|
-
display: block;
|
|
7348
|
-
padding: 40px 24px;
|
|
7349
|
-
color: var(--ax-muted);
|
|
7350
|
-
font: 13px/1 -apple-system, BlinkMacSystemFont, sans-serif;
|
|
7351
|
-
text-align: center;
|
|
7352
|
-
}
|
|
7353
|
-
`;function Re(){let t=nt(process.cwd(),".agentx/intent/ledger.sqlite");if(!rt(t))return null;try{let e=new go(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-ya>6e4&&(ya=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var ya=0;function ne(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function _a(t,e,a=[]){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(ba({peers:a}))}var ge={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:"API",color:"#3a7bd5"}};function fo(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in ge)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in ge)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in ge)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 ge)return s}return"workflow"}return t}function xo(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 vo(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 Ea(t,e,a){return _t(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 bo(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:B(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 i=o.slice(6);if(i&&!at(i))return{id:i,name:i,avatar:B(i),kind:"a2a"}}let l=o||r||s;if(l&&!at(r||o||"")){let i=r||o||s,c=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":"mesh";return{id:i,name:o||r||i,avatar:B(l),kind:c}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,l=typeof s.username=="string"?s.username:null,i=typeof s.name=="string"?s.name:null,c=l||(s.id!=null?String(s.id):null)||i;if(c&&!at(l||i||"")){let u=typeof n.channel=="string"?n.channel:"",m=wa(u);return{id:c,name:i||l||c,avatar:B(i||l||c),kind:m}}}let o=n.issueEvent||n.webhookEvent;if(o&&typeof o=="object"){let s=o.user;if(s&&typeof s=="object"&&(s.username||s.name)){let i=s.username||s.name,c=s.name||s.username;return{id:i,name:c,avatar:B(c),kind:"gitlab"}}let l=o.sender;if(l?.login)return{id:l.login,name:l.login,avatar:B(l.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 l=o||r||s;return{id:s,name:l,avatar:B(l),kind:wa(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:B(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:B(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:B(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:B(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:B(o),kind:"whatsapp"}}}return null}function wa(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function at(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 B(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 Sa(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}
|
|
7374
|
+
`;import{resolve as it,join as No}from"path";import{existsSync as lt,readdirSync as Bo,readFileSync as zo}from"fs";import qo from"better-sqlite3";var Aa=String.raw`[\w.-]+(?:/[\w.-]+)+`,To=new RegExp(`^(?:chat:)?(${Aa}):(?:issue|issues|merge_request|mr|pull|pr)s?:\\d+`),Co=new RegExp(`^\\[(?:GitLab|GitHub) (${Aa}) `);function Ca(t){if(!t)return null;let e=t.match(To);return e?e[1]:null}function ot(t){if(!t)return null;let e=t.trimStart().match(Co);return e?e[1]:null}function De(t,e,a){let n=t&&typeof t=="object"?t.context:null;return n&&typeof n.project=="string"&&n.project.trim()?n.project.trim():Ca(typeof n?.chatId=="string"?n.chatId:null)??Ca(e)??ot(a)}function Ao(t){let[e,...a]=t.split("/");return!a.length||e==="unmapped"||a[0].startsWith("_")?null:t}function Oe(t,e){return`${t}${e.kind==="mr"?"!":"#"}${e.n}`}var Mo=/\b(issue|merge_request|pull|MR|Issue)s?[:\s]+[#!]?(\d+)/,Io=/^\[(?:GitLab|GitHub) \S+ (issue|merge_request|pull|MR|Issue)s? [#!]?(\d+)/i,$o=t=>/^issue/i.test(t)?"issue":"mr";function jo(t){let e=t.subject.match(Mo)??t.inputPreview.trimStart().match(Io);return e?{kind:$o(e[1]),n:Number(e[2])}:null}function Lo(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 Ma(t){if(!Ao(t.projectId))return[];let e=jo(t);return e?[e]:Lo(t.inputPreview)}var Ro=6e4,Po=5*6e4,Do=40,Ia=6,$a=new Map;function ja(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 Ma(n)){let s=Oe(n.projectId,o);if(e.has(s)||e.set(s,{project:n.projectId,ref:o,github:r}),e.size>=Do)return[...e.values()]}}return[...e.values()]}async function La(t,e,a=fetch,n=Date.now()){let r={},o=[];for(let s of t){let l=Oe(s.project,s.ref),i=$a.get(l);i&&n-i.at<(s.github?Po:Ro)?i.item&&(r[l]=i.item):o.push(s)}for(let s=0;s<o.length;s+=Ia)await Promise.all(o.slice(s,s+Ia).map(async l=>{let i=Oe(l.project,l.ref),c=null;try{c=l.github?await Ho(l,e,a):await Oo(l,e,a)}catch{}$a.set(i,{at:n,item:c}),c&&(r[i]=c)}));return r}async function Ra(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 Oo(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 Ra(`${r}/${o}`,{"PRIVATE-TOKEN":n.token},a);if(!s)return null;let l=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:l&&typeof l.status=="string"?{status:l.status,url:String(l.web_url??"")}:null,mergedAt:s.merged_at?Date.parse(s.merged_at):null}}async function Ho(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 Ra(`https://api.github.com/repos/${t.project}/${n}`,r,a);return o?{kind:t.ref.kind,project:t.project,n:t.ref.n,title:String(o.title??""),state:o.merged_at?"merged":o.state==="open"?"opened":String(o.state??"opened"),draft:!!o.draft,url:String(o.html_url??""),pipeline:null,mergedAt:o.merged_at?Date.parse(o.merged_at):null}:null}function dt(){let t=it(process.cwd(),".agentx/intent/ledger.sqlite");if(!lt(t))return null;try{let e=new qo(t,{readonly:!0,fileMustExist:!0});return{db:e,close:()=>e.close()}}catch(e){let a=Date.now();return a-Pa>6e4&&(Pa=a,console.error(`[activity-graph] openLedger failed: ${e?.message??e}`)),null}}var Pa=0;function oe(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}var ge={gitlab:{label:"GitLab",color:"#fc6d26"},github:{label:"GitHub",color:"#6e7681"},telegram:{label:"Telegram",color:"#0088cc"},whatsapp:{label:"WhatsApp",color:"#25d366"},slack:{label:"Slack",color:"#4a154b"},discord:{label:"Discord",color:"#5865f2"},mesh:{label:"Mesh (a2a)",color:"#bf8700"},a2a:{label:"Agent \u2192 Agent",color:"#bf8700"},cron:{label:"Cron",color:"#6b7280"},workflow:{label:"Workflow",color:"#9333ea"},api:{label:"Web API",color:"#3a7bd5"},mcp:{label:"Agent tools (MCP)",color:"#bf8700"},voice:{label:"Voice",color:"#e5534b"},desktop:{label:"Desktop assistant",color:"#8957e5"},opencode:{label:"OpenCode",color:"#57606a"}};function Fo(t,e,a){if(t==="mesh"){let n=a?.context?.channel;if(typeof n=="string"&&n in ge)return n;if(e.startsWith("mesh.")){let r=e.slice(5);if(r==="a2a")return"a2a";if(r in ge)return r}return"mesh"}if(t==="workflow"){let n=a?.event?.payload,r=typeof n?.channel=="string"?n.channel:"";if(r&&r in ge)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 ge)return s}return"workflow"}return t}function Ha(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 Uo(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 Na(t,e,a){return It(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 Wo(t,e,a){if(!a||typeof a!="object")return null;if(t==="mesh"){if(typeof a.senderAgentId=="string"&&a.senderAgentId.trim()){let r=a.senderAgentId.trim();return{id:r,name:r,avatar:F(r),kind:"a2a"}}let n=a.context&&typeof a.context=="object"?a.context:null;if(n){let r=typeof n.senderUsername=="string"?n.senderUsername:null,o=typeof n.sender=="string"?n.sender:null,s=typeof n.senderId=="string"?n.senderId:null;if(o&&o.startsWith("agent:")){let i=o.slice(6);if(i&&!st(i))return{id:i,name:i,avatar:F(i),kind:"a2a"}}let l=o||r||s;if(l&&!st(r||o||"")){let i=r||o||s,c=e==="mesh.github"?"github":e==="mesh.gitlab"?"gitlab":e==="mesh.a2a"?"a2a":e==="mesh.voice"?"voice":e==="mesh.desktop"?"desktop":"mesh";return{id:i,name:o||r||i,avatar:F(l),kind:c}}}return e==="mesh.task"||e==="mesh.a2a"?{id:"__a2a",name:"Internal (A2A)",avatar:"\u21BB",kind:"a2a"}:null}if(t==="cron"){let n=typeof a.jobId=="string"?a.jobId:null;if(n)return{id:`cron:${n}`,name:`Cron: ${n}`,avatar:"\u23F1",kind:"cron"}}if(t==="workflow"){let n=a.event?.payload;if(n&&typeof n=="object"){if(n.sender&&typeof n.sender=="object"){let s=n.sender,l=typeof s.username=="string"?s.username:null,i=typeof s.name=="string"?s.name:null,c=l||(s.id!=null?String(s.id):null)||i;if(c&&!st(l||i||"")){let m=typeof n.channel=="string"?n.channel:"",u=Da(m);return{id:c,name:i||l||c,avatar:F(i||l||c),kind:u}}}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 i=s.username||s.name,c=s.name||s.username;return{id:i,name:c,avatar:F(c),kind:"gitlab"}}let l=o.sender;if(l?.login)return{id:l.login,name:l.login,avatar:F(l.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 l=o||r||s;return{id:s,name:l,avatar:F(l),kind:Da(t)}}}if(t==="gitlab"){let n=a.user||a.payload?.user;if(n&&typeof n=="object"&&(n.username||n.name)){let r=n.username||n.name,o=n.name||n.username;return{id:r,name:o,avatar:F(o),kind:"gitlab"}}}if(t==="github"){let n=a.sender||a.payload?.sender;if(n?.login)return{id:n.login,name:n.login,avatar:F(n.login),kind:"github"}}if(t==="telegram"){let n=a.message?.from||a.from;if(n?.username){let r=n.first_name||n.username;return{id:n.username,name:r,avatar:F(r),kind:"telegram"}}if(n?.id)return{id:String(n.id),name:n.first_name||`tg:${n.id}`,avatar:F(n.first_name||`tg${n.id}`),kind:"telegram"}}if(t==="whatsapp"){let n=a.from||a.payload?.from;if(n){let r=String(n),o=r.replace(/@.*$/,"");return{id:r,name:o,avatar:F(o),kind:"whatsapp"}}}return null}function Da(t){return t==="telegram"||t==="whatsapp"||t==="slack"||t==="discord"?t:"system"}function st(t){if(!t)return!1;let e=t.toLowerCase();return e==="graph-classifier"||e==="graph-agent"||e.startsWith("system:")||e.startsWith("internal:")||e.endsWith("-system")}function F(t){let e=String(t||"?").trim().split(/\s+/).filter(Boolean);return e.length>=2?(e[0][0]+e[1][0]).toUpperCase():String(t||"?").slice(0,2).toUpperCase()}function Ba(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}
|
|
7354
7375
|
${r}`:n)}e.comment?.body&&a.push(e.comment.body),e.issue?.title&&a.push(e.issue.title+(e.issue.body?`
|
|
7355
|
-
${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
|
|
7376
|
+
${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 Go(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 za(t,e,a){let n=Date.now(),r=n-a*3600*1e3,o=t.prepare(`
|
|
7356
7377
|
SELECT id, ts, source, project, subject, intent, raw_json
|
|
7357
7378
|
FROM intent_events WHERE ts >= ? ORDER BY ts ASC
|
|
7358
|
-
`).all(r),s=new Map,l=new Map;if(o.length>0){let
|
|
7379
|
+
`).all(r),s=new Map,l=new Map;if(o.length>0){let x=o.map(C=>C.id),w=x.map((C,L)=>`@id${L}`).join(","),A=Object.fromEntries(x.map((C,L)=>[`id${L}`,C])),$=t.prepare(`
|
|
7359
7380
|
SELECT event_id, decided_at, decided_by, agent_id, outcome, reason
|
|
7360
|
-
FROM intent_decisions WHERE event_id IN (${
|
|
7361
|
-
`).all(
|
|
7381
|
+
FROM intent_decisions WHERE event_id IN (${w}) ORDER BY decided_at ASC
|
|
7382
|
+
`).all(A);for(let C of $)s.has(C.event_id)||s.set(C.event_id,[]),s.get(C.event_id).push(C);let k=t.prepare(`
|
|
7362
7383
|
SELECT decision_event_id, decision_decided_by, resolved_at, status, duration_ms, result_summary
|
|
7363
|
-
FROM intent_resolutions WHERE decision_event_id IN (${
|
|
7364
|
-
`).all(
|
|
7384
|
+
FROM intent_resolutions WHERE decision_event_id IN (${w})
|
|
7385
|
+
`).all(A);for(let C of k)l.set(`${C.decision_event_id}|${C.decision_decided_by}`,C)}let i=new Map,c=new Map,m=new Map,u=new Map,g=[],b=e?.business?.projects??[],_=e?.business?.contactMap??[],I=Xe(e?.business??{});for(let x of o){let w=null;try{w=JSON.parse(x.raw_json)}catch{}let A=Na(x.source,w,_),$=Ba(x.source,w),k=x.project??De(w,x.subject,$),C=null,L=null;A?(C=A.client,L=A.project||`${A.client}/_chat`):k&&(C=_e(k,b),L=k);let R=Fo(x.source,x.intent||"",w),N=ge[R]||{label:R,color:"#6b7280"};m.has(R)||m.set(R,{id:R,label:N.label,color:N.color});let Y="__system",B,O=Wo(x.source,x.intent||"",w);if(O){Y=O.id,B=O.kind;let H=A?.displayName||O.name;(!u.has(O.id)||A?.displayName)&&u.set(O.id,{id:O.id,name:H,avatar:F(H),kind:O.kind})}else u.has("__system")||u.set("__system",{id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});for(let H of s.get(x.id)??[]){if(H.outcome!=="dispatched"||!H.agent_id)continue;let G=`${x.id}|${H.decided_by}`,z=l.get(G),X=H.decided_at,bt=z?.resolved_at??null,qe=bt===null,_n=z?.duration_ms??(qe?n-X:0),En=qe?"active":z?.status==="error"||z?.status==="fail"?"error":"completed",W,xe;if(C)W=C,xe=L;else{let Fe=I.get(H.agent_id);Fe?(W=Fe,xe=`${Fe}/_${x.source}`):(W="unmapped",xe=`unmapped/_${x.source}`)}i.has(W)||i.set(W,{id:W,name:W,color:Ha(W),projects:[]}),c.has(W)||c.set(W,new Set),c.get(W).add(xe),g.push({id:`${x.id}|${H.decided_by}`,agentId:H.agent_id,clientId:W,projectId:xe,channelId:R,initiatorId:Y,initiatorKind:B,subject:Go(x.subject),intent:x.intent||"",startedAt:X,resolvedAt:bt,duration:_n,active:qe,outcome:En,tokens:0,inputPreview:$,system:Uo(H.agent_id,e)})}}let E=[...i.values()].map(x=>({...x,projects:[...c.get(x.id)||[]].sort()})).sort((x,w)=>x.id.localeCompare(w.id)),S=[],d=new Set;if(e)for(let[x,w]of Object.entries(e.agents||{})){let A={id:x,name:w.name||x,tier:w.tier==="claude-code"?"lead":"worker",model:w.model||"",role:w.systemPrompt?w.systemPrompt.split(/[.\n]/)[0].slice(0,60):w.tier||""};S.push(A),d.add(x)}for(let x of g)d.has(x.agentId)||(S.push({id:x.agentId,name:x.agentId,tier:"worker",model:"",role:""}),d.add(x.agentId));S.sort((x,w)=>x.id.localeCompare(w.id));let p=[],h=new Set;for(let[x,w]of Object.entries(ge))p.push({id:x,label:w.label,color:w.color}),h.add(x);for(let x of m.values())h.has(x.id)||p.push(x);let f=[...u.values()];f.find(x=>x.id==="__system")||f.push({id:"__system",name:"Schedule",avatar:"\u23F1",kind:"system"});let y=e?.channels?.gitlab?.host;return{now:n,windowH:a,clients:E,agents:S,channels:p,initiators:f,dispatches:g,forges:{gitlab:typeof y=="string"?y:void 0,github:"https://github.com"}}}function ct(t){let e=dt();if(!e)return null;try{return za(e.db,ie,t)}finally{e.close()}}function qa(t){let e=new Map,a=new Map,n=new Map,r=new Map,o=[],s=0,l=0,i={};for(let{nodeId:c,snap:m}of t){i.gitlab??=m.forges?.gitlab,i.github??=m.forges?.github,m.now>s&&(s=m.now),m.windowH>l&&(l=m.windowH);for(let u of m.clients){let g=e.get(u.id);if(!g)e.set(u.id,{...u,projects:[...u.projects]});else{let b=Array.from(new Set([...g.projects,...u.projects])).sort();e.set(u.id,{...g,projects:b})}}for(let u of m.agents)a.has(u.id)||a.set(u.id,u);for(let u of m.channels)n.has(u.id)||n.set(u.id,u);for(let u of m.initiators)r.has(u.id)||r.set(u.id,u);for(let u of m.dispatches){let g=Xo(u);if(g.clientId!==u.clientId&&!e.has(g.clientId)&&e.set(g.clientId,{id:g.clientId,name:g.clientId,color:Ha(g.clientId),projects:[]}),g.projectId!==u.projectId){let b=e.get(g.clientId);b.projects.includes(g.projectId)||e.set(g.clientId,{...b,projects:[...b.projects,g.projectId].sort()})}o.push({...g,nodeId:c,id:`${c}::${g.id}`})}}return{now:s||Date.now(),windowH:l||6,localNodeId:t[0]?.nodeId,forges:i,clients:[...e.values()].sort((c,m)=>c.id.localeCompare(m.id)),agents:[...a.values()].sort((c,m)=>c.id.localeCompare(m.id)),channels:[...n.values()],initiators:[...r.values()],dispatches:o.sort((c,m)=>m.startedAt-c.startedAt)}}function Xo(t){if(t.clientId!=="unmapped")return t;let e=ot(t.inputPreview);if(!e)return t;let a=ie?.business?.projects??[];return{...t,projectId:e,clientId:_e(e,a)}}async function He(t){let e=ie?.channels?.gitlab,a=await La(ja(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 ie=null;function Fa(t){ie=t}async function Ua(t,e,a){if(a!=="/api/admin/activity-graph"&&!a.startsWith("/api/admin/activity-graph?"))return!1;let n=dt();if(!n)return oe(e,503,{error:"intent ledger not available",clients:[],agents:[],channels:[],initiators:[],dispatches:[]}),!0;try{let r=new URL(t.url||"/","http://_"),o=Wa(parseInt(r.searchParams.get("hours")||"6",10));oe(e,200,await He(za(n.db,ie,o)))}catch(r){oe(e,500,{error:r?.message??String(r)})}finally{n.close()}return!0}var Ko=5e3;async function pt(t,e,a,n=ct){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
|
|
7365
7386
|
|
|
7366
|
-
`);let
|
|
7387
|
+
`);let r=new URL(t.url||"/","http://_"),o=Wa(parseInt(r.searchParams.get("hours")||"6",10)),s=!1,l=()=>{s=!0};t.on("close",l),t.on("error",l),e.on("close",l),e.on("error",l);let i=setInterval(()=>{if(!s)try{e.write(`: hb
|
|
7367
7388
|
|
|
7368
|
-
`)}catch{
|
|
7389
|
+
`)}catch{l()}},25e3);try{for(;!s;){try{let m=await n(o),u=m&&await He(m);if(s)break;u?(e.write(`event: snapshot
|
|
7369
7390
|
`),e.write(`data: ${JSON.stringify(u)}
|
|
7370
7391
|
|
|
7371
|
-
`)
|
|
7372
|
-
data: ${JSON.stringify({error:u?.message??String(u)})}
|
|
7373
|
-
|
|
7374
|
-
`)}finally{i.close()}else e.write(`event: error
|
|
7392
|
+
`)):e.write(`event: error
|
|
7375
7393
|
data: ${JSON.stringify({error:"ledger not available"})}
|
|
7376
7394
|
|
|
7377
|
-
`)
|
|
7395
|
+
`)}catch(m){e.write(`event: error
|
|
7396
|
+
data: ${JSON.stringify({error:m?.message??String(m)})}
|
|
7397
|
+
|
|
7398
|
+
`)}let c=Date.now();for(;!s&&Date.now()-c<Ko;)await new Promise(m=>setTimeout(m,200))}}finally{clearInterval(i);try{e.end()}catch{}}return!0}function Wa(t){return!Number.isFinite(t)||t<1?6:Math.min(720,Math.max(1,t))}function Jo(t,e,a=5e3){let n=new Date(e).toISOString().slice(0,10),r=it(process.cwd(),".agentx/task-history",t,n);if(!lt(r)){let o=new Date(e-864e5).toISOString().slice(0,10),s=it(process.cwd(),".agentx/task-history",t,o);return lt(s)?Oa(s,e,a):null}return Oa(r,e,a)}function Oa(t,e,a){let n=null,r=1/0;for(let o of Bo(t)){if(!o.endsWith(".json"))continue;let s;try{s=JSON.parse(zo(No(t,o),"utf-8"))}catch{continue}let l=s.startedAt,i;if(typeof l=="number")i=l;else if(typeof l=="string"){let m=Date.parse(l);if(!Number.isFinite(m))continue;i=m}else continue;let c=Math.abs(i-e);c<r&&c<=a&&(n=s,r=c)}return n}async function Ga(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 oe(e,400,{error:"invalid dispatch id"}),!0;let s=r.slice(0,o),l=r.slice(o+1),i=dt();if(!i)return oe(e,503,{error:"ledger not available"}),!0;try{let c=i.db.prepare("SELECT id, ts, source, project, subject, intent, raw_json FROM intent_events WHERE id = ?").get(s);if(!c)return oe(e,404,{error:"event not found"}),!0;let m=i.db.prepare("SELECT decided_at, decided_by, agent_id, outcome, reason FROM intent_decisions WHERE event_id = ? AND decided_by = ?").get(s,l);if(!m)return oe(e,404,{error:"decision not found"}),!0;let u=i.db.prepare("SELECT resolved_at, status, duration_ms, result_summary FROM intent_resolutions WHERE decision_event_id = ? AND decision_decided_by = ?").get(s,l),g=null;try{g=JSON.parse(c.raw_json)}catch{}let b=Ba(c.source,g),_=g&&typeof g=="object"&&(g.text||g.message?.text||g.message?.caption||g.object_attributes?.note||g.object_attributes?.description||g.comment?.body||g.issue?.body||(typeof g.message=="string"?g.message:null)||(typeof g.prompt=="string"?g.prompt:null)||null)||b,I=null,E=null;if(m.agent_id){let y=Jo(m.agent_id,m.decided_at);if(y){typeof y.responseText=="string"&&(I=y.responseText);let x=y.transcript;Array.isArray(x)&&(E=x.length)}}let S=ie?.business?.projects??[],d=ie?.business?.contactMap??[],p=Xe(ie?.business??{}),h={client:"unmapped",project:`unmapped/_${c.source}`,via:"fallback"},f=Na(c.source,g,d);if(f)h={client:f.client,project:f.project||`${f.client}/_chat`,via:`contactMap (channel=${f.channel??"*"}${f.username?` username=${f.username}`:""}${f.chatId?` chatId=${f.chatId}`:""})`};else if(c.project||De(g,c.subject,b)){let y=c.project||De(g,c.subject,b);h={client:_e(y,S),project:y,via:c.project?`project namespace prefix (${y})`:`forge path in chat id / message (${y})`}}else if(m.agent_id){let y=p.get(m.agent_id);y&&(h={client:y,project:`${y}/_${c.source}`,via:`orgChart fallback (agent ${m.agent_id} reports up to a PM whose project belongs to ${y})`})}oe(e,200,{id:r,eventId:s,source:c.source,subject:c.subject,intent:c.intent,project:c.project,decidedBy:m.decided_by,agentId:m.agent_id,outcome:m.outcome,reason:m.reason,startedAt:m.decided_at,resolvedAt:u?.resolved_at??null,durationMs:u?.duration_ms??null,input:_,response:I,transcriptLen:E,resolutionStatus:u?.status??null,resultSummary:u?.result_summary??null,attribution:h})}catch(c){oe(e,500,{error:c?.message??String(c)})}finally{i.close()}return!0}import{existsSync as Zo,readFileSync as es}from"fs";import{resolve as Ka}from"path";Ue();function Xa(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=Vo.replace(/__AGENT_ID__/g,P(e));return M({title:`AgentX \xB7 ${P(e)}`,activeTab:"admin",subtitle:`Agent \xB7 ${P(e)}`,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:r,css:Yo,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>${Qo}</script>`})}var Vo=`
|
|
7378
7399
|
<!-- Breadcrumb -->
|
|
7379
7400
|
<div class="ax-crumb">
|
|
7380
7401
|
<a href="/admin">Settings</a>
|
|
@@ -7963,7 +7984,7 @@ data: ${JSON.stringify({error:"ledger not available"})}
|
|
|
7963
7984
|
</div>
|
|
7964
7985
|
</div>
|
|
7965
7986
|
</div>
|
|
7966
|
-
`,
|
|
7987
|
+
`,Yo=`
|
|
7967
7988
|
/* Agent-specific layout + legacy styles for bits the migration left in
|
|
7968
7989
|
* place (EasyMDE theming, skills tree, plain-editor). Shared chrome + tab
|
|
7969
7990
|
* primitives live in components.css.ts. */
|
|
@@ -8082,7 +8103,7 @@ textarea.inp.mono { font-family: var(--ax-mono); }
|
|
|
8082
8103
|
|
|
8083
8104
|
/* Agent-specific button variant used in rail context (no ax-btn wrapper) */
|
|
8084
8105
|
.ax-btn.lg { padding: 9px 16px; font-size: 13px; }
|
|
8085
|
-
`,
|
|
8106
|
+
`,Qo=`
|
|
8086
8107
|
const $ = (id) => document.getElementById(id);
|
|
8087
8108
|
const state = { agent: null, activeSkill: null, activeSkillFile: null, identityPath: null };
|
|
8088
8109
|
|
|
@@ -8936,15 +8957,15 @@ document.addEventListener('keydown', (e) => {
|
|
|
8936
8957
|
/* ===== Boot ===== */
|
|
8937
8958
|
initOptsToggles();
|
|
8938
8959
|
loadAgent();
|
|
8939
|
-
`;function
|
|
8940
|
-
`);return
|
|
8941
|
-
`);return
|
|
8960
|
+
`;function Ja(t,e,a,n=[],r){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Xa({agentId:a,peers:n,localToken:r}))}async function Va(t,e,a){try{let n=t.method==="GET"?void 0:await ks(t),r=new URL(t.url||"/","http://localhost"),o=Object.fromEntries(r.searchParams),s=a.match(/^\/api\/admin\/agent\/([a-z0-9][a-z0-9_-]*)(?:\/(.+))?$/);if(!s){Ne(e,404,{error:`unknown agent endpoint: ${a}`});return}let l=s[1],i=s[2]||"",c=`${t.method} ${i}`,u={"GET ":()=>we(l),"PATCH ":()=>ts(l,n),"PATCH capability":()=>rs(l,n),"POST mcp":()=>as(l,n),"DELETE mcp":()=>ns(l,n),"GET identity":()=>os(l),"GET identity/file":()=>ss(l,String(o.path||"")),"PUT identity/file":()=>is(l,n),"GET skills":()=>ls(l),"POST skills":()=>ds(l,n),"DELETE skills":()=>cs(l,n),"GET skills/tree":()=>ps(l,String(o.slug||"")),"GET skills/file":()=>us(l,String(o.slug||""),String(o.path||"")),"PUT skills/file":()=>ms(l,n),"GET skills/deps":()=>hs(l,String(o.slug||"")),"POST skills/install":()=>gs(l,n,t),"POST skills/deps":()=>fs(l,n,t),"GET channels":()=>xs(l),"GET activity":()=>vs(l,t),"GET handovers":()=>bs(l),"POST handovers":()=>ys(l,n),"DELETE handovers":()=>ws(n)}[c];if(!u){Ne(e,404,{error:`unknown agent sub-endpoint: ${c}`});return}let g=await u();Ne(e,200,g)}catch(n){Ne(e,400,{error:n?.message||"agent op failed"})}}function Ya(){let t=Ka(process.cwd(),"agentx.json");return Zo(t)?JSON.parse(es(t,"utf-8")):null}function U(t){let e=Ya();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 we(t){let{def:e,cfg:a}=U(t),n=e.workspace?ue(e.workspace):null;return{id:t,name:e.name||t,tier:e.tier,model:e.model,workspace:e.workspace,systemPrompt:e.systemPrompt||"",mentions:e.mentions||[],access:e.access||"private",maxConcurrent:e.maxConcurrent??1,maxExecutionMinutes:e.maxExecutionMinutes??20,permissionMode:e.permissionMode||"default",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 ts(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}=T(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:we(t)}}function as(t,e){let a=String(e?.name||"").trim(),n=String(e?.command||"").trim();if(!a)throw new Error("name required");if(!/^[a-zA-Z0-9_-]+$/.test(a))throw new Error("name must be identifier-safe (alnum, _, -)");if(!n)throw new Error("command required");let r=Array.isArray(e?.args)?e.args.map(l=>String(l)):[],o;if(e?.env&&typeof e.env=="object"){o={};for(let[l,i]of Object.entries(e.env))typeof i=="string"&&(o[l]=i);Object.keys(o).length===0&&(o=void 0)}let{summary:s}=T(l=>{if(!l.agents?.[t])throw new Error(`Agent "${t}" not found`);return l.agents[t].mcp=l.agents[t].mcp||{},l.agents[t].mcp[a]={command:n,args:r,...o?{env:o}:{}},`agent "${t}" mcp.${a} upserted`});return{summary:s,agent:we(t)}}function ns(t,e){let a=String(e?.name||"").trim();if(!a)throw new Error("name required");let{summary:n}=T(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:we(t)}}function rs(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}=T(r=>{if(!r.agents?.[t])throw new Error(`Agent "${t}" not found`);let o={...r.agents[t]};for(let[s,l]of Object.entries(a))l===void 0?delete o[s]:o[s]=l;return r.agents[t]=o,`agent "${t}" capability updated (${Object.keys(a).join(", ")})`});return{summary:n,agent:we(t)}}function os(t){let{def:e}=U(t);return ue(e.workspace)}function ss(t,e){if(!e)throw new Error("path query param required");let{def:a}=U(t);return Ee(a.workspace,e)}function is(t,e){let a=String(e?.path||"");if(!a)throw new Error("path required");let{def:n}=U(t);return Se(n.workspace,a,String(e?.content??""))}function ls(t){let{def:e}=U(t),a=ue(e.workspace);return{skills:a.skills,workspace:a.workspace}}function ds(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Te(n.workspace,a,{title:e?.title,content:e?.content})}function cs(t,e){let a=String(e?.slug||"").trim();if(!a)throw new Error("slug required");let{def:n}=U(t);return Ce(n.workspace,a)}function ps(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t),n=Rt(a.workspace,e),r=Ae(a.workspace,e);return{slug:e,tree:n,deps:r}}function us(t,e,a){if(!e||!a)throw new Error("slug and path query params required");let{def:n}=U(t);return Pt(n.workspace,e,a)}function ms(t,e){let a=String(e?.slug||""),n=String(e?.path||"");if(!a||!n)throw new Error("slug and path required");let{def:r}=U(t);return Dt(r.workspace,a,n,String(e?.content??""))}function hs(t,e){if(!e)throw new Error("slug query param required");let{def:a}=U(t);return Ae(a.workspace,e)}async function gs(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=Qa(e?.worker),{def:o}=U(t),s=[`Install the skills.sh package "${n}" into agent "${t}".`,`Workspace: ${o.workspace}`,`Run: cd ${o.workspace} && npx -y skills add ${n}`,`If that fails, fall back to: agentx skill install ${n}`,`Skills should land under ${o.workspace}/.claude/skills/. Report what was installed and any errors.`].join(`
|
|
8961
|
+
`);return Za(a,r,s,`install-${n}:${Date.now()}`)}async function fs(t,e,a){let n=String(e?.slug||"").trim();if(!n)throw new Error("slug required");let r=Qa(e?.worker),{def:o}=U(t),s=Ae(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 l=Ka(o.workspace,".claude","skills",n),i=[`Install dependencies for skill "${n}" in agent "${t}".`,`cd to: ${l}`,`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(`
|
|
8962
|
+
`);return Za(a,r,i,`deps-${t}-${n}:${Date.now()}`)}function Qa(t){if(t&&typeof t=="string")return t;let e=K();return e.dashboard?.draftAgent||e.node?.defaultAgent||Object.keys(e.agents).find(a=>a.includes("devops"))||Object.keys(e.agents)[0]}async function Za(t,e,a,n){let r=K(),o=(r.dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),s={"Content-Type":"application/json"},l=t.headers.authorization;l?s.Authorization=String(l):r.dashboard.token&&(s.Authorization=`Bearer ${r.dashboard.token}`);let i=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 i.text(),m;try{m=JSON.parse(c)}catch{m={content:c}}if(!i.ok)throw new Error(m?.error||`daemon /task HTTP ${i.status}`);return{worker:e,taskId:m?.taskId,content:m?.content,duration:m?.duration,error:m?.error}}function xs(t){let e=Ya(),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 vs(t,e){try{let n=(K().dashboard.daemonUrl||"http://localhost:18800").replace(/\/+$/,""),r=await fetch(`${n}/agents`);if(!r.ok)throw new Error(`daemon HTTP ${r.status}`);let s=(await r.json()).find(l=>l.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 ut(){return new _t}function bs(t){let e=ut(),{incoming:a,outgoing:n}=e.listByAgent(t);return{incoming:a,outgoing:n}}function ys(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,l=e?.summary?String(e.summary):void 0,i=e?.expiresAt?String(e.expiresAt):void 0,c=ut().set({channel:a,chatId:n,accountId:s,fromAgent:o,toAgent:r,summary:l,expiresAt:i,createdBy:"admin-ui"});return{summary:`Handed off ${a}:${n} from ${o} to ${r}`,record:c}}function ws(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:ut().remove(e,a,n)?"Released":"No active handover for that chat"}}function Ne(t,e,a){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a))}function ks(t){return new Promise((e,a)=>{let n="";t.on("data",r=>{n+=r}),t.on("end",()=>{try{e(n?JSON.parse(n):{})}catch(r){a(r)}}),t.on("error",a)})}var pe={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 en=[{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 mt(t={}){let e=`<script>window.UI_LABELS = ${JSON.stringify(pe)};</script>`,a=`<span id="ts" class="ax-mono" title="Last update">\u2014</span>
|
|
8942
8963
|
<span id="conn-dot" class="ax-dot ax-dot--ok ax-dot--pulse" title="connected"></span>
|
|
8943
8964
|
<span id="conn-label">live</span>`,n=`<div class="ax-app-live">
|
|
8944
8965
|
<section id="statstrip" class="ax-statstrip"></section>
|
|
8945
8966
|
<main id="grid" class="ax-live__body"></main>
|
|
8946
8967
|
</div>
|
|
8947
|
-
`;return
|
|
8968
|
+
`;return M({title:`${pe.brand} \xB7 ${pe.subtitle}`,activeTab:"live",subtitle:pe.subtitle,peers:t.peers,currentPeerId:t.currentPeerId,customHeader:void 0,noMain:!0,body:n,css:_s,scripts:e+`<script>${Es}</script>`,headExtras:`<script>
|
|
8948
8969
|
// rightExtras for the topbar are injected at runtime \u2014 they reference
|
|
8949
8970
|
// IDs (#ts, #conn-dot) that the script below addresses directly.
|
|
8950
8971
|
document.addEventListener('DOMContentLoaded', () => {
|
|
@@ -8955,7 +8976,7 @@ loadAgent();
|
|
|
8955
8976
|
extras.innerHTML = ${JSON.stringify(a)};
|
|
8956
8977
|
right.insertBefore(extras, right.firstChild);
|
|
8957
8978
|
});
|
|
8958
|
-
</script>`})}var
|
|
8979
|
+
</script>`})}var _s=`
|
|
8959
8980
|
/* --- Page frame --- */
|
|
8960
8981
|
.ax-app-live { min-height: 100vh; display: flex; flex-direction: column; }
|
|
8961
8982
|
|
|
@@ -9156,7 +9177,7 @@ loadAgent();
|
|
|
9156
9177
|
border-top-color: var(--ax-accent); border-radius: 50%;
|
|
9157
9178
|
animation: ax-spin 800ms linear infinite; display: inline-block;
|
|
9158
9179
|
}
|
|
9159
|
-
@keyframes ax-spin { to { transform: rotate(360deg); } }`,
|
|
9180
|
+
@keyframes ax-spin { to { transform: rotate(360deg); } }`,Es=`
|
|
9160
9181
|
'use strict';
|
|
9161
9182
|
|
|
9162
9183
|
const ui = { nodes: new Map(), summary: { nodes: 0, agents: 0, busy: 0, errors: 0 } };
|
|
@@ -9628,7 +9649,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
9628
9649
|
});
|
|
9629
9650
|
}
|
|
9630
9651
|
|
|
9631
|
-
`;var
|
|
9652
|
+
`;var tn=`
|
|
9632
9653
|
.mx-content{max-width:1180px;margin:0 auto;padding:0 24px 56px}
|
|
9633
9654
|
.mx-updated{margin:0;color:var(--ax-muted);font-size:11px;font-family:var(--ax-mono)}
|
|
9634
9655
|
.mx-section{margin-bottom:28px}.mx-section .ax-section-head{margin-bottom:14px}
|
|
@@ -9798,7 +9819,7 @@ function taskAction(nodeUrl, taskId, kind, body, hooks) {
|
|
|
9798
9819
|
.mx-summary{max-width:56vw}
|
|
9799
9820
|
}
|
|
9800
9821
|
@media(prefers-reduced-motion:reduce){.mx-drawer{transition:none}}
|
|
9801
|
-
`;var
|
|
9822
|
+
`;var an=`<script>
|
|
9802
9823
|
window.MX=(function(){
|
|
9803
9824
|
var ENT={'&':'&','<':'<','>':'>','"':'"',"'":'''};
|
|
9804
9825
|
function esc(v){return String(v==null?'':v).replace(/[&<>"']/g,function(c){return ENT[c]})}
|
|
@@ -9907,7 +9928,7 @@ window.MX=(function(){
|
|
|
9907
9928
|
verdict:verdict,verdictChip:verdictChip,mark:mark,causeLabel:causeLabel,
|
|
9908
9929
|
setHealth:setHealth,get:get};
|
|
9909
9930
|
})();
|
|
9910
|
-
</script>`;var
|
|
9931
|
+
</script>`;var nn=`<script>
|
|
9911
9932
|
window.MXD=(function(){
|
|
9912
9933
|
function el(id){return document.getElementById(id)}
|
|
9913
9934
|
function tz(){return -new Date().getTimezoneOffset()}
|
|
@@ -10121,7 +10142,7 @@ window.MXD=(function(){
|
|
|
10121
10142
|
|
|
10122
10143
|
return {openDay:openDay,openJob:openJob,openConversation:openConversation};
|
|
10123
10144
|
})();
|
|
10124
|
-
</script>`;var
|
|
10145
|
+
</script>`;var rn=`<script>
|
|
10125
10146
|
(function(){
|
|
10126
10147
|
var LANES=[
|
|
10127
10148
|
{id:'cron',name:'Scheduled',hint:'cron jobs'},
|
|
@@ -10437,7 +10458,7 @@ window.MXD=(function(){
|
|
|
10437
10458
|
window.addEventListener('scroll',hideTip,{passive:true});
|
|
10438
10459
|
load();
|
|
10439
10460
|
})();
|
|
10440
|
-
</script>`;var
|
|
10461
|
+
</script>`;var on=`<script>
|
|
10441
10462
|
(function(){
|
|
10442
10463
|
var showAll=document.getElementById('mx-show-all'),expanded=false;
|
|
10443
10464
|
var esc=MX.esc;
|
|
@@ -10584,17 +10605,17 @@ window.MXD=(function(){
|
|
|
10584
10605
|
}
|
|
10585
10606
|
load();setInterval(load,5000);
|
|
10586
10607
|
})();
|
|
10587
|
-
</script>`;var
|
|
10608
|
+
</script>`;var ee={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>',nodes:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><circle cx="6" cy="6" r="2"/><circle cx="18" cy="6" r="2"/><circle cx="12" cy="18" r="2"/><path d="M8 6h8M7 8l4 8M17 8l-4 8"/></svg>',agents:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="10" rx="2"/><circle cx="12" cy="5" r="2"/><path d="M12 7v4M8 16h.01M16 16h.01"/></svg>'};function te(t,e,a,n,r=""){return q({icon:t,title:e,lead:a,actionHtml:r}).replace("<h2>",`<h2 id="${n}">`)}var Ss=[{id:"activity",label:"Activity"},{id:"lifetime",label:"Lifetime"},{id:"ops",label:"Operations"}],Ts=[{days:0,label:"Today"},{days:7,label:"7d"},{days:30,label:"30d"},{days:90,label:"90d"}];function sn(t){let e=Me({kicker:"Operations",title:"Mesh operations",lead:"What the fleet actually did, how long it lived, and which of it was worth running."})+Ie([{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">
|
|
10588
10609
|
<div class="mx-tabs" role="tablist" aria-label="Mesh views">
|
|
10589
|
-
${
|
|
10610
|
+
${Ss.map((l,i)=>`<button class="mx-tab" type="button" role="tab" id="mx-tab-${l.id}" aria-controls="mx-view-${l.id}" aria-selected="${i===0}" data-view="${l.id}">${l.label}</button>`).join("")}
|
|
10590
10611
|
</div>
|
|
10591
10612
|
<div class="mx-range" id="mx-range" role="group" aria-label="History window">
|
|
10592
|
-
${
|
|
10613
|
+
${Ts.map(l=>`<button type="button" data-days="${l.days}" aria-pressed="${l.days===30}">${l.label}</button>`).join("")}
|
|
10593
10614
|
</div>
|
|
10594
10615
|
</div>
|
|
10595
10616
|
<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">
|
|
10596
10617
|
<section class="mx-section" aria-labelledby="mx-lanes-title">
|
|
10597
|
-
${
|
|
10618
|
+
${te(ee.activity,"What ran","One lane per origin. Each lane is scaled to its own peak so a quiet channel stays readable next to a busy one. Select a column for the day behind it.","mx-lanes-title")}
|
|
10598
10619
|
<div id="mx-lanes"><div class="mx-empty">Loading activity...</div></div>
|
|
10599
10620
|
<div class="mx-axis" id="mx-axis"></div>
|
|
10600
10621
|
<p class="mx-note">Coloured bars are runs that finished; the red cap on a column is the failures inside that day. Select any column for what ran that day, down to a single conversation.</p>
|
|
@@ -10602,32 +10623,32 @@ window.MXD=(function(){
|
|
|
10602
10623
|
|
|
10603
10624
|
<div class="mx-two">
|
|
10604
10625
|
<section class="mx-section" aria-labelledby="mx-origins-title">
|
|
10605
|
-
${
|
|
10626
|
+
${te(ee.breakage,"Where it breaks","Attempts per origin, with the failed share marked on the same bar.","mx-origins-title")}
|
|
10606
10627
|
<div class="mx-bars" id="mx-origins"><div class="mx-empty">Loading...</div></div>
|
|
10607
10628
|
</section>
|
|
10608
10629
|
<section class="mx-section" aria-labelledby="mx-causes-title">
|
|
10609
|
-
${
|
|
10630
|
+
${te(ee.breakage,"Why it fails","Failures grouped by cause class, matched from the recorded error text.","mx-causes-title")}
|
|
10610
10631
|
<div class="mx-bars" id="mx-causes"><div class="mx-empty">Loading...</div></div>
|
|
10611
10632
|
<p class="mx-note" id="mx-cause-note"></p>
|
|
10612
10633
|
</section>
|
|
10613
10634
|
</div>
|
|
10614
10635
|
|
|
10615
10636
|
<section class="mx-section" aria-labelledby="mx-scatter-title">
|
|
10616
|
-
${
|
|
10637
|
+
${te(ee.effort,"Effort against output","Every recurring job, plotted as runtime spent against tokens produced on its successful runs. Both axes are logarithmic.","mx-scatter-title")}
|
|
10617
10638
|
<div class="mx-scatter" id="mx-scatter"><div class="mx-empty">Loading jobs...</div></div>
|
|
10618
10639
|
<div class="mx-legend" id="mx-scatter-legend"></div>
|
|
10619
10640
|
<p class="mx-note">Bubble size is the number of runs. Anything not healthy is labelled on the chart; select it for the attempt history behind the verdict.</p>
|
|
10620
10641
|
</section>
|
|
10621
10642
|
</div>`,r=`<div class="mx-view" id="mx-view-lifetime" role="tabpanel" aria-labelledby="mx-tab-lifetime" hidden>
|
|
10622
10643
|
<section class="mx-section" aria-labelledby="mx-threads-title">
|
|
10623
|
-
${
|
|
10644
|
+
${te(ee.lifetime,"Thread lifetimes","A thread is one agent talking on one channel in one conversation. The bar is its real first-to-last span; each tick is a session cut. Select one for its turns, tokens and time.","mx-threads-title")}
|
|
10624
10645
|
<div class="mx-chips" id="mx-thread-chips"></div>
|
|
10625
10646
|
<div id="mx-threads"><div class="mx-empty">Loading threads...</div></div>
|
|
10626
10647
|
<p class="mx-note">Select a thread to walk its runs, then a run to see which tools it touched. Grey ticks are stale cuts, amber ticks are context-full cuts.</p>
|
|
10627
10648
|
</section>
|
|
10628
10649
|
|
|
10629
10650
|
<section class="mx-section" aria-labelledby="mx-rot-title">
|
|
10630
|
-
${
|
|
10651
|
+
${te(ee.cuts,"Session cuts","Why threads lost their session, across the fleet.","mx-rot-title")}
|
|
10631
10652
|
<div class="mx-bars" id="mx-rotations"><div class="mx-empty">Loading...</div></div>
|
|
10632
10653
|
<p class="mx-note" id="mx-rot-note"></p>
|
|
10633
10654
|
</section>
|
|
@@ -10635,23 +10656,23 @@ window.MXD=(function(){
|
|
|
10635
10656
|
<p id="mx-updated" class="mx-updated" aria-live="polite">Connecting to the fleet...</p>
|
|
10636
10657
|
|
|
10637
10658
|
<section class="mx-section" aria-labelledby="mx-auto-title">
|
|
10638
|
-
${
|
|
10659
|
+
${te(ee.schedules,"Today's automations","Persisted attempts are authoritative. Select a schedule to inspect its latest result and runtime.","mx-auto-title",'<div class="mx-section-actions"><span class="ax-tab-count" id="mx-run-count">0 schedules</span><button class="ax-btn ax-btn--ghost mx-show-all" id="mx-show-all" type="button" hidden>Show all</button></div>')}
|
|
10639
10660
|
<div class="ax-stack" id="mx-runs"><div class="mx-empty">Loading schedules...</div></div>
|
|
10640
10661
|
</section>
|
|
10641
10662
|
|
|
10642
10663
|
<div class="mx-columns">
|
|
10643
10664
|
<section class="mx-section" aria-labelledby="mx-active-title">
|
|
10644
|
-
${
|
|
10665
|
+
${te(ee.activity,"Activity provenance","Who initiated current work and where it is running.","mx-active-title",'<span class="ax-tab-count" id="mx-active-count">0 active</span>')}
|
|
10645
10666
|
<div class="ax-stack" id="mx-active"><div class="mx-empty">No activity loaded.</div></div>
|
|
10646
10667
|
</section>
|
|
10647
10668
|
<section class="mx-section" aria-labelledby="mx-nodes-title">
|
|
10648
|
-
${
|
|
10669
|
+
${te(ee.nodes,"Nodes","Reachability and capacity across the fleet.","mx-nodes-title",'<span class="ax-tab-count" id="mx-node-count">0 nodes</span>')}
|
|
10649
10670
|
<div class="ax-stack" id="mx-nodes"><div class="mx-empty">No nodes loaded.</div></div>
|
|
10650
10671
|
</section>
|
|
10651
10672
|
</div>
|
|
10652
10673
|
|
|
10653
10674
|
<section class="mx-section" aria-labelledby="mx-agents-title">
|
|
10654
|
-
${
|
|
10675
|
+
${te(ee.agents,"Agents and skills","Runtime, model, installed skills, and task totals by node.","mx-agents-title",'<span class="ax-tab-count" id="mx-agent-count">0 agents</span>')}
|
|
10655
10676
|
<div class="mx-agent-grid" id="mx-agents"><div class="mx-empty">No agents loaded.</div></div>
|
|
10656
10677
|
</section>
|
|
10657
10678
|
</div>`,s=`${e}<main class="mx-content">
|
|
@@ -10667,7 +10688,7 @@ window.MXD=(function(){
|
|
|
10667
10688
|
<button class="ax-btn ax-btn--ghost" id="mx-close" type="button" aria-label="Close details">Close</button>
|
|
10668
10689
|
</header>
|
|
10669
10690
|
<div class="mx-drawer__body" id="mx-drawer-body"></div>
|
|
10670
|
-
</aside>`;return
|
|
10691
|
+
</aside>`;return M({title:"AgentX \xB7 Mesh Operations",activeTab:"mesh",subtitle:"Operations",peers:t.peers,noMain:!0,body:s,css:tn,scripts:an+Cs+nn+rn+on})}var Cs=`<script>
|
|
10671
10692
|
(function(){
|
|
10672
10693
|
var tabs=Array.prototype.slice.call(document.querySelectorAll('.mx-tab'));
|
|
10673
10694
|
var range=document.getElementById('mx-range');
|
|
@@ -10695,7 +10716,7 @@ window.MXD=(function(){
|
|
|
10695
10716
|
var saved=null;try{saved=localStorage.getItem('mx-view')}catch(e){}
|
|
10696
10717
|
select(tabs.some(function(t){return t.dataset.view===saved})?saved:'activity');
|
|
10697
10718
|
})();
|
|
10698
|
-
</script>`;async function
|
|
10719
|
+
</script>`;async function ln(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 l=>{let i={Accept:"application/json"};l.token&&(i.Authorization=`Bearer ${l.token}`);try{let c=await fetch(l.url+"/analytics/mesh"+o,{headers:i,signal:n.signal});return c.ok?{node:l,data:await c.json()}:{node:l,error:`HTTP ${c.status}`}}catch(c){return{node:l,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return As(s,e.days)}function As(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,l=[],i=[],c=0,m=0,u=0,g=0,b=0,_=0;for(let{node:E,data:S}of t)if(S){a.runs+=S.totals.runs,a.errors+=S.totals.errors,a.hours+=S.totals.hours,a.agents+=S.totals.agents,a.threads+=S.totals.threads;for(let d of S.days){let p=n.get(d.day)||{day:d.day,cron:[0,0],workflow:[0,0],direct:[0,0]};for(let h of["cron","workflow","direct"])p[h][0]+=d[h]?.[0]||0,p[h][1]+=d[h]?.[1]||0;n.set(d.day,p)}for(let d of S.origins){let p=r.get(d.channel)||{channel:d.channel,runs:0,errors:0,hours:0};p.runs+=d.runs,p.errors+=d.errors,p.hours+=d.hours,r.set(d.channel,p)}for(let d of S.causes){let p=o.get(d.cause)||{cause:d.cause,count:0,agents:[],example:""};p.count+=d.count;for(let h of d.agents)p.agents.includes(h)||p.agents.push(h);p.example||(p.example=d.example),o.set(d.cause,p)}for(let d of S.rotations.byReason)s.set(d.reason,(s.get(d.reason)||0)+d.count);c+=S.rotations.total,m+=S.rotations.tokenSum||0,u+=S.rotations.tokenSamples||0,g=Math.max(g,S.rotations.maxTokens),b+=S.retention.traces,_+=S.retention.tracesWithSteps;for(let d of S.jobs)l.push({...d,node:E.name,nodeUrl:E.url});for(let d of S.threads)i.push({...d,node:E.name,nodeUrl:E.url})}let I=t.filter(E=>E.data).map(E=>E.data.since).filter(E=>Number.isFinite(E));return{generatedAt:Date.now(),windowDays:e,since:I.length?Math.min(...I):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,S)=>E.day.localeCompare(S.day)),origins:[...r.values()].map(E=>({...E,hours:Math.round(E.hours*100)/100})).sort((E,S)=>S.runs-E.runs),causes:[...o.values()].sort((E,S)=>S.count-E.count),jobs:l.sort((E,S)=>S.hours-E.hours),threads:i.sort((E,S)=>S.lastAt-S.firstAt-(E.lastAt-E.firstAt)||S.runs-E.runs),rotations:{total:c,byReason:[...s.entries()].map(([E,S])=>({reason:E,count:S})).sort((E,S)=>S.count-E.count),tokenSum:m,tokenSamples:u,maxTokens:g},retention:{traces:b,tracesWithSteps:_}}}async function dn(t,e,a,n){let r=a.replace(/\/+$/,""),o=e.find(l=>l.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 l=await fetch(r+n,{headers:s}),i=await l.text();t.writeHead(l.status,{"Content-Type":"application/json; charset=utf-8"}),t.end(i)}catch(l){t.writeHead(502,{"Content-Type":"application/json"}),t.end(JSON.stringify({error:l?.message||"upstream fetch failed"}))}}async function cn(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 l=>{let i={Accept:"application/json"};l.token&&(i.Authorization=`Bearer ${l.token}`);try{let c=await fetch(l.url+"/analytics/day"+o,{headers:i,signal:n.signal});return c.ok?{node:l,data:await c.json()}:{node:l,error:`HTTP ${c.status}`}}catch(c){return{node:l,error:c?.name==="AbortError"?"timeout":c?.message||"unreachable"}}}))}finally{clearTimeout(r)}return Ms(s,e.day)}function Ms(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:l}of t)if(l){a.runs+=l.totals.runs,a.errors+=l.totals.errors,a.ms+=l.totals.ms,a.inputTokens+=l.totals.inputTokens,a.outputTokens+=l.totals.outputTokens;for(let i of l.origins){let c=n.get(i.channel)||{channel:i.channel,runs:0,errors:0,ms:0};c.runs+=i.runs,c.errors+=i.errors,c.ms+=i.ms,n.set(i.channel,c)}for(let i of l.causes)r.set(i.cause,(r.get(i.cause)||0)+i.count);for(let i of l.conversations)o.push({...i,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,l)=>l.runs-s.runs),causes:[...r.entries()].map(([s,l])=>({cause:s,count:l})).sort((s,l)=>l.count-s.count),conversations:o.sort((s,l)=>l.ms-s.ms||l.turns-s.turns)}}function pn(t={}){let e=`
|
|
10699
10720
|
<select id="boardPicker" title="Switch board"></select>
|
|
10700
10721
|
<div class="search">
|
|
10701
10722
|
<span class="icon">\u2315</span>
|
|
@@ -10796,7 +10817,7 @@ window.MXD=(function(){
|
|
|
10796
10817
|
</footer>
|
|
10797
10818
|
</div>
|
|
10798
10819
|
</div>
|
|
10799
|
-
<script src="/sortable.min.js"></script>`;return
|
|
10820
|
+
<script src="/sortable.min.js"></script>`;return M({title:"AgentX \xB7 Boards",activeTab:"boards",subtitle:"Boards",subheader:e,peers:t.peers,currentPeerId:t.currentPeerId,noMain:!0,body:a,css:Is,scripts:`<script>${$s}</script>`,headExtras:`<script>
|
|
10800
10821
|
// The boards page has its own connection dot + wants body height:100%
|
|
10801
10822
|
// for the full-viewport kanban layout. Inject the dot into the topbar
|
|
10802
10823
|
// and override body height at runtime so the shared shell doesn't
|
|
@@ -10812,7 +10833,7 @@ window.MXD=(function(){
|
|
|
10812
10833
|
right.insertBefore(dot, right.firstChild);
|
|
10813
10834
|
}
|
|
10814
10835
|
});
|
|
10815
|
-
</script>`})}var
|
|
10836
|
+
</script>`})}var Is=`
|
|
10816
10837
|
/* Kanban subheader \u2014 replaces the legacy toolbar that used to live in <header>. */
|
|
10817
10838
|
.ax-subheader select, .ax-subheader input, .ax-subheader button {
|
|
10818
10839
|
background: var(--col); color: var(--text); border: 1px solid var(--border);
|
|
@@ -11065,7 +11086,7 @@ header a.link:hover { color: var(--accent); border-color: var(--accent); }
|
|
|
11065
11086
|
.draft-box .draft-row .hint { color: var(--muted); font-size: 12px; flex: 1; }
|
|
11066
11087
|
.draft-box .draft-row .hint.err { color: var(--red); }
|
|
11067
11088
|
.draft-box .draft-row .hint.ok { color: var(--green); }
|
|
11068
|
-
|
|
11089
|
+
`,$s=`
|
|
11069
11090
|
'use strict';
|
|
11070
11091
|
const state = {
|
|
11071
11092
|
boards: [], current: null, items: {},
|
|
@@ -12124,9 +12145,9 @@ function appendEvents(events) {
|
|
|
12124
12145
|
}
|
|
12125
12146
|
|
|
12126
12147
|
loadBoards().catch(e => toast('Init failed: ' + e.message));
|
|
12127
|
-
`;function
|
|
12148
|
+
`;function un(t={}){let a=`<h1>Plain-English glossary</h1>
|
|
12128
12149
|
<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>
|
|
12129
|
-
${
|
|
12150
|
+
${en.map(n=>{let r=n.alias?`<span class="alias" title="Schema key">${P(n.alias)}</span>`:"";return`<article class="term"><h3>${P(n.term)}${r}</h3><p>${P(n.definition)}</p></article>`}).join("")}`;return M({title:`${pe.brand} \xB7 Glossary`,activeTab:"glossary",subtitle:"Glossary",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:js})}var js=`
|
|
12130
12151
|
main { max-width: 760px; margin: 0 auto; padding: 32px 24px 80px; }
|
|
12131
12152
|
h1 { font-size: 22px; margin: 0 0 6px; font-weight: 600; letter-spacing: -0.01em; }
|
|
12132
12153
|
.lead {
|
|
@@ -12156,7 +12177,7 @@ article.term .alias {
|
|
|
12156
12177
|
}
|
|
12157
12178
|
article.term p {
|
|
12158
12179
|
margin: 0; color: var(--ax-text-2); font-size: 13px; line-height: 1.6;
|
|
12159
|
-
}`;function
|
|
12180
|
+
}`;function mn(t={}){let e=`<div class="ax-wf__root">
|
|
12160
12181
|
<aside class="ax-wf__list">
|
|
12161
12182
|
<header>
|
|
12162
12183
|
<h2>Workflows</h2>
|
|
@@ -12233,7 +12254,7 @@ article.term p {
|
|
|
12233
12254
|
</aside>
|
|
12234
12255
|
</div>
|
|
12235
12256
|
|
|
12236
|
-
<div id="wf-toast" class="ax-wf__toast" hidden></div>`;return
|
|
12257
|
+
<div id="wf-toast" class="ax-wf__toast" hidden></div>`;return M({title:"AgentX \xB7 Workflows",activeTab:"workflows",subtitle:"Workflows",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Ls,scripts:`<script>${me({workflowHealth:Mt})}${Rs}</script>`})}var Ls=`
|
|
12237
12258
|
.ax-wf__root {
|
|
12238
12259
|
display: grid;
|
|
12239
12260
|
grid-template-columns: 340px 1fr;
|
|
@@ -12617,7 +12638,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
12617
12638
|
font-size: 12px; z-index: 50;
|
|
12618
12639
|
}
|
|
12619
12640
|
.hint { color: var(--ax-muted); font-size: 11px; }
|
|
12620
|
-
`,
|
|
12641
|
+
`,Rs=`
|
|
12621
12642
|
(() => {
|
|
12622
12643
|
const $ = (sel) => document.querySelector(sel)
|
|
12623
12644
|
const $$ = (sel) => Array.from(document.querySelectorAll(sel))
|
|
@@ -13405,7 +13426,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13405
13426
|
setInterval(refresh, 15000)
|
|
13406
13427
|
})
|
|
13407
13428
|
})();
|
|
13408
|
-
`;function
|
|
13429
|
+
`;function hn(t={}){let e=`<div class="ax-proc__root">
|
|
13409
13430
|
<header class="ax-proc__header">
|
|
13410
13431
|
<h1>Procedures</h1>
|
|
13411
13432
|
<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>
|
|
@@ -13449,7 +13470,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13449
13470
|
<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>
|
|
13450
13471
|
<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>
|
|
13451
13472
|
</section>
|
|
13452
|
-
</div>`;return
|
|
13473
|
+
</div>`;return M({title:"AgentX \xB7 Procedures",activeTab:"procedures",subtitle:"Procedures",peers:t.peers,currentPeerId:t.currentPeerId,body:e,css:Ps,scripts:`<script>${Ds}</script>`})}var Ps=`
|
|
13453
13474
|
.ax-proc__root { padding: 18px 24px 40px; max-width: 1100px; margin: 0 auto; color: var(--ax-text); }
|
|
13454
13475
|
.ax-proc__header h1 { margin: 0 0 4px; font-size: 22px; font-weight: 600; letter-spacing: -0.01em; }
|
|
13455
13476
|
.ax-proc__header .hint { color: var(--ax-muted); font-size: 12px; margin: 0 0 18px; }
|
|
@@ -13475,7 +13496,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13475
13496
|
.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); }
|
|
13476
13497
|
.ax-proc__link { color: var(--ax-accent, #6366f1); text-decoration: none; font-size: 11px; }
|
|
13477
13498
|
.ax-proc__link:hover { text-decoration: underline; }
|
|
13478
|
-
`,
|
|
13499
|
+
`,Ds=`
|
|
13479
13500
|
(function(){
|
|
13480
13501
|
function $(sel){ return document.querySelector(sel) }
|
|
13481
13502
|
function esc(s){ return String(s||"").replace(/[&<>"']/g, function(c){ return ({'&':'&','<':'<','>':'>','"':'"',"'":'''})[c] }) }
|
|
@@ -13575,7 +13596,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13575
13596
|
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootAll)
|
|
13576
13597
|
else bootAll()
|
|
13577
13598
|
})();
|
|
13578
|
-
`;function
|
|
13599
|
+
`;function gn(t){let e=t.agentName||t.agentId,a=`<div class="ax-task-page"
|
|
13579
13600
|
data-task-id="${P(t.taskId)}"
|
|
13580
13601
|
data-agent-id="${P(t.agentId)}"
|
|
13581
13602
|
data-node-url="${P(t.nodeUrl)}"
|
|
@@ -13618,7 +13639,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13618
13639
|
<button type="button" id="task-send" class="ax-btn ax-btn--primary">send \u2192</button>
|
|
13619
13640
|
</div>
|
|
13620
13641
|
</footer>
|
|
13621
|
-
</div>`;return
|
|
13642
|
+
</div>`;return M({title:`AgentX \xB7 ${e}`,activeTab:"live",subtitle:"Task",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Os,scripts:`<script>${Hs}</script>`})}var Os=`
|
|
13622
13643
|
/* The shell gives <main> no padding, so page content butted straight against
|
|
13623
13644
|
the sticky topbar. Breathe. */
|
|
13624
13645
|
.ax-task-page {
|
|
@@ -13760,7 +13781,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
13760
13781
|
line-height: 1.55; text-wrap: pretty; white-space: pre-wrap; word-break: break-word;
|
|
13761
13782
|
}
|
|
13762
13783
|
|
|
13763
|
-
`,
|
|
13784
|
+
`,Hs=`
|
|
13764
13785
|
(function () {
|
|
13765
13786
|
var root = document.querySelector('.ax-task-page');
|
|
13766
13787
|
if (!root) return;
|
|
@@ -14116,7 +14137,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14116
14137
|
if ((e.metaKey || e.ctrlKey) && e.key === 'Enter') { e.preventDefault(); sendBtn.click(); }
|
|
14117
14138
|
});
|
|
14118
14139
|
})();
|
|
14119
|
-
`;function
|
|
14140
|
+
`;function fn(t){let e=t.agentName||t.agentId,a=`<div class="ax-history"
|
|
14120
14141
|
data-agent-id="${P(t.agentId)}"
|
|
14121
14142
|
data-agent-name="${P(e)}"
|
|
14122
14143
|
data-node-url="${P(t.nodeUrl)}">
|
|
@@ -14145,7 +14166,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14145
14166
|
<div class="ax-history__list" id="hist-list">
|
|
14146
14167
|
<div class="ax-history__empty">loading\u2026</div>
|
|
14147
14168
|
</div>
|
|
14148
|
-
</div>`;return
|
|
14169
|
+
</div>`;return M({title:`AgentX \xB7 ${e} history`,activeTab:"live",subtitle:"History",peers:t.peers,currentPeerId:t.currentPeerId,body:a,css:Ns,scripts:`<script>${Bs}</script>`})}var Ns=`
|
|
14149
14170
|
/* <main> carries no padding in the shell \u2014 without this the breadcrumb sits
|
|
14150
14171
|
flush against the sticky topbar. */
|
|
14151
14172
|
.ax-history {
|
|
@@ -14197,7 +14218,7 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14197
14218
|
-webkit-line-clamp: 2; -webkit-box-orient: vertical;
|
|
14198
14219
|
}
|
|
14199
14220
|
.ax-history__foot { margin-top: 6px; font-size: var(--ax-fs-xs); color: var(--ax-muted); font-family: var(--ax-mono); }
|
|
14200
|
-
`,
|
|
14221
|
+
`,Bs=`
|
|
14201
14222
|
(function () {
|
|
14202
14223
|
var root = document.querySelector('.ax-history');
|
|
14203
14224
|
if (!root) return;
|
|
@@ -14297,25 +14318,25 @@ details.ax-wf__panel pre { margin: 0; padding: 10px 14px; }
|
|
|
14297
14318
|
listEl.innerHTML = '<div class="ax-history__empty" style="color:var(--ax-err)">' + esc(e.message) + '</div>';
|
|
14298
14319
|
});
|
|
14299
14320
|
})();
|
|
14300
|
-
`;function
|
|
14321
|
+
`;function vn(t,e,a){let n=t.url||"";if(!n.startsWith("/api/workflows"))return!1;let r=t.method||"GET";if(n==="/api/workflows"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{workflows:a.store.list()}):!0;if(r==="POST"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let s=new URL(n,"http://_").searchParams,l=s.get("convertFromYaml")==="true"||s.get("convertFromYaml")==="1";return fe(t,e,i=>xn(e,a,i,{mode:"create",convertFromYaml:l}))}}if(n.startsWith("/api/workflows/runs"))return r==="GET"&&!a.requireScope(t,e,["dashboard:read"])?!0:qs(t,e,a,n);if(n.startsWith("/api/workflows/signal/")){if(r!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;if(!a.dispatcher)return j(e,501,{error:"dispatcher not enabled"});let s=decodeURIComponent(n.replace(/^\/api\/workflows\/signal\//,"").split("?")[0]);return s?fe(t,e,l=>{let i=l,c=a.dispatcher.emitSignal({name:s,scope:i?.scope,workflowId:i?.workflowId,payload:i?.payload});return j(e,200,{ok:!0,emission:c})}):j(e,400,{error:"signal name required"})}let o=n.match(/^\/api\/workflows\/([^\/?]+)(\/layout|\/validate)?(\?.*)?$/);if(o){let s=decodeURIComponent(o[1]),l=o[2];if(l==="/layout"){if(r==="GET")return a.requireScope(t,e,["dashboard:read"])?j(e,200,{layout:a.layouts.get(s)}):!0;if(r==="PUT")return a.requireScope(t,e,["dashboard:write"])?fe(t,e,i=>{try{let c=a.layouts.save(s,i);return j(e,200,{layout:c})}catch(c){return j(e,400,{error:"invalid layout",message:c.message})}}):!0}if(l==="/validate"&&r==="POST")return a.requireScope(t,e,["dashboard:read"])?fe(t,e,i=>{let c=We.safeParse(i);if(!c.success)return j(e,200,{ok:!1,issues:c.error.issues.map(u=>({path:u.path.join("."),message:u.message}))});let m=Ge(c.data).map(u=>({path:"",message:u}));return j(e,200,{ok:m.length===0,issues:m,workflow:c.data})}):!0;if(!l){if(r==="GET"){if(!a.requireScope(t,e,["dashboard:read"]))return!0;let i=a.store.get(s);return i?j(e,200,{workflow:i}):j(e,404,{error:"workflow not found"})}if(r==="PUT"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let i=new URL(n,"http://_").searchParams,c=i.get("convertFromYaml")==="true"||i.get("convertFromYaml")==="1";return fe(t,e,m=>xn(e,a,m,{mode:"update",id:s,convertFromYaml:c}))}if(r==="DELETE"){if(!a.requireScope(t,e,["dashboard:write"]))return!0;let i=a.store.delete(s);return a.layouts.delete(s),j(e,i?200:404,i?{ok:!0}:{error:"workflow not found"})}}}return j(e,404,{error:"unknown workflows endpoint",path:n})}var zs=["mesh"];function xn(t,e,a,n){let r=We.safeParse(a);if(!r.success)return j(t,400,{error:"invalid workflow",issues:r.error.issues.map(i=>({path:i.path.join("."),message:i.message}))});let o=r.data,s=Ge(o);if(s.length>0)return j(t,400,{error:"lint errors",issues:s.map(i=>({path:"",message:i}))});if(n.mode==="update"&&o.id!==n.id)return j(t,400,{error:"workflow id does not match path"});if(n.mode==="create"&&e.store.get(o.id))return j(t,409,{error:`workflow "${o.id}" already exists`});if(n.mode==="update"&&a&&typeof a=="object"){let i=a,c=e.store.get(n.id);if(c)for(let m of zs)!(m in i)&&m in c&&(o[m]=c[m])}let l;try{l=e.store.save(o,{convertFromYaml:n.convertFromYaml})}catch(i){let c=i?.message||String(i),m=i?.yamlPath,u=!!m||/yaml round-trip failed/.test(c);return j(t,u?409:500,{error:u?"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:u?"yaml-authored":"save-failed",...m?{path:m}:{}})}return e.layouts.sync(l.id,l.nodes.map(i=>i.id)),j(t,200,{workflow:l})}function qs(t,e,a,n){let r=new URL(n,"http://_").searchParams,o=n.replace(/^\/api\/workflows\/runs/,"");if(o===""||o.startsWith("?")){let i=Math.max(1,Math.min(500,Number(r.get("limit")||50))),c=r.get("workflowId")||void 0,m=r.get("summary")==="1"||r.get("summary")==="true",u=a.runs.list({workflowId:c,limit:i});if(!m)return j(e,200,{runs:u});let g=u.map(b=>({id:b.id,workflowId:b.workflowId,workflowVersion:b.workflowVersion,homeNode:b.homeNode,status:b.status,pending:b.pending,entityRef:b.entityRef,history:(b.history||[]).slice(-5),parentRunId:b.parentRunId,parentNodeId:b.parentNodeId,rootRunId:b.rootRunId,depth:b.depth,createdAt:b.createdAt,updatedAt:b.updatedAt}));return j(e,200,{runs:g})}let s=o.match(/^\/([^\/?]+)\/status$/);if(s){if((t.method||"GET").toUpperCase()!=="POST")return j(e,405,{error:"method not allowed"});if(!a.requireScope(t,e,["dashboard:write"]))return!0;let i=decodeURIComponent(s[1]);return fe(t,e,c=>{let m=c?.status;return m!=="paused"&&m!=="running"&&m!=="canceled"?j(e,400,{error:"status must be paused|running|canceled"}):a.runs.setStatus(i,m)?j(e,200,{ok:!0,runId:i,status:m}):j(e,404,{error:"run not found"})})}let l=o.match(/^\/([^\/?]+)(\/stream)?$/);if(l){let i=decodeURIComponent(l[1]);if(l[2])return Fs(t,e,a,i);let c=a.runs.get(i);return c?j(e,200,{run:c}):j(e,404,{error:"run not found"})}return j(e,404,{error:"unknown runs endpoint"})}function Fs(t,e,a,n){let r=a.runs.get(n);if(!r)return j(e,404,{error:"run not found"}),!0;e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache, no-transform",Connection:"keep-alive","X-Accel-Buffering":"no"}),e.write(`data: ${JSON.stringify(r)}
|
|
14301
14322
|
|
|
14302
|
-
`);let o=!1,s=()=>{o=!0,i?.(),clearInterval(
|
|
14323
|
+
`);let o=!1,s=()=>{o=!0,i?.(),clearInterval(m);try{e.end()}catch{}};t.on("close",s);let l=u=>{if(!o)try{e.write(`data: ${JSON.stringify(u)}
|
|
14303
14324
|
|
|
14304
|
-
`)}catch{s()}},i=a.runEvents?.subscribe(n,l),c=r.updatedAt,
|
|
14325
|
+
`)}catch{s()}},i=a.runEvents?.subscribe(n,l),c=r.updatedAt,m=setInterval(()=>{if(o)return;let u=a.runs.get(n);u&&u.updatedAt!==c&&(c=u.updatedAt,l(u))},2e3);return!0}function fe(t,e,a){let n="";return t.setEncoding("utf8"),t.on("data",r=>{n+=r}),t.on("end",()=>{let r;try{r=n?JSON.parse(n):{}}catch(s){j(e,400,{error:"invalid JSON body",message:s.message});return}let o;try{o=a(r)}catch(s){try{j(e,500,{error:"handler threw (sync)",message:s?.message??String(s)})}catch{}return}Promise.resolve(o).catch(s=>{try{j(e,500,{error:"handler threw",message:s?.message??String(s)})}catch{}})}),t.on("error",r=>j(e,400,{error:"body read failed",message:r.message})),!0}function j(t,e,a){return t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(a)),!0}function dc(t){let e=t.dashboard,a=t.boards,n=e.port,r=e.bind,o=e.token,s=new Map;for(let b of a)try{s.set(b.id,ti(b,t))}catch(_){console.error(` Board "${b.id}" failed to initialize: ${_.message}`)}let l=t.node?.id||"local",i=t.workflows?.dir?ke(process.cwd(),t.workflows.dir):void 0,c=new Et(i?{baseDir:i}:void 0),m=new St(i?{baseDir:i,nodeId:l}:{nodeId:l}),u=new Tt(i?{baseDir:i}:void 0);Fa(t),$t({business:t.business?.enabled===!0}),Us(async(b,_)=>{try{await Ys(b,_,{boards:a,sources:s,token:o,config:t,workflowStore:c,workflowRuns:m,workflowLayouts:u})}catch(I){v(_,500,{error:I.message||"internal error"})}}).listen(n,r,()=>{let b=r==="0.0.0.0"?"localhost":r;a.length===0?(console.log(`
|
|
14305
14326
|
Live dashboard: http://${b}:${n}
|
|
14306
14327
|
`),console.log(" (no boards configured \u2014 '/' serves the live view; add a board with 'agentx board add')")):(console.log(`
|
|
14307
14328
|
Kanban dashboard: http://${b}:${n}
|
|
14308
|
-
`),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 _s=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki","/admin/activity-graph"]);async function Es(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&_s.has(r)&&Ht("page",r),o==="GET"&&r==="/"){let d=Rt();if(!d.configExists||d.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(it({peers:O(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Va({peers:O(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(it({peers:O(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[d]=await ie(a.config);if(!d){v(e,503,{error:"no node available"});return}let p=await new Promise(f=>{let h="";t.on("data",y=>h+=y),t.on("end",()=>f(h)),t.on("error",()=>f(""))}),g=await fetch(d.url+r,{method:"POST",headers:{"Content-Type":"application/json",...d.token?{Authorization:`Bearer ${d.token}`}:{}},body:p||"{}"});e.writeHead(g.status,{"Content-Type":"application/json"}),e.end(await g.text())}catch(d){v(e,502,{error:"could not reach the node",message:String(d?.message||d)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let d=await ie(a.config),p=o==="POST"?void 0:n.searchParams.get("node"),g=o==="POST"?await re(t):void 0,f=g?.node??p,h=f?d.find($=>$.url===f):d[0];if(!h){v(e,400,{error:"unknown node"});return}let y=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",k=await fetch(h.url+r+y,{method:o,headers:{"Content-Type":"application/json",...h.token?{Authorization:`Bearer ${h.token}`}:{}},...o==="POST"?{body:JSON.stringify({...g,node:void 0})}:{}});v(e,k.status,await k.json().catch(()=>({error:`HTTP ${k.status}`})))}catch(d){v(e,502,{error:"could not reach the node",message:d?.message||String(d)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let d=await re(t),p={"Content-Type":"application/json"};a.config.dashboard.token&&(p.Authorization=`Bearer ${a.config.dashboard.token}`);let g=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${g}/api/workflows/editor/chat`,{method:"POST",headers:p,body:JSON.stringify(d??{})}),h=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,h)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[d]=await ie(a.config);if(!d){v(e,200,{configured:!1,workflows:[]});return}let p=await fetch(d.url+"/api/n8n/workflows",{headers:d.token?{Authorization:`Bearer ${d.token}`}:{}});v(e,p.status,await p.json().catch(()=>({configured:!1,workflows:[]})))}catch{v(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Wt({peers:O(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ut({peers:O(a.config)}));return}if(o==="GET"&&r==="/monitor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(zt({peers:O(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let d=new AbortController,p=setTimeout(()=>d.abort(),8e3);try{let g=wt(await ie(a.config,d.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let $=await Promise.all(g.map(async A=>{try{let w=await fetch(A.url+"/monitor",{headers:A.token?{Authorization:`Bearer ${A.token}`}:{},signal:d.signal});if(!w.ok)throw new Error(`HTTP ${w.status}`);return{name:A.name,url:A.url,ok:!0,data:await w.json()}}catch(w){return{name:A.name,url:A.url,ok:!1,error:w.message}}}));v(e,200,{nodes:$});return}let f=g.find($=>$.url===n.searchParams.get("node"));if(!f){v(e,400,{error:"Select a known node"});return}let h=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(h)||o==="POST"&&["register","ended","action","retry","clear"].includes(h))){v(e,405,{error:"Unknown monitor operation"});return}let y=o==="POST"?JSON.stringify(await yt(t)):void 0,k=await fetch(f.url+"/monitor/"+h+(h==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):h==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:y,signal:d.signal,headers:{"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}}});v(e,k.status,await k.json())}catch(g){v(e,502,{error:g.message})}finally{clearTimeout(p)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ga({peers:O(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ya({peers:O(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Qa({peers:O(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Za({peers:O(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Lt({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let d=n.searchParams.get("agent")||"",p=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!d){e.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),e.end("<p>Missing <code>?agent=</code>. Open this task from the Live page.</p>");return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(en({taskId:decodeURIComponent(l[1]),agentId:d,agentName:n.searchParams.get("name")||void 0,channel:n.searchParams.get("channel")||void 0,archived:n.searchParams.get("archived")==="1",ask:n.searchParams.get("ask")||void 0,askAt:n.searchParams.get("at")||void 0,nodeUrl:p,peers:O(a.config)}));return}let i=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(i){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(tn({agentId:decodeURIComponent(i[1]),agentName:n.searchParams.get("name")||void 0,nodeUrl:n.searchParams.get("node")||a.config.dashboard.daemonUrl,peers:O(a.config)}));return}if(o==="GET"&&r==="/graph"){e.writeHead(302,{Location:"/admin/graph"}),e.end();return}if(o==="GET"&&r==="/setup"){Pt(t,e);return}if(o==="POST"&&r==="/api/setup"){await Dt(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Ot(t,e);return}if(o==="GET"&&r==="/admin"){Vt(t,e,O(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){na(t,e,O(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}pa(t,e,O(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let d=String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(d==="fleet"){if(r==="/api/admin/activity-graph"){await Us(t,e,a);return}let p=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(p){let g=decodeURIComponent(p[1]),f=g.indexOf("::");if(f>0){let h=g.slice(0,f),y=g.slice(f+2),k=a.config.node?.id||a.config.node?.name||"local";if(h===k)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(y)}`;else{let $=(a.config.dashboard?.daemons||[]).find(A=>(A.name||A.url)===h);if($){let A=ut($.url.replace(/\/+$/,""),a.config);if(A){await rn(t,e,A,`/api/admin/activity-graph/dispatch/${encodeURIComponent(y)}`);return}}v(e,404,{error:`unknown node "${h}" in fleet dispatch id`});return}}}}else if(d&&d!=="primary"){let p=ut(d,a.config);if(!p){v(e,404,{error:`unknown peer: ${d}`});return}let g=(n.search||"").replace(/[?&]peer=[^&]*/g,h=>h.startsWith("?")?"?":"");await rn(t,e,p,r+(g==="?"?"":g));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await ua(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await Fs(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:d}=await import("./doctor-FS2BX6H4.js"),g=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",f=await d({running:g});v(e,200,f)}catch(d){v(e,500,{error:d?.message||String(d)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fa({peers:O(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await ga(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(xa({peers:O(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(va({peers:O(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 Is(a)(t,e);return}if(o==="GET"&&r==="/admin/activity-graph"){_a(t,e,O(a.config));return}if(o==="GET"&&r==="/api/admin/activity-graph"&&await Ma(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await Ia(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await ja(t,e,r))return;let c=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(c){Pa(t,e,c[1],O(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let d=t.headers.authorization||"",p=d.startsWith("Bearer ")?d.slice(7):"";if(p!==a.token){let g=new ee,f=p?g.verify(p):null;if(!f||!ve(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await Yt(t,e);return}if(r.startsWith("/api/admin/graph/")){await ra(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await Da(t,e,r);return}if(r.startsWith("/api/admin/")){await Qt(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(Gt);return}if(o==="GET"&&r.startsWith("/assets/")){let d=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(d)){v(e,400,{error:"invalid asset name"});return}let p=zs("web/"+d);try{let g=await qs(p),f=d.endsWith(".map")?"application/json; charset=utf-8":d.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",h=n.searchParams.has("v");e.writeHead(200,{"Content-Type":f,"Cache-Control":h?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(g)}catch{v(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let d=await pt(a.config);v(e,200,d)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let d=n.searchParams.get("date")||new Date().toISOString().slice(0,10),p=n.searchParams.get("timezone")||"UTC",g=await pt(a.config,{date:d,timezone:p});v(e,200,g)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let d=(p,g,f,h)=>{let y=parseInt(n.searchParams.get(p)||"",10);return Number.isFinite(y)?Math.max(f,Math.min(h,y)):g};try{let p=await ie(a.config);v(e,200,await Xa(p,{days:d("days",30,0,180),tzOffsetMinutes:d("tzOffset",0,-840,840),limit:d("limit",60,1,200)}))}catch(p){v(e,502,{error:p.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let d=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(d)){v(e,400,{error:"day=YYYY-MM-DD query param required"});return}let p=(g,f,h,y)=>{let k=parseInt(n.searchParams.get(g)||"",10);return Number.isFinite(k)?Math.max(h,Math.min(y,k)):f};try{let g=await ie(a.config);v(e,200,await Ja(g,{day:d,tzOffsetMinutes:p("tzOffset",0,-840,840),limit:p("limit",40,1,200)}))}catch(g){v(e,502,{error:g.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}let p=n.searchParams,g;if(r==="/api/mesh/thread"){let[f,h,y]=[p.get("agent"),p.get("channel"),p.get("chat")];if(!f||!h||!y){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/thread?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(h)}&chat=${encodeURIComponent(y)}&limit=${encodeURIComponent(p.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[f,h]=[p.get("kind"),p.get("key")];if(!f||!h){v(e,400,{error:"kind and key required"});return}g=`/analytics/job?kind=${encodeURIComponent(f)}&key=${encodeURIComponent(h)}&limit=${encodeURIComponent(p.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[f,h,y]=[p.get("agent"),p.get("channel"),p.get("chat")];if(!f||!h||!y){v(e,400,{error:"agent, channel, chat required"});return}g=`/analytics/conversation?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(h)}&chat=${encodeURIComponent(y)}&tzOffset=${encodeURIComponent(p.get("tzOffset")||"0")}`}else{let f=p.get("task");if(!f){v(e,400,{error:"task required"});return}g=`/analytics/run/${encodeURIComponent(f)}`}try{await Ka(e,await ie(a.config),d,g)}catch(f){v(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/live/stream"){js(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task");if(!p||!g||!f){v(e,400,{error:"node, agent, task query params required"});return}await Ls(t,e,a,p,g,f);return}if(o==="GET"&&r==="/api/task/history"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),g=d.searchParams.get("agent"),f=d.searchParams.get("task"),h=d.searchParams.get("limit")||"50";if(!p||!g){v(e,400,{error:"node and agent query params required"});return}await Ds(e,a,p,g,f,h);return}if(o==="POST"&&r==="/api/task/action"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),g=d.searchParams.get("task"),f=d.searchParams.get("kind");if(!p||!g||f!=="cancel"&&f!=="followup"){v(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await Os(t,e,a,p,g,f);return}if(o==="GET"&&r==="/api/agents"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let p=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:d});if(!p.ok)throw new Error(`HTTP ${p.status}`);let g=await p.json();v(e,200,g)}catch(d){v(e,502,{error:d.message||"agents fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let d=await re(t);try{let p=await Ns(a.config,d);v(e,200,p)}catch(p){v(e,502,{error:p.message||"draft failed"})}return}let u=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(u&&o==="POST"){let d=u[1];if(!Rs(t,e,[`agent:${d}`]))return;await Ps(t,e,a.config,d);return}if(r.startsWith("/api/")&&a.token){let d=t.headers.authorization||"",p=d.startsWith("Bearer ")?d.slice(7):"";if(p!==a.token){let g=new ee,f=p?g.verify(p):null;if(!f||!ve(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){v(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="GET"&&r==="/events"){let p=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"});let g=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(k=>({name:k.name,url:k.url,token:k.token}))],f={flag:!1},h=[];t.on("close",()=>{f.flag=!0;for(let k of h)try{k.abort()}catch{}});let y=setInterval(()=>{if(!f.flag)try{e.write(`: ping
|
|
14329
|
+
`),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 Vs=new Set(["/","/live","/mesh","/monitor","/activity","/boards","/glossary","/workflows","/workflows/editor","/procedures","/processes","/graph","/setup","/admin","/admin/graph","/admin/health","/admin/observability","/admin/ledger","/admin/cost","/admin/projects","/admin/wiki"]);async function Ys(t,e,a){let n=new URL(t.url||"/","http://localhost"),r=n.pathname,o=(t.method||"GET").toUpperCase();if(e.setHeader("Access-Control-Allow-Origin","*"),e.setHeader("Access-Control-Allow-Methods","GET, POST, PATCH, OPTIONS"),e.setHeader("Access-Control-Allow-Headers","Content-Type, Authorization, X-Requested-With"),o==="OPTIONS"){e.writeHead(204),e.end();return}if(o==="GET"&&Vs.has(r)&&Wt("page",r),o==="GET"&&r==="/"){let d=zt();if(!d.configExists||d.agentCount===0){e.writeHead(302,{Location:"/setup"}),e.end();return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mt({peers:D(a.config)}));return}if(o==="GET"&&r==="/boards"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(pn({peers:D(a.config)}));return}if(o==="GET"&&r==="/live"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mt({peers:D(a.config)}));return}if(o==="POST"&&r.match(/^\/webhook\/n8n\/[A-Za-z0-9._:-]{1,64}$/)){try{let[d]=await le(a.config);if(!d){v(e,503,{error:"no node available"});return}let p=await new Promise(f=>{let y="";t.on("data",x=>y+=x),t.on("end",()=>f(y)),t.on("error",()=>f(""))}),h=await fetch(d.url+r,{method:"POST",headers:{"Content-Type":"application/json",...d.token?{Authorization:`Bearer ${d.token}`}:{}},body:p||"{}"});e.writeHead(h.status,{"Content-Type":"application/json"}),e.end(await h.text())}catch(d){v(e,502,{error:"could not reach the node",message:String(d?.message||d)})}return}if(r==="/api/assistant"||r.startsWith("/api/assistant/")){try{let d=await le(a.config),p=o==="POST"?void 0:n.searchParams.get("node"),h=o==="POST"?await se(t):void 0,f=h?.node??p,y=f?d.find(A=>A.url===f):d[0];if(!y){v(e,400,{error:"unknown node"});return}let x=n.search?n.search.replace(/([?&])node=[^&]*/,"$1").replace(/[?&]$/,""):"",w=await fetch(y.url+r+x,{method:o,headers:{"Content-Type":"application/json",...y.token?{Authorization:`Bearer ${y.token}`}:{}},...o==="POST"?{body:JSON.stringify({...h,node:void 0})}:{}});v(e,w.status,await w.json().catch(()=>({error:`HTTP ${w.status}`})))}catch(d){v(e,502,{error:"could not reach the node",message:d?.message||String(d)})}return}if(o==="POST"&&r==="/api/workflows/editor/chat"){try{let d=await se(t),p={"Content-Type":"application/json"};a.config.dashboard.token&&(p.Authorization=`Bearer ${a.config.dashboard.token}`);let h=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${h}/api/workflows/editor/chat`,{method:"POST",headers:p,body:JSON.stringify(d??{})}),y=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,y)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(o==="GET"&&r==="/api/n8n/workflows"){try{let[d]=await le(a.config);if(!d){v(e,200,{configured:!1,workflows:[]});return}let p=await fetch(d.url+"/api/n8n/workflows",{headers:d.token?{Authorization:`Bearer ${d.token}`}:{}});v(e,p.status,await p.json().catch(()=>({configured:!1,workflows:[]})))}catch{v(e,200,{configured:!1,workflows:[]})}return}if(o==="GET"&&r==="/workflows/editor"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Zt({peers:D(a.config)}));return}if(o==="GET"&&r==="/activity"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Qt({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(Kt({peers:D(a.config)}));return}if(r==="/api/monitor"||r.startsWith("/api/monitor/")){let d=new AbortController,p=setTimeout(()=>d.abort(),8e3);try{let h=At(await le(a.config,d.signal),a.config.mesh.peers);if(o==="GET"&&r==="/api/monitor"){let A=await Promise.all(h.map(async $=>{try{let k=await fetch($.url+"/monitor",{headers:$.token?{Authorization:`Bearer ${$.token}`}:{},signal:d.signal});if(!k.ok)throw new Error(`HTTP ${k.status}`);return{name:$.name,url:$.url,ok:!0,data:await k.json()}}catch(k){return{name:$.name,url:$.url,ok:!1,error:k.message}}}));v(e,200,{nodes:A});return}let f=h.find(A=>A.url===n.searchParams.get("node"));if(!f){v(e,400,{error:"Select a known node"});return}let y=r.slice(13);if(!(o==="GET"&&["discover","actions","activity"].includes(y)||o==="POST"&&["register","ended","action","retry","clear"].includes(y))){v(e,405,{error:"Unknown monitor operation"});return}let x=o==="POST"?JSON.stringify(await Ct(t)):void 0,w=await fetch(f.url+"/monitor/"+y+(y==="actions"?"?offset="+encodeURIComponent(n.searchParams.get("offset")||"0"):y==="activity"?"?hours="+encodeURIComponent(n.searchParams.get("hours")||"24"):""),{method:o,body:x,signal:d.signal,headers:{"Content-Type":"application/json",...f.token?{Authorization:`Bearer ${f.token}`}:{}}});v(e,w.status,await w.json())}catch(h){v(e,502,{error:h.message})}finally{clearTimeout(p)}return}if(o==="GET"&&r==="/mesh"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(sn({peers:D(a.config)}));return}if(o==="GET"&&r==="/glossary"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(un({peers:D(a.config)}));return}if(o==="GET"&&r==="/workflows"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(mn({peers:D(a.config)}));return}if(o==="GET"&&r==="/procedures"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(hn({peers:D(a.config)}));return}if(o==="GET"&&r==="/processes"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Bt({}));return}let l=o==="GET"&&r.match(/^\/tasks\/([^/]+)$/);if(l){let d=n.searchParams.get("agent")||"",p=n.searchParams.get("node")||a.config.dashboard.daemonUrl;if(!d){e.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),e.end("<p>Missing <code>?agent=</code>. Open this task from the Live page.</p>");return}e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(gn({taskId:decodeURIComponent(l[1]),agentId:d,agentName:n.searchParams.get("name")||void 0,channel:n.searchParams.get("channel")||void 0,archived:n.searchParams.get("archived")==="1",ask:n.searchParams.get("ask")||void 0,askAt:n.searchParams.get("at")||void 0,nodeUrl:p,peers:D(a.config)}));return}let i=o==="GET"&&r.match(/^\/agents\/([^/]+)\/history$/);if(i){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(fn({agentId:decodeURIComponent(i[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"){qt(t,e);return}if(o==="POST"&&r==="/api/setup"){await Ft(t,e);return}if(o==="POST"&&r==="/api/setup/start-daemon"){await Ut(t,e);return}if(o==="GET"&&r==="/admin"){ra(t,e,D(a.config),a.token);return}if(o==="GET"&&r==="/admin/graph"){pa(t,e,D(a.config),a.token);return}if(o==="GET"&&(r==="/admin/health"||r==="/admin/observability")){if(r==="/admin/observability"){e.writeHead(302,{Location:"/admin/health"}),e.end();return}ba(t,e,D(a.config));return}if(r.startsWith("/api/admin/")||r.startsWith("/api/workflows")||r.startsWith("/api/agents")){let d=String(t.headers["x-agentx-peer"]||"").trim()||n.searchParams.get("peer")||"";if(d==="fleet"){if(r==="/api/admin/activity-graph"){await fi(t,e,a);return}if(r==="/api/admin/activity-graph/stream"){await pt(t,e,r,h=>kn(h,a.config));return}let p=r.match(/^\/api\/admin\/activity-graph\/dispatch\/(.+)$/);if(p){let h=decodeURIComponent(p[1]),f=h.indexOf("::");if(f>0){let y=h.slice(0,f),x=h.slice(f+2),w=a.config.node?.id||a.config.node?.name||"local";if(y===w)t.url=`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`;else{let A=(a.config.dashboard?.daemons||[]).find($=>($.name||$.url)===y);if(A){let $=vt(A.url.replace(/\/+$/,""),a.config);if($){await bn(t,e,$,`/api/admin/activity-graph/dispatch/${encodeURIComponent(x)}`);return}}v(e,404,{error:`unknown node "${y}" in fleet dispatch id`});return}}}}else if(d&&d!=="primary"){let p=vt(d,a.config);if(!p){v(e,404,{error:`unknown peer: ${d}`});return}let h=(n.search||"").replace(/[?&]peer=[^&]*/g,y=>y.startsWith("?")?"?":"");await bn(t,e,p,r+(h==="?"?"":h));return}}if(o==="GET"&&r.startsWith("/api/admin/observability/")&&await ya(t,e,r))return;if(o==="GET"&&r==="/api/admin/logs/stream"){await xi(t,e);return}if(o==="GET"&&r==="/api/admin/doctor"){try{let{runDoctorChecks:d}=await import("./doctor-DW27MR2T.js"),h=new URL(t.url||"/","http://_").searchParams.get("running")!=="false",f=await d({running:h});v(e,200,f)}catch(d){v(e,500,{error:d?.message||String(d)})}return}if(o==="GET"&&r==="/admin/ledger"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ea({peers:D(a.config)}));return}if(o==="GET"&&r.startsWith("/api/admin/ledger/")&&await _a(t,e,r))return;if(o==="GET"&&r==="/admin/cost"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Sa({peers:D(a.config)}));return}if(o==="GET"&&r==="/admin/projects"){e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(Ta({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 ni(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 Ua(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/stream")&&await pt(t,e,r)||o==="GET"&&r.startsWith("/api/admin/activity-graph/dispatch/")&&await Ga(t,e,r))return;let c=o==="GET"&&r.match(/^\/admin\/agents\/([a-z0-9][a-z0-9_-]*)$/);if(c){Ja(t,e,c[1],D(a.config),a.token);return}if(r.startsWith("/api/admin/")&&a.token){let d=t.headers.authorization||"",p=d.startsWith("Bearer ")?d.slice(7):"";if(p!==a.token){let h=new ae,f=p?h.verify(p):null;if(!f||!ve(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if(o==="GET"&&r==="/api/admin/config"){await oa(t,e);return}if(r.startsWith("/api/admin/graph/")){await ua(t,e,r);return}if(r.startsWith("/api/admin/agent/")){await Va(t,e,r);return}if(r.startsWith("/api/admin/")){await sa(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(ea);return}if(o==="GET"&&r.startsWith("/assets/")){let d=r.slice(8);if(!/^[a-zA-Z0-9._-]+\.(js|map|css)$/.test(d)){v(e,400,{error:"invalid asset name"});return}let p=hi("web/"+d);try{let h=await gi(p),f=d.endsWith(".map")?"application/json; charset=utf-8":d.endsWith(".css")?"text/css; charset=utf-8":"application/javascript; charset=utf-8",y=n.searchParams.has("v");e.writeHead(200,{"Content-Type":f,"Cache-Control":y?"public, max-age=31536000, immutable":"public, max-age=60"}),e.end(h)}catch{v(e,404,{error:"asset not found",hint:"run: npm run build:web"})}return}if(o==="GET"&&r==="/api/live"){try{let d=await xt(a.config);v(e,200,d)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh"){try{let d=n.searchParams.get("date")||new Date().toISOString().slice(0,10),p=n.searchParams.get("timezone")||"UTC",h=await xt(a.config,{date:d,timezone:p});v(e,200,h)}catch(d){v(e,502,{error:d.message})}return}if(o==="GET"&&r==="/api/mesh/analytics"){let d=(p,h,f,y)=>{let x=parseInt(n.searchParams.get(p)||"",10);return Number.isFinite(x)?Math.max(f,Math.min(y,x)):h};try{let p=await le(a.config);v(e,200,await ln(p,{days:d("days",30,0,180),tzOffsetMinutes:d("tzOffset",0,-840,840),limit:d("limit",60,1,200)}))}catch(p){v(e,502,{error:p.message})}return}if(o==="GET"&&r==="/api/mesh/day"){let d=n.searchParams.get("day")||"";if(!/^\d{4}-\d{2}-\d{2}$/.test(d)){v(e,400,{error:"day=YYYY-MM-DD query param required"});return}let p=(h,f,y,x)=>{let w=parseInt(n.searchParams.get(h)||"",10);return Number.isFinite(w)?Math.max(y,Math.min(x,w)):f};try{let h=await le(a.config);v(e,200,await cn(h,{day:d,tzOffsetMinutes:p("tzOffset",0,-840,840),limit:p("limit",40,1,200)}))}catch(h){v(e,502,{error:h.message})}return}if(o==="GET"&&(r==="/api/mesh/thread"||r==="/api/mesh/job"||r==="/api/mesh/run"||r==="/api/mesh/conversation")){let d=n.searchParams.get("node");if(!d){v(e,400,{error:"node query param required"});return}let p=n.searchParams,h;if(r==="/api/mesh/thread"){let[f,y,x]=[p.get("agent"),p.get("channel"),p.get("chat")];if(!f||!y||!x){v(e,400,{error:"agent, channel, chat required"});return}h=`/analytics/thread?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(y)}&chat=${encodeURIComponent(x)}&limit=${encodeURIComponent(p.get("limit")||"120")}`}else if(r==="/api/mesh/job"){let[f,y]=[p.get("kind"),p.get("key")];if(!f||!y){v(e,400,{error:"kind and key required"});return}h=`/analytics/job?kind=${encodeURIComponent(f)}&key=${encodeURIComponent(y)}&limit=${encodeURIComponent(p.get("limit")||"120")}`}else if(r==="/api/mesh/conversation"){let[f,y,x]=[p.get("agent"),p.get("channel"),p.get("chat")];if(!f||!y||!x){v(e,400,{error:"agent, channel, chat required"});return}h=`/analytics/conversation?agent=${encodeURIComponent(f)}&channel=${encodeURIComponent(y)}&chat=${encodeURIComponent(x)}&tzOffset=${encodeURIComponent(p.get("tzOffset")||"0")}`}else{let f=p.get("task");if(!f){v(e,400,{error:"task required"});return}h=`/analytics/run/${encodeURIComponent(f)}`}try{await dn(e,await le(a.config),d,h)}catch(f){v(e,502,{error:f.message})}return}if(o==="GET"&&r==="/api/live/stream"){oi(t,e,a.config);return}if(o==="GET"&&r==="/api/task/stream"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),h=d.searchParams.get("agent"),f=d.searchParams.get("task");if(!p||!h||!f){v(e,400,{error:"node, agent, task query params required"});return}await si(t,e,a,p,h,f);return}if(o==="GET"&&r==="/api/task/history"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),h=d.searchParams.get("agent"),f=d.searchParams.get("task"),y=d.searchParams.get("limit")||"50";if(!p||!h){v(e,400,{error:"node and agent query params required"});return}await di(e,a,p,h,f,y);return}if(o==="POST"&&r==="/api/task/action"){let d=new URL(t.url||"/","http://localhost"),p=d.searchParams.get("node"),h=d.searchParams.get("task"),f=d.searchParams.get("kind");if(!p||!h||f!=="cancel"&&f!=="followup"){v(e,400,{error:"node, task, kind=cancel|followup query params required"});return}await ci(t,e,a,p,h,f);return}if(o==="GET"&&r==="/api/agents"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let p=await fetch(a.config.dashboard.daemonUrl.replace(/\/+$/,"")+"/agents",{headers:d});if(!p.ok)throw new Error(`HTTP ${p.status}`);let h=await p.json();v(e,200,h)}catch(d){v(e,502,{error:d.message||"agents fetch failed"})}return}if(o==="POST"&&r==="/api/draft"){let d=await se(t);try{let p=await ui(a.config,d);v(e,200,p)}catch(p){v(e,502,{error:p.message||"draft failed"})}return}let m=r.match(/^\/api\/public\/agents\/([^/]+)\/messages$/);if(m&&o==="POST"){let d=m[1];if(!ii(t,e,[`agent:${d}`]))return;await li(t,e,a.config,d);return}if(r.startsWith("/api/")&&a.token){let d=t.headers.authorization||"",p=d.startsWith("Bearer ")?d.slice(7):"";if(p!==a.token){let h=new ae,f=p?h.verify(p):null;if(!f||!ve(f,"dashboard:write")){v(e,401,{error:"unauthorized"});return}}}if((o==="POST"||o==="PATCH"||o==="DELETE"||o==="PUT")&&r.startsWith("/api/")&&t.headers["x-requested-with"]!=="agentx-board"){v(e,400,{error:"missing X-Requested-With: agentx-board"});return}if(o==="GET"&&r==="/events"){let p=new URL(t.url||"/","http://localhost").searchParams.toString();e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*"});let h=[{name:a.config.node.name||"local",url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(w=>({name:w.name,url:w.url,token:w.token}))],f={flag:!1},y=[];t.on("close",()=>{f.flag=!0;for(let w of y)try{w.abort()}catch{}});let x=setInterval(()=>{if(!f.flag)try{e.write(`: ping
|
|
14309
14330
|
|
|
14310
|
-
`)}catch{}},15e3);t.on("close",()=>clearInterval(
|
|
14331
|
+
`)}catch{}},15e3);t.on("close",()=>clearInterval(x));for(let w of h)(async()=>{let A={Accept:"text/event-stream"};w.token&&(A.Authorization=`Bearer ${w.token}`);let $=new AbortController;y.push($);try{let k=await fetch(`${w.url.replace(/\/+$/,"")}/events${p?`?${p}`:""}`,{headers:A,signal:$.signal});if(!k.ok||!k.body)return;let C=k.body.getReader(),L=new TextDecoder,R="";for(;!f.flag;){let{done:N,value:Y}=await C.read();if(N)break;R+=L.decode(Y,{stream:!0});let B;for(;(B=R.indexOf(`
|
|
14311
14332
|
|
|
14312
|
-
`))>=0;){let
|
|
14333
|
+
`))>=0;){let O=R.slice(0,B);if(R=R.slice(B+2),f.flag)break;try{e.write(O+`
|
|
14313
14334
|
|
|
14314
|
-
`)}catch{f.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let d=new URL(t.url||"/","http://localhost"),p=Math.max(1,Math.min(500,Number(d.searchParams.get("limit")||50))),
|
|
14315
|
-
`;
|
|
14335
|
+
`)}catch{f.flag=!0}}}}catch{}})();return}if(o==="GET"&&r==="/api/workflows/runs"){try{let d=new URL(t.url||"/","http://localhost"),p=Math.max(1,Math.min(500,Number(d.searchParams.get("limit")||50))),h=d.searchParams.get("workflowId")||void 0,f=d.searchParams.get("summary")==="1"||d.searchParams.get("summary")==="true",y=a.workflowRuns.list({limit:p,workflowId:h}),x=`?limit=${p}${h?`&workflowId=${encodeURIComponent(h)}`:""}${f?"&summary=1":""}`,w=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(L=>({url:L.url,token:L.token}))],A=await Promise.all(w.map(async L=>{let R={};L.token&&(R.Authorization=`Bearer ${L.token}`);try{let N=new AbortController,Y=setTimeout(()=>N.abort(),5e3);try{let B=await fetch(`${L.url.replace(/\/+$/,"")}/api/workflows/runs${x}`,{headers:R,signal:N.signal});if(!B.ok)return[];let O=await B.json();return Array.isArray(O.runs)?O.runs:[]}finally{clearTimeout(Y)}}catch{return[]}})),$=new Map;for(let L of y)$.set(L.id,L);for(let L of A)for(let R of L)$.set(R.id,R);let k=Array.from($.values()).sort((L,R)=>L.updatedAt<R.updatedAt?1:-1).slice(0,p),C=f?k.map(L=>ei(L)):k;v(e,200,{runs:C})}catch(d){v(e,502,{error:"runs fetch failed",message:d.message||String(d)})}return}let g=o==="GET"&&r.match(/^\/api\/workflows\/runs\/([^\/]+)$/);if(g){let d=decodeURIComponent(g[1]),p=a.workflowRuns.get(d);if(p){v(e,200,{run:p});return}let h=[{url:a.config.dashboard.daemonUrl,token:a.config.dashboard.token},...(a.config.dashboard.daemons||[]).map(f=>({url:f.url,token:f.token}))];for(let f of h)try{let y={};f.token&&(y.Authorization=`Bearer ${f.token}`);let x=await fetch(`${f.url.replace(/\/+$/,"")}/api/workflows/runs/${encodeURIComponent(d)}`,{headers:y});if(x.ok){v(e,200,await x.json());return}}catch{}v(e,404,{error:"run not found on any configured peer"});return}if(o==="GET"&&r==="/api/actions/builtin"){try{let d={};a.config.dashboard.token&&(d.Authorization=`Bearer ${a.config.dashboard.token}`);let p=a.config.dashboard.daemonUrl.replace(/\/+$/,""),h=await fetch(`${p}/api/actions/builtin`,{headers:d}),f=await h.json().catch(()=>({error:`HTTP ${h.status}`}));v(e,h.status,f)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}let b=o==="POST"&&r.match(/^\/workflows\/([^/]+)\/run$/);if(b){try{let d=await se(t).catch(()=>({})),p={"Content-Type":"application/json"};a.config.dashboard.token&&(p.Authorization=`Bearer ${a.config.dashboard.token}`);let h=a.config.dashboard.daemonUrl.replace(/\/+$/,""),f=await fetch(`${h}/workflows/${encodeURIComponent(b[1])}/run`,{method:"POST",headers:p,body:JSON.stringify(d??{})}),y=await f.json().catch(()=>({error:`HTTP ${f.status}`}));v(e,f.status,y)}catch(d){v(e,502,{error:"daemon unreachable",message:d.message||String(d)})}return}if(r.startsWith("/api/workflows")&&vn(t,e,{store:a.workflowStore,runs:a.workflowRuns,layouts:a.workflowLayouts,requireScope:(p,h,f)=>{if(a.token)return!0;let y=Ke(p);if(!y)return!0;let x=new ae().verify(y);if(!x)return v(h,401,{error:"invalid or revoked token"}),!1;for(let w of f)if(!ve(x,w))return v(h,403,{error:`token missing scope: ${w}`,scopes:x.scopes}),!1;return!0}}))return;if(o==="GET"&&r==="/api/boards"){v(e,200,a.boards.map(d=>({id:d.id,name:d.name,source:d.source,primaryToolLabel:d.primaryToolLabel,labels:d.labels,columns:d.columns,timeRangeDays:d.timeRangeDays})));return}let _=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/members$/);if(_&&o==="GET"){let d=a.sources.get(_[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let p=typeof d.listMembers=="function"?await d.listMembers():[];v(e,200,p)}catch(p){v(e,502,{error:p.message})}return}let I=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/milestones$/);if(I&&o==="GET"){let d=a.sources.get(I[1]);if(!d){v(e,404,{error:"unknown board"});return}try{let p=typeof d.listMilestones=="function"?await d.listMilestones():[];v(e,200,p)}catch(p){v(e,502,{error:p.message})}return}let E=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items\/(.+?)\/move$/),S=r.match(/^\/api\/boards\/([a-z0-9_-]+)\/items(?:\/(.+))?$/);if(E&&o==="PATCH"){let[,d,p]=E,h=decodeURIComponent(p),f=a.boards.find($=>$.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let y=a.sources.get(d);if(!y){v(e,503,{error:`board "${d}" source unavailable`});return}let x=await se(t),w=f.columns.find($=>$.id===x.to),A=f.columns.find($=>$.id===x.from);if(!w){v(e,400,{error:`unknown 'to' column: ${x.to}`});return}try{await Zs(y,h,A,w),ht({actor:gt(t),action:"move",boardId:d,itemId:h,payload:{from:x.from,to:x.to}}),v(e,200,{ok:!0})}catch($){v(e,502,{error:$.message||"transition failed"})}return}if(S){let[,d,p]=S,h=p?decodeURIComponent(p):void 0,f=a.boards.find(x=>x.id===d);if(!f){v(e,404,{error:`unknown board: ${d}`});return}let y=a.sources.get(d);if(!y){v(e,503,{error:`board "${d}" source unavailable`});return}if(o==="GET"&&!h){let{columns:x,totals:w}=await Qs(f,y,n.searchParams);v(e,200,{columns:x,totals:w});return}if(o==="GET"&&h){try{let x=typeof y.getItem=="function"?await y.getItem(h):null;if(!x){v(e,404,{error:"not found"});return}v(e,200,x)}catch(x){v(e,502,{error:x.message})}return}if(o==="PATCH"&&h){let x=await se(t);try{let w=typeof y.updateItem=="function"?await y.updateItem(h,x):null;if(!w){v(e,501,{error:"update unsupported"});return}ht({actor:gt(t),action:"update",boardId:d,itemId:h,payload:x}),v(e,200,w)}catch(w){v(e,502,{error:w.message})}return}if(o==="POST"&&!h){let x=await se(t);if(!x.title){v(e,400,{error:"title required"});return}if(!y.capabilities.create||!y.create){v(e,400,{error:`source ${y.type} does not support create`});return}try{let w=await y.create({title:x.title,description:x.description,labels:x.labels,assigneeUsernames:x.assigneeUsernames,milestoneTitle:x.milestoneTitle,projectHint:x.projectHint});ht({actor:gt(t),action:"create",boardId:d,itemId:w.id,payload:{title:x.title}}),v(e,201,w)}catch(w){v(e,502,{error:w.message})}return}}if(o==="GET"&&/^\/[a-z][a-z-]*\/?$/.test(r)){let d=r.replace(/^\/+|\/+$/g,""),h={health:"/admin/health",ledger:"/admin/ledger",cost:"/admin/cost",projects:"/admin/projects",graph:"/admin/graph",wiki:"/admin/wiki/",observability:"/admin/health"}[d];if(h){e.writeHead(302,{Location:h}),e.end();return}}v(e,404,{error:"not found",path:r})}async function Qs(t,e,a){if(!e.capabilities.listAll||!e.listAll){let d={};for(let p of t.columns)d[p.id]=[];return{columns:d,totals:Object.fromEntries(t.columns.map(p=>[p.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,l=a.get("assignee")||void 0,i=parseInt(a.get("days")||String(t.timeRangeDays),10),c=parseInt(a.get("closedDays")||String(t.closedWindowDays??30),10),m=t.columns.some(d=>d.kind!=="closed"),u=t.columns.some(d=>d.kind==="closed"),g=m?await e.listAll({sinceDays:i,labels:n.length?n:void 0,search:o,milestone:s,state:"opened"}):[],b=u?await e.listAll({sinceDays:c,labels:n.length?n:void 0,search:o,milestone:s,state:"closed"}):[],_={};for(let d of t.columns)_[d.id]=[];let I=t.columns.find(d=>d.kind==="closed");for(let d of b)I&&_[I.id].push({...d,stage:I.id});let E=t.columns.filter(d=>d.kind!=="closed");for(let d of g){let p=yt(d,E);if(!p)continue;let h=_[p];h&&h.push({...d,stage:p})}if(l)for(let d of Object.keys(_))_[d]=_[d].filter(p=>p.assignee===l);for(let d of Object.keys(_))_[d].sort((p,h)=>{let f=(p.priority??99)-(h.priority??99);return f!==0?f:(h.updatedAt||"").localeCompare(p.updatedAt||"")});let S=Object.fromEntries(Object.entries(_).map(([d,p])=>[d,p.length]));return{columns:_,totals:S}}async function Zs(t,e,a,n){let r=wt(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 ei(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 ti(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 Lt(a.host,a.token,t.source.projects,n,(...r)=>console.log("[board]",...r))}throw new Error(`unsupported board source: ${t.source.type}`)}function ht(t){try{let e=ke(process.cwd(),".agentx");yn(e)||Gs(e,{recursive:!0});let a=JSON.stringify({ts:new Date().toISOString(),...t})+`
|
|
14336
|
+
`;Ws(ke(e,"board-audit.jsonl"),a)}catch{}}function gt(t){let e=t.headers["x-forwarded-for"];return(Array.isArray(e)?e[0]:e?.split(",")[0])||t.socket.remoteAddress||"unknown"}async function ai(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)}`:"",[l,i,c,m,u]=await Promise.all([fetch(t+"/health",{headers:r,signal:a}).catch(()=>null),fetch(t+"/agents",{headers:r,signal:a}).catch(()=>null),fetch(t+"/mesh",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons",{headers:r,signal:a}).catch(()=>null),fetch(t+"/crons/runs"+s,{headers:r,signal:a}).catch(()=>null)]);if(!i||!i.ok)return o.error=i?`HTTP ${i.status}`:"unreachable",o;let g=await i.json();if(o.agents=g.map(b=>({id:b.id,name:b.name,tier:b.tier,model:b.model,skillCount:Number.isFinite(b.skillCount)?b.skillCount:void 0,active:b.active||0,total:b.total||0,errors:b.errors||0,lastActive:b.lastActive,lastSummary:b.lastSummary,hourlyTasks:Array.isArray(b.hourlyTasks)?b.hourlyTasks:void 0,runningTasks:Array.isArray(b.runningTasks)?b.runningTasks:[]})),l&&l.ok){let b=await l.json();o.uptimeSec=b.uptime,o.name=b.node?.name||b.node?.id||t,o.id=b.node?.id||t,b.usage&&(o.usage=b.usage)}if(m&&m.ok){let b=await m.json();o.crons=b.map(_=>({id:_.id,enabled:_.enabled===!0,schedule:String(_.schedule||""),timezone:_.timezone,agent:String(_.agent||""),model:_.model,nextRun:_.nextRun,retryPending:_.retryPending===!0,consecutiveErrors:Number(_.consecutiveErrors)||0}))}if(u&&u.ok){let b=await u.json();o.cronRuns=Array.isArray(b.runs)?b.runs:[]}o.reachable=!0,o._peers=Array.isArray(c&&await ri(c))?o._peers:void 0}catch(s){o.error=s.message||String(s)}return o}var Be=null;function ni(t){if(Be)return Be;let e=ke(process.cwd(),".agentx/wiki");return Be=Gt({wikiDir:e,pathPrefix:"/admin/wiki",mode:"graph"}),Be}var ft=new WeakMap;async function ri(t){if(ft.has(t))return ft.get(t);try{let e=t.ok?await t.json():null;return ft.set(t,e),e}catch{return null}}async function ze(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 le(t,e){let a=t.dashboard,n=a.daemonUrl.replace(/\/+$/,""),r=new Map;r.set(n,{name:"primary",url:n,token:a.token});for(let s of a.daemons){let l=s.url.replace(/\/+$/,"");r.has(l)||r.set(l,{name:s.name,url:l,token:s.token})}let o=await ze(n,a.token,e);for(let s of o)r.has(s.url)||r.set(s.url,s);return[...r.values()]}async function xt(t,e){let a=new AbortController,n=setTimeout(()=>a.abort(),3e3);try{let r=await le(t,a.signal),o=await Promise.all(r.map(s=>ai(s.url,s.token,a.signal,e)));return{ts:new Date().toISOString(),nodes:o}}finally{clearTimeout(n)}}function oi(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,i)=>{n||e.write(`event: ${l}
|
|
14316
14337
|
data: ${JSON.stringify(i)}
|
|
14317
14338
|
|
|
14318
|
-
`)},o=async()=>{try{let l=await
|
|
14339
|
+
`)},o=async()=>{try{let l=await xt(a);r("snapshot",l)}catch(l){r("error",{message:l.message})}};o();let s=setInterval(o,2e3);t.on("close",()=>{n=!0,clearInterval(s),e.end()})}async function si(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),l=new Set;l.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let _ of a.config.dashboard.daemons)l.add(_.url.replace(/\/+$/,""));try{let _=await ze(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let I of _)l.add(I.url.replace(/\/+$/,""))}catch{}if(!l.has(s)){v(e,403,{error:"node not in dashboard allowlist",target:s});return}let i=s===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(_=>_.url.replace(/\/+$/,"")===s)?.token,c={Accept:"text/event-stream"};i&&(c.Authorization=`Bearer ${i}`);let m=new AbortController,u;try{u=await fetch(`${s}/agents/${encodeURIComponent(r)}/tasks/${encodeURIComponent(o)}/stream`,{headers:c,signal:m.signal})}catch(_){v(e,502,{error:_.message||"upstream connect failed"});return}if(!u.ok||!u.body){v(e,u.status||502,{error:`upstream HTTP ${u.status}`});return}e.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive","Access-Control-Allow-Origin":"*","X-Accel-Buffering":"no"});let g=u.body.getReader();(async()=>{try{for(;;){let{value:_,done:I}=await g.read();if(I)break;_&&e.write(_)}}catch{}finally{try{e.end()}catch{}}})(),t.on("close",()=>{m.abort();try{e.end()}catch{}})}function ii(t,e,a){let n=Ke(t);if(!n)return v(e,401,{error:"missing token",hint:"pass Authorization: Bearer <token> (agentx token create)"}),null;let r=new ae().verify(n);if(!r)return v(e,401,{error:"invalid or revoked token"}),null;for(let o of a)if(!ve(r,o))return v(e,403,{error:`token missing scope: ${o}`,scopes:r.scopes}),null;return r}async function li(t,e,a,n){let r=a.agents?.[n];if(!r){v(e,404,{error:"unknown agent"});return}if(r.access!=="public"){v(e,403,{error:"agent is private",hint:`set agents.${n}.access = "public" to expose it`});return}let o;try{o=await se(t)}catch{v(e,400,{error:"invalid JSON body"});return}let s=o?.message;if(!s||typeof s!="string"){v(e,400,{error:"required: { message: string, context?: {...} }"});return}let l=a.dashboard.daemonUrl.replace(/\/+$/,""),i={"Content-Type":"application/json"};a.dashboard.token&&(i.Authorization=`Bearer ${a.dashboard.token}`);try{let c=await fetch(`${l}/task`,{method:"POST",headers:i,body:JSON.stringify({agent:n,message:s,context:{channel:"public-api",sender:o.context?.sender||"api",...o.context||{}}})}),m=await c.text();e.writeHead(c.status,{"Content-Type":c.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),e.end(m)}catch(c){v(e,502,{error:c.message||"upstream call failed"})}}async function di(t,e,a,n,r,o){let s=a.replace(/\/+$/,""),l=new Set;l.add(e.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let u of e.config.dashboard.daemons)l.add(u.url.replace(/\/+$/,""));try{let u=await ze(e.config.dashboard.daemonUrl.replace(/\/+$/,""),e.config.dashboard.token);for(let g of u)l.add(g.url.replace(/\/+$/,""))}catch{}if(!l.has(s)){v(t,403,{error:"node not in dashboard allowlist",target:s});return}let i=s===e.config.dashboard.daemonUrl.replace(/\/+$/,"")?e.config.dashboard.token:e.config.dashboard.daemons.find(u=>u.url.replace(/\/+$/,"")===s)?.token,c={Accept:"application/json"};i&&(c.Authorization=`Bearer ${i}`);let m=r?`/agents/${encodeURIComponent(n)}/tasks/${encodeURIComponent(r)}`:`/agents/${encodeURIComponent(n)}/tasks?limit=${encodeURIComponent(o)}`;try{let u=await fetch(`${s}${m}`,{headers:c}),g=await u.text();t.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),t.end(g)}catch(u){v(t,502,{error:u.message||"upstream fetch failed"})}}async function ci(t,e,a,n,r,o){let s=n.replace(/\/+$/,""),l=new Set;l.add(a.config.dashboard.daemonUrl.replace(/\/+$/,""));for(let u of a.config.dashboard.daemons)l.add(u.url.replace(/\/+$/,""));try{let u=await ze(a.config.dashboard.daemonUrl.replace(/\/+$/,""),a.config.dashboard.token);for(let g of u)l.add(g.url.replace(/\/+$/,""))}catch{}if(!l.has(s)){v(e,403,{error:"node not in dashboard allowlist",target:s});return}let i=s===a.config.dashboard.daemonUrl.replace(/\/+$/,"")?a.config.dashboard.token:a.config.dashboard.daemons.find(u=>u.url.replace(/\/+$/,"")===s)?.token,c={"Content-Type":"application/json",Accept:"application/json"};i&&(c.Authorization=`Bearer ${i}`);let m="{}";try{let u=await se(t);m=u?JSON.stringify(u):"{}"}catch{}try{let u=await fetch(`${s}/api/tasks/${encodeURIComponent(r)}/${o}`,{method:"POST",headers:c,body:m}),g=await u.text();e.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json; charset=utf-8","Access-Control-Allow-Origin":"*"}),e.end(g)}catch(u){v(e,502,{error:u.message||"upstream fetch failed"})}}var pi=`
|
|
14319
14340
|
You are helping draft a new GitLab issue. Follow these conventions strictly.
|
|
14320
14341
|
|
|
14321
14342
|
Title pattern:
|
|
@@ -14347,16 +14368,16 @@ Return ONLY a single JSON object on one line \u2014 no prose, no code fences, no
|
|
|
14347
14368
|
Shape:
|
|
14348
14369
|
{ "title": string, "description": string, "labels": string[], "assigneeUsername": string | null, "kind": string }
|
|
14349
14370
|
If you don't have enough information to pick a label confidently, omit it rather than guessing.
|
|
14350
|
-
`;async function
|
|
14371
|
+
`;async function ui(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):
|
|
14351
14372
|
- ${r.knownLabels.slice(0,60).join(`
|
|
14352
14373
|
- `)}`:"",r.members?.length?`Possible assignees (GitLab usernames): ${r.members.slice(0,20).join(", ")}`:"","","Produce the JSON draft now."].filter(Boolean).join(`
|
|
14353
|
-
`),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",l={"Content-Type":"application/json"};t.dashboard.token&&(l.Authorization=`Bearer ${t.dashboard.token}`);let i=await fetch(s,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:
|
|
14374
|
+
`),s=t.dashboard.daemonUrl.replace(/\/+$/,"")+"/task",l={"Content-Type":"application/json"};t.dashboard.token&&(l.Authorization=`Bearer ${t.dashboard.token}`);let i=await fetch(s,{method:"POST",headers:l,body:JSON.stringify({agent:n,message:o,context:{channel:"a2a",sender:"board-dashboard",systemPrompt:pi}})});if(!i.ok)throw new Error(`daemon /task HTTP ${i.status}: ${await i.text().catch(()=>"")}`);let c=await i.json();if(c.error)throw new Error(String(c.error));let m=(c.content||"").toString(),u=mi(m);if(!u||typeof u.title!="string")throw new Error("agent did not return a valid JSON draft. Raw: "+m.slice(0,400));let g=Array.isArray(u.labels)?u.labels.filter(b=>typeof b=="string"):[];return r.primaryLabel&&!g.includes(r.primaryLabel)&&g.unshift(r.primaryLabel),r.columnLabel&&!g.includes(r.columnLabel)&&g.unshift(r.columnLabel),{title:u.title.trim(),description:(u.description||"").toString(),labels:g,assigneeUsername:typeof u.assigneeUsername=="string"?u.assigneeUsername:void 0,kind:typeof u.kind=="string"?u.kind:void 0,raw:m}}function mi(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 hi(t){let e=Js(Ks(import.meta.url));return ke(e,t)}async function gi(t){return Xs(t)}function v(t,e,a){t.writeHead(e,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify(a))}async function se(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 wn(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:wn(s),tokenScope:s.dashboardToken||s.token?"proxy-ready":void 0})),o=r.length>0?[{id:"fleet",name:"Fleet (all peers)",dashboardUrl:"",tokenScope:"merged across nodes"}]:[];return[n,...r,...o]}async function fi(t,e,a){let n=new URL(t.url||"/","http://_"),r=parseInt(n.searchParams.get("hours")||"6",10)||6;v(e,200,await He(await kn(r,a.config)))}async function kn(t,e){let a=e.node?.id||e.node?.name||"local",n=[],r=ct(t);r&&n.push({nodeId:a,snap:r});let o=(e.dashboard?.daemons||[]).filter(l=>l.url),s=await Promise.all(o.map(async l=>{let i=vt(l.url.replace(/\/+$/,""),e);if(!i)return null;try{let c=new AbortController,m=setTimeout(()=>c.abort(),8e3);try{let u=await fetch(`${i.url}/api/admin/activity-graph?hours=${t}`,{headers:{Accept:"application/json","X-Agentx-Peer":"primary",...i.token?{Authorization:`Bearer ${i.token}`}:{}},signal:c.signal});return u.ok?{nodeId:l.name||l.url,snap:await u.json()}:null}finally{clearTimeout(m)}}catch{return null}}));for(let l of s)l&&n.push(l);return qa(n)}async function xi(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 u=process.env.HOME||"",g=[u&&`${u}/.agentx/logs/daemon-stdout.log`,"/tmp/agentx-daemon.log"].filter(Boolean),b=g.find(_=>yn(_));if(!b){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:g}));return}r="tail",o=["-F","-n","200",b]}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}
|
|
14354
14375
|
|
|
14355
|
-
`);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),l="",i=
|
|
14356
|
-
`))>=0;){let b=l.slice(0,
|
|
14376
|
+
`);let s=a(r,o,{stdio:["ignore","pipe","pipe"]}),l="",i=u=>{l+=u.toString("utf8");let g;for(;(g=l.indexOf(`
|
|
14377
|
+
`))>=0;){let b=l.slice(0,g).replace(/\r$/,"");l=l.slice(g+1);try{e.write(`event: line
|
|
14357
14378
|
data: ${b.replace(/\n/g," ")}
|
|
14358
14379
|
|
|
14359
14380
|
`)}catch{}}};s.stdout?.on("data",i),s.stderr?.on("data",i);let c=setInterval(()=>{try{e.write(`: hb
|
|
14360
14381
|
|
|
14361
|
-
`)}catch{}},15e3),
|
|
14362
|
-
//# sourceMappingURL=board-dashboard-
|
|
14382
|
+
`)}catch{}},15e3),m=()=>{clearInterval(c);try{s.kill()}catch{}try{e.end()}catch{}};t.on("close",m),s.on("exit",m),s.on("error",m)}async function bn(t,e,a,n){let r=a.url+n,o=(t.method||"GET").toUpperCase(),l=o!=="GET"&&o!=="HEAD"?await new Promise((u,g)=>{let b=[];t.on("data",_=>b.push(_)),t.on("end",()=>u(Buffer.concat(b))),t.on("error",g)}):void 0,i={},c=t.headers["content-type"];c&&(i["Content-Type"]=Array.isArray(c)?c[0]:c);let m=t.headers["x-requested-with"];m&&(i["X-Requested-With"]=Array.isArray(m)?m[0]:m),a.token&&(i.Authorization=`Bearer ${a.token}`),i["X-Agentx-Peer"]="primary";try{let u=await fetch(r,{method:o,headers:i,body:l&&l.length>0?l:void 0}),g=Buffer.from(await u.arrayBuffer());e.writeHead(u.status,{"Content-Type":u.headers.get("content-type")||"application/json","Cache-Control":"no-store","Access-Control-Allow-Origin":"*"}),e.end(g)}catch(u){v(e,502,{error:`proxy to peer failed: ${u?.message||u}`,target:r})}}function vt(t,e){let a=t.replace(/\/+$/,""),n=(e.dashboard?.daemons||[]).find(r=>r.url.replace(/\/+$/,"")===a);return n?{url:wn(n),token:n.dashboardToken||n.token}:null}export{dc as startBoardDashboard};
|
|
14383
|
+
//# sourceMappingURL=board-dashboard-BU6QJK6X.js.map
|