agentix-cli 0.151.0 → 0.152.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-WAWZFD66.js → App-NCB3Y5DS.js} +2 -2
- package/dist/{ChatApp-TRJIS3O4.js → ChatApp-HOWN5H7Y.js} +2 -2
- package/dist/{absorb-eval-CFWLHUTB.js → absorb-eval-JXRNSZII.js} +2 -2
- package/dist/agent-DMXUUMEU.js +2 -0
- package/dist/{board-dashboard-5V6RHW3E.js → board-dashboard-POWARL34.js} +402 -241
- package/dist/board-dashboard-POWARL34.js.map +1 -0
- package/dist/{chunk-X6C6U4GL.js → chunk-24QMHUU2.js} +5 -5
- package/dist/{chunk-X6C6U4GL.js.map → chunk-24QMHUU2.js.map} +1 -1
- package/dist/{chunk-ALE354ZC.js → chunk-7UH3DXAG.js} +2 -2
- package/dist/chunk-ADG6NBZY.js +862 -0
- package/dist/chunk-ADG6NBZY.js.map +1 -0
- package/dist/{chunk-IMITYHBT.js → chunk-CZEBLLZQ.js} +2 -2
- package/dist/{chunk-XD7HTMOP.js → chunk-DZUJP6L7.js} +2 -2
- package/dist/{chunk-TZZBGWLX.js → chunk-E4V5EADX.js} +6 -6
- package/dist/{chunk-XVJXXELY.js → chunk-GI5CY27P.js} +2 -2
- package/dist/{chunk-LVS5ESTS.js → chunk-HS7ATV4Z.js} +2 -2
- package/dist/{chunk-RGJZV5RY.js → chunk-ILZRO6SN.js} +2 -2
- package/dist/{chunk-UG2OF2EI.js → chunk-IVBCCSDR.js} +2 -2
- package/dist/{chunk-V3VWYIJ3.js → chunk-JDX7AYIB.js} +2 -2
- package/dist/{chunk-PUSBK2OQ.js → chunk-JHAQE46R.js} +46 -46
- package/dist/chunk-JHAQE46R.js.map +1 -0
- package/dist/chunk-JJOLZPUY.js +35 -0
- package/dist/chunk-JJOLZPUY.js.map +1 -0
- package/dist/{chunk-2PJKGZWP.js → chunk-JNG3P5V2.js} +2 -2
- package/dist/chunk-JNG3P5V2.js.map +1 -0
- package/dist/{chunk-2GJQDJBF.js → chunk-LDLRDBAD.js} +2 -2
- package/dist/{chunk-DJQIJF4R.js → chunk-LOTCKF22.js} +2 -2
- package/dist/{chunk-O7SYQXKS.js → chunk-MTBY46CL.js} +8 -8
- package/dist/{chunk-FGJNSYHM.js → chunk-P25TJ4XN.js} +3 -3
- package/dist/{chunk-6LFOX6Q5.js → chunk-P4EZJIQ4.js} +257 -256
- package/dist/chunk-P4EZJIQ4.js.map +1 -0
- package/dist/{chunk-X3T2GCSI.js → chunk-PC24JMEH.js} +2 -2
- package/dist/{chunk-EJTKLVIW.js → chunk-PGLTBNGZ.js} +2 -2
- package/dist/{chunk-4GXJMHSA.js → chunk-QSNKF5VD.js} +2 -2
- package/dist/{chunk-DFGANY25.js → chunk-R4R7EYY3.js} +2 -2
- package/dist/{chunk-Q5NLNLD5.js → chunk-RNAKP7WY.js} +2 -2
- package/dist/{chunk-L6IW6HWE.js → chunk-SQUTRMKH.js} +23 -20
- package/dist/chunk-SQUTRMKH.js.map +1 -0
- package/dist/{chunk-C5UTFHPB.js → chunk-TNZBQAUR.js} +2 -2
- package/dist/{chunk-Y5MFVVTM.js → chunk-U23LVMMZ.js} +2 -2
- package/dist/{chunk-YGDJV4ZZ.js → chunk-UFYKUC4E.js} +2 -2
- package/dist/{chunk-CTQ25CUL.js → chunk-VIZVF6KH.js} +2 -2
- package/dist/{chunk-ETBDN5WX.js → chunk-XE3CGJV4.js} +2 -2
- package/dist/{chunk-UALK4F3W.js → chunk-YBUCVI45.js} +2 -2
- package/dist/{chunk-DWXCZRBJ.js → chunk-YJZQRFET.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/{client-VT7GT3SK.js → client-6IOWB5AT.js} +2 -2
- package/dist/{compaction-FS6XNRLM.js → compaction-PFXWL4H7.js} +3 -3
- package/dist/{config-NZS2UTHI.js → config-SHIT5WJE.js} +2 -2
- package/dist/{config-mutate-LINLC354.js → config-mutate-6ACI5COM.js} +2 -2
- package/dist/config-mutator-LAEX6HOH.js +2 -0
- package/dist/{context-planner-3JDA7FNR.js → context-planner-DJB6CKY6.js} +2 -2
- package/dist/{contributions-67B3BYLV.js → contributions-N7K6LNL7.js} +2 -2
- package/dist/{doctor-FOKX4K2G.js → doctor-T7QAQRCJ.js} +2 -2
- package/dist/{follow-up-tool-JOIOYOON.js → follow-up-tool-HQ2GWF4K.js} +2 -2
- package/dist/{grants-QXF7N6SS.js → grants-HSLB62EG.js} +2 -2
- package/dist/heal-RGM7X2ZG.js +2 -0
- package/dist/hub-53IMEYGX.js +2 -0
- package/dist/index.d.ts +125 -6
- package/dist/index.js +1 -1
- package/dist/memory-extract-GHLBXV4H.js +2 -0
- package/dist/{program-XFZBG3EI.js → program-LSXONKPW.js} +225 -219
- package/dist/program-LSXONKPW.js.map +1 -0
- package/dist/{promote-WNYNTGKC.js → promote-626PE5VM.js} +2 -2
- package/dist/{providers-55NC2SFN.js → providers-BDJXGHEY.js} +2 -2
- package/dist/{query-ZU2DDCEH.js → query-GR3SOD6A.js} +2 -2
- package/dist/{query-settings-BXRIJWWO.js → query-settings-6XZHNFXE.js} +2 -2
- package/dist/{registry-7BITIEQ2.js → registry-SAY7ROZV.js} +2 -2
- package/dist/{request-planner-DLQP2NV6.js → request-planner-DWYXUVF4.js} +2 -2
- package/dist/{review-candidates-3BMHLIBW.js → review-candidates-GXWMKZKA.js} +2 -2
- package/dist/routing-TB6BBRH4.js +2 -0
- package/dist/schedule-tool-EI2SRMZM.js +2 -0
- package/dist/{scheduler-SYI5MZ3H.js → scheduler-VOZIMG5F.js} +2 -2
- package/dist/{seat-6JF7BYM7.js → seat-H6F6H55Y.js} +2 -2
- package/dist/{select-JT4I3JOH.js → select-OUBL6EMZ.js} +2 -2
- package/dist/{set-enabled-JRGFKA3S.js → set-enabled-NYJHFXHY.js} +2 -2
- package/dist/tool-FWATXW5Q.js +6 -0
- package/dist/tool-FWATXW5Q.js.map +1 -0
- package/dist/{tool-P6GVYNDO.js → tool-HXFGNBLS.js} +2 -2
- package/dist/wiki-PG5ZBOMH.js +2 -0
- package/dist/wiki-enrich-BIQZWJRB.js +2 -0
- package/package.json +1 -1
- package/dist/agent-6KCTPI7E.js +0 -2
- package/dist/board-dashboard-5V6RHW3E.js.map +0 -1
- package/dist/chunk-2PJKGZWP.js.map +0 -1
- package/dist/chunk-5I7NJMK6.js +0 -35
- package/dist/chunk-5I7NJMK6.js.map +0 -1
- package/dist/chunk-6LFOX6Q5.js.map +0 -1
- package/dist/chunk-CBML7UCP.js +0 -861
- package/dist/chunk-CBML7UCP.js.map +0 -1
- package/dist/chunk-L6IW6HWE.js.map +0 -1
- package/dist/chunk-PUSBK2OQ.js.map +0 -1
- package/dist/config-mutator-FUMSW5HD.js +0 -2
- package/dist/heal-U67X6NIN.js +0 -2
- package/dist/hub-QETWDYPD.js +0 -2
- package/dist/memory-extract-ATD6YLRK.js +0 -2
- package/dist/program-XFZBG3EI.js.map +0 -1
- package/dist/routing-FVZCQJ6T.js +0 -2
- package/dist/schedule-tool-TDVJHRQX.js +0 -2
- package/dist/tool-UDOUNWQT.js +0 -6
- package/dist/tool-UDOUNWQT.js.map +0 -1
- package/dist/wiki-MTZHDFHK.js +0 -2
- package/dist/wiki-enrich-CHR4RCRE.js +0 -2
- /package/dist/{App-WAWZFD66.js.map → App-NCB3Y5DS.js.map} +0 -0
- /package/dist/{ChatApp-TRJIS3O4.js.map → ChatApp-HOWN5H7Y.js.map} +0 -0
- /package/dist/{absorb-eval-CFWLHUTB.js.map → absorb-eval-JXRNSZII.js.map} +0 -0
- /package/dist/{agent-6KCTPI7E.js.map → agent-DMXUUMEU.js.map} +0 -0
- /package/dist/{chunk-ALE354ZC.js.map → chunk-7UH3DXAG.js.map} +0 -0
- /package/dist/{chunk-IMITYHBT.js.map → chunk-CZEBLLZQ.js.map} +0 -0
- /package/dist/{chunk-XD7HTMOP.js.map → chunk-DZUJP6L7.js.map} +0 -0
- /package/dist/{chunk-TZZBGWLX.js.map → chunk-E4V5EADX.js.map} +0 -0
- /package/dist/{chunk-XVJXXELY.js.map → chunk-GI5CY27P.js.map} +0 -0
- /package/dist/{chunk-LVS5ESTS.js.map → chunk-HS7ATV4Z.js.map} +0 -0
- /package/dist/{chunk-RGJZV5RY.js.map → chunk-ILZRO6SN.js.map} +0 -0
- /package/dist/{chunk-UG2OF2EI.js.map → chunk-IVBCCSDR.js.map} +0 -0
- /package/dist/{chunk-V3VWYIJ3.js.map → chunk-JDX7AYIB.js.map} +0 -0
- /package/dist/{chunk-2GJQDJBF.js.map → chunk-LDLRDBAD.js.map} +0 -0
- /package/dist/{chunk-DJQIJF4R.js.map → chunk-LOTCKF22.js.map} +0 -0
- /package/dist/{chunk-O7SYQXKS.js.map → chunk-MTBY46CL.js.map} +0 -0
- /package/dist/{chunk-FGJNSYHM.js.map → chunk-P25TJ4XN.js.map} +0 -0
- /package/dist/{chunk-X3T2GCSI.js.map → chunk-PC24JMEH.js.map} +0 -0
- /package/dist/{chunk-EJTKLVIW.js.map → chunk-PGLTBNGZ.js.map} +0 -0
- /package/dist/{chunk-4GXJMHSA.js.map → chunk-QSNKF5VD.js.map} +0 -0
- /package/dist/{chunk-DFGANY25.js.map → chunk-R4R7EYY3.js.map} +0 -0
- /package/dist/{chunk-Q5NLNLD5.js.map → chunk-RNAKP7WY.js.map} +0 -0
- /package/dist/{chunk-C5UTFHPB.js.map → chunk-TNZBQAUR.js.map} +0 -0
- /package/dist/{chunk-Y5MFVVTM.js.map → chunk-U23LVMMZ.js.map} +0 -0
- /package/dist/{chunk-YGDJV4ZZ.js.map → chunk-UFYKUC4E.js.map} +0 -0
- /package/dist/{chunk-CTQ25CUL.js.map → chunk-VIZVF6KH.js.map} +0 -0
- /package/dist/{chunk-ETBDN5WX.js.map → chunk-XE3CGJV4.js.map} +0 -0
- /package/dist/{chunk-UALK4F3W.js.map → chunk-YBUCVI45.js.map} +0 -0
- /package/dist/{chunk-DWXCZRBJ.js.map → chunk-YJZQRFET.js.map} +0 -0
- /package/dist/{client-VT7GT3SK.js.map → client-6IOWB5AT.js.map} +0 -0
- /package/dist/{compaction-FS6XNRLM.js.map → compaction-PFXWL4H7.js.map} +0 -0
- /package/dist/{config-NZS2UTHI.js.map → config-SHIT5WJE.js.map} +0 -0
- /package/dist/{config-mutate-LINLC354.js.map → config-mutate-6ACI5COM.js.map} +0 -0
- /package/dist/{config-mutator-FUMSW5HD.js.map → config-mutator-LAEX6HOH.js.map} +0 -0
- /package/dist/{context-planner-3JDA7FNR.js.map → context-planner-DJB6CKY6.js.map} +0 -0
- /package/dist/{contributions-67B3BYLV.js.map → contributions-N7K6LNL7.js.map} +0 -0
- /package/dist/{doctor-FOKX4K2G.js.map → doctor-T7QAQRCJ.js.map} +0 -0
- /package/dist/{follow-up-tool-JOIOYOON.js.map → follow-up-tool-HQ2GWF4K.js.map} +0 -0
- /package/dist/{grants-QXF7N6SS.js.map → grants-HSLB62EG.js.map} +0 -0
- /package/dist/{heal-U67X6NIN.js.map → heal-RGM7X2ZG.js.map} +0 -0
- /package/dist/{hub-QETWDYPD.js.map → hub-53IMEYGX.js.map} +0 -0
- /package/dist/{memory-extract-ATD6YLRK.js.map → memory-extract-GHLBXV4H.js.map} +0 -0
- /package/dist/{promote-WNYNTGKC.js.map → promote-626PE5VM.js.map} +0 -0
- /package/dist/{providers-55NC2SFN.js.map → providers-BDJXGHEY.js.map} +0 -0
- /package/dist/{query-ZU2DDCEH.js.map → query-GR3SOD6A.js.map} +0 -0
- /package/dist/{query-settings-BXRIJWWO.js.map → query-settings-6XZHNFXE.js.map} +0 -0
- /package/dist/{registry-7BITIEQ2.js.map → registry-SAY7ROZV.js.map} +0 -0
- /package/dist/{request-planner-DLQP2NV6.js.map → request-planner-DWYXUVF4.js.map} +0 -0
- /package/dist/{review-candidates-3BMHLIBW.js.map → review-candidates-GXWMKZKA.js.map} +0 -0
- /package/dist/{routing-FVZCQJ6T.js.map → routing-TB6BBRH4.js.map} +0 -0
- /package/dist/{schedule-tool-TDVJHRQX.js.map → schedule-tool-EI2SRMZM.js.map} +0 -0
- /package/dist/{scheduler-SYI5MZ3H.js.map → scheduler-VOZIMG5F.js.map} +0 -0
- /package/dist/{seat-6JF7BYM7.js.map → seat-H6F6H55Y.js.map} +0 -0
- /package/dist/{select-JT4I3JOH.js.map → select-OUBL6EMZ.js.map} +0 -0
- /package/dist/{set-enabled-JRGFKA3S.js.map → set-enabled-NYJHFXHY.js.map} +0 -0
- /package/dist/{tool-P6GVYNDO.js.map → tool-HXFGNBLS.js.map} +0 -0
- /package/dist/{wiki-MTZHDFHK.js.map → wiki-PG5ZBOMH.js.map} +0 -0
- /package/dist/{wiki-enrich-CHR4RCRE.js.map → wiki-enrich-BIQZWJRB.js.map} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as
|
|
2
|
-
`).filter(Boolean);if(!n.length)return null;let i=JSON.parse(n[0]),r=i.run?.workflowId;if(!r)return null;let s=i.run?.status??"unknown";for(let a=n.length-1;a>=0;a--){let o=JSON.parse(n[a]),l=o.status??o.run?.status;if(l){s=l;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var
|
|
3
|
-
`),
|
|
4
|
-
`).pop()?.slice(0,300)||"no output";async function hn(t,e,n,i=
|
|
5
|
-
`,{mode:384}),bn(i,n)}function
|
|
1
|
+
import{a as Re}from"./chunk-GTJIKXDB.js";import{A as Zt,H as rn,j as B}from"./chunk-JJOLZPUY.js";import{a as w}from"./chunk-7LN4VKDU.js";import{f as en,i as tn,k as Ae,l as _e,n as q,o as M,q as nn}from"./chunk-24QMHUU2.js";import{t as Jt,u as Yt}from"./chunk-HS7ATV4Z.js";import{d as Gt,e as Kt}from"./chunk-AQASR6KR.js";import{b as Qt}from"./chunk-YMX3QCV7.js";import{a as qt,b as Ht,d as zt,e as Xt}from"./chunk-MNG2AMKZ.js";import{g as Ft,h as Wt,i as Vt,k as Ut,l as Bt}from"./chunk-VIZVF6KH.js";import{a as Mt,c as jt}from"./chunk-KP7KDLZ2.js";import{X as Ot,Z as ne,_ as ve,aa as $e,b as xe}from"./chunk-UFYKUC4E.js";import{q as Lt}from"./chunk-GI5CY27P.js";import{a as Pt,b as Nt}from"./chunk-XE3CGJV4.js";import{Ca as Se,Ka as Tt,La as Ct,Q as _t,R as Rt,S as It,T as Et,Ua as Dt,n as te,o as $t,p as At,q as ni}from"./chunk-SQUTRMKH.js";import{a as we,h as ri}from"./chunk-BRK6M6LA.js";import{f as ke,n as ii}from"./chunk-UIBUZ2N3.js";import{existsSync as si,readdirSync as oi,readFileSync as ai,statSync as li}from"fs";import{resolve as ci}from"path";function sn(t,e,n=Date.now(),i=7){let r=i*864e5,s=new Map;for(let a of e){let o=s.get(a.workflowId);o?o.push(a):s.set(a.workflowId,[a])}return t.map(a=>{let o=s.get(a.id)??[],l=o.filter(g=>n-g.at<=r),c=o.filter(g=>n-g.at>r&&n-g.at<=r*2),u=l.filter(g=>g.status==="failed").length,d=o.filter(g=>g.status==="paused").length,p=o.length?Math.max(...o.map(g=>g.at)):null,f=o.length?c.length>0&&l.length===0?"dormant":l.length>0&&u*2>=l.length?"failing":l.length>0?"active":"quiet":"never";return{id:a.id,name:a.name||a.id,state:f,lastRunAt:p,recent:l.length,prior:c.length,failed:u,paused:d}}).sort((a,o)=>{let l={dormant:0,failing:1,active:2,quiet:3,never:4};return l[a.state]-l[o.state]||(o.lastRunAt??0)-(a.lastRunAt??0)})}var re=new Map;function Wa(t,e=1e3){if(!si(t))return[];let n=oi(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let a=ci(t,s);return{path:a,mtime:li(a).mtimeMs}}).sort((s,a)=>a.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of re.keys())i.has(s)||re.delete(s);let r=[];for(let{path:s,mtime:a}of n){let o=re.get(s);if(o&&o.mtime===a){o.summary&&r.push(o.summary);continue}let l=ui(s,a);re.set(s,{mtime:a,summary:l}),l&&r.push(l)}return r}function ui(t,e){try{let n=ai(t,"utf-8").split(`
|
|
2
|
+
`).filter(Boolean);if(!n.length)return null;let i=JSON.parse(n[0]),r=i.run?.workflowId;if(!r)return null;let s=i.run?.status??"unknown";for(let a=n.length-1;a>=0;a--){let o=JSON.parse(n[a]),l=o.status??o.run?.status;if(l){s=l;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var di={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},pi=(t,e,n)=>{try{return Lt(t,e,n)}catch{return null}},on=864e5;function qa(t){let e=t.now??Date.now(),n={...di,...t.thresholds},i=t.nextFire??pi,r=[];for(let o of t.crons){let l=t.cronRuns.get(o.id)??[],c=o.timezone||"UTC",u=l.map(f=>({at:Date.parse(f.startedAt),status:f.status})),d=l[0],p={id:`cron:${o.id}`,source:"cron",kind:"schedule",name:A(o.id,k.text),trigger:{schedule:A(o.schedule,k.text),timezone:c},agent:o.agent||null,enabled:o.enabled,state:o.enabled?"enabled":"disabled",nextRunAt:o.enabled?Ie(o.nextRun)??Ie(i(o.schedule,new Date(e),c)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:bi(d.status==="success"?void 0:d.errorSummary,k.summary)}:null,lastSuccessAt:l.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:an(u),sampledRuns:l.length,flags:[],attention:null};p.flags=ln(p,u,o.schedule,c,null,e,n,i),r.push(cn(p))}let s=new Map(sn(t.workflows.map(o=>({id:o.id,name:o.title})),t.workflowRuns,e).map(o=>[o.id,o])),a=new Map;for(let o of t.workflowRuns){let l=a.get(o.workflowId);l?l.push(o):a.set(o.workflowId,[o])}for(let o of t.workflows){let l=o.nodes.find(I=>I.type.startsWith("trigger."));if(!l||l.type!=="trigger.cron"&&l.type!=="trigger.hook")continue;let c=l.config??{},u=o.state||"active",d=u==="active",p=(a.get(o.id)??[]).slice().sort((I,be)=>be.at-I.at),f=p.map(I=>({at:I.at,status:mi(I.status)})),g=f[0],h=l.type==="trigger.cron",y=typeof c.spec=="string"?c.spec:"",C=typeof c.timezone=="string"?c.timezone:"UTC",O={id:`workflow:${o.id}`,source:"workflow",kind:h?"schedule":"event",name:A(o.title||o.id,k.text),trigger:h?{schedule:A(y,k.text),timezone:C}:{event:A(typeof c.event=="string"?c.event:"",k.text),filters:yi(c.filter,o)},agent:hi(o),enabled:d,state:u,nextRunAt:h&&d&&y?Ie(i(y,new Date(e),C)):null,lastRun:g?{at:new Date(g.at).toISOString(),status:g.status}:null,lastSuccessAt:(()=>{let I=f.find(be=>be.status==="success");return I?new Date(I.at).toISOString():null})(),consecutiveFailures:an(f),sampledRuns:p.length,flags:[],attention:null},ee=Date.parse(o.updated||o.created||"");O.flags=h?ln(O,f,y,C,Number.isFinite(ee)?ee:null,e,n,i):fi(O,s.get(o.id)?.state==="dormant",Number.isFinite(ee)?ee:null,e,n),r.push(cn(O))}return r.sort(gi).slice(0,k.routines)}function an(t){let e=0;for(let n of t)if(!(n.status==="running"||n.status==="paused"||n.status==="unknown"))if(n.status==="failed"||n.status==="timeout")e++;else break;return e}function ln(t,e,n,i,r,s,a,o){let l=[],c=e.length?e[0].at:null;if(!t.enabled){let p=dn(c,r,s,a);return p&&l.push(p),l}if(t.consecutiveFailures>=a.failStreak&&l.push({reason:"failing",detail:`${t.consecutiveFailures} failed attempts in a row`}),c===null)return l.push({reason:"never-ran",detail:"No persisted attempt"}),l;let u=new Date(c),d=null;for(let p=0;p<a.missedFires&&(d=o(n,u,i),!!d);p++)u=d;return d&&s>d.getTime()+a.graceMs&&l.push({reason:"overdue",detail:`No attempt since ${new Date(c).toISOString()}; ${a.missedFires} scheduled fires missed`}),l}function fi(t,e,n,i,r){let s=[],a=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let o=dn(a,n,i,r);return o&&s.push(o),s}return t.consecutiveFailures>=r.failStreak&&s.push({reason:"failing",detail:`${t.consecutiveFailures} failed runs in a row`}),a===null?s.push({reason:"never-ran",detail:"No run recorded for this trigger"}):e&&s.push({reason:"dormant",detail:"Fired in the prior week, silent in the last one"}),s}function dn(t,e,n,i){let r=Math.max(t??0,e??0);return r&&n-r<i.disabledDays*on?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/on)} days`:"Disabled and never ran"}}function cn(t){let e=new Set(t.flags.map(n=>n.reason));return t.attention=e.has("failing")?"critical":e.has("overdue")||e.has("dormant")||e.has("never-ran")?"warning":e.has("disabled-long")?"info":null,t}var un={critical:0,warning:1,info:2};function gi(t,e){let n=t.attention?un[t.attention]:3,i=e.attention?un[e.attention]:3;return n-i||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function mi(t){switch(t){case"completed":case"ok":return"success";case"failed":return"failed";case"timeout":return"timeout";case"canceled":return"canceled";case"running":return"running";case"paused":return"paused";default:return"unknown"}}function hi(t){if(t.ownerAgent)return A(t.ownerAgent,k.text);let e=t.nodes.find(n=>n.type==="agent"&&typeof n.config?.agentId=="string"&&n.config.agentId);return e?A(String(e.config.agentId),k.text):null}function yi(t,e){let n=[],i=e?.project;if(i&&n.push(A(`project=${i}`,k.filterValue)),t&&typeof t=="object"&&!Array.isArray(t))for(let[r,s]of Object.entries(t)){let a=Array.isArray(s)?s.map(String):s==null?[]:[String(s)];a.length&&n.push(A(`${r}=${a.join(",")}`,k.filterValue))}return n.slice(0,k.filters)}function Ie(t){if(!t)return null;let e=t instanceof Date?t:new Date(t);return Number.isFinite(e.getTime())?e.toISOString():null}function A(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function bi(t,e){return t===void 0?void 0:A(t,e)}import{mkdirSync as wi,readFileSync as ki,renameSync as Si,writeFileSync as xi}from"fs";import{resolve as vi}from"path";function pn(t){return vi(_e(t),"_state.json")}function x(t){try{let e=JSON.parse(ki(pn(t),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{},...e?.popped&&typeof e.popped=="object"?{popped:e.popped}:{},...typeof e?.passAt=="string"?{passAt:e.passAt}:{},...Array.isArray(e?.wanted)?{wanted:e.wanted.filter(n=>typeof n=="string")}:{}}}catch{return{snoozed:{}}}}function H(t,e){wi(_e(t),{recursive:!0});let n=pn(t),i=`${n}.${process.pid}.tmp`;xi(i,JSON.stringify(e,null,2)+`
|
|
3
|
+
`),Si(i,n)}function fn(t,e,n,i=Date.now()){let r=x(t),s={};for(let[a,o]of Object.entries(r.snoozed))Date.parse(o)>i&&(s[a]=o);s[e]=n.toISOString(),H(t,{...r,snoozed:s})}function Ka(t,e){H(t,{...x(t),lastDigest:e})}function Ee(t,e,n,i=Date.now()){let r=x(t),s=new Set(n),a={};for(let[l,c]of Object.entries(r.popped??{}))s.has(l)&&(a[l]=c);a[e]=new Date(i).toISOString();let o=(r.wanted??[]).filter(l=>l!==e&&s.has(l));H(t,{...r,popped:a,wanted:o})}function gn(t,e){let n=x(t);H(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function Ja(t,e=Date.now()){H(t,{...x(t),popped:{},passAt:new Date(e).toISOString()})}import{existsSync as z,readdirSync as Fi,readFileSync as Wi}from"fs";import{resolve as _}from"path";import{randomBytes as yn}from"crypto";import{existsSync as Ai,mkdirSync as _i,readdirSync as Ri,readFileSync as Ii,renameSync as bn,unlinkSync as Ei,writeFileSync as Ti}from"fs";import{resolve as wn}from"path";function mn(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var $i=t=>t.trim().split(`
|
|
4
|
+
`).pop()?.slice(0,300)||"no output";async function hn(t,e,n,i=Re){let r=await i(t.bin,[...mn(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${$i(r.stderr||r.stdout)}`}}async function Qa(t,e,n,i,r=Re){return(await r(t.bin,[...mn(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var Ci=2e3,Di=t=>hn(t.wacli,t.to,t.text);function Te(t){return wn(t,".agentx","whatsapp-triage","drafts")}var Pi=t=>/^[a-z0-9-]{8,64}$/.test(t),ie=(t,e)=>wn(Te(t),`${e}.json`);function kn(t,e){_i(Te(t),{recursive:!0});let n=ie(t,e.id),i=`${n}.${process.pid}.tmp`;Ti(i,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{mode:384}),bn(i,n)}function sl(t,e,n=Date.now()){let i=e.text.trim().slice(0,Ci);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${yn(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return kn(t,r),r}function se(t,e){if(!Pi(e))return null;try{return JSON.parse(Ii(ie(t,e),"utf-8"))}catch{return null}}function Sn(t,e){let n=Te(t);return Ai(n)?Ri(n).filter(i=>i.endsWith(".json")).map(i=>se(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function xn(t,e,n,i={}){let r=se(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${ie(t,e)}.${process.pid}.${yn(3).toString("hex")}.claim`;try{bn(ie(t,e),s)}catch{return{ok:!1,error:`reply draft "${e}" is already being decided`}}let a={...r,decided_by:i.by??"operator",decided_at:new Date(i.now??Date.now()).toISOString()};if(n==="no")a.status="rejected";else{let o=await(i.send??Di)(r).catch(l=>({ok:!1,error:String(l?.message??l)}));o.ok?a.status="sent":(a.status="failed",a.error=o.error)}kn(t,a);try{Ei(s)}catch{}return a.status==="failed"?{ok:!1,error:a.error??"send failed"}:{ok:!0,draft:a}}ii();Et();Et();var ll=["done","skipped"],Ni=1e3;function Li(t){t.exec(`
|
|
6
6
|
CREATE TABLE IF NOT EXISTS request_plans (
|
|
7
7
|
request_id TEXT PRIMARY KEY,
|
|
8
8
|
created_by TEXT NOT NULL,
|
|
@@ -50,9 +50,9 @@ import{a as Ae}from"./chunk-GTJIKXDB.js";import{A as Yt,H as rn,j as Lt}from"./c
|
|
|
50
50
|
FOREIGN KEY (request_id) REFERENCES request_plans(request_id) ON DELETE CASCADE
|
|
51
51
|
);
|
|
52
52
|
CREATE INDEX IF NOT EXISTS idx_request_plan_events ON request_plan_events(request_id, at);
|
|
53
|
-
`)}function $n(t){return!!t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'request_plans'").get()}function
|
|
53
|
+
`)}function $n(t){return!!t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'request_plans'").get()}function Ce(t){return{requestId:t.request_id,createdBy:t.created_by,createdAt:t.created_at,state:t.state,finishedAt:t.finished_at??null,notifiedAt:t.notified_at??null}}function vn(t){return{requestId:t.request_id,idx:t.idx,name:t.name,kind:t.kind,agentId:t.agent_id,doneWhen:t.done_when,state:t.state,needsApproval:!!t.needs_approval,approval:t.approval,cardId:t.card_id??null,message:t.message??null,toChannel:t.to_channel??null,toChat:t.to_chat??null,toAccount:t.to_account??null,checkUrl:t.check_url??null,checkContains:t.check_contains??null,stallMinutes:t.stall_minutes??null,evidence:t.evidence??null,note:t.note??null,dispatchedAt:t.dispatched_at??null,updatedAt:t.updated_at,nudges:t.nudges,lastNudgeAt:t.last_nudge_at??null,notifiedAt:t.notified_at??null}}var Oi={state:"state",approval:"approval",cardId:"card_id",message:"message",evidence:"evidence",note:"note",dispatchedAt:"dispatched_at",updatedAt:"updated_at",nudges:"nudges",lastNudgeAt:"last_nudge_at",notifiedAt:"notified_at"},oe=class{constructor(e){this.db=e;Li(e)}create(e,n,i,r){let s=this.db.prepare("INSERT INTO request_plans (request_id, created_by, created_at, state) VALUES (?, ?, ?, 'active')"),a=this.db.prepare(`INSERT INTO request_plan_steps (request_id, idx, name, kind, agent_id, done_when, state, needs_approval, message,
|
|
54
54
|
to_channel, to_chat, to_account, check_url, check_contains, stall_minutes, dispatched_at, updated_at)
|
|
55
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);this.db.transaction(()=>{s.run(e,n,r),i.forEach((o,l)=>{let c=l===0,u=c&&o.agentId===n&&o.kind!=="message";a.run(e,l+1,o.name,o.kind,o.agentId,o.doneWhen,c?"active":"pending",o.needsApproval?1:0,o.message??null,o.toChannel??null,o.toChat??null,o.toAccount??null,o.checkUrl??null,o.checkContains??null,o.stallMinutes??null,u?r:null,r)}),this.event(e,null,"created",`${i.length} steps, written by ${n}`,r)})()}get(e){let n=this.db.prepare("SELECT * FROM request_plans WHERE request_id = ?").get(e);return n?Ee(n):null}steps(e){return this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? ORDER BY idx").all(e).map(vn)}step(e,n){let i=this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? AND idx = ?").get(e,n);return i?vn(i):null}listActive(){return this.db.prepare("SELECT * FROM request_plans WHERE state = 'active' ORDER BY created_at, rowid").all().map(Ee)}updateStep(e,n,i){let r=[],s=[];for(let[a,o]of Object.entries(i)){let l=Li[a];!l||o===void 0||(r.push(`${l} = ?`),s.push(typeof o=="boolean"?o?1:0:o))}r.length&&this.db.prepare(`UPDATE request_plan_steps SET ${r.join(", ")} WHERE request_id = ? AND idx = ?`).run(...s,e,n)}finish(e,n,i){return this.db.prepare("UPDATE request_plans SET state = ?, finished_at = ? WHERE request_id = ? AND state = 'active'").run(n,i,e).changes>0}markNotified(e,n){this.db.prepare("UPDATE request_plans SET notified_at = ? WHERE request_id = ?").run(n,e)}awaitingSummary(){return this.db.prepare("SELECT * FROM request_plans WHERE state = 'done' AND notified_at IS NULL ORDER BY finished_at").all().map(Ee)}event(e,n,i,r,s){this.db.prepare("INSERT INTO request_plan_events (request_id, step, at, kind, detail) VALUES (?, ?, ?, ?, ?)").run(e,n,s,i,r.replace(/\s+/g," ").trim().slice(0,Pi))}events(e,n=200){return this.db.prepare("SELECT request_id, step, at, kind, detail FROM request_plan_events WHERE request_id = ? ORDER BY at, rowid LIMIT ?").all(e,n).map(i=>({requestId:i.request_id,step:i.step??null,at:i.at,kind:i.kind,detail:i.detail}))}},ll=$t;import{existsSync as Oi,readFileSync as Mi}from"fs";Tt();ni();function An(t){let e=Ct(t),n={};if(Oi(e))try{n=It(JSON.parse(Mi(e,"utf-8")))}catch{n={}}let i=ke.safeParse(n?.requests);return i.success?i.data:ke.parse(void 0)}async function gl(t,e={}){let n=(t.channels??[]).filter(i=>!be.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...be].join(", ")}`}:Dt(i=>{let r=i.requests??={};for(let s of["enabled","channels","from","staleAfterHours","retentionDays"])t[s]!==void 0&&(r[s]=t[s]);if(t.plans){let s=r.plans??={};for(let a of["enabled","stallMinutes","maxNudges","approveKinds","disabledAgents","requireForWork","requireOverMinutes"])t.plans[a]!==void 0&&(s[a]=t.plans[a])}if(t.checkers){let s=r.checkers??={};for(let a of["enabled","checkEveryMinutes"])t.checkers[a]!==void 0&&(s[a]=t.checkers[a])}},{configPath:e.configPath,reload:e.reload})}var In=["card","schedule","memory","wiki","whatsapp","request"],Wi=280;function N(t,e=Wi){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Te(t){if(t.configPath)return _(t.configPath);let e=[_(t.root,"agentx.json"),_(t.root,".agentx","config.json")];return e.find(n=>H(n))??e[0]}function Ce(t){return t.wikiDir?_(t.wikiDir):_(t.root,".agentx","wiki")}function Vi(t){return j(t.root,"pending").map(Ui)}function Ui(t){return{key:`card:${t.id}`,kind:"card",title:t.title,ask:t.ask,yes:`tell ${t.raised_by} yes`,no:`tell ${t.raised_by} no`,recommend:t.recommend,if_silent:t.if_silent,expires:t.expires,...t.source?{source:t.source}:{},raised_by:t.raised_by,...t.node?{node:t.node}:{},created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.draft?{draft:t.draft}:{},...t.context||t.draft?{detail:N([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Bi(t){let e=Te(t);if(!H(e))return[];let n;try{n=JSON.parse(Fi(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,a]of Object.entries(n?.crons??{})){let o=a?.approval;if(!o||o.action!=="create"&&o.action!=="delete")continue;let l=a.timezone||"UTC",c=a.schedule?jt(a.schedule):"",u=a.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${a.schedule})`:"no schedule",d=String(a.prompt??a.command??""),p=o.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${a.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${a.agent??"the agent"} run this ${u}?`:`Remove the schedule "${s}" (${u})?`,yes:p?"enable it":"remove it",no:p?"drop the request":"keep the schedule",raised_by:String(o.requestedBy??"unknown"),created_at:String(o.requestedAt??""),detail:N(`${d}${p&&a.schedule?` \xB7 first run ${Wt(Ft(a.schedule,l,i),l)}`:""}`),more:"agentx schedule list"})}return r}function En(t){let e=_(t,".agentx","memory");return H(e)?ji(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function qi(t){let e=En(t.root);if(e.length===0)return[];let n=new Se(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:N(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Hi(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function zi(t){return Gt(Ce(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:N(`${Hi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Xi(t){return Sn(t.root,"pending").map(e=>({key:`whatsapp:${e.id}`,kind:"whatsapp",title:`WhatsApp reply to ${e.chat_name||e.to}`,ask:`Send this to ${e.chat_name||e.to}? "${e.text}"`,yes:"send it on WhatsApp",no:"drop the draft",raised_by:e.agent,created_at:e.created_at,detail:N(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function z(t){if(t.requests)return t.requests;if(_(t.root)!==process.cwd()||!H(_(t.root,".agentx","db.sqlite")))return null;let e=we({quiet:!0});if(!e)return null;let n=_n.get(e);return!n&&!At(e)?null:(n||_n.set(e,n=new _t(e)),n)}var _n=new WeakMap;function El(t){if(t.plans)return t.plans;if(t.requests||_(t.root)!==process.cwd()||!H(_(t.root,".agentx","db.sqlite")))return null;let e=we({quiet:!0});if(!e||!$n(e))return null;let n=Rn.get(e);return n||Rn.set(e,n=new se(e)),n}var Rn=new WeakMap;function Gi(t){let e=z(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${N(n.text,80)}`,ask:`Ask ${n.agentId} to pick it up again?`,yes:`hand it back to ${n.agentId}`,no:"drop the request",raised_by:n.agentId,created_at:new Date(n.createdAt).toISOString(),detail:N(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var Tn={card:Vi,schedule:Bi,memory:qi,wiki:zi,whatsapp:Xi,request:Gi};function Ki(t,e){let n=t.expires?Date.parse(t.expires):1/0,i=e.expires?Date.parse(e.expires):1/0;return n!==i?n-i:(Date.parse(t.created_at)||0)-(Date.parse(e.created_at)||0)}function Tl(t,e={}){let n=t.now??Date.now(),{snoozed:i}=x(t.root),r=[],s=[],a=0;for(let o of e.kinds??In){let l;try{l=Tn[o](t)}catch(c){s.push({kind:o,error:String(c?.message??c).slice(0,200)});continue}for(let c of l){let u=i[c.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){a++;continue}c.snoozed_until=u}r.push(c)}}return r.sort(Ki),{items:r,snoozed:a,errors:s}}function Ji(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!In.includes(n)||!i?null:{kind:n,ref:i}}function Yi(t,e,n){switch(e){case"card":return B(t.root,n)?.status==="pending";case"wiki":return Xt(Ce(t),n)?.status==="pending";case"whatsapp":return ie(t.root,n)?.status==="pending";default:return Tn[e](t).some(i=>i.key===`${e}:${n}`)}}async function Cn(t,e,n,i={}){let r=Ji(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:a}=r,o=t.now??Date.now(),l=i.by??"operator";if(n==="later"){if(!Yi(t,s,a))return{ok:!1,error:`nothing waiting for "${e}"`};let u=i.laterHours&&i.laterHours>0?i.laterHours:24,d=new Date(o+u*36e5);return fn(t.root,e,d,o),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let c=n==="yes";switch(s){case"card":{let u=nn(t.root,a,c?"yes":"no",{by:l,note:i.note,now:o,choice:i.choice,text:i.text});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${c?"yes":"no"}${u.card.choice?` (${u.card.choice}${u.card.choice_suggested?", the suggested option":""})`:""}`}:u}case"schedule":{let u=await(c?Vt:Ut)(a,{configPath:Te(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=a.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=a.slice(0,u),p=a.slice(u+1);if(!En(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new Se(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,c?"approved":"rejected",l),{ok:!0,message:`${e} ${c?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${p}" isn't waiting for review`}}case"wiki":{let u=Ce(t),d=c?Kt(u,a,{by:l,force:i.force,now:o}):Jt(u,a,{by:l,reason:i.note,now:o});return d.ok?{ok:!0,message:c?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await xn(t.root,a,c?"yes":"no",{by:l,now:o,send:t.sendWhatsApp});return u.ok?{ok:!0,message:c?`${e}: sent to ${u.draft.chat_name||u.draft.to}`:`${e}: dropped, nothing sent`}:u}case"request":{let u=z(t),d=u?.get(a);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:c?An(Te(t)).enabled?(u.requestPickup(a,o),{ok:!0,message:`${e}: ${d.agentId} will be asked to pick it up again`}):{ok:!1,error:"Requests are off, so nothing would hand it back. Turn them on (agentx requests settings --enabled on), or answer no to drop it."}:(u.close(a,"dropped",i.note?.trim()||`dropped by ${l}`,o),{ok:!0,message:`${e}: dropped`})}}}var Dn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Dl(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/screen"||t==="/native/notes"||t==="/requests"||t.startsWith("/requests/")||t==="/watchers"||t.startsWith("/watchers/")||t==="/follow-up"||t.startsWith("/follow-up/")||t==="/events/recent"||/^\/agents\/[^/]+\/events$/.test(t)||t==="/a2a/delegations"||t.startsWith("/a2a/delegations/")||t==="/traces"||t.startsWith("/traces/")||t==="/voice/history"||t.startsWith("/voice/history/")||t==="/voice/transcribe"||t==="/voice/speak"||t==="/app-files"||t==="/calls"||t.startsWith("/calls/")||t==="/webrtc/camera"||t.startsWith("/webrtc/camera/")||t==="/mesh/guests"||t.startsWith("/mesh/guests/")||t==="/wiki/agents"||t==="/wiki/entries"||t==="/wiki/articles"||t==="/wiki/article"||t==="/wiki/notes"||t==="/api/wiki/curate"||t==="/api/wiki/curate/restore"||t==="/api/signals/stopped"||t.startsWith("/api/signals/stopped/")||t==="/api/review-gate/reviews"}function Pl(t){return t==="/reload"||t==="/api/processes/kill"||t==="/send"||t==="/send/agent"||t==="/send/contact"||t==="/mesh/announce"||t==="/voice/settings"||t==="/voice/preview"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(t)||/^\/mesh\/guests\/[^/]+\/(pause|resume|end|update)$/.test(t)||/^\/crons\/[^/]+\/enabled$/.test(t)||/^\/workflow-runs\/[^/]+\/cancel$/.test(t)||t==="/api/signals/stop"||t==="/api/signals/resume"||t==="/api/signals/drop"||t==="/api/review-gate/replay"}function Nl(t){return Dn.has(t)}function Ll(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Dn.has(t.remoteAddress))return{allowed:!0,reason:"loopback"};if(t.acceptedTokens.size===0)return{allowed:!0,reason:"no-tokens-configured"};let e=t.authorizationHeader||"",n=e.startsWith("Bearer ")?e.slice(7).trim():"";return n&&t.acceptedTokens.has(n)?{allowed:!0,reason:"token"}:{allowed:!1,reason:"missing-or-invalid-token"}}function Ol(t,e=process.env){let n=new Set;e.MESH_TOKEN&&n.add(e.MESH_TOKEN);for(let i of t.mesh?.peers||[])i.token&&n.add(i.token);return n}function Ml(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function oe(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Zi(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function Qi(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Fl(t,e=Qi()){let n=oe(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Zi(n),s=[oe(t.host),oe(t["x-forwarded-host"])].filter(Boolean).map(a=>a.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=oe(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Wl(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as rr,mkdirSync as Is,readFileSync as Es,renameSync as Ts,writeFileSync as Cs}from"fs";import{homedir as Ds}from"os";import{dirname as Ps,join as Ns}from"path";import{execFile as us,execFileSync as ds}from"child_process";import{execFileSync as es}from"child_process";import{existsSync as Nn,mkdirSync as ts,readdirSync as ns,readFileSync as Ln,renameSync as rs,writeFileSync as is}from"fs";import{homedir as On}from"os";import{join as Pe}from"path";var v="siri:",Mn="com.apple.ttsbundle.gryphon-neural_",jn=t=>!!t&&t.startsWith(Mn),ss=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],os=()=>{try{return es("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},De;function Ne(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&De!==void 0)return De;let{platform:n=process.platform,exists:i=Nn,prefDomain:r=os}=t,s=n==="darwin"&&ss.every(a=>i(a))&&r();return e||(De=s),s}var Fn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],Wn={aaron:"male",damon:"male",daniel:"male",pierre:"male",samer:"male",arthur:"male",gordon:"male",martin:"male",nora:"female",simone:"female",marie:"female",soha:"female",martha:"female",catherine:"female",helena:"female",nicky:"female"},Le=t=>Wn[t.toLowerCase()]??null;function ae(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var as=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function ls(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(as)){let a=`${i}-${r}`,o=`${Mn}${s}_${a}_premium`;e.has(o)||e.set(o,{id:o,name:s[0].toUpperCase()+s.slice(1),locale:a,quality:"premium",gender:Wn[s]??null,siri:!0})}return[...e.values()]}function le(t=Fn,e={}){if(!Ne(e))return[];let n=[];for(let i of t){let r;try{r=ns(i)}catch{continue}for(let s of r)try{n.push(Ln(Pe(i,s,"Info.plist"),"latin1"))}catch{}}return ls(n)}var Pn=`#!/bin/sh
|
|
55
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);this.db.transaction(()=>{s.run(e,n,r),i.forEach((o,l)=>{let c=l===0,u=c&&o.agentId===n&&o.kind!=="message";a.run(e,l+1,o.name,o.kind,o.agentId,o.doneWhen,c?"active":"pending",o.needsApproval?1:0,o.message??null,o.toChannel??null,o.toChat??null,o.toAccount??null,o.checkUrl??null,o.checkContains??null,o.stallMinutes??null,u?r:null,r)}),this.event(e,null,"created",`${i.length} steps, written by ${n}`,r)})()}get(e){let n=this.db.prepare("SELECT * FROM request_plans WHERE request_id = ?").get(e);return n?Ce(n):null}steps(e){return this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? ORDER BY idx").all(e).map(vn)}step(e,n){let i=this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? AND idx = ?").get(e,n);return i?vn(i):null}listActive(){return this.db.prepare("SELECT * FROM request_plans WHERE state = 'active' ORDER BY created_at, rowid").all().map(Ce)}updateStep(e,n,i){let r=[],s=[];for(let[a,o]of Object.entries(i)){let l=Oi[a];!l||o===void 0||(r.push(`${l} = ?`),s.push(typeof o=="boolean"?o?1:0:o))}r.length&&this.db.prepare(`UPDATE request_plan_steps SET ${r.join(", ")} WHERE request_id = ? AND idx = ?`).run(...s,e,n)}finish(e,n,i){return this.db.prepare("UPDATE request_plans SET state = ?, finished_at = ? WHERE request_id = ? AND state = 'active'").run(n,i,e).changes>0}markNotified(e,n){this.db.prepare("UPDATE request_plans SET notified_at = ? WHERE request_id = ?").run(n,e)}awaitingSummary(){return this.db.prepare("SELECT * FROM request_plans WHERE state = 'done' AND notified_at IS NULL ORDER BY finished_at").all().map(Ce)}event(e,n,i,r,s){this.db.prepare("INSERT INTO request_plan_events (request_id, step, at, kind, detail) VALUES (?, ?, ?, ?, ?)").run(e,n,s,i,r.replace(/\s+/g," ").trim().slice(0,Ni))}events(e,n=200){return this.db.prepare("SELECT request_id, step, at, kind, detail FROM request_plan_events WHERE request_id = ? ORDER BY at, rowid LIMIT ?").all(e,n).map(i=>({requestId:i.request_id,step:i.step??null,at:i.at,kind:i.kind,detail:i.detail}))}},cl=_t;import{existsSync as Mi,readFileSync as ji}from"fs";Dt();ri();function An(t){let e=Pt(t),n={};if(Mi(e))try{n=Tt(JSON.parse(ji(e,"utf-8")))}catch{n={}}let i=Se.safeParse(n?.requests);return i.success?i.data:Se.parse(void 0)}async function ml(t,e={}){let n=(t.channels??[]).filter(i=>!we.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...we].join(", ")}`}:Nt(i=>{let r=i.requests??={};for(let s of["enabled","channels","from","staleAfterHours","retentionDays"])t[s]!==void 0&&(r[s]=t[s]);if(t.plans){let s=r.plans??={};for(let a of["enabled","stallMinutes","maxNudges","approveKinds","disabledAgents","requireForWork","requireOverMinutes"])t.plans[a]!==void 0&&(s[a]=t.plans[a])}if(t.checkers){let s=r.checkers??={};for(let a of["enabled","checkEveryMinutes"])t.checkers[a]!==void 0&&(s[a]=t.checkers[a])}},{configPath:e.configPath,reload:e.reload})}var In=["card","schedule","memory","wiki","whatsapp","request"],Vi=280;function j(t,e=Vi){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function De(t){if(t.configPath)return _(t.configPath);let e=[_(t.root,"agentx.json"),_(t.root,".agentx","config.json")];return e.find(n=>z(n))??e[0]}function Pe(t){return t.wikiDir?_(t.wikiDir):_(t.root,".agentx","wiki")}function Ui(t){return M(t.root,"pending").map(Bi)}function Bi(t){return{key:`card:${t.id}`,kind:"card",title:t.title,ask:t.ask,yes:`tell ${t.raised_by} yes`,no:`tell ${t.raised_by} no`,recommend:t.recommend,if_silent:t.if_silent,expires:t.expires,...t.source?{source:t.source}:{},raised_by:t.raised_by,...t.node?{node:t.node}:{},created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.draft?{draft:t.draft}:{},...t.context||t.draft?{detail:j([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function qi(t){let e=De(t);if(!z(e))return[];let n;try{n=JSON.parse(Wi(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,a]of Object.entries(n?.crons??{})){let o=a?.approval;if(!o||o.action!=="create"&&o.action!=="delete")continue;let l=a.timezone||"UTC",c=a.schedule?Ft(a.schedule):"",u=a.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${a.schedule})`:"no schedule",d=String(a.prompt??a.command??""),p=o.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${a.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${a.agent??"the agent"} run this ${u}?`:`Remove the schedule "${s}" (${u})?`,yes:p?"enable it":"remove it",no:p?"drop the request":"keep the schedule",raised_by:String(o.requestedBy??"unknown"),created_at:String(o.requestedAt??""),detail:j(`${d}${p&&a.schedule?` \xB7 first run ${Vt(Wt(a.schedule,l,i),l)}`:""}`),more:"agentx schedule list"})}return r}function En(t){let e=_(t,".agentx","memory");return z(e)?Fi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Hi(t){let e=En(t.root);if(e.length===0)return[];let n=new xe(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:j(s.content),more:`agentx memory facts held --agent ${r}`});return i}function zi(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function Xi(t){return Kt(Pe(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:j(`${zi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Gi(t){return Sn(t.root,"pending").map(e=>({key:`whatsapp:${e.id}`,kind:"whatsapp",title:`WhatsApp reply to ${e.chat_name||e.to}`,ask:`Send this to ${e.chat_name||e.to}? "${e.text}"`,yes:"send it on WhatsApp",no:"drop the draft",raised_by:e.agent,created_at:e.created_at,detail:j(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function X(t){if(t.requests)return t.requests;if(_(t.root)!==process.cwd()||!z(_(t.root,".agentx","db.sqlite")))return null;let e=ke({quiet:!0});if(!e)return null;let n=_n.get(e);return!n&&!Rt(e)?null:(n||_n.set(e,n=new It(e)),n)}var _n=new WeakMap;function Cl(t){if(t.plans)return t.plans;if(t.requests||_(t.root)!==process.cwd()||!z(_(t.root,".agentx","db.sqlite")))return null;let e=ke({quiet:!0});if(!e||!$n(e))return null;let n=Rn.get(e);return n||Rn.set(e,n=new oe(e)),n}var Rn=new WeakMap;function Ki(t){let e=X(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:B(n,120).headline,ask:`Not finished. Ask ${n.agentId} to pick it up again?`,yes:`hand it back to ${n.agentId}`,no:"drop the request",raised_by:n.agentId,created_at:new Date(n.createdAt).toISOString(),detail:j(`${n.attentionReason??"It needs attention"}. You said (${n.channel}): ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var Tn={card:Ui,schedule:qi,memory:Hi,wiki:Xi,whatsapp:Gi,request:Ki};function Ji(t,e){let n=t.expires?Date.parse(t.expires):1/0,i=e.expires?Date.parse(e.expires):1/0;return n!==i?n-i:(Date.parse(t.created_at)||0)-(Date.parse(e.created_at)||0)}function Dl(t,e={}){let n=t.now??Date.now(),{snoozed:i}=x(t.root),r=[],s=[],a=0;for(let o of e.kinds??In){let l;try{l=Tn[o](t)}catch(c){s.push({kind:o,error:String(c?.message??c).slice(0,200)});continue}for(let c of l){let u=i[c.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){a++;continue}c.snoozed_until=u}r.push(c)}}return r.sort(Ji),{items:r,snoozed:a,errors:s}}function Yi(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!In.includes(n)||!i?null:{kind:n,ref:i}}function Zi(t,e,n){switch(e){case"card":return q(t.root,n)?.status==="pending";case"wiki":return Gt(Pe(t),n)?.status==="pending";case"whatsapp":return se(t.root,n)?.status==="pending";default:return Tn[e](t).some(i=>i.key===`${e}:${n}`)}}async function Cn(t,e,n,i={}){let r=Yi(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:a}=r,o=t.now??Date.now(),l=i.by??"operator";if(n==="later"){if(!Zi(t,s,a))return{ok:!1,error:`nothing waiting for "${e}"`};let u=i.laterHours&&i.laterHours>0?i.laterHours:24,d=new Date(o+u*36e5);return fn(t.root,e,d,o),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let c=n==="yes";switch(s){case"card":{let u=nn(t.root,a,c?"yes":"no",{by:l,note:i.note,now:o,choice:i.choice,text:i.text});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${c?"yes":"no"}${u.card.choice?` (${u.card.choice}${u.card.choice_suggested?", the suggested option":""})`:""}`}:u}case"schedule":{let u=await(c?Ut:Bt)(a,{configPath:De(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=a.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=a.slice(0,u),p=a.slice(u+1);if(!En(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new xe(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,c?"approved":"rejected",l),{ok:!0,message:`${e} ${c?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${p}" isn't waiting for review`}}case"wiki":{let u=Pe(t),d=c?Jt(u,a,{by:l,force:i.force,now:o}):Yt(u,a,{by:l,reason:i.note,now:o});return d.ok?{ok:!0,message:c?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await xn(t.root,a,c?"yes":"no",{by:l,now:o,send:t.sendWhatsApp});return u.ok?{ok:!0,message:c?`${e}: sent to ${u.draft.chat_name||u.draft.to}`:`${e}: dropped, nothing sent`}:u}case"request":{let u=X(t),d=u?.get(a);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:c?An(De(t)).enabled?(u.requestPickup(a,o),{ok:!0,message:`${e}: ${d.agentId} will be asked to pick it up again`}):{ok:!1,error:"Requests are off, so nothing would hand it back. Turn them on (agentx requests settings --enabled on), or answer no to drop it."}:(u.close(a,"dropped",i.note?.trim()||`dropped by ${l}`,o),{ok:!0,message:`${e}: dropped`})}}}var Dn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Nl(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/screen"||t==="/native/notes"||t==="/requests"||t.startsWith("/requests/")||t==="/watchers"||t.startsWith("/watchers/")||t==="/follow-up"||t.startsWith("/follow-up/")||t==="/events/recent"||/^\/agents\/[^/]+\/events$/.test(t)||t==="/a2a/delegations"||t.startsWith("/a2a/delegations/")||t==="/traces"||t.startsWith("/traces/")||t==="/voice/history"||t.startsWith("/voice/history/")||t==="/voice/transcribe"||t==="/voice/speak"||t==="/app-files"||t==="/calls"||t.startsWith("/calls/")||t==="/webrtc/camera"||t.startsWith("/webrtc/camera/")||t==="/mesh/guests"||t.startsWith("/mesh/guests/")||t==="/wiki/agents"||t==="/wiki/entries"||t==="/wiki/articles"||t==="/wiki/article"||t==="/wiki/notes"||t==="/api/wiki/curate"||t==="/api/wiki/curate/restore"||t==="/api/signals/stopped"||t.startsWith("/api/signals/stopped/")||t==="/api/review-gate/reviews"}function Ll(t){return t==="/reload"||t==="/api/processes/kill"||t==="/send"||t==="/send/agent"||t==="/send/contact"||t==="/mesh/announce"||t==="/voice/settings"||t==="/voice/preview"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(t)||/^\/mesh\/guests\/[^/]+\/(pause|resume|end|update)$/.test(t)||/^\/crons\/[^/]+\/enabled$/.test(t)||/^\/workflow-runs\/[^/]+\/cancel$/.test(t)||t==="/api/signals/stop"||t==="/api/signals/resume"||t==="/api/signals/drop"||t==="/api/review-gate/replay"}function Ol(t){return Dn.has(t)}function Ml(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Dn.has(t.remoteAddress))return{allowed:!0,reason:"loopback"};if(t.acceptedTokens.size===0)return{allowed:!0,reason:"no-tokens-configured"};let e=t.authorizationHeader||"",n=e.startsWith("Bearer ")?e.slice(7).trim():"";return n&&t.acceptedTokens.has(n)?{allowed:!0,reason:"token"}:{allowed:!1,reason:"missing-or-invalid-token"}}function jl(t,e=process.env){let n=new Set;e.MESH_TOKEN&&n.add(e.MESH_TOKEN);for(let i of t.mesh?.peers||[])i.token&&n.add(i.token);return n}function Fl(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function ae(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Qi(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function es(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Vl(t,e=es()){let n=ae(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Qi(n),s=[ae(t.host),ae(t["x-forwarded-host"])].filter(Boolean).map(a=>a.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=ae(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Ul(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as rr,mkdirSync as Es,readFileSync as Ts,renameSync as Cs,writeFileSync as Ds}from"fs";import{homedir as Ps}from"os";import{dirname as Ns,join as Ls}from"path";import{execFile as ds,execFileSync as ps}from"child_process";import{execFileSync as ts}from"child_process";import{existsSync as Nn,mkdirSync as ns,readdirSync as rs,readFileSync as Ln,renameSync as is,writeFileSync as ss}from"fs";import{homedir as On}from"os";import{join as Le}from"path";var v="siri:",Mn="com.apple.ttsbundle.gryphon-neural_",jn=t=>!!t&&t.startsWith(Mn),os=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],as=()=>{try{return ts("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ne;function Oe(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Ne!==void 0)return Ne;let{platform:n=process.platform,exists:i=Nn,prefDomain:r=as}=t,s=n==="darwin"&&os.every(a=>i(a))&&r();return e||(Ne=s),s}var Fn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],Wn={aaron:"male",damon:"male",daniel:"male",pierre:"male",samer:"male",arthur:"male",gordon:"male",martin:"male",nora:"female",simone:"female",marie:"female",soha:"female",martha:"female",catherine:"female",helena:"female",nicky:"female"},Me=t=>Wn[t.toLowerCase()]??null;function le(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var ls=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function cs(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(ls)){let a=`${i}-${r}`,o=`${Mn}${s}_${a}_premium`;e.has(o)||e.set(o,{id:o,name:s[0].toUpperCase()+s.slice(1),locale:a,quality:"premium",gender:Wn[s]??null,siri:!0})}return[...e.values()]}function ce(t=Fn,e={}){if(!Oe(e))return[];let n=[];for(let i of t){let r;try{r=rs(i)}catch{continue}for(let s of r)try{n.push(Ln(Le(i,s,"Info.plist"),"latin1"))}catch{}}return cs(n)}var Pn=`#!/bin/sh
|
|
56
56
|
# Written by agentx; shared by the daemon and AgentX Voice. Do not edit.
|
|
57
57
|
# siri-say.sh [voice] < text speak one line. A Siri voice id switches
|
|
58
58
|
# the OS default for it; any other id is
|
|
@@ -157,31 +157,31 @@ wait "$say_pid"
|
|
|
157
157
|
status=$?
|
|
158
158
|
say_pid=
|
|
159
159
|
finish $status
|
|
160
|
-
`,
|
|
160
|
+
`,us=(t=On())=>Le(t,".agentx","voice","siri-say.sh");function Vn(t=On()){let e=us(t);return Nn(e)&&Ln(e,"utf8")===Pn||(ns(Le(t,".agentx","voice"),{recursive:!0}),ss(`${e}.tmp`,Pn,{mode:493}),is(`${e}.tmp`,e)),e}var Un=`ObjC.import("AVFoundation")
|
|
161
161
|
const vs = $.AVSpeechSynthesisVoice.speechVoices, out = []
|
|
162
162
|
for (let i = 0; i < vs.count; i++) {
|
|
163
163
|
const v = vs.objectAtIndex(i)
|
|
164
164
|
out.push([v.identifier.js, v.name.js, v.language.js, Number(v.quality), Number(v.gender)].join("\\t"))
|
|
165
165
|
}
|
|
166
|
-
out.join("\\n")`,
|
|
167
|
-
`)){let[i,r,s,a,o]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!
|
|
168
|
-
`)[0]}`),F={at:t,voices:
|
|
169
|
-
`),
|
|
170
|
-
${tr(r,e.voice.introduce===!0&&!!i)}`}var
|
|
166
|
+
out.join("\\n")`,fs=new Set(["Fred","Kathy","Ralph","Junior"]),gs={Flo:"female",Sandy:"female",Shelley:"female",Grandma:"female",Kathy:"female",Eddy:"male",Reed:"male",Rocko:"male",Grandpa:"male",Fred:"male",Ralph:"male",Junior:"male"};function Bn(t){let e=[];for(let n of t.split(`
|
|
167
|
+
`)){let[i,r,s,a,o]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!fs.has(r)||e.push({id:i,name:r,locale:s,quality:a==="3"?"premium":a==="2"?"enhanced":"standard",gender:o==="1"?"male":o==="2"?"female":gs[r]??null})}return e}var ms=10*60*1e3,Yl=60*1e3,F=null,je=!1;function Fe(t=Date.now(),e=ms){if(process.platform!=="darwin")return[];if(F)t-F.at>e&&!je&&(je=!0,ds("osascript",["-l","JavaScript","-e",Un],{timeout:1e4},(n,i)=>{je=!1,n||(F={at:Date.now(),voices:[...Bn(String(i)),...ce()]})}));else try{F={at:t,voices:[...Bn(ps("osascript",["-l","JavaScript","-e",Un],{encoding:"utf8",timeout:1e4})),...ce()]}}catch(n){We(`[voice] could not list system voices: ${String(n?.message??n).split(`
|
|
168
|
+
`)[0]}`),F={at:t,voices:ce()}}return F.voices}var We=t=>process.stderr.write(t+`
|
|
169
|
+
`),ue=new Set;function Zl(t){We=t}function N(t,e){ue.has(t)||(ue.add(t),We(e))}function zn(t){for(let e of ue)t(e)&&ue.delete(e)}var Xn=()=>{};function Ql(t){Xn=t}function Gn(t){try{Xn(t)}catch(e){N("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var hs={premium:3,enhanced:2,standard:1},ys=new Set(["Grandma","Grandpa"]);function qn(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!ys.has(t.name)?1:0;return hs[t.quality]*10+e}var W=t=>t.toLowerCase().split(/[-_]/)[0],Hn=t=>t.id.startsWith("com.apple.voice.");function Ve(t,e,n,i=new Set){let r=G(t.filter(o=>!o.siri&&W(o.locale)===W(e)),e);if(r.some(Hn)&&(r=r.filter(Hn)),n==="female"||n==="male"){let o=r.filter(l=>l.gender===n);o.length&&(r=o)}if(!r.length)return null;let s=r.filter(o=>o.quality===r[0].quality),a=new Set([...i].map(o=>o.toLowerCase()));return s.find(o=>!a.has(o.name.toLowerCase()))??s[0]}function G(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=W(e),r=t.filter(s=>W(s.locale)===i);return(r.length?r:t).slice().sort((s,a)=>qn(a)-qn(s)||+(a.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(a.name)||s.locale.localeCompare(a.locale))}function K(t,e,n="en"){let i=t.trim();if(!i)return null;let r=e.find(c=>c.id===i);if(r)return r;if(i.toLowerCase().startsWith(v)){let c=i.slice(v.length).trim().toLowerCase(),u=G(e.filter(p=>p.siri&&p.name.toLowerCase()===c),n)[0];if(u||!c)return u??null;let d=K(c,e.filter(p=>W(p.locale)===W(n)),n);return d&&N(`siri:${c}`,`[voice] Siri voice "${c}" is not installed; speaking with ${d.name} (${d.locale}) instead.`),d}e=e.filter(c=>!c.siri);let s=/^(.+?)\s*\((premium|enhanced)\)$/i.exec(i),a=(s?s[1]:i.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),o=G(e.filter(c=>c.name.toLowerCase()===a),n);return(s?o.find(c=>c.quality===s[2].toLowerCase()):void 0)??o[0]??null}function Kn(t,e,n=new Set){let i=new Map;if(!e.length)return i;let r=new Set([...n].map(a=>a.toLowerCase())),s="female";for(let a of t){let o=a.gender==="female"||a.gender==="male",l=o?a.gender:s,c=e.filter(d=>!r.has(d.name.toLowerCase())),u=c.find(d=>d.gender===l)??(o?e.find(d=>d.gender===l):void 0)??c[0]??e[i.size%e.length];i.set(a.id,u),r.add(u.name.toLowerCase()),o||(s=s==="female"?"male":"female")}return i}$t();var Ue="system",bs=t=>t.trim().toLowerCase()===Ue,ws="21m00Tcm4TlvDq8ikWAM";function Be(t,e,n={},i=Fe()){let r=e[t],s=r?.name||t,a=r?.voice,o=He(e,n,i).get(t)??null,l=vs(t,a?.system,a?.gender,n,i);return{agentId:t,name:s,provider:a?.provider??n.provider??"system",elevenlabsVoiceId:a?.elevenlabsVoiceId||null,systemVoice:o?.id??null,systemVoiceName:o?pe(o):null,systemByLanguage:l,fallback:(n.fallback??"system")==="system",gender:a?.gender??null,style:a?.style||null,intro:a?.intro||As(s,r?.systemPrompt),...a?.rate?{rate:a.rate}:{},...a?.priority?{priority:a.priority}:{}}}var pe=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function ks(t,e,n,i){if(!e||!n.length)return null;let r=K(e,n,i);return r||(N(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),Gn(e)),r}function Qn(t,e){let n=t.trim();if(n.toLowerCase().startsWith(v))return{locale:e,gender:Me(n.slice(v.length).trim())};let i=le(n);return i?{locale:i.locale,gender:Me(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var er=t=>t.toLowerCase().split(/[-_]/)[0],Jn=(t,e)=>typeof t=="string"?t:t?.[er(e)];function de(t,e,n,i){if(e!==void 0)return bs(e)?null:ks(t,e,n,i)??void 0}var qe=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function Ss(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,a=[],o=de("voice.system",Jn(e.system,r),n,r),l=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=Jn(u.system,r),p=de(u.id,d,n,r),f=p!==void 0?p:d!==void 0&&n.length?xs(u,d,r,o,n,l()):o!==void 0&&qe(o,u.gender)?o:void 0;f!==void 0?s.set(u.id,f):a.push({id:u.id,gender:u.gender??null})}let c=l();for(let[u,d]of Kn(a,G(n.filter(p=>!p.siri),r),c))s.set(u,d);return s}function xs(t,e,n,i,r,s){for(let o of t.fallbacks??[]){let l=de(`${t.id}.fallbacks`,o,r,n);if(l!==void 0)return l}if(i!==void 0&&qe(i,t.gender))return i;let a=Qn(e,n);return Ve(r,a.locale,t.gender??a.gender,s)??void 0}function vs(t,e,n,i,r){if(typeof e=="string")return{};let s={},a=(o,l,c)=>{if(!(!l||typeof l=="string"))for(let[u,d]of Object.entries(l)){let p=de(`${o}.${u}`,d,r,u);p===void 0&&r.length&&(p=Ve(r,u,n??Qn(d,u).gender)??void 0),p!==void 0&&c(p)&&(s[er(u)]=p)}};return a("voice.system",i.system,o=>qe(o,n)),a(t,e,()=>!0),s}function ic(t,e){let n=e?te(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?pe(i):null}}function He(t,e={},n=Fe()){let i=Object.entries(t).map(([r,s])=>({id:r,system:s.voice?.system,gender:s.voice?.gender,fallbacks:s.voice?.fallbacks}));return Ss(i,e,n)}function ze(t,e){let n={provider:t.provider,elevenlabs:$s(e,t.elevenlabsVoiceId),system:t.systemVoice,fallback:t.fallback},i=Object.entries(t.systemByLanguage??{});return i.length&&(n.languages=Object.fromEntries(i.map(([r,s])=>[r,s?.id??null]))),t.rate&&t.rate!==1&&(n.rate=t.rate),t.priority&&t.priority!=="normal"&&(n.priority=t.priority),n}function $s(t,e){return t||e||process.env.AGENTX_VOICE_ID||ws}function As(t,e){let n=(e??"").split(/(?<=\.)\s/)[0]??"",i=/^You are (.+?)\.?$/i.exec(n.trim());if(!i)return`Hello, this is ${t}.`;let r=i[1].replace(/\s*\([^)]*\)/g,"").trim(),[s,...a]=r.split(/,\s*/),o=a.join(", ");return o&&s.toLowerCase()===t.toLowerCase()?`Hello, this is ${t}, ${o}.`:!/^an? /i.test(r)&&r.toLowerCase().includes(t.toLowerCase())?`Hello, this is ${r}.`:`Hello, this is ${t}, ${r}.`}var _s=8*60*60*1e3,Rs=500,Yn=class{constructor(e=_s){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(Zn(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=Zn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>Rs&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},Zn=(t,e)=>`${t}\0${e}`;function tr(t,e){let n=t.style?` Your speaking manner: ${t.style}.`:"";return e?`[VOICE INTRO] This is your first spoken exchange with this person in a while. Open with one short sentence introducing yourself in your own manner, along the lines of "${t.intro}", then answer.${n}`:"[VOICE CASUAL] You have already introduced yourself in this voice conversation. Do not introduce yourself or greet again; talk casually, like a colleague in the same office."+n}function sc(t,e,n,i={}){let r=e[t],s=Be(t,e,i),a=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:ze(s),persona:a||`You are ${s.name}.`,introLine:tr(s,n)}}var Is="[VOICE MODE] This question arrived by voice and your reply will be spoken aloud by a TTS engine. Answer in two or three short sentences. Plain language, no markdown, no code blocks, no bullet points, no URLs. Speak conversationally.";function oc(t){let e=t;if(e?.channel!=="voice"||!e.voice||typeof e.voice!="object")return;let n=s=>typeof s=="string"?s.replace(/\s+/g," ").slice(0,200):"",i=n(e.voice.intro),r={agentId:"",name:"",provider:"system",elevenlabsVoiceId:null,systemVoice:null,systemVoiceName:null,systemByLanguage:{},fallback:!0,gender:null,style:n(e.voice.style)||null,intro:i||"Hello."};return`${Is}
|
|
170
|
+
${tr(r,e.voice.introduce===!0&&!!i)}`}var Os="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",ir=(t=Ps())=>Ls(t,".agentx","voice","health.json");function Ms(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===Ue)return!0;if(i.toLowerCase().startsWith(v)){let r=i.slice(v.length).trim().toLowerCase();return e.some(s=>s.siri&&s.name.toLowerCase()===r)}return K(i,e,n)!==null}function js(t){let e=t.voice?.locale??"en",n=[],i=(r,s)=>{if(typeof s=="string")n.push({owner:r,name:s,locale:e,perLanguage:!1});else for(let[a,o]of Object.entries(s??{}))n.push({owner:r,name:o,locale:a,perLanguage:!0})};i("voice.system",t.voice?.system);for(let[r,s]of Object.entries(t.agents))(s.voice?.provider??t.voice?.provider??"system")!=="system"&&t.voice?.fallback==="none"||i(r,s.voice?.system);return n}function Fs(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:a,perLanguage:o}of js(t)){if(Ms(s,e,a))continue;i??=He(t.agents,t.voice,e);let l=n.get(s)??{voice:s,agents:[],speaksWith:{}};l.agents.includes(r)||l.agents.push(r);let c=i.get(r);r!=="voice.system"&&!o&&(l.speaksWith[r]=c?pe(c):"the OS default voice"),n.set(s,l)}return[...n.values()]}function Xe(t){let e=le(t);if(e)return`Siri ${e.name[0].toUpperCase()}${e.name.slice(1)} (${e.locale})`;if(t.toLowerCase().startsWith(v)){let n=t.slice(v.length).trim();return`Siri ${n[0]?.toUpperCase()??""}${n.slice(1)}`}return t}function Ws(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${Xe(n.voice)}: ${i}`});return{title:t.length===1?"AgentX: a voice is not installed":`AgentX: ${t.length} voices are not installed`,message:`${e.join(`
|
|
171
171
|
`)}
|
|
172
|
-
Reinstall in ${
|
|
173
|
-
`),
|
|
172
|
+
Reinstall in ${Os}. Agents switch back on their own once it is installed.`}}function Vs(t=ir()){if(!rr(t))return null;try{let e=JSON.parse(Ts(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function Us(t,e){Es(Ns(t),{recursive:!0}),Ds(`${t}.tmp`,JSON.stringify(e,null,2)+`
|
|
173
|
+
`),Cs(`${t}.tmp`,t)}var nr=class{constructor(e){this.deps=e}running=!1;missingNow=!1;hasMissing(){return this.missingNow}async check(e,n,i=new Date){if(this.running||!n.length)return null;this.running=!0;try{let r=this.deps.file??ir(),s=new Map((Vs(r)?.missing??[]).map(d=>[d.voice,d])),a=Fs(e,n),o=a.map(d=>({...d,since:s.get(d.voice)?.since??i.toISOString(),...s.get(d.voice)?.notifiedAt?{notifiedAt:s.get(d.voice).notifiedAt}:{}})),l=[...s.keys()].filter(d=>!a.some(p=>p.voice===d));for(let d of l)this.deps.log(`[voice] ${Xe(d)} is installed again; its agents speak with it again`);l.length&&zn(d=>l.some(p=>d===p||d.endsWith(`:${p}`)));let c=o.filter(d=>!d.notifiedAt);if(c.length){let{title:d,message:p}=Ws(c);try{await this.deps.notify(d,p);for(let f of c)f.notifiedAt=i.toISOString();this.deps.log(`[voice] told the owner: ${c.map(f=>Xe(f.voice)).join(", ")} not installed`)}catch(f){this.deps.log(`[voice] could not send the missing-voice notice: ${f?.message??f}`)}}this.missingNow=o.length>0;let u={checkedAt:i.toISOString(),missing:o};return(!rr(r)||JSON.stringify(o)!==JSON.stringify([...s.values()]))&&Us(r,u),u}finally{this.running=!1}}};import{readFileSync as Ke,writeFileSync as ur,existsSync as Je,readdirSync as Ys,statSync as Zs}from"fs";import{resolve as Ye,join as Qs}from"path";import{existsSync as sr,mkdirSync as Bs,readFileSync as qs,writeFileSync as or}from"fs";import{dirname as Hs,resolve as ar}from"path";import{z as m}from"zod";var zs=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),Xs=m.object({id:m.string(),title:m.string(),description:m.string().optional(),assignee:m.string().optional(),labels:m.array(m.string()).default([]),milestone:m.string().optional(),status:m.enum(["todo","doing","blocked","done"]).default("todo"),priority:m.number().int().optional(),estimatedSeconds:m.number().int().optional(),source:zs.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),Gs=m.object({version:m.literal(1),items:m.array(Xs).default([])}),fe=class{constructor(e){this.path=e}jsonPath(){return ar(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return ar(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return sr(this.jsonPath())}load(){let e=this.jsonPath();if(!sr(e))return{version:1,items:[]};let n=qs(e,"utf-8");try{return Gs.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();Bs(Hs(n),{recursive:!0}),or(n,JSON.stringify(e,null,2)+`
|
|
174
174
|
`),or(this.mdPath(),this.toMarkdown(e))}list(){return this.load().items}findById(e){return this.list().find(n=>n.id===e)}add(e){let n=this.load();if(n.items.some(s=>s.id===e.id))throw new Error(`backlog item ${e.id} already exists`);let i=new Date().toISOString(),r={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??i,updatedAt:i};return n.items.push(r),this.save(n),r}addMany(e){let n=this.load(),i=new Set(n.items.map(a=>a.id)),r=new Date().toISOString(),s=[];for(let a of e){if(i.has(a.id))continue;let o={...a,labels:a.labels??[],status:a.status??"todo",createdAt:a.createdAt??r,updatedAt:r};n.items.push(o),s.push(o),i.add(o.id)}return s.length&&this.save(n),s}update(e,n){let i=this.load(),r=i.items.findIndex(a=>a.id===e);if(r<0)throw new Error(`backlog item ${e} not found`);let s={...i.items[r],...n,id:i.items[r].id,createdAt:i.items[r].createdAt,updatedAt:new Date().toISOString()};return i.items[r]=s,this.save(i),s}remove(e){let n=this.load(),i=n.items.length;return n.items=n.items.filter(r=>r.id!==e),n.items.length===i?!1:(this.save(n),!0)}toMarkdown(e){let n=["# Backlog","","_Generated from `backlog.json`. Do not edit by hand \u2014 use `agentx backlog` commands._",""],i={doing:[],blocked:[],todo:[],done:[]};for(let s of e.items)i[s.status].push(s);let r=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[s,a]of r)if(i[s].length){n.push(`## ${a}`,"");for(let o of i[s]){let l=s==="done"?"x":" ",c=o.assignee?`@${o.assignee} `:"",u=o.estimatedSeconds?` [time: ${Math.round(o.estimatedSeconds/60)}m]`:"",d=o.source?` (${o.source.type}: ${o.source.project}#${o.source.iid})`:"";n.push(`- [${l}] ${c}${o.title}${u}${d}`),o.source?.url&&n.push(` - <${o.source.url}>`),o.labels.length&&n.push(` - labels: ${o.labels.join(", ")}`),o.milestone&&n.push(` - milestone: ${o.milestone}`),o.blocker&&n.push(` - BLOCKED: ${o.blocker}`)}n.push("")}return n.join(`
|
|
175
|
-
`)}};function
|
|
176
|
-
`):[]}writeMd(e){let n=
|
|
177
|
-
`))}async listOpen(e){if(this.store.exists())return this.store.list().filter(s=>s.status!=="done"&&(!s.assignee||s.assignee.toLowerCase()===e.toLowerCase())).map(s=>this.toWorkItem(s));let n=this.readMd(),i=[];for(let r=0;r<n.length;r++){let s=n[r].match(
|
|
178
|
-
`);for(let a=0;a<s.length;a++){let o=s[a].match(
|
|
175
|
+
`)}};function bc(t){return`${t.type}:${t.project}:${t.iid}`}function lr(t,e,n){let i=[];if(e.type==="gitlab"){let r=n.channels.gitlab?.agentMappings??[];for(let s of t){let a=r.find(o=>o.agentId===s);a?.gitlabUsernames?.length?i.push(a.gitlabUsernames[0]):i.push(s)}}else if(e.type==="github"){let r=n.channels.github?.agentMappings??[];for(let s of t){let a=r.find(o=>o.agentId===s);a?.githubUsernames?.length?i.push(a.githubUsernames[0]):i.push(s)}}return i}async function Ge(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?Ks(t.source,e,n,i):t.source.type==="github"?Js(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function Ks(t,e,n,i){let r=n.channels.gitlab,s=r?.token,a=r?.host||(t.host?`https://${t.host}`:void 0);if(!s||!a)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let o=[],l=async(f,g={})=>fetch(`${a}/api/v4${f}`,{...g,headers:{"PRIVATE-TOKEN":s,"Content-Type":"application/json",...g.headers||{}}}),c=encodeURIComponent(t.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async g=>{try{let h=await fetch(`${a}/api/v4/users?username=${encodeURIComponent(g)}`,{headers:{"PRIVATE-TOKEN":s}});if(!h.ok)return null;let y=await h.json();return Array.isArray(y)&&y[0]?.id?y[0].id:null}catch{return null}}))).filter(g=>typeof g=="number"));let d;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")d=0;else try{let f=await l(`/projects/${c}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(f.ok){let g=await f.json();Array.isArray(g)&&g[0]?.id&&(d=g[0].id)}}catch(f){i(`[backlog-sync] milestone lookup failed: ${f.message}`)}let p={};if(e.title!==void 0&&(p.title=e.title),e.description!==void 0&&(p.description=e.description),e.labels!==void 0&&(p.labels=e.labels.join(",")),e.addLabels?.length&&(p.add_labels=e.addLabels.join(",")),e.removeLabels?.length&&(p.remove_labels=e.removeLabels.join(",")),u!==void 0&&(p.assignee_ids=u),d!==void 0&&(p.milestone_id=d),e.state&&(p.state_event=e.state==="closed"?"close":"reopen"),Object.keys(p).length)try{let f=await l(`/projects/${c}/issues/${t.iid}`,{method:"PUT",body:JSON.stringify(p)});if(o.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let g=await f.text().catch(()=>"");return{ok:!1,attempts:o,error:`PUT issue ${f.status}: ${g.slice(0,200)}`,url:t.url}}}catch(f){return o.push({kind:"PUT issue",ok:!1,error:f.message}),{ok:!1,attempts:o,error:f.message,url:t.url}}if(e.note)try{let f=await l(`/projects/${c}/issues/${t.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});o.push({kind:"POST note",ok:f.ok,status:f.status})}catch(f){o.push({kind:"POST note",ok:!1,error:f.message})}return{ok:o.every(f=>f.ok),attempts:o,url:t.url}}async function Js(t,e,n,i){let s=n.channels.github?.token;if(!s)return{ok:!1,error:"github token not configured",attempts:[]};let a=[],o=async(p,f={})=>fetch(`https://api.github.com${p}`,{...f,headers:{Authorization:`Bearer ${s}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...f.headers||{}}}),l=t.project,c;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")c=null;else try{let p=await o(`/repos/${l}/milestones?state=all&per_page=100`);if(p.ok){let f=await p.json(),g=Array.isArray(f)?f.find(h=>h.title===e.milestoneTitle):null;g?.number&&(c=g.number)}}catch(p){i(`[backlog-sync] github milestone lookup failed: ${p.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let p=await o(`/repos/${l}/issues/${t.iid}`);if(p.ok){let f=await p.json(),g=Array.isArray(f.labels)?f.labels.map(y=>typeof y=="string"?y:y.name):[],h=new Set([...g,...e.addLabels??[]]);for(let y of e.removeLabels??[])h.delete(y);u=[...h]}}catch(p){i(`[backlog-sync] github label fetch failed: ${p.message}`)}let d={};if(e.title!==void 0&&(d.title=e.title),e.description!==void 0&&(d.body=e.description),u!==void 0&&(d.labels=u),e.assigneeUsernames!==void 0&&(d.assignees=e.assigneeUsernames),c!==void 0&&(d.milestone=c),e.state&&(d.state=e.state),Object.keys(d).length)try{let p=await o(`/repos/${l}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(a.push({kind:"PATCH issue",ok:p.ok,status:p.status}),!p.ok){let f=await p.text().catch(()=>"");return{ok:!1,attempts:a,error:`PATCH issue ${p.status}: ${f.slice(0,200)}`,url:t.url}}}catch(p){return a.push({kind:"PATCH issue",ok:!1,error:p.message}),{ok:!1,attempts:a,error:p.message,url:t.url}}if(e.note)try{let p=await o(`/repos/${l}/issues/${t.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});a.push({kind:"POST comment",ok:p.ok,status:p.status})}catch(p){a.push({kind:"POST comment",ok:!1,error:p.message})}return{ok:a.every(p=>p.ok),attempts:a,url:t.url}}var Ze=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,ge=/@([a-z0-9_-]+)/i,cr=/\[time:\s*([0-9hm\s]+)\]/i;function eo(t){let e=t.match(/(\d+)\s*h/i),n=t.match(/(\d+)\s*m/i);return(e?parseInt(e[1],10)*3600:0)+(n?parseInt(n[1],10)*60:0)}var Qe=class{constructor(e,n,i=()=>{}){this.path=e;this.daemon=n;this.log=i;this.store=new fe(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=Ye(process.cwd(),this.path);return Je(e)?Ke(e,"utf-8").split(`
|
|
176
|
+
`):[]}writeMd(e){let n=Ye(process.cwd(),this.path);ur(n,e.join(`
|
|
177
|
+
`))}async listOpen(e){if(this.store.exists())return this.store.list().filter(s=>s.status!=="done"&&(!s.assignee||s.assignee.toLowerCase()===e.toLowerCase())).map(s=>this.toWorkItem(s));let n=this.readMd(),i=[];for(let r=0;r<n.length;r++){let s=n[r].match(Ze);if(!s||s[2].toLowerCase()==="x")continue;let o=s[3],l=o.match(ge);if(l&&l[1].toLowerCase()!==e.toLowerCase())continue;let c=o.match(cr),u=o.replace(ge,"").replace(cr,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:l?l[1]:void 0,estimatedSeconds:c?eo(c[1]):void 0,priority:r})}return i}async listAll(e={}){return this.store.exists()?this.store.list().map(n=>this.toWorkItem(n)):[]}async claim(e,n){if(!this.store.exists())return;let i=this.store.findById(n);if(!i)return;let r=this.store.update(n,{assignee:i.assignee||e,status:"doing"});if(r.source&&this.daemon){let s=lr([r.assignee||e],r.source,this.daemon);Ge(r,{assigneeUsernames:s,addLabels:["Doing"],removeLabels:["To Do"]},this.daemon,this.log).catch(a=>this.log(`[backlog-sync] claim failed for ${n}: ${a?.message??a}`))}}async report(e,n){if(this.store.exists()&&this.store.findById(e)){let o={};n.status==="done"?o.status="done":n.status==="blocked"?(o.status="blocked",o.blocker=n.blocker||n.note||void 0):n.status==="in-progress"&&(o.status="doing"),n.timeSeconds&&(o.estimatedSeconds=n.timeSeconds);let l=this.store.update(e,o);if(l.source&&this.daemon){let c={};n.status==="done"?(c.addLabels=["Done"],c.removeLabels=["Doing"]):n.status==="blocked"&&(c.addLabels=["Blocked"]),n.note&&(c.note=n.note),Object.keys(c).length&&Ge(l,c,this.daemon,this.log).catch(u=>this.log(`[backlog-sync] report failed for ${e}: ${u?.message??u}`))}return}if(!e.startsWith("backlog:"))throw new Error(`not a backlog id: ${e}`);let i=parseInt(e.slice(8),10),r=this.readMd(),s=r[i];if(!s)throw new Error(`backlog line ${i} missing`);if(!s.match(Ze))throw new Error(`backlog line ${i} not a checkbox`);if(n.status==="done"){r[i]=s.replace(/- \[ \]/,"- [x]");let o=n.timeSeconds?` <!-- done by agent, ${Math.round(n.timeSeconds/60)}m -->`:" <!-- done by agent -->";r.splice(i+1,0,o)}else n.status==="blocked"?r.splice(i+1,0,` <!-- BLOCKED: ${n.blocker||n.note||"?"} -->`):n.note&&r.splice(i+1,0,` <!-- ${n.note.replace(/-->/g,"\u2014 >")} -->`);this.writeMd(r)}toWorkItem(e){let n={todo:"todo",doing:"doing",blocked:"onhold",done:"done"}[e.status];return{id:e.id,title:e.title,description:e.description,assignee:e.assignee,estimatedSeconds:e.estimatedSeconds,priority:e.priority,labels:e.labels,stage:n,milestone:e.milestone,url:e.source?.url,updatedAt:e.updatedAt,state:e.status==="done"?"closed":"opened"}}},et=class{constructor(e,n){this.root=e;this.glob=n}type="wiki";capabilities={listAll:!1,create:!1,transition:!1,labels:!1,search:!1};walk(e,n){if(Je(e))for(let i of Ys(e)){let r=Qs(e,i);Zs(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(Ye(process.cwd(),this.root),n);let i=[];for(let r of n){let s=Ke(r,"utf-8").split(`
|
|
178
|
+
`);for(let a=0;a<s.length;a++){let o=s[a].match(Ze);if(!o||o[2].toLowerCase()==="x")continue;let l=o[3].match(ge);!l||l[1].toLowerCase()!==e.toLowerCase()||i.push({id:`wiki:${r}:${a}`,title:o[3].replace(ge,"").trim(),assignee:l[1],priority:a})}}return i}async claim(){}async report(e,n){let i=e.split(":"),r=parseInt(i[i.length-1],10),s=i.slice(1,-1).join(":");if(!Je(s))return;let a=Ke(s,"utf-8").split(`
|
|
179
179
|
`);n.status==="done"&&a[r]&&(a[r]=a[r].replace(/- \[ \]/,"- [x]"),ur(s,a.join(`
|
|
180
|
-
`)))}},Qe=class{constructor(e,n,i,r,s){this.host=e;this.token=n;this.projects=i;this.agentUsernames=r;this.log=s}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[n,i]of Object.entries(this.agentUsernames))if(i.some(r=>r.toLowerCase()===e.toLowerCase()))return n}mapIssue(e,n){let i=e.references?.full?.split("#")[0]||n,r=[],s;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(s=e.labels.map(c=>({name:c.name,color:c.color,text_color:c.text_color})),r=s.map(c=>c.name)):r=e.labels);let o=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(c=>({username:c.username,name:c.name,avatarUrl:c.avatar_url})),l=o[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:l?this.usernameToAgent(l)||l:void 0,assignees:o,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:r,labelDetails:s,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,n={}){let i=await fetch(`${this.host}/api/v4${e}`,{...n,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...n.headers||{}}});if(!i.ok)throw new Error(`GitLab ${i.status}: ${await i.text().catch(()=>"")}`);return i.json()}async listOpen(e){let n=this.agentUsernames[e]||[];if(!n.length)return[];let i=[],r=this.projects.length?this.projects:["__ALL__"];for(let s of n)for(let a of r)try{let o=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,l=a==="__ALL__"?`/issues?${o}`:`/projects/${encodeURIComponent(a)}/issues?${o}`,c=await this.api(l);for(let u of c){let d=this.mapIssue(u,a);d.assignee=e,i.push(d)}}catch(o){this.log(`[business] GitLab listOpen failed for ${s} on ${a}: ${o.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),a=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(a,{method:"PUT"})}catch(o){this.log(`[business] claim label update failed: ${o.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),a=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let o=Math.max(1,Math.round(n.timeSeconds/60)),l=o>=60?`${Math.floor(o/60)}h${o%60?` ${o%60}m`:""}`:`${o}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}/add_spent_time?duration=${encodeURIComponent(l)}`,{method:"POST"})}catch(c){this.log(`[business] add_spent_time failed: ${c.message}`)}}if(n.status==="done")try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(o){this.log(`[business] done label update failed: ${o.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(o){this.log(`[business] blocked label update failed: ${o.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(o){this.log(`[business] report note failed: ${o.message}`)}}async listAll(e={}){let n=e.sinceDays??30,i=new Date(Date.now()-n*24*36e5).toISOString(),r=new URLSearchParams,s=e.state??"opened";r.set("state",s),r.set("updated_after",i),r.set("scope","all"),r.set("per_page","100"),r.set("with_labels_details","true"),r.set("order_by","updated_at"),r.set("sort","desc"),e.labels?.length&&r.set("labels",e.labels.join(",")),e.milestone&&r.set("milestone",e.milestone),e.search&&r.set("search",e.search);let a=this.projects.length?this.projects:["__ALL__"],o=[];for(let c of a)try{let u=c==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)o.push(this.mapIssue(p,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=o;if(e.notLabels?.length){let c=new Set(e.notLabels);l=l.filter(u=>!(u.labels||[]).some(d=>c.has(d)))}if(e.withoutScopedPrefix){let c=e.withoutScopedPrefix+"::";l=l.filter(u=>!(u.labels||[]).some(d=>d.startsWith(c)))}return l}async setState(e,n){let{project:i,iid:r,type:s}=this.parseId(e),a=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?state_event=${n}`,{method:"PUT"})}async getItem(e){let{project:n,iid:i}=this.parseId(e);try{let r=await this.api(`/projects/${encodeURIComponent(n)}/issues/${i}?with_labels_details=true`);return{...this.mapIssue(r,n),descriptionHtml:r.description_html||void 0,createdAt:r.created_at,author:r.author?{username:r.author.username,name:r.author.name,avatarUrl:r.author.avatar_url}:void 0,allLabels:Array.isArray(r.labels)?typeof r.labels[0]=="object"?r.labels.map(a=>a.name):r.labels:[]}}catch(r){return this.log(`[board] GitLab getItem failed for ${e}: ${r.message}`),null}}async updateItem(e,n){let{project:i,iid:r}=this.parseId(e),s;n.assigneeUsernames&&(s=(await Promise.all(n.assigneeUsernames.map(async u=>{try{let d=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(d)&&d[0]?.id?d[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let a;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")a=0;else try{let c=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(a=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${c.message}`)}let o={};n.title!==void 0&&(o.title=n.title),n.description!==void 0&&(o.description=n.description),n.labels!==void 0&&(o.labels=n.labels.join(",")),n.addLabels?.length&&(o.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(o.remove_labels=n.removeLabels.join(",")),s!==void 0&&(o.assignee_ids=s),a!==void 0&&(o.milestone_id=a);let l=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(o)});return this.mapIssue(l,i)}async listMembers(){let e=new Map;for(let n of this.projects)try{let i=await this.api(`/projects/${encodeURIComponent(n)}/members/all?per_page=100`);for(let r of i)r.username&&!e.has(r.username)&&e.set(r.username,{username:r.username,name:r.name,avatarUrl:r.avatar_url})}catch(i){this.log(`[board] listMembers failed for ${n}: ${i.message}`)}return[...e.values()].sort((n,i)=>n.username.localeCompare(i.username))}async listMilestones(){let e=new Map;for(let i of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(i)}/milestones?per_page=100`);for(let s of r)s.title&&!e.has(s.title)&&e.set(s.title,{id:s.id,title:s.title,state:s.state,dueDate:s.due_date})}catch(r){this.log(`[board] listMilestones failed for ${i}: ${r.message}`)}let n=[...e.values()];return n.sort((i,r)=>i.state!==r.state?i.state==="active"?-1:1:i.title.localeCompare(r.title)),n}async create(e){let n=e.projectHint||this.projects[0];if(!n)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let i,r=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];r.length&&(i=(await Promise.all(r.map(async c=>{try{let u=await this.api(`/users?username=${encodeURIComponent(c)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${c}: ${u.message}`),null}}))).filter(c=>typeof c=="number"));let s;if(e.milestoneTitle)try{let l=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(s=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${l.message}`)}let a={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(a.assignee_ids=i),s!==void 0&&(a.milestone_id=s);let o=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(a)});return this.mapIssue(o,n)}async transition(e,n,i){await this.transitionMany(e,n?[n]:[],i?[i]:[])}async transitionMany(e,n,i){let{project:r,iid:s,type:a}=this.parseId(e),o=a==="issue"?"issues":"merge_requests",l=new URLSearchParams;n.length&&l.set("add_labels",n.join(",")),i.length&&l.set("remove_labels",i.join(",")),l.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${o}/${s}?${l.toString()}`,{method:"PUT"})}parseId(e){let i=e.replace(/^gitlab:/,"").split(":"),r=i.pop(),s=i.pop()==="mr"?"mr":"issue";return{project:i.join(":"),type:s,iid:r}}};function vc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Ye(i.path,e,n);case"wiki":return new Ze(i.path,i.glob);case"gitlab":{let r=e.channels.gitlab;if(!r?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let s={};for(let o of r.agentMappings)o.gitlabUsernames.length&&(s[o.agentId]=o.gitlabUsernames);let a=i.projects.length?i.projects:r.routes.map(o=>o.project);return new Qe(r.host,r.token,a,s,n)}}}var et="unmapped";function tt(t,e=[]){if(!t)return et;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let i=t.indexOf("/");return i>0?t.slice(0,i):t}function eo(t){let e=new Map,n=t.projects??[],i=t.orgChart??{};for(let s of n)s.pm&&(e.has(s.pm)||e.set(s.pm,tt(s.id,n)));let r=(s,a=new Set)=>{if(e.has(s))return e.get(s);if(a.has(s))return;a.add(s);let o=i[s]?.reportsTo;if(!o)return;let l=r(o,a);return l&&e.set(s,l),l};for(let s of Object.keys(i))r(s);return e}function to(t,e,n=[]){if(!n.length)return;let i=n.filter(r=>!r.channel||r.channel===t);return i.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??i.find(r=>r.username&&e.username&&r.username===e.username)??i.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??i.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function Ac(t,e){let n=to(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return tt(t.project,e.projects);if(t.agentId){let i=eo(e).get(t.agentId);if(i)return i}return et}function _c(t,e){let n=String(t||"").split(":");if(n.length<3)return{agentId:e};let[i,r,...s]=n,a=s.join(":"),o={agentId:e||i,channel:r};return r==="gitlab"||r==="github"?o.project=a.split(":")[0]:r==="cron"||r==="api"||(o.chatId=a.split("@")[0]),o}var no=t=>t===et?"internal":"client";function ro(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??no(t),respondWithinMinutes:io(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Rc(t){let e=new Set;for(let n of t.projects??[])e.add(tt(n.id,t.projects));for(let n of t.contactMap??[])e.add(n.client);for(let n of Object.keys(t.clients??{}))e.add(n);return[...e].sort().map(n=>ro(n,t))}function io(t){let e=/^(\d+)\s*([mhd])$/.exec(String(t??"").trim());if(!e)return;let n=Number(e[1]);return e[2]==="m"?n:e[2]==="h"?n*60:n*1440}var so=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,oo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function dr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(oo)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=ao(i);if(!r)return{cleanText:t};let s=n.index??0,a=n[1]??"";return{cleanText:(t.slice(0,s)+a+t.slice(s+n[0].length)).trim(),ui:r}}function Ec(t){if(!t||!t.includes("agentx:ui"))return t;let e=so.exec(t);return e?t.slice(0,e.index).trimEnd():t}function ao(t){let e;try{e=JSON.parse(t)}catch{return null}if(!e||typeof e!="object")return null;let n={};if(Array.isArray(e.buttons)){let i=[],r=[],s=[];for(let a of e.buttons)!a||typeof a.label!="string"||(typeof a.url=="string"&&/^https?:\/\//i.test(a.url)?i.push({label:a.label,url:a.url}):typeof a.reply=="string"&&a.reply.trim()?r.push({label:a.label,reply:a.reply.trim()}):a.action!=null&&s.push(a.label));i.length&&(n.buttons=i),r.length&&(n.replies=r),s.length&&(n.skippedActions=s)}if(e.poll&&typeof e.poll=="object"){let i=e.poll.question,r=e.poll.options;typeof i=="string"&&i.trim()&&Array.isArray(r)&&r.filter(s=>typeof s=="string").length>=2&&(n.poll={question:i,options:r.filter(s=>typeof s=="string"),multiple:e.poll.multiple===!0})}if(e.media&&typeof e.media=="object"){let{type:i,url:r,caption:s}=e.media;["image","document","audio","video"].includes(i)&&typeof r=="string"&&r&&(n.media={type:i,url:r,...typeof s=="string"?{caption:s}:{}})}if(Array.isArray(e.quickReplies)){let i=e.quickReplies.filter(r=>typeof r=="string"&&r.trim()).map(r=>r.trim());i.length&&(n.quickReplies=i)}return!n.buttons&&!n.poll&&!n.media&&!n.quickReplies&&!n.replies&&!n.skippedActions?null:n}function Cc(t,e){let n=`${e}/call?to=${encodeURIComponent(t.from)}&callId=${encodeURIComponent(t.callId)}`;return t.reason==="camera"?`\u{1F4F7} ${t.from} is sharing a phone camera \u2014 tap to watch: ${n}&watch=1`:`\u{1F4DE} ${t.from} is calling \u2014 tap to join: ${n}`}var lo=5*6e4;function D(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var pr=class{subs=new Set;log;forwarder;localName;allowedCallers;pending=new Map;cleanupTimer;ringHandler;recentRings=new Map;constructor(e,n=[],i=console.error.bind(console,"[webrtc]")){this.localName=e,this.allowedCallers=new Set(n.map(D)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${D(n)}`}cleanupExpired(){let e=Date.now();for(let[n,i]of this.pending){let r=i.filter(s=>s.expiresAt>e);r.length===0?this.pending.delete(n):r.length!==i.length&&this.pending.set(n,r)}for(let[n,i]of this.recentRings)i<=e&&this.recentRings.delete(n)}setForwarder(e){this.forwarder=e}setRingHandler(e){this.ringHandler=e}subscribe(e,n,i){return this.addSubscriber(e,n,{kind:"sse",res:i})}subscribeInternal(e,n,i){return this.addSubscriber(e,n,{kind:"callback",deliver:i})}addSubscriber(e,n,i){let r={callId:e,recipient:n,sink:i};this.subs.add(r);let s=i.kind==="sse"?"sse":"internal";this.log(`subscribe[${s}] call=${e} as=${n} (${this.subs.size} total)`);let a=this.pendingKey(e,n),o=this.pending.get(a);if(o&&o.length){let l=Date.now(),c=o.filter(u=>u.expiresAt>l);for(let{signal:u}of c)this.deliverTo(r,u);this.pending.delete(a),c.length&&this.log(`flushed ${c.length} buffered signal(s) to new subscriber call=${e} as=${n}`)}return()=>{this.subs.delete(r),this.log(`unsubscribe[${s}] call=${e} as=${n} (${this.subs.size} remaining)`)}}deliverTo(e,n){try{return e.sink.kind==="sse"?e.sink.res.write(`event: signal
|
|
180
|
+
`)))}},tt=class{constructor(e,n,i,r,s){this.host=e;this.token=n;this.projects=i;this.agentUsernames=r;this.log=s}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[n,i]of Object.entries(this.agentUsernames))if(i.some(r=>r.toLowerCase()===e.toLowerCase()))return n}mapIssue(e,n){let i=e.references?.full?.split("#")[0]||n,r=[],s;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(s=e.labels.map(c=>({name:c.name,color:c.color,text_color:c.text_color})),r=s.map(c=>c.name)):r=e.labels);let o=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(c=>({username:c.username,name:c.name,avatarUrl:c.avatar_url})),l=o[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:l?this.usernameToAgent(l)||l:void 0,assignees:o,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:r,labelDetails:s,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,n={}){let i=await fetch(`${this.host}/api/v4${e}`,{...n,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...n.headers||{}}});if(!i.ok)throw new Error(`GitLab ${i.status}: ${await i.text().catch(()=>"")}`);return i.json()}async listOpen(e){let n=this.agentUsernames[e]||[];if(!n.length)return[];let i=[],r=this.projects.length?this.projects:["__ALL__"];for(let s of n)for(let a of r)try{let o=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,l=a==="__ALL__"?`/issues?${o}`:`/projects/${encodeURIComponent(a)}/issues?${o}`,c=await this.api(l);for(let u of c){let d=this.mapIssue(u,a);d.assignee=e,i.push(d)}}catch(o){this.log(`[business] GitLab listOpen failed for ${s} on ${a}: ${o.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),a=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(a,{method:"PUT"})}catch(o){this.log(`[business] claim label update failed: ${o.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),a=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let o=Math.max(1,Math.round(n.timeSeconds/60)),l=o>=60?`${Math.floor(o/60)}h${o%60?` ${o%60}m`:""}`:`${o}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}/add_spent_time?duration=${encodeURIComponent(l)}`,{method:"POST"})}catch(c){this.log(`[business] add_spent_time failed: ${c.message}`)}}if(n.status==="done")try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(o){this.log(`[business] done label update failed: ${o.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(o){this.log(`[business] blocked label update failed: ${o.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(o){this.log(`[business] report note failed: ${o.message}`)}}async listAll(e={}){let n=e.sinceDays??30,i=new Date(Date.now()-n*24*36e5).toISOString(),r=new URLSearchParams,s=e.state??"opened";r.set("state",s),r.set("updated_after",i),r.set("scope","all"),r.set("per_page","100"),r.set("with_labels_details","true"),r.set("order_by","updated_at"),r.set("sort","desc"),e.labels?.length&&r.set("labels",e.labels.join(",")),e.milestone&&r.set("milestone",e.milestone),e.search&&r.set("search",e.search);let a=this.projects.length?this.projects:["__ALL__"],o=[];for(let c of a)try{let u=c==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)o.push(this.mapIssue(p,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=o;if(e.notLabels?.length){let c=new Set(e.notLabels);l=l.filter(u=>!(u.labels||[]).some(d=>c.has(d)))}if(e.withoutScopedPrefix){let c=e.withoutScopedPrefix+"::";l=l.filter(u=>!(u.labels||[]).some(d=>d.startsWith(c)))}return l}async setState(e,n){let{project:i,iid:r,type:s}=this.parseId(e),a=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${a}/${r}?state_event=${n}`,{method:"PUT"})}async getItem(e){let{project:n,iid:i}=this.parseId(e);try{let r=await this.api(`/projects/${encodeURIComponent(n)}/issues/${i}?with_labels_details=true`);return{...this.mapIssue(r,n),descriptionHtml:r.description_html||void 0,createdAt:r.created_at,author:r.author?{username:r.author.username,name:r.author.name,avatarUrl:r.author.avatar_url}:void 0,allLabels:Array.isArray(r.labels)?typeof r.labels[0]=="object"?r.labels.map(a=>a.name):r.labels:[]}}catch(r){return this.log(`[board] GitLab getItem failed for ${e}: ${r.message}`),null}}async updateItem(e,n){let{project:i,iid:r}=this.parseId(e),s;n.assigneeUsernames&&(s=(await Promise.all(n.assigneeUsernames.map(async u=>{try{let d=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(d)&&d[0]?.id?d[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let a;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")a=0;else try{let c=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(a=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${c.message}`)}let o={};n.title!==void 0&&(o.title=n.title),n.description!==void 0&&(o.description=n.description),n.labels!==void 0&&(o.labels=n.labels.join(",")),n.addLabels?.length&&(o.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(o.remove_labels=n.removeLabels.join(",")),s!==void 0&&(o.assignee_ids=s),a!==void 0&&(o.milestone_id=a);let l=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(o)});return this.mapIssue(l,i)}async listMembers(){let e=new Map;for(let n of this.projects)try{let i=await this.api(`/projects/${encodeURIComponent(n)}/members/all?per_page=100`);for(let r of i)r.username&&!e.has(r.username)&&e.set(r.username,{username:r.username,name:r.name,avatarUrl:r.avatar_url})}catch(i){this.log(`[board] listMembers failed for ${n}: ${i.message}`)}return[...e.values()].sort((n,i)=>n.username.localeCompare(i.username))}async listMilestones(){let e=new Map;for(let i of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(i)}/milestones?per_page=100`);for(let s of r)s.title&&!e.has(s.title)&&e.set(s.title,{id:s.id,title:s.title,state:s.state,dueDate:s.due_date})}catch(r){this.log(`[board] listMilestones failed for ${i}: ${r.message}`)}let n=[...e.values()];return n.sort((i,r)=>i.state!==r.state?i.state==="active"?-1:1:i.title.localeCompare(r.title)),n}async create(e){let n=e.projectHint||this.projects[0];if(!n)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let i,r=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];r.length&&(i=(await Promise.all(r.map(async c=>{try{let u=await this.api(`/users?username=${encodeURIComponent(c)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${c}: ${u.message}`),null}}))).filter(c=>typeof c=="number"));let s;if(e.milestoneTitle)try{let l=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(s=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${l.message}`)}let a={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(a.assignee_ids=i),s!==void 0&&(a.milestone_id=s);let o=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(a)});return this.mapIssue(o,n)}async transition(e,n,i){await this.transitionMany(e,n?[n]:[],i?[i]:[])}async transitionMany(e,n,i){let{project:r,iid:s,type:a}=this.parseId(e),o=a==="issue"?"issues":"merge_requests",l=new URLSearchParams;n.length&&l.set("add_labels",n.join(",")),i.length&&l.set("remove_labels",i.join(",")),l.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${o}/${s}?${l.toString()}`,{method:"PUT"})}parseId(e){let i=e.replace(/^gitlab:/,"").split(":"),r=i.pop(),s=i.pop()==="mr"?"mr":"issue";return{project:i.join(":"),type:s,iid:r}}};function Ac(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Qe(i.path,e,n);case"wiki":return new et(i.path,i.glob);case"gitlab":{let r=e.channels.gitlab;if(!r?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let s={};for(let o of r.agentMappings)o.gitlabUsernames.length&&(s[o.agentId]=o.gitlabUsernames);let a=i.projects.length?i.projects:r.routes.map(o=>o.project);return new tt(r.host,r.token,a,s,n)}}}var nt="unmapped";function rt(t,e=[]){if(!t)return nt;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let i=t.indexOf("/");return i>0?t.slice(0,i):t}function to(t){let e=new Map,n=t.projects??[],i=t.orgChart??{};for(let s of n)s.pm&&(e.has(s.pm)||e.set(s.pm,rt(s.id,n)));let r=(s,a=new Set)=>{if(e.has(s))return e.get(s);if(a.has(s))return;a.add(s);let o=i[s]?.reportsTo;if(!o)return;let l=r(o,a);return l&&e.set(s,l),l};for(let s of Object.keys(i))r(s);return e}function no(t,e,n=[]){if(!n.length)return;let i=n.filter(r=>!r.channel||r.channel===t);return i.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??i.find(r=>r.username&&e.username&&r.username===e.username)??i.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??i.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function Rc(t,e){let n=no(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return rt(t.project,e.projects);if(t.agentId){let i=to(e).get(t.agentId);if(i)return i}return nt}function Ic(t,e){let n=String(t||"").split(":");if(n.length<3)return{agentId:e};let[i,r,...s]=n,a=s.join(":"),o={agentId:e||i,channel:r};return r==="gitlab"||r==="github"?o.project=a.split(":")[0]:r==="cron"||r==="api"||(o.chatId=a.split("@")[0]),o}var ro=t=>t===nt?"internal":"client";function io(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??ro(t),respondWithinMinutes:so(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Ec(t){let e=new Set;for(let n of t.projects??[])e.add(rt(n.id,t.projects));for(let n of t.contactMap??[])e.add(n.client);for(let n of Object.keys(t.clients??{}))e.add(n);return[...e].sort().map(n=>io(n,t))}function so(t){let e=/^(\d+)\s*([mhd])$/.exec(String(t??"").trim());if(!e)return;let n=Number(e[1]);return e[2]==="m"?n:e[2]==="h"?n*60:n*1440}var oo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,ao=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function dr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(ao)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=lo(i);if(!r)return{cleanText:t};let s=n.index??0,a=n[1]??"";return{cleanText:(t.slice(0,s)+a+t.slice(s+n[0].length)).trim(),ui:r}}function Cc(t){if(!t||!t.includes("agentx:ui"))return t;let e=oo.exec(t);return e?t.slice(0,e.index).trimEnd():t}function lo(t){let e;try{e=JSON.parse(t)}catch{return null}if(!e||typeof e!="object")return null;let n={};if(Array.isArray(e.buttons)){let i=[],r=[],s=[];for(let a of e.buttons)!a||typeof a.label!="string"||(typeof a.url=="string"&&/^https?:\/\//i.test(a.url)?i.push({label:a.label,url:a.url}):typeof a.reply=="string"&&a.reply.trim()?r.push({label:a.label,reply:a.reply.trim()}):a.action!=null&&s.push(a.label));i.length&&(n.buttons=i),r.length&&(n.replies=r),s.length&&(n.skippedActions=s)}if(e.poll&&typeof e.poll=="object"){let i=e.poll.question,r=e.poll.options;typeof i=="string"&&i.trim()&&Array.isArray(r)&&r.filter(s=>typeof s=="string").length>=2&&(n.poll={question:i,options:r.filter(s=>typeof s=="string"),multiple:e.poll.multiple===!0})}if(e.media&&typeof e.media=="object"){let{type:i,url:r,caption:s}=e.media;["image","document","audio","video"].includes(i)&&typeof r=="string"&&r&&(n.media={type:i,url:r,...typeof s=="string"?{caption:s}:{}})}if(Array.isArray(e.quickReplies)){let i=e.quickReplies.filter(r=>typeof r=="string"&&r.trim()).map(r=>r.trim());i.length&&(n.quickReplies=i)}return!n.buttons&&!n.poll&&!n.media&&!n.quickReplies&&!n.replies&&!n.skippedActions?null:n}function Pc(t,e){let n=`${e}/call?to=${encodeURIComponent(t.from)}&callId=${encodeURIComponent(t.callId)}`;return t.reason==="camera"?`\u{1F4F7} ${t.from} is sharing a phone camera \u2014 tap to watch: ${n}&watch=1`:`\u{1F4DE} ${t.from} is calling \u2014 tap to join: ${n}`}var co=5*6e4;function D(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var pr=class{subs=new Set;log;forwarder;localName;allowedCallers;pending=new Map;cleanupTimer;ringHandler;recentRings=new Map;constructor(e,n=[],i=console.error.bind(console,"[webrtc]")){this.localName=e,this.allowedCallers=new Set(n.map(D)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${D(n)}`}cleanupExpired(){let e=Date.now();for(let[n,i]of this.pending){let r=i.filter(s=>s.expiresAt>e);r.length===0?this.pending.delete(n):r.length!==i.length&&this.pending.set(n,r)}for(let[n,i]of this.recentRings)i<=e&&this.recentRings.delete(n)}setForwarder(e){this.forwarder=e}setRingHandler(e){this.ringHandler=e}subscribe(e,n,i){return this.addSubscriber(e,n,{kind:"sse",res:i})}subscribeInternal(e,n,i){return this.addSubscriber(e,n,{kind:"callback",deliver:i})}addSubscriber(e,n,i){let r={callId:e,recipient:n,sink:i};this.subs.add(r);let s=i.kind==="sse"?"sse":"internal";this.log(`subscribe[${s}] call=${e} as=${n} (${this.subs.size} total)`);let a=this.pendingKey(e,n),o=this.pending.get(a);if(o&&o.length){let l=Date.now(),c=o.filter(u=>u.expiresAt>l);for(let{signal:u}of c)this.deliverTo(r,u);this.pending.delete(a),c.length&&this.log(`flushed ${c.length} buffered signal(s) to new subscriber call=${e} as=${n}`)}return()=>{this.subs.delete(r),this.log(`unsubscribe[${s}] call=${e} as=${n} (${this.subs.size} remaining)`)}}deliverTo(e,n){try{return e.sink.kind==="sse"?e.sink.res.write(`event: signal
|
|
181
181
|
data: ${JSON.stringify(n)}
|
|
182
182
|
|
|
183
|
-
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=D(e.to);if(n===D(this.localName)||this.hasSubscriberFor(e.callId,n))return this.fanOut(e),{ok:!0};if(!this.forwarder)return{ok:!1,error:"mesh forwarder not wired"};let r=await this.forwarder(e.to,e);return r?{ok:r}:{ok:!1,error:`forward to "${e.to}" failed`}}hasSubscriberFor(e,n){for(let i of this.subs)if(i.callId===e&&D(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(D(e.from)))return this.log(`reject inbound ${e.kind} from "${e.from}": not in allowedCallers`),{ok:!1,error:"caller not allowed"};if(e.kind==="ring"){let i=Date.now(),r=this.recentRings.get(e.callId);if(r&&r>i)return this.log(`dedup ring for call=${e.callId} (already notified)`),{ok:!0};if(this.recentRings.set(e.callId,i+
|
|
184
|
-
`),
|
|
183
|
+
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=D(e.to);if(n===D(this.localName)||this.hasSubscriberFor(e.callId,n))return this.fanOut(e),{ok:!0};if(!this.forwarder)return{ok:!1,error:"mesh forwarder not wired"};let r=await this.forwarder(e.to,e);return r?{ok:r}:{ok:!1,error:`forward to "${e.to}" failed`}}hasSubscriberFor(e,n){for(let i of this.subs)if(i.callId===e&&D(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(D(e.from)))return this.log(`reject inbound ${e.kind} from "${e.from}": not in allowedCallers`),{ok:!1,error:"caller not allowed"};if(e.kind==="ring"){let i=Date.now(),r=this.recentRings.get(e.callId);if(r&&r>i)return this.log(`dedup ring for call=${e.callId} (already notified)`),{ok:!0};if(this.recentRings.set(e.callId,i+co),this.ringHandler)try{this.ringHandler(e)}catch(s){this.log(`ringHandler threw: ${s.message}`)}else this.log(`ring received for call=${e.callId} but no handler wired`);return{ok:!0}}if(this.fanOut(e)===0){let i=this.pendingKey(e.callId,e.to),r=this.pending.get(i)||[];r.push({signal:e,expiresAt:Date.now()+3e4}),this.pending.set(i,r),this.log(`buffered ${e.kind} for call=${e.callId} to=${e.to} (no subscriber yet, ${r.length} pending)`)}return{ok:!0}}fanOut(e){let n=0,i=D(e.to);for(let r of this.subs)r.callId===e.callId&&D(r.recipient)===i&&(this.deliverTo(r,e)?n++:this.subs.delete(r));return n}get subscriberCount(){return this.subs.size}shutdown(){this.cleanupTimer&&clearInterval(this.cleanupTimer);for(let e of this.subs)if(e.sink.kind==="sse")try{e.sink.res.end()}catch{}this.subs.clear(),this.pending.clear()}};import{mkdirSync as uo,readFileSync as fr,renameSync as po,rmSync as fo,writeFileSync as go}from"fs";import{homedir as mo}from"os";import{dirname as ho,join as yo}from"path";var gr=yo(mo(),".agentx","call.json");function bo(t=gr,e=Date.now()){try{let n=JSON.parse(fr(t,"utf-8"));if(n?.active===!0&&!(n.until&&Date.parse(n.until)<=e))return{active:!0,mode:"call",reason:`in a call${n.reason?`: ${n.reason}`:""}`}}catch{}return{active:!1,mode:null,reason:"not in a call"}}function mr(t=Mt,e=bo){let n=t();return n.active?n:e()}function Fc(t,e,n=gr,i=Date.now()){let r=null;try{r=JSON.parse(fr(n,"utf-8"))}catch{}if(r&&r.source&&r.source!=="daemon")return;if(!t){r&&fo(n,{force:!0});return}uo(ho(n),{recursive:!0});let s=`${n}.${process.pid}.tmp`;go(s,JSON.stringify({active:!0,source:"daemon",reason:t,until:new Date(i+e).toISOString()})+`
|
|
184
|
+
`),po(s,n)}var wo={perClient:5,global:10,windowMs:10*60*1e3,lockoutMs:5*60*1e3},hr=class{constructor(e=wo,n=Date.now){this.opts=e;this.now=n}clients=new Map;all={failures:[],lockedUntil:0};retryAfter(e){let n=this.now(),i=Math.max(this.all.lockedUntil,this.clients.get(e)?.lockedUntil??0);return i>n?Math.ceil((i-n)/1e3):0}fail(e){let n=this.clients.get(e);n||this.clients.set(e,n={failures:[],lockedUntil:0}),this.bump(n,this.opts.perClient),this.bump(this.all,this.opts.global)}succeed(e){this.clients.delete(e)}bump(e,n){let i=this.now();e.failures=e.failures.filter(r=>i-r<this.opts.windowMs),e.failures.push(i),e.failures.length>=n&&(e.lockedUntil=i+this.opts.lockoutMs)}},ko="That code didn't work. Check it, or run agentx app pair for a new one.",So=400;async function Uc(t,e){let n=Date.now(),i=e.log??(c=>console.log(c)),r=t.socket.remoteAddress||"unknown",s=e.limiter.retryAfter(r);if(s>0)return i(`[app] pair-code refused from ${r}: locked out for ${s}s more`),{status:429,body:{error:"too many attempts",retryAfter:s},retryAfter:s};let a=null;try{a=(await Qt(t,1024)).code}catch{}let o=e.codes.redeem(a),l=o?e.verify(o.token):null;return await xo(n,e.minMs??So),!o||!l?(e.limiter.fail(r),i(`[app] pair-code failed from ${r}`),{status:401,body:{error:ko}}):(e.limiter.succeed(r),i(`[app] pair-code paired ${o.tokenId} (${l}) from ${r}`),{status:200,body:{device:l},token:o.token})}async function xo(t,e){let n=t+e-Date.now();n>0&&await new Promise(i=>setTimeout(i,n))}import{execFile as Fo}from"child_process";import{mkdtempSync as Do,rmSync as Po,writeFileSync as No}from"fs";import{tmpdir as Lo}from"os";import{join as Sr}from"path";import{randomBytes as vo}from"crypto";var E={top:8,side:32,bottom:60},it={height:56,keep:52},yr=`
|
|
185
185
|
:root {
|
|
186
186
|
--ac-paper: #fafaf9; --ac-soft: #f4f4f2; --ac-edge: #e9e9e6;
|
|
187
187
|
--ac-text: #0b1413; --ac-muted: #4a5856; --ac-subtle: #7c8987;
|
|
@@ -310,16 +310,16 @@ button.primary:hover:not(:disabled) { transform: translateY(-1px); background: v
|
|
|
310
310
|
button.primary:disabled { opacity: .55; cursor: not-allowed; }
|
|
311
311
|
kbd { font: 11px var(--ac-mono); color: var(--ac-subtle); }
|
|
312
312
|
button.primary kbd { color: inherit; opacity: .7; }
|
|
313
|
-
`;var br=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),wr=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function
|
|
313
|
+
`;var br=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),wr=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function $o(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?br(n):wr(n)}`}function Ao(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[wr(n)],br(n)].join(" ")}function _o(t){let e=t.trim().split(/[\s_-]+/).filter(Boolean);return(e.length>1?e[0][0]+e[1][0]:t.trim().slice(0,1)).toUpperCase()}function Ro(t){return t.origin?.kind==="request"?"Hand it back":t.draft?"Send":t.choices?.length?"Choose":"Yes"}var st=t=>`<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${t}</svg>`,Io=st('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),Eo=st('<path d="m6 15 6-6 6 6"/>'),To=st('<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>');function kr(t,e={}){let n=e.now??Date.now(),i=e.from||t.raised_by,r=vo(12).toString("base64"),s=t.choices??[],a=t.origin?.kind==="reminder",o=t.origin?.kind==="request",l=Xt(t),c=s.map((p,f)=>`<button class="opt" role="radio" aria-checked="false" data-i="${f}"><span class="n">${f+1}</span><span class="t">${w(p)}</span>${f===l.index?'<i class="dot"></i>':""}</button>`).join(""),u=t.recommend?`<span class="rec"><i class="dot"></i>${w(i)} recommends</span>`:"",d={choices:s,draft:t.draft??"",placeholder:Ht,chime:e.sound==="chime",volume:Math.min(1,Math.max(0,e.volume??.4)),theme:e.theme??"system",pick:e.pick&&e.pick<=s.length?e.pick-1:l.index};return`<!doctype html>
|
|
314
314
|
<html lang="en"><head><meta charset="utf-8">
|
|
315
315
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${r}'">
|
|
316
316
|
<title>AgentX</title>
|
|
317
317
|
<style>${yr}</style></head>
|
|
318
318
|
<body><div class="wrap"><main class="card${e.still?" still":""}">
|
|
319
|
-
<div class="head" title="Drag to move"><span class="avatar">${w(
|
|
320
|
-
<div class="who"><b>${w(i)}</b><span>${w(
|
|
319
|
+
<div class="head" title="Drag to move"><span class="avatar">${w(_o(i))}</span>
|
|
320
|
+
<div class="who"><b>${w(i)}</b><span>${w($o(t.created_at,n))}</span></div>
|
|
321
321
|
<span class="kind${a?"":" decision"}">${a?"Reminder":o?"Request":"Decision"}</span>
|
|
322
|
-
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${
|
|
322
|
+
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${Eo}</button></div>
|
|
323
323
|
<div class="body"><h1 dir="auto">${w(t.title)}</h1>
|
|
324
324
|
${t.context?`<p class="context" dir="auto">${w(t.context)}</p>`:""}
|
|
325
325
|
<p class="ask" dir="auto">${w(t.ask)}</p>
|
|
@@ -328,15 +328,15 @@ ${c?`<div class="options" role="radiogroup">${c}</div>`:""}
|
|
|
328
328
|
${l.why?`<p class="why" dir="auto">${w(l.why)}</p>`:""}
|
|
329
329
|
${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><span class="edited"><i class="dot"></i>Edited</span><button class="reset" id="reset">Reset</button></div>
|
|
330
330
|
<textarea id="text" dir="auto" rows="2" spellcheck="true"></textarea>`:""}
|
|
331
|
-
<div class="notes"><div>${
|
|
332
|
-
<div>${
|
|
331
|
+
<div class="notes"><div>${Io}<span>${o?"It stays in Open requests on the Approvals page until you close it.":`If you don't answer by ${w(Ao(t.expires,n))}: ${w(t.if_silent)}.`}</span></div>
|
|
332
|
+
<div>${To}<span>Nothing goes out until you click.</span></div></div>
|
|
333
333
|
</div><div class="foot"><button class="btn later" id="later">Not now<kbd>esc</kbd></button>
|
|
334
334
|
<button class="btn" id="no">${o?"Drop":"No"}</button>
|
|
335
|
-
<button class="btn primary" id="yes">${
|
|
335
|
+
<button class="btn primary" id="yes">${Ro(t)}<kbd>\u2318\u21A9</kbd></button></div>
|
|
336
336
|
</main></div>
|
|
337
337
|
<script type="application/json" id="data">${JSON.stringify(d).replace(/</g,"\\u003c")}</script>
|
|
338
|
-
<script nonce="${r}">${
|
|
339
|
-
</body></html>`}var
|
|
338
|
+
<script nonce="${r}">${Co}</script>
|
|
339
|
+
</body></html>`}var Co=`
|
|
340
340
|
(function () {
|
|
341
341
|
var d = JSON.parse(document.getElementById("data").textContent);
|
|
342
342
|
var root = document.documentElement;
|
|
@@ -425,10 +425,10 @@ ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><sp
|
|
|
425
425
|
});
|
|
426
426
|
} catch (e) {}
|
|
427
427
|
})();
|
|
428
|
-
`;var
|
|
428
|
+
`;var Oo=440,Mo=`
|
|
429
429
|
ObjC.import("Cocoa"); ObjC.import("WebKit")
|
|
430
430
|
function run(argv) {
|
|
431
|
-
var path = argv[0], side = ${E.side}, gripTop = ${E.top}, gripEnd = ${E.top+
|
|
431
|
+
var path = argv[0], side = ${E.side}, gripTop = ${E.top}, gripEnd = ${E.top+it.height}, keep = ${it.keep}, w = Number(argv[1]) + 2 * side, h = 420, secs = Number(argv[2]), capture = argv[3] || ""
|
|
432
432
|
var app = $.NSApplication.sharedApplication
|
|
433
433
|
app.setActivationPolicy($.NSApplicationActivationPolicyAccessory)
|
|
434
434
|
ObjC.registerSubclass({ name: "AgentXCardView", superclass: "WKWebView", methods: {
|
|
@@ -500,21 +500,21 @@ function run(argv) {
|
|
|
500
500
|
}
|
|
501
501
|
function gone(why) { return JSON.stringify({ action: "dismiss", why: why }) }
|
|
502
502
|
function quoted(s) { return "'" + String(s).replace(/'/g, "'\\\\''") + "'" }
|
|
503
|
-
`;function
|
|
503
|
+
`;function jo(t,e){let n=t.trim().split(`
|
|
504
504
|
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&vr.includes(i.why))return{action:"dismiss",why:i.why};if(i?.action!=="yes")return{action:"dismiss"};let r=e.choices??[],s;if(r.length){if(typeof i.choice!="string"||!r.includes(i.choice))return{action:"dismiss"};s=i.choice}let a;return e.draft&&(a=typeof i.text=="string"?i.text.replace(/\r\n?/g,`
|
|
505
|
-
`).trim():"",!a||a.length>
|
|
505
|
+
`).trim():"",!a||a.length>qt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...a?{text:a}:{}}}async function xr(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=Do(Sr(Lo(),"agentx-card-"));try{let s=Sr(r,"card.html");No(s,kr(t,{...e,still:!!e.capture}),{mode:384});let a=["-l","JavaScript","-e",Mo,s,String(Oo),String(i),...e.capture?[e.capture]:[]],o=await n("/usr/bin/osascript",a,(i+10)*1e3);return o.ok?jo(o.stdout,t):null}finally{Po(r,{recursive:!0,force:!0})}}var vr=["not now","timed out","closed"],Wo=(t,e,n)=>new Promise(i=>{try{Fo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),$r=160,ot=15e3;function Ar(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>$r?e.slice(0,$r):e}async function Vo(t,e,n,i,r){let s=e.sound==="chime"?i?"":"Glass":e.sound,a=s?Zt(s):null;if(a&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),a],ot),!!e.speak)if(r){let o;await Promise.race([r(Ar(t)),new Promise(l=>{o=setTimeout(l,ot)})]),clearTimeout(o)}else{let o=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...o,"--",Ar(t)],ot)}}function Ir(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function Uo(t,e,n){return Ir(["on run argv","set opts to items 3 thru -1 of argv",'set pick to choose from list opts with title (item 1 of argv) with prompt (item 2 of argv) OK button name "Next" cancel button name "Not now"','if pick is false then return ""',"return item 1 of pick","end run"],[t,e,...n])}function _r(t,e,n,i,r){return Ir(["on run argv","set AppleScript's text item delimiters to linefeed","set btns to text items of (item 3 of argv)","set secs to (item 5 of argv) as integer","if (count of argv) > 5 then","set r to display dialog (item 2 of argv) with title (item 1 of argv) default answer (item 6 of argv) buttons btns default button (item 4 of argv) giving up after secs","else","set r to display dialog (item 2 of argv) with title (item 1 of argv) buttons btns default button (item 4 of argv) giving up after secs","end if",'if gave up of r then return ""',"if (count of argv) > 5 then return (button returned of r) & linefeed & (text returned of r)","return button returned of r","end run"],[t,e,n.join(`
|
|
506
506
|
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function Rr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
|
|
507
|
-
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function
|
|
507
|
+
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function at(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
|
|
508
508
|
|
|
509
|
-
`)}async function Er(t,e,n={}){let i=n.run??
|
|
509
|
+
`)}async function Er(t,e,n={}){let i=n.run??Wo,r=(e.style??"card")==="card",s=Vo(t,e,i,r,n.speak).catch(()=>{});if(r){let a=await xr(t,{timeoutSeconds:e.timeoutSeconds,sound:e.sound,volume:e.volume,theme:e.theme,from:n.from,capture:n.capture,pick:n.pick},i).catch(()=>null);if(a)return a}return await s,Bo(t,e,i)}async function Bo(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=(i+5)*1e3,s=`${t.raised_by}: ${t.title}`,a;if(t.choices?.length){let c=await n("/usr/bin/osascript",Uo(s,at(t),t.choices),r);if(a=c.stdout.replace(/\n$/,""),!c.ok||!t.choices.includes(a))return{action:"dismiss"};if(!t.draft)return{action:"yes",choice:a}}if(t.draft){let c=a?`${a}
|
|
510
510
|
|
|
511
|
-
Message (edit it if you like):`:`${
|
|
511
|
+
Message (edit it if you like):`:`${at(t)}
|
|
512
512
|
|
|
513
|
-
Message (edit it if you like):`,d=await n("/usr/bin/osascript",_r(s,c,a?["Cancel","Send"]:["Not now","No","Send"],i,
|
|
514
|
-
`)[0]}); Siri voices will not switch`),null}}var
|
|
515
|
-
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as
|
|
516
|
-
`)[0].slice(0,200);l.push(`${c}: ${d}`),a.log(`[voice] phone transcription with ${c} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:l.join("; ")}]}function
|
|
517
|
-
`)[0].slice(0,160)}`),u("ElevenLabs could not speak this answer.",502)}}function
|
|
513
|
+
Message (edit it if you like):`,d=await n("/usr/bin/osascript",_r(s,c,a?["Cancel","Send"]:["Not now","No","Send"],i,zt(t.draft,a)),r),p=d.ok?Rr(d.stdout):null;if(p?.button==="Send"){let f=p.text.trim();return f?{action:"yes",...a?{choice:a}:{},text:f}:{action:"dismiss"}}return p?.button==="No"?{action:"no"}:{action:"dismiss"}}let o=await n("/usr/bin/osascript",_r(s,at(t),["Not now","No","Yes"],i),r),l=o.ok?Rr(o.stdout):null;return l?.button==="Yes"?{action:"yes"}:l?.button==="No"?{action:"no"}:{action:"dismiss"}}var ut=24*36e5,lt=!1,qo=10*6e4,Tr=-1/0;function Cr(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=x(t.root),a=r?Date.parse(r):NaN,o=M(t.root,"pending").filter(c=>Date.parse(c.expires)>e),l=o.find(c=>s.includes(`card:${c.id}`));if(l)return l;for(let c of o){let u=`card:${c.id}`;if(n[u]||rn(t.root,c.id,e))continue;let d=i[u];if(d&&Date.parse(d)>e)continue;let p=Date.parse(c.created_at);if(!(e-p>ut&&!(p<=a)))return c}return null}function ct(t){try{return X(t)?.listByState("needs_attention")??[]}catch{return[]}}var Dr=new Map;function Ho(t){let e=t.now??Date.now(),{popped:n={},snoozed:i}=x(t.root);return ct(t).find(r=>{let s=`request:${r.id}`,a=i[s];return Dr.get(r.id)===B(r,Ae.title).headline?!1:!n[s]&&!(a&&Date.parse(a)>e)&&e-r.updatedAt<=ut})??null}function zo(t,e){return{id:t.id,title:B(t,Ae.title).headline,context:t.attentionReason??"It is not finished and nothing is retrying it.",ask:`Hand it back to ${t.agentId}, or drop it?`,say:"A request you made is not finished.",recommend:"",if_silent:"keep",expires:new Date(e+ut).toISOString(),raised_by:t.agentId,created_at:new Date(t.createdAt).toISOString(),status:"pending",origin:{kind:"request",id:t.id}}}async function bu(t){let{ctx:e,settings:n,log:i}=t;if(!n.enabled||(t.platform??process.platform)!=="darwin")return"off";if(lt)return"busy";let r=Cr(e)?null:Ho(e),s=r?zo(r,e.now??Date.now()):Cr(e);if(!s)return"none";let a=(t.focus??mr)();if(a.active)return"held";let o=`${r?"request":"card"}:${s.id}`,l=(x(e.root).wanted??[]).includes(o)?null:en(s);if(l){if(r)Dr.set(r.id,s.title);else{let c=[...M(e.root,"pending").map(u=>`card:${u.id}`),...ct(e).map(u=>`request:${u.id}`)];Ee(e.root,o,c,e.now)}return i(`[approvals] popup: ${o} not shown, back to ${s.raised_by}: ${l}`),t.returnToAuthor?.(s,tn(s,l)),"returned"}lt=!0;try{let c=[...M(e.root,"pending").map(y=>`card:${y.id}`),...ct(e).map(y=>`request:${y.id}`)];Ee(e.root,o,c,e.now),i(`[approvals] popup: showing ${o} from ${s.raised_by}`);let u=e.now??Date.now(),d=!!r&&u-Tr<qo;r&&n.speak&&(Tr=u);let p=t.agentName?.(s.raised_by)??(s.node?`${s.raised_by} on ${s.node}`:void 0),f=await(t.show??Er)(s,d?{...n,speak:!1}:n,{from:p,speak:t.speak});if(f.action==="dismiss")return i(`[approvals] popup: ${o} left waiting: ${f.why??"no answer"} (${jt(a)} when shown)`),"shown";if(!(r?X(e)?.get(r.id)?.state==="needs_attention":q(e.root,s.id)?.status==="pending"))return i(`[approvals] popup: ${o} was answered elsewhere; popup answer ignored`),"shown";let h=await Cn(e,o,f.action,{by:"operator (popup)",...f.action==="yes"?{choice:f.choice,text:f.text}:{}});return i(h.ok?`[approvals] popup: ${h.message}`:`[approvals] popup: ${o} not recorded: ${h.error}`),"shown"}catch(c){return i(`[approvals] popup failed for ${o}: ${c?.message??c}`),"shown"}finally{lt=!1}}function wu(t,e,n){if(!n)return{ok:!1,error:"the Mac popup is off; turn it on with `agentx approvals settings --popup on`"};let i=e.startsWith("card:")?q(t.root,e.slice(5)):null;return i?i.status!=="pending"?{ok:!1,error:`${e} is already ${i.status}`}:(gn(t.root,e),{ok:!0,message:`${e} will show on the Mac within a minute`}):{ok:!1,error:`no card "${e}"; the popup shows decision cards only`}}import{closeSync as J,createReadStream as Xo,fstatSync as Go,openSync as Ko,realpathSync as Pr}from"fs";import{isAbsolute as Jo,resolve as Nr,sep as Lr}from"path";var Au="/app-files",Yo=/^[A-Za-z0-9_.:-]{1,64}$/;function Zo(t,e,n=process.cwd()){if(!e||e.length>ne.pathChars||e.includes("\0"))return{ok:!1,status:400,error:"bad file path"};if(e.split(/[\\/]/).includes(".."))return{ok:!1,status:403,error:`the path leaves the workspace: copy the file into ${$e}/ first`};if(!ve(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=Pr(Nr(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=Pr(Jo(e)?e:Nr(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+Lr))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${$e}/ first`};let s=ve(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function Qo(t,e){let n=t.replace(/[^\x20-\x7e]/g,"_").replace(/["\\;]/g,"_").slice(0,120)||"file";return`${e==="file"?"attachment":"inline"}; filename="${n}"; filename*=UTF-8''${encodeURIComponent(t.slice(0,120))}`}function ea(t,e,n){return{"Content-Type":t,"Content-Disposition":Qo(e,n),"X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; img-src 'self'; media-src 'self'; sandbox","Cache-Control":"private, max-age=3600","Accept-Ranges":"bytes"}}function ta(t,e){let n=/^bytes=(\d*)-(\d*)$/.exec(String(t||"").trim());if(!n||!n[1]&&!n[2])return null;let i,r;return n[1]?(i=Number(n[1]),r=n[2]?Math.min(Number(n[2]),e-1):e-1):(i=Math.max(0,e-Number(n[2])),r=e-1),i>r||i>=e?"unsatisfiable":{start:i,end:r}}function _u(t,e,n,i){let r=(C,O)=>{e.writeHead(C,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(O))};if(t.method!=="GET"&&t.method!=="HEAD")return r(405,{error:"GET only"});let s=n.searchParams.get("agent")||"",a=n.searchParams.get("file")||"";if(!Yo.test(s))return r(400,{error:"bad agent id"});let o=i.workspaceOf(s);if(!o)return r(404,{error:`no agent "${s}" on this computer`});let l=Zo(o,a,i.cwd);if(!l.ok)return i.log?.(`[app-files] refused ${JSON.stringify(a.slice(0,200))} from ${s}: ${l.error}`),r(l.status,{error:l.error});let c;try{c=Ko(l.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let C=Go(c);if(!C.isFile())return J(c),r(404,{error:"not a file"});u=C.size}catch{return J(c),r(404,{error:"file not found"})}if(u>ne.bytes)return J(c),r(413,{error:`the file is larger than ${ne.bytes/1024/1024} MB`});let d=l.path.split(Lr).pop()||"file",p=ea(l.mime,d,l.kind),f=ta(t.headers.range,u);if(f==="unsatisfiable"){J(c),e.writeHead(416,{...p,"Content-Range":`bytes */${u}`}),e.end();return}let{start:g,end:h}=f??{start:0,end:u-1};if(e.writeHead(f?206:200,{...p,"Content-Length":String(u?h-g+1:0),...f?{"Content-Range":`bytes ${g}-${h}/${u}`}:{}}),t.method==="HEAD"||u===0){J(c),e.end();return}let y=Xo("",{fd:c,start:g,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as Y}from"child_process";import{readFileSync as na,writeFileSync as ra}from"fs";import{tmpdir as ia}from"os";import{join as sa}from"path";$t();var Or=t=>t&&t!==1?Math.round(175*t):null,me=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function oa(){if(process.env.ELEVENLABS_API_KEY)return process.env.ELEVENLABS_API_KEY;for(let t of[`${process.env.HOME}/.elevenlabs/key`,`${process.env.HOME}/.agentx/elevenlabs-key.txt`])try{let e=na(t,"utf8").trim();if(e)return e}catch{}return null}function Lu(t=oa()){let e=0;return async(n,i)=>{if(n.voice.provider==="system")return null;if(!t){if(n.voice.fallback)return null;throw new Error("ElevenLabs is the voice provider but no key is set")}try{let r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${n.voice.elevenlabs}/stream?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n.text,model_id:"eleven_flash_v2_5",...me(n.voice.rate)?{voice_settings:{speed:me(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=sa(ia(),`agentx-say-${process.pid}-${++e}.mp3`);return ra(s,Buffer.from(await r.arrayBuffer())),s}catch(r){if(i.aborted||!n.voice.fallback)throw r;return N(`elevenlabs:${String(r?.message??r).slice(0,40)}`,`[voice] ElevenLabs failed (${String(r?.message??r).slice(0,160)}); speaking with the system voice`),null}}}function Mr(t,e){let n=t.languages&&te(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var aa=(t,e="")=>{let n=Mr(t,e),i=Or(t.rate);return[...n&&!jn(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function la(t,e,n){if(!n)return["say",aa(t,e)];let i=Mr(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function Ou(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Mu(t=dt()){if(t)try{Y("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function ju(t=dt()){if(t)try{Y("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function dt(t={},e){if(!Oe(t))return null;try{return Vn(e)}catch(n){return N("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
|
|
514
|
+
`)[0]}); Siri voices will not switch`),null}}var Fu=(t,e)=>{if(!t){let[n,i]=la(e.voice,e.text,dt()),r=Or(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,a=Y(n,i,{stdio:["pipe","ignore","ignore"],env:s});return a.stdin?.on("error",()=>{}),a.stdin?.end(e.text),a}return process.platform==="darwin"?Y("afplay",[t],{stdio:"ignore"}):Y("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as jr}from"child_process";import{accessSync as ca,constants as ua,readFileSync as Fr}from"fs";import{homedir as da}from"os";import{basename as V,delimiter as Wr,dirname as pa,extname as fa,join as pt}from"path";var P={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function Vr(t){let e=Array.isArray(t)?t[0]:t;return!e||!/^\d{1,9}$/.test(e.trim())?{status:400,error:"Say how long the recording is (X-Audio-Duration-Ms)."}:Number(e)>P.ms+2e3?{status:413,error:gt()}:null}var gt=()=>`The recording is longer than ${P.ms/6e4} minutes.`,ga={"audio/webm":"webm","video/webm":"webm","audio/ogg":"ogg","audio/mp4":"m4a","video/mp4":"m4a","audio/x-m4a":"m4a","audio/aac":"aac","audio/mpeg":"mp3","audio/wav":"wav","audio/x-wav":"wav","audio/wave":"wav"};function Ur(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return ga[e]??null}function Br(t,e){let n=[];return t!=="local"&&e.key&&n.push("elevenlabs"),e.ffmpeg&&(e.mlx?n.push("mlx-whisper"):e.whisper&&n.push("whisper")),n}function mt(t,e){return t==="local"&&e.key&&!e.ffmpeg?"Speech to text is set to local, and this computer has no ffmpeg.":(e.mlx||e.whisper)&&!e.ffmpeg?"This computer has Whisper but no ffmpeg to read the recording.":"Add an ElevenLabs key on this computer, or install mlx-whisper and ffmpeg."}function ft(t,e,n=process.env.PATH??""){let i=da(),r=[pt(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(Wr).filter(Boolean)];for(let s of[e,...r.map(a=>pt(a,t))])if(s)try{return ca(s,ua.X_OK),s}catch{}return null}function Hu(t){return{key:t,mlx:ft("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:ft("whisper",process.env.AGENTX_WHISPER),ffmpeg:ma()}}var ma=()=>ft("ffmpeg",process.env.AGENTX_FFMPEG);async function qr(t,e){return e?ha(t,e):null}async function ha(t,e){let n=String(P.ms/1e3+5);try{let r=[...(await ya(e,["-nostdin","-hide_banner","-t",n,"-i",t,"-f","null","-"],3e4)).matchAll(/time=(\d+):(\d+):(\d+(?:\.\d+)?)/g)],s=r[r.length-1];return s?Number(s[1])*3600+Number(s[2])*60+Number(s[3]):null}catch{return null}}async function Hr(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([Fr(t)],{type:e}),V(t));let s=await fetch("https://api.elevenlabs.io/v1/speech-to-text",{method:"POST",headers:{"xi-api-key":n},body:r,signal:i??AbortSignal.timeout(6e4)});if(!s.ok)throw new Error(`ElevenLabs ${s.status}: ${(await s.text().catch(()=>"")).slice(0,160)}`);let a=await s.json();if(typeof a.text!="string")throw new Error("ElevenLabs returned no text");return a.text.trim()}async function zr(t,e,n,i,r){let s=t==="mlx-whisper"?["--model",process.env.AGENTX_MLX_MODEL||"mlx-community/whisper-large-v3-turbo","--output-format","txt","--output-dir",r,n]:[n,"--model",process.env.AGENTX_WHISPER_MODEL||"base","--output_format","txt","--output_dir",r,"--fp16","False"],a={...process.env,PATH:`${pa(i)}${Wr}${process.env.PATH??""}`};await ba(e,s,12e4,a);try{return Fr(pt(r,V(n,fa(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function ya(t,e,n){return new Promise((i,r)=>{let s=jr(t,e,{stdio:["ignore","ignore","pipe"]}),a="",o=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${V(t)} took too long`))},n);s.stderr.on("data",l=>{a=(a+l).slice(-8192)}),s.on("error",l=>{clearTimeout(o),r(l)}),s.on("exit",l=>{clearTimeout(o),l===0?i(a):r(new Error(`${V(t)} exited ${l}`))})})}function ba(t,e,n,i=process.env){return new Promise((r,s)=>{let a=jr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),o="",l="",c=setTimeout(()=>{a.kill("SIGKILL"),s(new Error(`${V(t)} took longer than ${n/1e3}s`))},n);a.stdout.on("data",u=>{o.length<4096&&(o+=u)}),a.stderr.on("data",u=>{l.length<4096&&(l+=u)}),a.on("error",u=>{clearTimeout(c),s(u)}),a.on("exit",u=>{clearTimeout(c),u===0?r(o):s(new Error(`${V(t)} exited ${u}: ${l.trim().split(`
|
|
515
|
+
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as wa,rm as ka,writeFile as Sa}from"fs/promises";import{tmpdir as xa}from"os";import{join as Xr}from"path";ni();var va=64*1024,$a=2,ht=0;function nd(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function rd(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?Aa(t,e,i):Ia(t,e,i)}async function Aa(t,e,n){let i=String(t.headers["content-type"]||""),r=Ur(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=Vr(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let a=await Gr(t,P.bytes);if(!a)return b(e,413,{error:Ca()});if(!a.length)return b(e,400,{error:"The recording is empty."});if(ht>=$a)return b(e,429,{error:"This computer is already writing down other recordings. Try again in a moment."});let o=n.stt(),l=n.host(),c=Br(o,l);if(!l.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",p=c.length?"":" "+mt(o,l);return b(e,503,{error:"Voice input isn't set up on this computer.",hint:`Install ffmpeg ${d} for voice input from the phone.${p}`,setup:!1})}if(!c.length)return b(e,503,{error:"Voice input isn't set up on this computer.",hint:mt(o,l),setup:!1});ht++;let u;try{let d=await wa(Xr(xa(),"agentx-phone-voice-"));try{u=await _a(d,`speech.${r}`,a,i,l,c,n)}finally{await ka(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{ht--}b(e,u[0],u[1])}async function _a(t,e,n,i,r,s,a){let o=Xr(t,e);if(await Sa(o,n,{mode:384}),r.ffmpeg){let c=await(a.measure??qr)(o,r.ffmpeg);if(c==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(c*1e3>P.ms+2e3)return[413,{error:gt()}]}let l=[];for(let c of s)try{let u=await Ra(c,o,i,r,t,a);return a.log(`[voice] phone recording transcribed with ${c} (${Math.round(n.length/1024)} KB)`),u?[200,{text:u,engine:c}]:[422,{error:"No words were heard. Hold the orb and speak, then let go.",engine:c}]}catch(u){let d=String(u?.message??u).split(`
|
|
516
|
+
`)[0].slice(0,200);l.push(`${c}: ${d}`),a.log(`[voice] phone transcription with ${c} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:l.join("; ")}]}function Ra(t,e,n,i,r,s){let a=s.engines?.[t];if(a)return a(e,n,i,r);if(t==="elevenlabs")return Hr(e,n,i.key);let o=t==="mlx-whisper"?i.mlx:i.whisper;return zr(t,o,e,i.ffmpeg,r)}async function Ia(t,e,n){let i=await Gr(t,va);if(!i)return b(e,413,{error:"request too large"});let r;try{r=JSON.parse(i.toString("utf8")||"{}")}catch{return b(e,400,{error:"expected JSON"})}let s=typeof r?.agent=="string"?r.agent:"",a=typeof r?.peer=="string"&&r.peer?r.peer:void 0;if(!s)return b(e,400,{error:"agent is required"});let o=Ea(typeof r?.text=="string"?r.text:"",n.spokenMaxChars?.());if(!o)return b(e,422,{error:"Nothing in this answer can be said aloud."});let l=n.pronounce?n.pronounce(o):o,c=n.voiceOf(s,a);if(!c)return b(e,404,{error:`Unknown agent: ${s}`});let u=(p,f=200)=>b(e,f,{fallback:"browser",reason:p,text:l});if(c.provider!=="elevenlabs")return u("This agent speaks with a system voice, which only plays on the computer.");let d=n.elevenLabsKey();if(!d)return u("No ElevenLabs key is set on this computer.");try{let p=await(n.synth??Ta)(d,c,l);e.writeHead(200,{"Content-Type":"audio/mpeg","Content-Length":p.length,"Cache-Control":"no-store","X-Spoken-Chars":String(l.length)}),e.end(p)}catch(p){return n.log(`[voice] phone answer synthesis failed: ${String(p?.message??p).split(`
|
|
517
|
+
`)[0].slice(0,160)}`),u("ElevenLabs could not speak this answer.",502)}}function Ea(t,e){let n=dr(Ot(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return At(n,e)}async function Ta(t,e,n){let i=me(e.rate),r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(e.elevenlabs)}?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n,model_id:"eleven_flash_v2_5",...i?{voice_settings:{speed:i}}:{}}),signal:AbortSignal.timeout(6e4)});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text().catch(()=>"")).slice(0,160)}`);return Buffer.from(await r.arrayBuffer())}var Ca=()=>`The recording is larger than ${P.bytes/1024/1024} MB, more than ${P.ms/6e4} minutes of speech.`;function id(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?ze(Be(t,r,n.voice)):null}function Gr(t,e){return Number(t.headers["content-length"])>e?(t.resume(),Promise.resolve(null)):new Promise((n,i)=>{let r=[],s=0;t.on("data",a=>{if(!(s>e)){if(s+=a.length,s>e){r.length=0,n(null);return}r.push(a)}}),t.on("end",()=>{s<=e&&n(Buffer.concat(r))}),t.on("error",i)})}function b(t,e,n){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}import{existsSync as $,readFileSync as kt,writeFileSync as St,mkdirSync as he,readdirSync as wt,rmSync as Da,statSync as R}from"fs";import{resolve as Kr,relative as Pa,dirname as xt,join as L,extname as Z,basename as vt}from"path";var S=200*1024,Jr=new Set([".md",".markdown",".txt"]),U=new Set([".md",".markdown",".txt",".json",".jsonc",".yaml",".yml",".toml",".sh",".bash",".zsh",".py",".js",".mjs",".ts",".tsx",".jsx",".css",".html",".lock",".cfg",".ini",".env",".gitignore"]),Na=6,La=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function T(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=Kr(t);if($(n)||he(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=Kr(n,e);if(Pa(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function Yr(t){let e=Z(t).toLowerCase();if(!Jr.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function yt(t,e){let n=t.split(/\r?\n/).find(i=>i.trim().startsWith("#"));return n&&n.replace(/^#+\s*/,"").trim().slice(0,120)||e}function ld(t){let e=T(t,"."),n=[],i=new Set,r=[];try{r=wt(e)}catch{}for(let o of La){let l=L(e,o);if($(l)&&R(l).isFile()){let c=R(l).size,u=c>0&&c<S?bt(l):"";n.push({path:o,title:yt(u,o),size:c,exists:!0}),i.add(o)}else n.push({path:o,title:o,size:0,exists:!1}),i.add(o)}for(let o of r){if(i.has(o))continue;let l=L(e,o);try{let c=R(l);if(!c.isFile()||!Jr.has(Z(o).toLowerCase()))continue;let u=c.size>0&&c.size<S?bt(l):"";n.push({path:o,title:yt(u,o),size:c.size,exists:!0})}catch{}}let s=[],a=L(e,".claude","skills");if($(a))try{for(let o of wt(a)){let l=L(a,o),c;try{c=R(l)}catch{continue}if(!c.isDirectory())continue;let u=L(l,"SKILL.md");if(!$(u))continue;let d=R(u),p=d.size<S?bt(u):"";s.push({slug:o,title:yt(p,o),size:d.size,path:`.claude/skills/${o}/SKILL.md`})}}catch{}return s.sort((o,l)=>o.slug.localeCompare(l.slug)),{identity:n,skills:s,workspace:e}}function bt(t){try{return kt(t,"utf-8")}catch{return""}}function cd(t,e){let n=T(t,e);if(Yr(n),!$(n))return{path:e,content:""};if(R(n).size>S)throw new Error(`File is too large to edit in the admin panel (> ${S/1024} KB).`);return{path:e,content:kt(n,"utf-8")}}function ud(t,e,n){let i=T(t,e);Yr(i);let r=Buffer.from(n,"utf-8");if(r.length>S)throw new Error(`File too large (${r.length} > ${S} bytes).`);return he(xt(i),{recursive:!0}),St(i,r),{path:e,bytes:r.length}}function dd(t,e,n={}){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Skill slug must be lowercase (letters, digits, -, _) and start with a letter or digit.");let i=`.claude/skills/${e}/SKILL.md`,r=T(t,i);if($(r))throw new Error(`Skill "${e}" already exists.`);he(xt(r),{recursive:!0});let s=n.content?.trim()?n.content:Oa(e,n.title);return St(r,s),{slug:e,path:i}}function pd(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=T(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);if(!R(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return Da(n,{recursive:!0,force:!0}),{slug:e}}function fd(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=T(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);let i=[];return r(n,"",0,i),i.sort((s,a)=>s.kind!==a.kind?s.kind==="dir"?-1:1:s.path.localeCompare(a.path)),i;function r(s,a,o,l){if(o>Na)return;let c=[];try{c=wt(s)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let d=L(s,u),p=a?`${a}/${u}`:u,f;try{f=R(d)}catch{continue}if(f.isDirectory())l.push({path:`${p}/`,kind:"dir",size:0,editable:!1}),r(d,p,o+1,l);else if(f.isFile()){let g=Z(u).toLowerCase(),h=U.has(g)||U.has(u.toLowerCase());l.push({path:p,kind:"file",size:f.size,editable:h&&f.size<S})}}}}function gd(t,e,n){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let i=T(t,`.claude/skills/${e}/${n}`);if(!$(i)||!R(i).isFile())throw new Error(`File not found: ${n}`);let r=Z(i).toLowerCase(),s=vt(i).toLowerCase();if(!U.has(r)&&!U.has(s))throw new Error(`File type not editable: ${n}`);if(R(i).size>S)throw new Error(`File too large to edit (> ${S/1024} KB): ${n}`);return{path:n,content:kt(i,"utf-8")}}function md(t,e,n,i){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let r=T(t,`.claude/skills/${e}/${n}`),s=Z(r).toLowerCase(),a=vt(r).toLowerCase();if(!U.has(s)&&!U.has(a))throw new Error(`File type not editable: ${n}`);let o=Buffer.from(i,"utf-8");if(o.length>S)throw new Error(`File too large (${o.length} > ${S} bytes).`);return he(xt(r),{recursive:!0}),St(r,o),{path:n,bytes:o.length}}function hd(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=T(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);let i=r=>$(L(n,r));return i("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:i("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:i("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:i("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:i("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function Oa(t,e){return`# ${e?.trim()||t}
|
|
518
518
|
|
|
519
519
|
Describe what this skill does and when the agent should use it. Keep it under ~5 lines \u2014 the agent reads this to decide whether to invoke the skill.
|
|
520
520
|
|
|
@@ -527,7 +527,7 @@ Document the arguments, commands, or files the skill expects. Example:
|
|
|
527
527
|
|
|
528
528
|
\`\`\`bash
|
|
529
529
|
# Example invocation
|
|
530
|
-
claude-code ${
|
|
530
|
+
claude-code ${vt(t)} --arg value
|
|
531
531
|
\`\`\`
|
|
532
|
-
`}
|
|
533
|
-
//# sourceMappingURL=chunk-
|
|
532
|
+
`}Dt();var Zr={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function Qr(t){return{...Zr,...t??{},regions:{...t?.regions??{}},buffer:{...Zr.buffer,...t?.buffer??{}}}}function wd(t){try{return Qr(Ct(t).screen)}catch{return Qr(void 0)}}var Ma=/^[a-z][\w-]*$/,ei=["window","screen","menubar","notifications"];function Q(t,e,n,i){let r=Number(t);if(t===""||t===null||!Number.isFinite(r)||!n(r))throw new Error(`${e} must be ${i}`);return r}var ye=(t,e)=>Q(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function ti(t){let e=typeof t=="string"?t.split(",").map(Number):[t?.x,t?.y,t?.width,t?.height].map(Number);if(e.length!==4||!e.every(Number.isFinite)||e[2]<=0||e[3]<=0)throw new Error("a region is x,y,width,height in screen points, with width and height above 0");return{x:e[0],y:e[1],width:e[2],height:e[3]}}function kd(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=ye(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=ye(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=ye(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Q(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Q(e.changeThreshold,"changeThreshold",r=>r>=0&&r<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let r={...n.regions??{}};for(let[s,a]of Object.entries(e.regions)){if(!Ma.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);a===null?delete r[s]:r[s]=ti(a)}n.regions=r}if(e.buffer&&typeof e.buffer=="object"){let r=e.buffer,s={...n.buffer??{}};"enabled"in r&&(s.enabled=!!r.enabled),"seconds"in r&&(s.seconds=Q(r.seconds,"buffer.seconds",a=>a>0&&a<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Q(r.fps,"buffer.fps",a=>a>0&&a<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=ye(r.maxPixels,"buffer.maxPixels")),"region"in r&&(s.region=String(r.region).trim()),n.buffer=s}let i=n.buffer?.region;if(i!==void 0&&!ei.includes(i)&&!n.regions?.[i])try{ti(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...ei,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{sn as a,Wa as b,rt as c,to as d,no as e,Rc as f,Ic as g,Ec as h,dr as i,Cc as j,Pc as k,D as l,pr as m,k as n,qa as o,mr as p,Fc as q,Qa as r,Di as s,sl as t,xn as u,x as v,Ka as w,Ja as x,ll as y,oe as z,cl as A,An as B,ml as C,X as D,Cl as E,Dl as F,Cn as G,hr as H,Uc as I,Er as J,bu as K,wu as L,Au as M,ea as N,_u as O,Nl as P,Ll as Q,Ol as R,Ml as S,jl as T,Fl as U,Vl as V,Ul as W,Yl as X,Fe as Y,Zl as Z,Ql as _,G as $,K as aa,oa as ba,Lu as ca,Ou as da,Mu as ea,ju as fa,dt as ga,Fu as ha,Ue as ia,Be as ja,pe as ka,Ss as la,vs as ma,ic as na,He as oa,ze as pa,$s as qa,As as ra,Yn as sa,tr as ta,sc as ua,Is as va,oc as wa,Os as xa,Fs as ya,Xe as za,Vs as Aa,nr as Ba,P as Ca,Vr as Da,Ur as Ea,Br as Fa,Hu as Ga,ma as Ha,Hr as Ia,zr as Ja,nd as Ka,rd as La,Ca as Ma,id as Na,Gr as Oa,fe as Pa,bc as Qa,lr as Ra,Ge as Sa,tt as Ta,Ac as Ua,ld as Va,cd as Wa,ud as Xa,dd as Ya,pd as Za,fd as _a,gd as $a,md as ab,hd as bb,Zr as cb,Qr as db,wd as eb,ei as fb,kd as gb};
|
|
533
|
+
//# sourceMappingURL=chunk-JHAQE46R.js.map
|