agentix-cli 0.143.0 → 0.144.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-UTDCBFZI.js → App-N2U77ED7.js} +2 -2
- package/dist/{ChatApp-7P22XAL2.js → ChatApp-GYVTECF6.js} +2 -2
- package/dist/{absorb-eval-EGO6JJOV.js → absorb-eval-WSAVWCZV.js} +2 -2
- package/dist/{agent-AI6LNZV2.js → agent-SLRGXBMK.js} +2 -2
- package/dist/{board-dashboard-ZKN5Y3GJ.js → board-dashboard-B3T7VCRQ.js} +4 -4
- package/dist/{chunk-SDSSRNSU.js → chunk-2GJFLPS7.js} +3 -3
- package/dist/{chunk-NYWIN4BW.js → chunk-3LAQ74H7.js} +2 -2
- package/dist/{chunk-THWDSPX4.js → chunk-45TKVOJX.js} +2 -2
- package/dist/{chunk-RB5W3FVO.js → chunk-4JHMV3D3.js} +2 -2
- package/dist/{chunk-QSKG754X.js → chunk-5TTHN7DP.js} +12 -8
- package/dist/chunk-5TTHN7DP.js.map +1 -0
- package/dist/{chunk-PYI7ZAU3.js → chunk-BAO77R4L.js} +2 -2
- package/dist/{chunk-YYPTXXCJ.js → chunk-CZWEXRIE.js} +2 -2
- package/dist/{chunk-OMO7UTWW.js → chunk-DFWPTNZ5.js} +2 -2
- package/dist/chunk-DG2DC43E.js +11 -0
- package/dist/chunk-DG2DC43E.js.map +1 -0
- package/dist/chunk-DPIQCHXB.js +62 -0
- package/dist/chunk-DPIQCHXB.js.map +1 -0
- package/dist/{chunk-3WBOWXAN.js → chunk-EX4AREN5.js} +2 -2
- package/dist/{chunk-MFUN3ZS3.js → chunk-GOAMSJ2D.js} +2 -2
- package/dist/{chunk-YVNGPYXN.js → chunk-GWBBWYGM.js} +58 -55
- package/dist/chunk-GWBBWYGM.js.map +1 -0
- package/dist/{chunk-WY5ZOEOE.js → chunk-JGX5IWNX.js} +2 -2
- package/dist/chunk-KV4ZA7FS.js +4 -0
- package/dist/chunk-KV4ZA7FS.js.map +1 -0
- package/dist/{chunk-YXFTUOZR.js → chunk-LLJZMS23.js} +2 -2
- package/dist/{chunk-L4RCA3OC.js → chunk-LVQHNTXV.js} +2 -2
- package/dist/{chunk-UNIXYV3U.js → chunk-M7527M7D.js} +2 -2
- package/dist/{chunk-IABJLTZN.js → chunk-MXWAREAQ.js} +2 -2
- package/dist/{chunk-GB4YT5IG.js → chunk-PJGLIAEP.js} +247 -240
- package/dist/chunk-PJGLIAEP.js.map +1 -0
- package/dist/{chunk-ERG5OUKH.js → chunk-Q73QQPDB.js} +2 -2
- package/dist/{chunk-O2CYERSX.js → chunk-QI4FYJGJ.js} +2 -2
- package/dist/{chunk-HPQ3AAG3.js → chunk-R5VGRKUW.js} +2 -2
- package/dist/{chunk-N2HLL25P.js → chunk-RGBQULXX.js} +2 -2
- package/dist/{chunk-6CTQPGBR.js → chunk-RV4WJZW5.js} +2 -2
- package/dist/{chunk-QVPBSV5Z.js → chunk-SFUNL7RV.js} +2 -2
- package/dist/{chunk-7H6HDN3K.js → chunk-SVNYI6GR.js} +2 -2
- package/dist/{chunk-DKLVB5L6.js → chunk-TTBCXVPJ.js} +6 -6
- package/dist/chunk-TTBCXVPJ.js.map +1 -0
- package/dist/{chunk-XWHD2Z3Z.js → chunk-UII54DAP.js} +2 -2
- package/dist/{chunk-5BXAKMYK.js → chunk-UNZRZOED.js} +2 -2
- package/dist/{chunk-Y4CYQV7G.js → chunk-VY7TBMJU.js} +2 -2
- package/dist/chunk-VY7TBMJU.js.map +1 -0
- package/dist/{chunk-AJUWIBLV.js → chunk-VYLMC5DO.js} +2 -2
- package/dist/{chunk-SHEUCITK.js → chunk-WBG6NA7R.js} +2 -2
- package/dist/{chunk-SHEUCITK.js.map → chunk-WBG6NA7R.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{client-E66ELJK7.js → client-B7FXDTYK.js} +2 -2
- package/dist/config-MLP33NWR.js +2 -0
- package/dist/{config-mutate-QBDKJNHA.js → config-mutate-XQRUAVEH.js} +2 -2
- package/dist/config-mutator-5JFTMQ43.js +2 -0
- package/dist/{contributions-L5XZJ3DP.js → contributions-ESUSYUQG.js} +2 -2
- package/dist/{doctor-3ZUFSE6R.js → doctor-DIYZGSIS.js} +2 -2
- package/dist/{failure-candidates-XZSZP4HT.js → failure-candidates-NQX2JMMS.js} +2 -2
- package/dist/{follow-up-tool-6OCQUSC3.js → follow-up-tool-QXEYEWX7.js} +2 -2
- package/dist/{grants-CEUGZBQ4.js → grants-MM7U6GCK.js} +2 -2
- package/dist/{hub-MOQRSVCQ.js → hub-OC7PH2AR.js} +2 -2
- package/dist/index.d.ts +213 -76
- package/dist/index.js +1 -1
- package/dist/{program-AR6F763U.js → program-LZPM6I2Q.js} +289 -254
- package/dist/program-LZPM6I2Q.js.map +1 -0
- package/dist/{promote-ZGJEPCBE.js → promote-SIC6RWCX.js} +2 -2
- package/dist/{query-JLTHESIZ.js → query-OP2MSR2G.js} +2 -2
- package/dist/{query-settings-GMEL3EKR.js → query-settings-67332F5V.js} +2 -2
- package/dist/{registry-MFD3XJBR.js → registry-G2ZG5TIN.js} +2 -2
- package/dist/{request-planner-4ORFYSAT.js → request-planner-THTPE3FP.js} +2 -2
- package/dist/{review-candidates-77NDFTGM.js → review-candidates-7PS7CHXF.js} +2 -2
- package/dist/{routing-3FL3KYPJ.js → routing-PE7DB7WA.js} +2 -2
- package/dist/schedule-tool-3FXRKJGN.js +2 -0
- package/dist/{scheduler-QLL7ZHYW.js → scheduler-YTXCIQTZ.js} +2 -2
- package/dist/{seat-RBKONP63.js → seat-6DMK4274.js} +2 -2
- package/dist/{select-MOUDR6PQ.js → select-CLDYPAOS.js} +2 -2
- package/dist/{set-enabled-JKYF3QIA.js → set-enabled-ZH2DH4GU.js} +2 -2
- package/dist/tool-4AO3ZMAY.js +6 -0
- package/dist/tool-4AO3ZMAY.js.map +1 -0
- package/dist/{tool-Y3ZTSZGE.js → tool-MKDTKBJ4.js} +3 -3
- package/dist/{tool-Y3ZTSZGE.js.map → tool-MKDTKBJ4.js.map} +1 -1
- package/dist/traces-GVEQZX24.js +2 -0
- package/dist/{wiki-3FSSLQAE.js → wiki-CH2HYJVI.js} +2 -2
- package/dist/wiki-enrich-VEAYFVR2.js +2 -0
- package/dist/wiki-enrich-VEAYFVR2.js.map +1 -0
- package/dist/workflow-pilot-HCPSMGIC.js +2 -0
- package/dist/workflow-pilot-HCPSMGIC.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-3W2BHUGM.js +0 -11
- package/dist/chunk-3W2BHUGM.js.map +0 -1
- package/dist/chunk-AKWBDCMU.js +0 -4
- package/dist/chunk-AKWBDCMU.js.map +0 -1
- package/dist/chunk-DKLVB5L6.js.map +0 -1
- package/dist/chunk-GB4YT5IG.js.map +0 -1
- package/dist/chunk-K22XMF6M.js +0 -62
- package/dist/chunk-K22XMF6M.js.map +0 -1
- package/dist/chunk-QSKG754X.js.map +0 -1
- package/dist/chunk-Y4CYQV7G.js.map +0 -1
- package/dist/chunk-YVNGPYXN.js.map +0 -1
- package/dist/config-3C3Z7VKG.js +0 -2
- package/dist/config-mutator-ZI3SQIUN.js +0 -2
- package/dist/program-AR6F763U.js.map +0 -1
- package/dist/schedule-tool-5KJMXBRZ.js +0 -2
- package/dist/tool-C4JNMTEF.js +0 -6
- package/dist/tool-C4JNMTEF.js.map +0 -1
- package/dist/wiki-enrich-HQWXZRID.js +0 -2
- /package/dist/{App-UTDCBFZI.js.map → App-N2U77ED7.js.map} +0 -0
- /package/dist/{ChatApp-7P22XAL2.js.map → ChatApp-GYVTECF6.js.map} +0 -0
- /package/dist/{absorb-eval-EGO6JJOV.js.map → absorb-eval-WSAVWCZV.js.map} +0 -0
- /package/dist/{agent-AI6LNZV2.js.map → agent-SLRGXBMK.js.map} +0 -0
- /package/dist/{board-dashboard-ZKN5Y3GJ.js.map → board-dashboard-B3T7VCRQ.js.map} +0 -0
- /package/dist/{chunk-SDSSRNSU.js.map → chunk-2GJFLPS7.js.map} +0 -0
- /package/dist/{chunk-NYWIN4BW.js.map → chunk-3LAQ74H7.js.map} +0 -0
- /package/dist/{chunk-THWDSPX4.js.map → chunk-45TKVOJX.js.map} +0 -0
- /package/dist/{chunk-RB5W3FVO.js.map → chunk-4JHMV3D3.js.map} +0 -0
- /package/dist/{chunk-PYI7ZAU3.js.map → chunk-BAO77R4L.js.map} +0 -0
- /package/dist/{chunk-YYPTXXCJ.js.map → chunk-CZWEXRIE.js.map} +0 -0
- /package/dist/{chunk-OMO7UTWW.js.map → chunk-DFWPTNZ5.js.map} +0 -0
- /package/dist/{chunk-3WBOWXAN.js.map → chunk-EX4AREN5.js.map} +0 -0
- /package/dist/{chunk-MFUN3ZS3.js.map → chunk-GOAMSJ2D.js.map} +0 -0
- /package/dist/{chunk-WY5ZOEOE.js.map → chunk-JGX5IWNX.js.map} +0 -0
- /package/dist/{chunk-YXFTUOZR.js.map → chunk-LLJZMS23.js.map} +0 -0
- /package/dist/{chunk-L4RCA3OC.js.map → chunk-LVQHNTXV.js.map} +0 -0
- /package/dist/{chunk-UNIXYV3U.js.map → chunk-M7527M7D.js.map} +0 -0
- /package/dist/{chunk-IABJLTZN.js.map → chunk-MXWAREAQ.js.map} +0 -0
- /package/dist/{chunk-ERG5OUKH.js.map → chunk-Q73QQPDB.js.map} +0 -0
- /package/dist/{chunk-O2CYERSX.js.map → chunk-QI4FYJGJ.js.map} +0 -0
- /package/dist/{chunk-HPQ3AAG3.js.map → chunk-R5VGRKUW.js.map} +0 -0
- /package/dist/{chunk-N2HLL25P.js.map → chunk-RGBQULXX.js.map} +0 -0
- /package/dist/{chunk-6CTQPGBR.js.map → chunk-RV4WJZW5.js.map} +0 -0
- /package/dist/{chunk-QVPBSV5Z.js.map → chunk-SFUNL7RV.js.map} +0 -0
- /package/dist/{chunk-7H6HDN3K.js.map → chunk-SVNYI6GR.js.map} +0 -0
- /package/dist/{chunk-XWHD2Z3Z.js.map → chunk-UII54DAP.js.map} +0 -0
- /package/dist/{chunk-5BXAKMYK.js.map → chunk-UNZRZOED.js.map} +0 -0
- /package/dist/{chunk-AJUWIBLV.js.map → chunk-VYLMC5DO.js.map} +0 -0
- /package/dist/{client-E66ELJK7.js.map → client-B7FXDTYK.js.map} +0 -0
- /package/dist/{config-3C3Z7VKG.js.map → config-MLP33NWR.js.map} +0 -0
- /package/dist/{config-mutate-QBDKJNHA.js.map → config-mutate-XQRUAVEH.js.map} +0 -0
- /package/dist/{config-mutator-ZI3SQIUN.js.map → config-mutator-5JFTMQ43.js.map} +0 -0
- /package/dist/{contributions-L5XZJ3DP.js.map → contributions-ESUSYUQG.js.map} +0 -0
- /package/dist/{doctor-3ZUFSE6R.js.map → doctor-DIYZGSIS.js.map} +0 -0
- /package/dist/{failure-candidates-XZSZP4HT.js.map → failure-candidates-NQX2JMMS.js.map} +0 -0
- /package/dist/{follow-up-tool-6OCQUSC3.js.map → follow-up-tool-QXEYEWX7.js.map} +0 -0
- /package/dist/{grants-CEUGZBQ4.js.map → grants-MM7U6GCK.js.map} +0 -0
- /package/dist/{hub-MOQRSVCQ.js.map → hub-OC7PH2AR.js.map} +0 -0
- /package/dist/{promote-ZGJEPCBE.js.map → promote-SIC6RWCX.js.map} +0 -0
- /package/dist/{query-JLTHESIZ.js.map → query-OP2MSR2G.js.map} +0 -0
- /package/dist/{query-settings-GMEL3EKR.js.map → query-settings-67332F5V.js.map} +0 -0
- /package/dist/{registry-MFD3XJBR.js.map → registry-G2ZG5TIN.js.map} +0 -0
- /package/dist/{request-planner-4ORFYSAT.js.map → request-planner-THTPE3FP.js.map} +0 -0
- /package/dist/{review-candidates-77NDFTGM.js.map → review-candidates-7PS7CHXF.js.map} +0 -0
- /package/dist/{routing-3FL3KYPJ.js.map → routing-PE7DB7WA.js.map} +0 -0
- /package/dist/{schedule-tool-5KJMXBRZ.js.map → schedule-tool-3FXRKJGN.js.map} +0 -0
- /package/dist/{scheduler-QLL7ZHYW.js.map → scheduler-YTXCIQTZ.js.map} +0 -0
- /package/dist/{seat-RBKONP63.js.map → seat-6DMK4274.js.map} +0 -0
- /package/dist/{select-MOUDR6PQ.js.map → select-CLDYPAOS.js.map} +0 -0
- /package/dist/{set-enabled-JKYF3QIA.js.map → set-enabled-ZH2DH4GU.js.map} +0 -0
- /package/dist/{wiki-3FSSLQAE.js.map → traces-GVEQZX24.js.map} +0 -0
- /package/dist/{wiki-enrich-HQWXZRID.js.map → wiki-CH2HYJVI.js.map} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as Ie}from"./chunk-GTJIKXDB.js";import{q 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 o=n.length-1;o>=0;o--){let a=JSON.parse(n[o]),l=a.status??a.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
|
|
5
|
-
`,{mode:384})
|
|
1
|
+
import{a as Ie}from"./chunk-GTJIKXDB.js";import{q as sn}from"./chunk-S2GAEH2F.js";import{a as w}from"./chunk-7LN4VKDU.js";import{a as re}from"./chunk-IMLAPB7G.js";import{e as an,g as ln,i as cn,j as _e,l as q,m as W,o as un}from"./chunk-KV4ZA7FS.js";import{t as nn,u as rn}from"./chunk-RGBQULXX.js";import{d as en,e as tn}from"./chunk-AQASR6KR.js";import{b as on}from"./chunk-YMX3QCV7.js";import{a as Yt,b as Zt,d as Qt}from"./chunk-VY7TBMJU.js";import{a as Bt,b as Ht}from"./chunk-WBG6NA7R.js";import{g as zt,h as Xt,i as Gt,k as Kt,l as Jt}from"./chunk-JGX5IWNX.js";import{X as qt,Z as ne,_ as Ae,aa as Re,b as $e}from"./chunk-45TKVOJX.js";import{q as Vt}from"./chunk-3LAQ74H7.js";import{a as Ft,b as Ut}from"./chunk-SFUNL7RV.js";import{Ba as ve,I as Tt,J as Ct,Ja as Mt,K as Dt,Ka as Wt,L as Pt,P as te,Q as Lt,R as Nt,S as Ot,Sa as jt,T as xe,n as ee,o as It,p as Et,q as ci}from"./chunk-DPIQCHXB.js";import{a as ke,h as ui}from"./chunk-BRK6M6LA.js";import{f as Se,n as di}from"./chunk-UIBUZ2N3.js";import{existsSync as pi,readdirSync as gi,readFileSync as fi,statSync as mi}from"fs";import{resolve as hi}from"path";function dn(t,e,n=Date.now(),i=7){let r=i*864e5,s=new Map;for(let o of e){let a=s.get(o.workflowId);a?a.push(o):s.set(o.workflowId,[o])}return t.map(o=>{let a=s.get(o.id)??[],l=a.filter(f=>n-f.at<=r),c=a.filter(f=>n-f.at>r&&n-f.at<=r*2),u=l.filter(f=>f.status==="failed").length,d=a.filter(f=>f.status==="paused").length,p=a.length?Math.max(...a.map(f=>f.at)):null,g=a.length?c.length>0&&l.length===0?"dormant":l.length>0&&u*2>=l.length?"failing":l.length>0?"active":"quiet":"never";return{id:o.id,name:o.name||o.id,state:g,lastRunAt:p,recent:l.length,prior:c.length,failed:u,paused:d}}).sort((o,a)=>{let l={dormant:0,failing:1,active:2,quiet:3,never:4};return l[o.state]-l[a.state]||(a.lastRunAt??0)-(o.lastRunAt??0)})}var ie=new Map;function el(t,e=1e3){if(!pi(t))return[];let n=gi(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let o=hi(t,s);return{path:o,mtime:mi(o).mtimeMs}}).sort((s,o)=>o.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of ie.keys())i.has(s)||ie.delete(s);let r=[];for(let{path:s,mtime:o}of n){let a=ie.get(s);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let l=yi(s,o);ie.set(s,{mtime:o,summary:l}),l&&r.push(l)}return r}function yi(t,e){try{let n=fi(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 o=n.length-1;o>=0;o--){let a=JSON.parse(n[o]),l=a.status??a.run?.status;if(l){s=l;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var bi={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},wi=(t,e,n)=>{try{return Vt(t,e,n)}catch{return null}},pn=864e5;function il(t){let e=t.now??Date.now(),n={...bi,...t.thresholds},i=t.nextFire??wi,r=[];for(let a of t.crons){let l=t.cronRuns.get(a.id)??[],c=a.timezone||"UTC",u=l.map(g=>({at:Date.parse(g.startedAt),status:g.status})),d=l[0],p={id:`cron:${a.id}`,source:"cron",kind:"schedule",name:A(a.id,k.text),trigger:{schedule:A(a.schedule,k.text),timezone:c},agent:a.agent||null,enabled:a.enabled,state:a.enabled?"enabled":"disabled",nextRunAt:a.enabled?Ee(a.nextRun)??Ee(i(a.schedule,new Date(e),c)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:Ai(d.status==="success"?void 0:d.errorSummary,k.summary)}:null,lastSuccessAt:l.find(g=>g.status==="success")?.startedAt??null,consecutiveFailures:gn(u),sampledRuns:l.length,flags:[],attention:null};p.flags=fn(p,u,a.schedule,c,null,e,n,i),r.push(mn(p))}let s=new Map(dn(t.workflows.map(a=>({id:a.id,name:a.title})),t.workflowRuns,e).map(a=>[a.id,a])),o=new Map;for(let a of t.workflowRuns){let l=o.get(a.workflowId);l?l.push(a):o.set(a.workflowId,[a])}for(let a of t.workflows){let l=a.nodes.find(I=>I.type.startsWith("trigger."));if(!l||l.type!=="trigger.cron"&&l.type!=="trigger.hook")continue;let c=l.config??{},u=a.state||"active",d=u==="active",p=(o.get(a.id)??[]).slice().sort((I,we)=>we.at-I.at),g=p.map(I=>({at:I.at,status:xi(I.status)})),f=g[0],h=l.type==="trigger.cron",y=typeof c.spec=="string"?c.spec:"",C=typeof c.timezone=="string"?c.timezone:"UTC",M={id:`workflow:${a.id}`,source:"workflow",kind:h?"schedule":"event",name:A(a.title||a.id,k.text),trigger:h?{schedule:A(y,k.text),timezone:C}:{event:A(typeof c.event=="string"?c.event:"",k.text),filters:$i(c.filter,a)},agent:vi(a),enabled:d,state:u,nextRunAt:h&&d&&y?Ee(i(y,new Date(e),C)):null,lastRun:f?{at:new Date(f.at).toISOString(),status:f.status}:null,lastSuccessAt:(()=>{let I=g.find(we=>we.status==="success");return I?new Date(I.at).toISOString():null})(),consecutiveFailures:gn(g),sampledRuns:p.length,flags:[],attention:null},Q=Date.parse(a.updated||a.created||"");M.flags=h?fn(M,g,y,C,Number.isFinite(Q)?Q:null,e,n,i):ki(M,s.get(a.id)?.state==="dormant",Number.isFinite(Q)?Q:null,e,n),r.push(mn(M))}return r.sort(Si).slice(0,k.routines)}function gn(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 fn(t,e,n,i,r,s,o,a){let l=[],c=e.length?e[0].at:null;if(!t.enabled){let p=yn(c,r,s,o);return p&&l.push(p),l}if(t.consecutiveFailures>=o.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<o.missedFires&&(d=a(n,u,i),!!d);p++)u=d;return d&&s>d.getTime()+o.graceMs&&l.push({reason:"overdue",detail:`No attempt since ${new Date(c).toISOString()}; ${o.missedFires} scheduled fires missed`}),l}function ki(t,e,n,i,r){let s=[],o=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let a=yn(o,n,i,r);return a&&s.push(a),s}return t.consecutiveFailures>=r.failStreak&&s.push({reason:"failing",detail:`${t.consecutiveFailures} failed runs in a row`}),o===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 yn(t,e,n,i){let r=Math.max(t??0,e??0);return r&&n-r<i.disabledDays*pn?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/pn)} days`:"Disabled and never ran"}}function mn(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 hn={critical:0,warning:1,info:2};function Si(t,e){let n=t.attention?hn[t.attention]:3,i=e.attention?hn[e.attention]:3;return n-i||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function xi(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 vi(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 $i(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 o=Array.isArray(s)?s.map(String):s==null?[]:[String(s)];o.length&&n.push(A(`${r}=${o.join(",")}`,k.filterValue))}return n.slice(0,k.filters)}function Ee(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 Ai(t,e){return t===void 0?void 0:A(t,e)}import{mkdirSync as Ri,readFileSync as _i,renameSync as Ii,writeFileSync as Ei}from"fs";import{resolve as Ti}from"path";function bn(t){return Ti(_e(t),"_state.json")}function x(t){try{let e=JSON.parse(_i(bn(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 B(t,e){Ri(_e(t),{recursive:!0});let n=bn(t),i=`${n}.${process.pid}.tmp`;Ei(i,JSON.stringify(e,null,2)+`
|
|
3
|
+
`),Ii(i,n)}function wn(t,e,n,i=Date.now()){let r=x(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),B(t,{...r,snoozed:s})}function cl(t,e){B(t,{...x(t),lastDigest:e})}function Te(t,e,n,i=Date.now()){let r=x(t),s=new Set(n),o={};for(let[l,c]of Object.entries(r.popped??{}))s.has(l)&&(o[l]=c);o[e]=new Date(i).toISOString();let a=(r.wanted??[]).filter(l=>l!==e&&s.has(l));B(t,{...r,popped:o,wanted:a})}function kn(t,e){let n=x(t);B(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function ul(t,e=Date.now()){B(t,{...x(t),popped:{},passAt:new Date(e).toISOString()})}import{existsSync as H,readdirSync as zi,readFileSync as Xi}from"fs";import{resolve as R}from"path";import{randomBytes as vn}from"crypto";import{existsSync as Di,mkdirSync as Pi,readdirSync as Li,readFileSync as Ni,renameSync as $n,unlinkSync as Oi,writeFileSync as Mi}from"fs";import{resolve as An}from"path";function Sn(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var Ci=t=>t.trim().split(`
|
|
4
|
+
`).pop()?.slice(0,300)||"no output";async function xn(t,e,n,i=Ie){let r=await i(t.bin,[...Sn(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${Ci(r.stderr||r.stdout)}`}}async function gl(t,e,n,i,r=Ie){return(await r(t.bin,[...Sn(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var Wi=2e3,ji=t=>xn(t.wacli,t.to,t.text);function Ce(t){return An(t,".agentx","whatsapp-triage","drafts")}var Fi=t=>/^[a-z0-9-]{8,64}$/.test(t),se=(t,e)=>An(Ce(t),`${e}.json`);function Rn(t,e){Pi(Ce(t),{recursive:!0});let n=se(t,e.id),i=`${n}.${process.pid}.tmp`;Mi(i,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{mode:384}),$n(i,n)}function wl(t,e,n=Date.now()){let i=e.text.trim().slice(0,Wi);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${vn(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return Rn(t,r),r}function oe(t,e){if(!Fi(e))return null;try{return JSON.parse(Ni(se(t,e),"utf-8"))}catch{return null}}function _n(t,e){let n=Ce(t);return Di(n)?Li(n).filter(i=>i.endsWith(".json")).map(i=>oe(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function In(t,e,n,i={}){let r=oe(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${se(t,e)}.${process.pid}.${vn(3).toString("hex")}.claim`;try{$n(se(t,e),s)}catch{return{ok:!1,error:`reply draft "${e}" is already being decided`}}let o={...r,decided_by:i.by??"operator",decided_at:new Date(i.now??Date.now()).toISOString()};if(n==="no")o.status="rejected";else{let a=await(i.send??ji)(r).catch(l=>({ok:!1,error:String(l?.message??l)}));a.ok?o.status="sent":(o.status="failed",o.error=a.error)}Rn(t,o);try{Oi(s)}catch{}return o.status==="failed"?{ok:!1,error:o.error??"send failed"}:{ok:!0,draft:o}}di();xe();xe();var xl=["done","skipped"],Ui=1e3;function Vi(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 Ie}from"./chunk-GTJIKXDB.js";import{q as nn}from"./chunk-S2GAEH2F.js
|
|
|
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
|
|
53
|
+
`)}function Tn(t){return!!t.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'request_plans'").get()}function De(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 En(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 qi={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"},ae=class{constructor(e){this.db=e;Vi(e)}create(e,n,i,r){let s=this.db.prepare("INSERT INTO request_plans (request_id, created_by, created_at, state) VALUES (?, ?, ?, 'active')"),o=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((a,l)=>{let c=l===0,u=c&&a.agentId===n&&a.kind!=="message";o.run(e,l+1,a.name,a.kind,a.agentId,a.doneWhen,c?"active":"pending",a.needsApproval?1:0,a.message??null,a.toChannel??null,a.toChat??null,a.toAccount??null,a.checkUrl??null,a.checkContains??null,a.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(Rn)}step(e,n){let i=this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? AND idx = ?").get(e,n);return i?Rn(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[o,a]of Object.entries(i)){let l=Wi[o];!l||a===void 0||(r.push(`${l} = ?`),s.push(typeof a=="boolean"?a?1:0:a))}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,Oi))}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}))}},ul=Dt;import{existsSync as ji,readFileSync as Ui}from"fs";Mt();si();function In(t){let e=Wt(t),n={};if(ji(e))try{n=Nt(JSON.parse(Ui(e,"utf-8")))}catch{n={}}let i=ve.safeParse(n?.requests);return i.success?i.data:ve.parse(void 0)}async function hl(t,e={}){let n=(t.channels??[]).filter(i=>!ke.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...ke].join(", ")}`}:jt(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 o of["enabled","stallMinutes","maxNudges","approveKinds","disabledAgents"])t.plans[o]!==void 0&&(s[o]=t.plans[o])}if(t.checkers){let s=r.checkers??={};for(let o of["enabled","checkEveryMinutes"])t.checkers[o]!==void 0&&(s[o]=t.checkers[o])}},{configPath:e.configPath,reload:e.reload})}var Cn=["card","schedule","memory","wiki","whatsapp","request"],qi=280;function L(t,e=qi){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 R(t.configPath);let e=[R(t.root,"agentx.json"),R(t.root,".agentx","config.json")];return e.find(n=>H(n))??e[0]}function Pe(t){return t.wikiDir?R(t.wikiDir):R(t.root,".agentx","wiki")}function Bi(t){return q(t.root,"pending").map(Hi)}function Hi(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:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function zi(t){let e=De(t);if(!H(e))return[];let n;try{n=JSON.parse(Vi(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,o]of Object.entries(n?.crons??{})){let a=o?.approval;if(!a||a.action!=="create"&&a.action!=="delete")continue;let l=o.timezone||"UTC",c=o.schedule?Bt(o.schedule):"",u=o.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${o.schedule})`:"no schedule",d=String(o.prompt??o.command??""),p=a.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${o.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${o.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(a.requestedBy??"unknown"),created_at:String(a.requestedAt??""),detail:L(`${d}${p&&o.schedule?` \xB7 first run ${zt(Ht(o.schedule,l,i),l)}`:""}`),more:"agentx schedule list"})}return r}function Dn(t){let e=R(t,".agentx","memory");return H(e)?Fi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Xi(t){let e=Dn(t.root);if(e.length===0)return[];let n=new $e(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:L(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Gi(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 Ki(t){return Qt(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:L(`${Gi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Ji(t){return $n(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:L(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function z(t){if(t.requests)return t.requests;if(R(t.root)!==process.cwd()||!H(R(t.root,".agentx","db.sqlite")))return null;let e=Se({quiet:!0});if(!e)return null;let n=En.get(e);return!n&&!Pt(e)?null:(n||En.set(e,n=new Lt(e)),n)}var En=new WeakMap;function Cl(t){if(t.plans)return t.plans;if(t.requests||R(t.root)!==process.cwd()||!H(R(t.root,".agentx","db.sqlite")))return null;let e=Se({quiet:!0});if(!e||!_n(e))return null;let n=Tn.get(e);return n||Tn.set(e,n=new ae(e)),n}var Tn=new WeakMap;function Yi(t){let e=z(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${L(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:L(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var Pn={card:Bi,schedule:zi,memory:Xi,wiki:Ki,whatsapp:Ji,request:Yi};function Zi(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}=A(t.root),r=[],s=[],o=0;for(let a of e.kinds??Cn){let l;try{l=Pn[a](t)}catch(c){s.push({kind:a,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){o++;continue}c.snoozed_until=u}r.push(c)}}return r.sort(Zi),{items:r,snoozed:o,errors:s}}function Qi(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!Cn.includes(n)||!i?null:{kind:n,ref:i}}function es(t,e,n){switch(e){case"card":return V(t.root,n)?.status==="pending";case"wiki":return Zt(Pe(t),n)?.status==="pending";case"whatsapp":return oe(t.root,n)?.status==="pending";default:return Pn[e](t).some(i=>i.key===`${e}:${n}`)}}async function Ln(t,e,n,i={}){let r=Qi(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:o}=r,a=t.now??Date.now(),l=i.by??"operator";if(n==="later"){if(!es(t,s,o))return{ok:!1,error:`nothing waiting for "${e}"`};let u=i.laterHours&&i.laterHours>0?i.laterHours:24,d=new Date(a+u*36e5);return mn(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let c=n==="yes";switch(s){case"card":{let u=on(t.root,o,c?"yes":"no",{by:l,note:i.note,now:a,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}case"schedule":{let u=await(c?Xt:Gt)(o,{configPath:De(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=o.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=o.slice(0,u),p=o.slice(u+1);if(!Dn(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let g=new $e(t.root);return g.held(d).some(f=>f.id===p)?(g.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?en(u,o,{by:l,force:i.force,now:a}):tn(u,o,{by:l,reason:i.note,now:a});return d.ok?{ok:!0,message:c?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await An(t.root,o,c?"yes":"no",{by:l,now:a,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(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:c?In(De(t)).enabled?(u.requestPickup(o,a),{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(o,"dropped",i.note?.trim()||`dropped by ${l}`,a),{ok:!0,message:`${e}: dropped`})}}}var Nn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Ll(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||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 Nl(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 Nn.has(t)}function Ml(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Nn.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 Wl(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 jl(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 le(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function ts(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function ns(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Fl(t,e=ns()){let n=le(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=ts(n),s=[le(t.host),le(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=le(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Vl(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as or,mkdirSync as Cs,readFileSync as Ds,renameSync as Ps,writeFileSync as Ls}from"fs";import{homedir as Ns}from"os";import{dirname as Os,join as Ms}from"path";import{execFile as gs,execFileSync as fs}from"child_process";import{execFileSync as rs}from"child_process";import{existsSync as Mn,mkdirSync as is,readdirSync as ss,readFileSync as Wn,renameSync as os,writeFileSync as as}from"fs";import{homedir as jn}from"os";import{join as Ne}from"path";var x="siri:",Un="com.apple.ttsbundle.gryphon-neural_",Fn=t=>!!t&&t.startsWith(Un),ls=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],cs=()=>{try{return rs("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Le;function Oe(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Le!==void 0)return Le;let{platform:n=process.platform,exists:i=Mn,prefDomain:r=cs}=t,s=n==="darwin"&&ls.every(o=>i(o))&&r();return e||(Le=s),s}var Vn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],qn={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=>qn[t.toLowerCase()]??null;function ce(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 us=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function ds(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(us)){let o=`${i}-${r}`,a=`${Un}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:qn[s]??null,siri:!0})}return[...e.values()]}function ue(t=Vn,e={}){if(!Oe(e))return[];let n=[];for(let i of t){let r;try{r=ss(i)}catch{continue}for(let s of r)try{n.push(Wn(Ne(i,s,"Info.plist"),"latin1"))}catch{}}return ds(n)}var On=`#!/bin/sh
|
|
55
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`);this.db.transaction(()=>{s.run(e,n,r),i.forEach((a,l)=>{let c=l===0,u=c&&a.agentId===n&&a.kind!=="message";o.run(e,l+1,a.name,a.kind,a.agentId,a.doneWhen,c?"active":"pending",a.needsApproval?1:0,a.message??null,a.toChannel??null,a.toChat??null,a.toAccount??null,a.checkUrl??null,a.checkContains??null,a.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?De(n):null}steps(e){return this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? ORDER BY idx").all(e).map(En)}step(e,n){let i=this.db.prepare("SELECT * FROM request_plan_steps WHERE request_id = ? AND idx = ?").get(e,n);return i?En(i):null}listActive(){return this.db.prepare("SELECT * FROM request_plans WHERE state = 'active' ORDER BY created_at, rowid").all().map(De)}updateStep(e,n,i){let r=[],s=[];for(let[o,a]of Object.entries(i)){let l=qi[o];!l||a===void 0||(r.push(`${l} = ?`),s.push(typeof a=="boolean"?a?1:0:a))}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(De)}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,Ui))}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}))}},vl=Lt;import{existsSync as Bi,readFileSync as Hi}from"fs";jt();ui();function Cn(t){let e=Ft(t),n={};if(Bi(e))try{n=Mt(JSON.parse(Hi(e,"utf-8")))}catch{n={}}let i=ve.safeParse(n?.requests);return i.success?i.data:ve.parse(void 0)}async function El(t,e={}){let n=(t.channels??[]).filter(i=>!ke.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...ke].join(", ")}`}:Ut(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 o of["enabled","stallMinutes","maxNudges","approveKinds","disabledAgents"])t.plans[o]!==void 0&&(s[o]=t.plans[o])}if(t.checkers){let s=r.checkers??={};for(let o of["enabled","checkEveryMinutes"])t.checkers[o]!==void 0&&(s[o]=t.checkers[o])}},{configPath:e.configPath,reload:e.reload})}var Ln=["card","schedule","memory","wiki","whatsapp","request"],Gi=280;function L(t,e=Gi){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Pe(t){if(t.configPath)return R(t.configPath);let e=[R(t.root,"agentx.json"),R(t.root,".agentx","config.json")];return e.find(n=>H(n))??e[0]}function Le(t){return t.wikiDir?R(t.wikiDir):R(t.root,".agentx","wiki")}function Ki(t){return W(t.root,"pending").map(Ji)}function Ji(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:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Yi(t){let e=Pe(t);if(!H(e))return[];let n;try{n=JSON.parse(Xi(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,o]of Object.entries(n?.crons??{})){let a=o?.approval;if(!a||a.action!=="create"&&a.action!=="delete")continue;let l=o.timezone||"UTC",c=o.schedule?zt(o.schedule):"",u=o.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${o.schedule})`:"no schedule",d=String(o.prompt??o.command??""),p=a.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${o.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${o.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(a.requestedBy??"unknown"),created_at:String(a.requestedAt??""),detail:L(`${d}${p&&o.schedule?` \xB7 first run ${Gt(Xt(o.schedule,l,i),l)}`:""}`),more:"agentx schedule list"})}return r}function Nn(t){let e=R(t,".agentx","memory");return H(e)?zi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Zi(t){let e=Nn(t.root);if(e.length===0)return[];let n=new $e(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:L(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Qi(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 es(t){return tn(Le(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:L(`${Qi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function ts(t){return _n(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:L(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function z(t){if(t.requests)return t.requests;if(R(t.root)!==process.cwd()||!H(R(t.root,".agentx","db.sqlite")))return null;let e=Se({quiet:!0});if(!e)return null;let n=Dn.get(e);return!n&&!Nt(e)?null:(n||Dn.set(e,n=new Ot(e)),n)}var Dn=new WeakMap;function Bl(t){if(t.plans)return t.plans;if(t.requests||R(t.root)!==process.cwd()||!H(R(t.root,".agentx","db.sqlite")))return null;let e=Se({quiet:!0});if(!e||!Tn(e))return null;let n=Pn.get(e);return n||Pn.set(e,n=new ae(e)),n}var Pn=new WeakMap;function ns(t){let e=z(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${L(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:L(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var On={card:Ki,schedule:Yi,memory:Zi,wiki:es,whatsapp:ts,request:ns};function rs(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 Hl(t,e={}){let n=t.now??Date.now(),{snoozed:i}=x(t.root),r=[],s=[],o=0;for(let a of e.kinds??Ln){let l;try{l=On[a](t)}catch(c){s.push({kind:a,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){o++;continue}c.snoozed_until=u}r.push(c)}}return r.sort(rs),{items:r,snoozed:o,errors:s}}function is(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!Ln.includes(n)||!i?null:{kind:n,ref:i}}function ss(t,e,n){switch(e){case"card":return q(t.root,n)?.status==="pending";case"wiki":return en(Le(t),n)?.status==="pending";case"whatsapp":return oe(t.root,n)?.status==="pending";default:return On[e](t).some(i=>i.key===`${e}:${n}`)}}async function Mn(t,e,n,i={}){let r=is(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:o}=r,a=t.now??Date.now(),l=i.by??"operator";if(n==="later"){if(!ss(t,s,o))return{ok:!1,error:`nothing waiting for "${e}"`};let u=i.laterHours&&i.laterHours>0?i.laterHours:24,d=new Date(a+u*36e5);return wn(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let c=n==="yes";switch(s){case"card":{let u=un(t.root,o,c?"yes":"no",{by:l,note:i.note,now:a,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}case"schedule":{let u=await(c?Kt:Jt)(o,{configPath:Pe(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=o.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=o.slice(0,u),p=o.slice(u+1);if(!Nn(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let g=new $e(t.root);return g.held(d).some(f=>f.id===p)?(g.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=Le(t),d=c?nn(u,o,{by:l,force:i.force,now:a}):rn(u,o,{by:l,reason:i.note,now:a});return d.ok?{ok:!0,message:c?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await In(t.root,o,c?"yes":"no",{by:l,now:a,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(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:c?Cn(Pe(t)).enabled?(u.requestPickup(o,a),{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(o,"dropped",i.note?.trim()||`dropped by ${l}`,a),{ok:!0,message:`${e}: dropped`})}}}var Wn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Xl(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||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 Gl(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 Kl(t){return Wn.has(t)}function Jl(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Wn.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 Yl(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 Zl(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 le(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function os(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function as(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function ec(t,e=as()){let n=le(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=os(n),s=[le(t.host),le(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=le(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function tc(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as cr,mkdirSync as Os,readFileSync as Ms,renameSync as Ws,writeFileSync as js}from"fs";import{homedir as Fs}from"os";import{dirname as Us,join as Vs}from"path";import{execFile as bs,execFileSync as ws}from"child_process";import{execFileSync as ls}from"child_process";import{existsSync as Fn,mkdirSync as cs,readdirSync as us,readFileSync as Un,renameSync as ds,writeFileSync as ps}from"fs";import{homedir as Vn}from"os";import{join as Oe}from"path";var v="siri:",qn="com.apple.ttsbundle.gryphon-neural_",Bn=t=>!!t&&t.startsWith(qn),gs=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],fs=()=>{try{return ls("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ne;function Me(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=Fn,prefDomain:r=fs}=t,s=n==="darwin"&&gs.every(o=>i(o))&&r();return e||(Ne=s),s}var Hn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],zn={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"},We=t=>zn[t.toLowerCase()]??null;function ce(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 ms=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function hs(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(ms)){let o=`${i}-${r}`,a=`${qn}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:zn[s]??null,siri:!0})}return[...e.values()]}function ue(t=Hn,e={}){if(!Me(e))return[];let n=[];for(let i of t){let r;try{r=us(i)}catch{continue}for(let s of r)try{n.push(Un(Oe(i,s,"Info.plist"),"latin1"))}catch{}}return hs(n)}var jn=`#!/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
|
|
@@ -64,7 +64,7 @@ D=com.apple.Accessibility K=SpokenContentDefaultVoiceSelectionsByLanguage
|
|
|
64
64
|
dir="$HOME/.agentx/voice" lock="$HOME/.agentx/voice/siri.lock" saved="$HOME/.agentx/voice/siri-saved.plist"
|
|
65
65
|
stops="$dir/stop"
|
|
66
66
|
read_s=\${AGENTX_SAY_READ_S:-5} stale_s=\${AGENTX_SAY_STALE_S:-30} max_s=\${AGENTX_SAY_MAX_S:-300}
|
|
67
|
-
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${
|
|
67
|
+
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${Hn.join(" ")}"}
|
|
68
68
|
if [ "$1" = --stop ]; then
|
|
69
69
|
mkdir -p "$dir" || exit 1
|
|
70
70
|
# Queued lines see this change and drop. The owner's trap stops say,
|
|
@@ -157,32 +157,33 @@ wait "$say_pid"
|
|
|
157
157
|
status=$?
|
|
158
158
|
say_pid=
|
|
159
159
|
finish $status
|
|
160
|
-
`,
|
|
160
|
+
`,ys=(t=Vn())=>Oe(t,".agentx","voice","siri-say.sh");function Xn(t=Vn()){let e=ys(t);return Fn(e)&&Un(e,"utf8")===jn||(cs(Oe(t,".agentx","voice"),{recursive:!0}),ps(`${e}.tmp`,jn,{mode:493}),ds(`${e}.tmp`,e)),e}var Gn=`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,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!
|
|
168
|
-
`)[0]}`),
|
|
169
|
-
`),de=new Set;function
|
|
170
|
-
${
|
|
166
|
+
out.join("\\n")`,ks=new Set(["Fred","Kathy","Ralph","Junior"]),Ss={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 Kn(t){let e=[];for(let n of t.split(`
|
|
167
|
+
`)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!ks.has(r)||e.push({id:i,name:r,locale:s,quality:o==="3"?"premium":o==="2"?"enhanced":"standard",gender:a==="1"?"male":a==="2"?"female":Ss[r]??null})}return e}var xs=10*60*1e3,uc=60*1e3,j=null,je=!1;function Fe(t=Date.now(),e=xs){if(process.platform!=="darwin")return[];if(j)t-j.at>e&&!je&&(je=!0,bs("osascript",["-l","JavaScript","-e",Gn],{timeout:1e4},(n,i)=>{je=!1,n||(j={at:Date.now(),voices:[...Kn(String(i)),...ue()]})}));else try{j={at:t,voices:[...Kn(ws("osascript",["-l","JavaScript","-e",Gn],{encoding:"utf8",timeout:1e4})),...ue()]}}catch(n){Ue(`[voice] could not list system voices: ${String(n?.message??n).split(`
|
|
168
|
+
`)[0]}`),j={at:t,voices:ue()}}return j.voices}var Ue=t=>process.stderr.write(t+`
|
|
169
|
+
`),de=new Set;function dc(t){Ue=t}function N(t,e){de.has(t)||(de.add(t),Ue(e))}function Zn(t){for(let e of de)t(e)&&de.delete(e)}var Qn=()=>{};function pc(t){Qn=t}function er(t){try{Qn(t)}catch(e){N("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var vs={premium:3,enhanced:2,standard:1},$s=new Set(["Grandma","Grandpa"]);function Jn(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!$s.has(t.name)?1:0;return vs[t.quality]*10+e}var F=t=>t.toLowerCase().split(/[-_]/)[0],Yn=t=>t.id.startsWith("com.apple.voice.");function Ve(t,e,n,i=new Set){let r=X(t.filter(a=>!a.siri&&F(a.locale)===F(e)),e);if(r.some(Yn)&&(r=r.filter(Yn)),n==="female"||n==="male"){let a=r.filter(l=>l.gender===n);a.length&&(r=a)}if(!r.length)return null;let s=r.filter(a=>a.quality===r[0].quality),o=new Set([...i].map(a=>a.toLowerCase()));return s.find(a=>!o.has(a.name.toLowerCase()))??s[0]}function X(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=F(e),r=t.filter(s=>F(s.locale)===i);return(r.length?r:t).slice().sort((s,o)=>Jn(o)-Jn(s)||+(o.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(o.name)||s.locale.localeCompare(o.locale))}function G(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=X(e.filter(p=>p.siri&&p.name.toLowerCase()===c),n)[0];if(u||!c)return u??null;let d=G(c,e.filter(p=>F(p.locale)===F(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),o=(s?s[1]:i.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),a=X(e.filter(c=>c.name.toLowerCase()===o),n);return(s?a.find(c=>c.quality===s[2].toLowerCase()):void 0)??a[0]??null}function tr(t,e,n=new Set){let i=new Map;if(!e.length)return i;let r=new Set([...n].map(o=>o.toLowerCase())),s="female";for(let o of t){let a=o.gender==="female"||o.gender==="male",l=a?o.gender:s,c=e.filter(d=>!r.has(d.name.toLowerCase())),u=c.find(d=>d.gender===l)??(a?e.find(d=>d.gender===l):void 0)??c[0]??e[i.size%e.length];i.set(o.id,u),r.add(u.name.toLowerCase()),a||(s=s==="female"?"male":"female")}return i}It();var qe="system",As=t=>t.trim().toLowerCase()===qe,Rs="21m00Tcm4TlvDq8ikWAM";function Be(t,e,n={},i=Fe()){let r=e[t],s=r?.name||t,o=r?.voice,a=ze(e,n,i).get(t)??null,l=Ts(t,o?.system,o?.gender,n,i);return{agentId:t,name:s,provider:o?.provider??n.provider??"system",elevenlabsVoiceId:o?.elevenlabsVoiceId||null,systemVoice:a?.id??null,systemVoiceName:a?ge(a):null,systemByLanguage:l,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||Ds(s,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var ge=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function _s(t,e,n,i){if(!e||!n.length)return null;let r=G(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.`),er(e)),r}function sr(t,e){let n=t.trim();if(n.toLowerCase().startsWith(v))return{locale:e,gender:We(n.slice(v.length).trim())};let i=ce(n);return i?{locale:i.locale,gender:We(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var or=t=>t.toLowerCase().split(/[-_]/)[0],nr=(t,e)=>typeof t=="string"?t:t?.[or(e)];function pe(t,e,n,i){if(e!==void 0)return As(e)?null:_s(t,e,n,i)??void 0}var He=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function Is(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,o=[],a=pe("voice.system",nr(e.system,r),n,r),l=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=nr(u.system,r),p=pe(u.id,d,n,r),g=p!==void 0?p:d!==void 0&&n.length?Es(u,d,r,a,n,l()):a!==void 0&&He(a,u.gender)?a:void 0;g!==void 0?s.set(u.id,g):o.push({id:u.id,gender:u.gender??null})}let c=l();for(let[u,d]of tr(o,X(n.filter(p=>!p.siri),r),c))s.set(u,d);return s}function Es(t,e,n,i,r,s){for(let a of t.fallbacks??[]){let l=pe(`${t.id}.fallbacks`,a,r,n);if(l!==void 0)return l}if(i!==void 0&&He(i,t.gender))return i;let o=sr(e,n);return Ve(r,o.locale,t.gender??o.gender,s)??void 0}function Ts(t,e,n,i,r){if(typeof e=="string")return{};let s={},o=(a,l,c)=>{if(!(!l||typeof l=="string"))for(let[u,d]of Object.entries(l)){let p=pe(`${a}.${u}`,d,r,u);p===void 0&&r.length&&(p=Ve(r,u,n??sr(d,u).gender)??void 0),p!==void 0&&c(p)&&(s[or(u)]=p)}};return o("voice.system",i.system,a=>He(a,n)),o(t,e,()=>!0),s}function yc(t,e){let n=e?ee(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?ge(i):null}}function ze(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 Is(i,e,n)}function Xe(t,e){let n={provider:t.provider,elevenlabs:Cs(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 Cs(t,e){return t||e||process.env.AGENTX_VOICE_ID||Rs}function Ds(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,...o]=r.split(/,\s*/),a=o.join(", ");return a&&s.toLowerCase()===t.toLowerCase()?`Hello, this is ${t}, ${a}.`:!/^an? /i.test(r)&&r.toLowerCase().includes(t.toLowerCase())?`Hello, this is ${r}.`:`Hello, this is ${t}, ${r}.`}var Ps=8*60*60*1e3,Ls=500,rr=class{constructor(e=Ps){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(ir(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=ir(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>Ls&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},ir=(t,e)=>`${t}\0${e}`;function ar(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 bc(t,e,n,i={}){let r=e[t],s=Be(t,e,i),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:Xe(s),persona:o||`You are ${s.name}.`,introLine:ar(s,n)}}var Ns="[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 wc(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`${Ns}
|
|
170
|
+
${ar(r,e.voice.introduce===!0&&!!i)}`}var qs="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",ur=(t=Fs())=>Vs(t,".agentx","voice","health.json");function Bs(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===qe)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 G(i,e,n)!==null}function Hs(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[o,a]of Object.entries(s??{}))n.push({owner:r,name:a,locale:o,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 zs(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:o,perLanguage:a}of Hs(t)){if(Bs(s,e,o))continue;i??=ze(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"&&!a&&(l.speaksWith[r]=c?ge(c):"the OS default voice"),n.set(s,l)}return[...n.values()]}function Ge(t){let e=ce(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 Xs(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${Ge(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
|
-
`),
|
|
174
|
-
`),
|
|
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 o=0;o<s.length;o++){let a=s[o].match(
|
|
179
|
-
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),
|
|
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 a=(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=a[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:a,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 o of r)try{let a=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,l=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,c=await this.api(l);for(let u of c){let d=this.mapIssue(u,o);d.assignee=e,i.push(d)}}catch(a){this.log(`[business] GitLab listOpen failed for ${s} on ${o}: ${a.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),o=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(o,{method:"PUT"})}catch(a){this.log(`[business] claim label update failed: ${a.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let a=Math.max(1,Math.round(n.timeSeconds/60)),l=a>=60?`${Math.floor(a/60)}h${a%60?` ${a%60}m`:""}`:`${a}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${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)}/${o}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(a){this.log(`[business] done label update failed: ${a.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(a){this.log(`[business] blocked label update failed: ${a.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(a){this.log(`[business] report note failed: ${a.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 o=this.projects.length?this.projects:["__ALL__"],a=[];for(let c of o)try{let u=c==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=a;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),o=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${o}/${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(o=>o.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 o;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")o=0;else try{let c=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(o=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${c.message}`)}let a={};n.title!==void 0&&(a.title=n.title),n.description!==void 0&&(a.description=n.description),n.labels!==void 0&&(a.labels=n.labels.join(",")),n.addLabels?.length&&(a.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(a.remove_labels=n.removeLabels.join(",")),s!==void 0&&(a.assignee_ids=s),o!==void 0&&(a.milestone_id=o);let l=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});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 o={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(o.assignee_ids=i),s!==void 0&&(o.milestone_id=s);let a=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(o)});return this.mapIssue(a,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:o}=this.parseId(e),a=o==="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)}/${a}/${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 a of r.agentMappings)a.gitlabUsernames.length&&(s[a.agentId]=a.gitlabUsernames);let o=i.projects.length?i.projects:r.routes.map(a=>a.project);return new tt(r.host,r.token,o,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 ro(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,o=new Set)=>{if(e.has(s))return e.get(s);if(o.has(s))return;o.add(s);let a=i[s]?.reportsTo;if(!a)return;let l=r(a,o);return l&&e.set(s,l),l};for(let s of Object.keys(i))r(s);return e}function io(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 _c(t,e){let n=io(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=ro(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,o=s.join(":"),a={agentId:e||i,channel:r};return r==="gitlab"||r==="github"?a.project=o.split(":")[0]:r==="cron"||r==="api"||(a.chatId=o.split("@")[0]),a}var so=t=>t===nt?"internal":"client";function oo(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??so(t),respondWithinMinutes:ao(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=>oo(n,t))}function ao(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 lo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,co=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function fr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(co)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=uo(i);if(!r)return{cleanText:t};let s=n.index??0,o=n[1]??"";return{cleanText:(t.slice(0,s)+o+t.slice(s+n[0].length)).trim(),ui:r}}function Cc(t){if(!t||!t.includes("agentx:ui"))return t;let e=lo.exec(t);return e?t.slice(0,e.index).trimEnd():t}function uo(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 o of e.buttons)!o||typeof o.label!="string"||(typeof o.url=="string"&&/^https?:\/\//i.test(o.url)?i.push({label:o.label,url:o.url}):typeof o.reply=="string"&&o.reply.trim()?r.push({label:o.label,reply:o.reply.trim()}):o.action!=null&&s.push(o.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 po=5*6e4;function D(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var mr=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 o=this.pendingKey(e,n),a=this.pending.get(o);if(a&&a.length){let l=Date.now(),c=a.filter(u=>u.expiresAt>l);for(let{signal:u}of c)this.deliverTo(r,u);this.pending.delete(o),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
|
|
172
|
+
Reinstall in ${qs}. Agents switch back on their own once it is installed.`}}function Gs(t=ur()){if(!cr(t))return null;try{let e=JSON.parse(Ms(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function Ks(t,e){Os(Us(t),{recursive:!0}),js(`${t}.tmp`,JSON.stringify(e,null,2)+`
|
|
173
|
+
`),Ws(`${t}.tmp`,t)}var lr=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??ur(),s=new Map((Gs(r)?.missing??[]).map(d=>[d.voice,d])),o=zs(e,n),a=o.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=>!o.some(p=>p.voice===d));for(let d of l)this.deps.log(`[voice] ${Ge(d)} is installed again; its agents speak with it again`);l.length&&Zn(d=>l.some(p=>d===p||d.endsWith(`:${p}`)));let c=a.filter(d=>!d.notifiedAt);if(c.length){let{title:d,message:p}=Xs(c);try{await this.deps.notify(d,p);for(let g of c)g.notifiedAt=i.toISOString();this.deps.log(`[voice] told the owner: ${c.map(g=>Ge(g.voice)).join(", ")} not installed`)}catch(g){this.deps.log(`[voice] could not send the missing-voice notice: ${g?.message??g}`)}}this.missingNow=a.length>0;let u={checkedAt:i.toISOString(),missing:a};return(!cr(r)||JSON.stringify(a)!==JSON.stringify([...s.values()]))&&Ks(r,u),u}finally{this.running=!1}}};import{readFileSync as Je,writeFileSync as hr,existsSync as Ye,readdirSync as io,statSync as so}from"fs";import{resolve as Ze,join as oo}from"path";import{existsSync as dr,mkdirSync as Js,readFileSync as Ys,writeFileSync as pr}from"fs";import{dirname as Zs,resolve as gr}from"path";import{z as m}from"zod";var Qs=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),eo=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:Qs.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),to=m.object({version:m.literal(1),items:m.array(eo).default([])}),fe=class{constructor(e){this.path=e}jsonPath(){return gr(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return gr(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return dr(this.jsonPath())}load(){let e=this.jsonPath();if(!dr(e))return{version:1,items:[]};let n=Ys(e,"utf-8");try{return to.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();Js(Zs(n),{recursive:!0}),pr(n,JSON.stringify(e,null,2)+`
|
|
174
|
+
`),pr(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(o=>o.id)),r=new Date().toISOString(),s=[];for(let o of e){if(i.has(o.id))continue;let a={...o,labels:o.labels??[],status:o.status??"todo",createdAt:o.createdAt??r,updatedAt:r};n.items.push(a),s.push(a),i.add(a.id)}return s.length&&this.save(n),s}update(e,n){let i=this.load(),r=i.items.findIndex(o=>o.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,o]of r)if(i[s].length){n.push(`## ${o}`,"");for(let a of i[s]){let l=s==="done"?"x":" ",c=a.assignee?`@${a.assignee} `:"",u=a.estimatedSeconds?` [time: ${Math.round(a.estimatedSeconds/60)}m]`:"",d=a.source?` (${a.source.type}: ${a.source.project}#${a.source.iid})`:"";n.push(`- [${l}] ${c}${a.title}${u}${d}`),a.source?.url&&n.push(` - <${a.source.url}>`),a.labels.length&&n.push(` - labels: ${a.labels.join(", ")}`),a.milestone&&n.push(` - milestone: ${a.milestone}`),a.blocker&&n.push(` - BLOCKED: ${a.blocker}`)}n.push("")}return n.join(`
|
|
175
|
+
`)}};function Cc(t){return`${t.type}:${t.project}:${t.iid}`}function fr(t,e,n){let i=[];if(e.type==="gitlab"){let r=n.channels.gitlab?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.gitlabUsernames?.length?i.push(o.gitlabUsernames[0]):i.push(s)}}else if(e.type==="github"){let r=n.channels.github?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.githubUsernames?.length?i.push(o.githubUsernames[0]):i.push(s)}}return i}async function Ke(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?no(t.source,e,n,i):t.source.type==="github"?ro(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function no(t,e,n,i){let r=n.channels.gitlab,s=r?.token,o=r?.host||(t.host?`https://${t.host}`:void 0);if(!s||!o)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let a=[],l=async(g,f={})=>fetch(`${o}/api/v4${g}`,{...f,headers:{"PRIVATE-TOKEN":s,"Content-Type":"application/json",...f.headers||{}}}),c=encodeURIComponent(t.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async f=>{try{let h=await fetch(`${o}/api/v4/users?username=${encodeURIComponent(f)}`,{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(f=>typeof f=="number"));let d;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")d=0;else try{let g=await l(`/projects/${c}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(g.ok){let f=await g.json();Array.isArray(f)&&f[0]?.id&&(d=f[0].id)}}catch(g){i(`[backlog-sync] milestone lookup failed: ${g.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 g=await l(`/projects/${c}/issues/${t.iid}`,{method:"PUT",body:JSON.stringify(p)});if(a.push({kind:"PUT issue",ok:g.ok,status:g.status}),!g.ok){let f=await g.text().catch(()=>"");return{ok:!1,attempts:a,error:`PUT issue ${g.status}: ${f.slice(0,200)}`,url:t.url}}}catch(g){return a.push({kind:"PUT issue",ok:!1,error:g.message}),{ok:!1,attempts:a,error:g.message,url:t.url}}if(e.note)try{let g=await l(`/projects/${c}/issues/${t.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});a.push({kind:"POST note",ok:g.ok,status:g.status})}catch(g){a.push({kind:"POST note",ok:!1,error:g.message})}return{ok:a.every(g=>g.ok),attempts:a,url:t.url}}async function ro(t,e,n,i){let s=n.channels.github?.token;if(!s)return{ok:!1,error:"github token not configured",attempts:[]};let o=[],a=async(p,g={})=>fetch(`https://api.github.com${p}`,{...g,headers:{Authorization:`Bearer ${s}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...g.headers||{}}}),l=t.project,c;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")c=null;else try{let p=await a(`/repos/${l}/milestones?state=all&per_page=100`);if(p.ok){let g=await p.json(),f=Array.isArray(g)?g.find(h=>h.title===e.milestoneTitle):null;f?.number&&(c=f.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 a(`/repos/${l}/issues/${t.iid}`);if(p.ok){let g=await p.json(),f=Array.isArray(g.labels)?g.labels.map(y=>typeof y=="string"?y:y.name):[],h=new Set([...f,...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 a(`/repos/${l}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(o.push({kind:"PATCH issue",ok:p.ok,status:p.status}),!p.ok){let g=await p.text().catch(()=>"");return{ok:!1,attempts:o,error:`PATCH issue ${p.status}: ${g.slice(0,200)}`,url:t.url}}}catch(p){return o.push({kind:"PATCH issue",ok:!1,error:p.message}),{ok:!1,attempts:o,error:p.message,url:t.url}}if(e.note)try{let p=await a(`/repos/${l}/issues/${t.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});o.push({kind:"POST comment",ok:p.ok,status:p.status})}catch(p){o.push({kind:"POST comment",ok:!1,error:p.message})}return{ok:o.every(p=>p.ok),attempts:o,url:t.url}}var Qe=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,me=/@([a-z0-9_-]+)/i,mr=/\[time:\s*([0-9hm\s]+)\]/i;function ao(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 et=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=Ze(process.cwd(),this.path);return Ye(e)?Je(e,"utf-8").split(`
|
|
176
|
+
`):[]}writeMd(e){let n=Ze(process.cwd(),this.path);hr(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(Qe);if(!s||s[2].toLowerCase()==="x")continue;let a=s[3],l=a.match(me);if(l&&l[1].toLowerCase()!==e.toLowerCase())continue;let c=a.match(mr),u=a.replace(me,"").replace(mr,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:l?l[1]:void 0,estimatedSeconds:c?ao(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=fr([r.assignee||e],r.source,this.daemon);Ke(r,{assigneeUsernames:s,addLabels:["Doing"],removeLabels:["To Do"]},this.daemon,this.log).catch(o=>this.log(`[backlog-sync] claim failed for ${n}: ${o?.message??o}`))}}async report(e,n){if(this.store.exists()&&this.store.findById(e)){let a={};n.status==="done"?a.status="done":n.status==="blocked"?(a.status="blocked",a.blocker=n.blocker||n.note||void 0):n.status==="in-progress"&&(a.status="doing"),n.timeSeconds&&(a.estimatedSeconds=n.timeSeconds);let l=this.store.update(e,a);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&&Ke(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(Qe))throw new Error(`backlog line ${i} not a checkbox`);if(n.status==="done"){r[i]=s.replace(/- \[ \]/,"- [x]");let a=n.timeSeconds?` <!-- done by agent, ${Math.round(n.timeSeconds/60)}m -->`:" <!-- done by agent -->";r.splice(i+1,0,a)}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"}}},tt=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(Ye(e))for(let i of io(e)){let r=oo(e,i);so(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(Ze(process.cwd(),this.root),n);let i=[];for(let r of n){let s=Je(r,"utf-8").split(`
|
|
178
|
+
`);for(let o=0;o<s.length;o++){let a=s[o].match(Qe);if(!a||a[2].toLowerCase()==="x")continue;let l=a[3].match(me);!l||l[1].toLowerCase()!==e.toLowerCase()||i.push({id:`wiki:${r}:${o}`,title:a[3].replace(me,"").trim(),assignee:l[1],priority:o})}}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(!Ye(s))return;let o=Je(s,"utf-8").split(`
|
|
179
|
+
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),hr(s,o.join(`
|
|
180
|
+
`)))}},nt=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 a=(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=a[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:a,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 o of r)try{let a=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,l=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,c=await this.api(l);for(let u of c){let d=this.mapIssue(u,o);d.assignee=e,i.push(d)}}catch(a){this.log(`[business] GitLab listOpen failed for ${s} on ${o}: ${a.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),o=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(o,{method:"PUT"})}catch(a){this.log(`[business] claim label update failed: ${a.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let a=Math.max(1,Math.round(n.timeSeconds/60)),l=a>=60?`${Math.floor(a/60)}h${a%60?` ${a%60}m`:""}`:`${a}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${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)}/${o}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(a){this.log(`[business] done label update failed: ${a.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(a){this.log(`[business] blocked label update failed: ${a.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(a){this.log(`[business] report note failed: ${a.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 o=this.projects.length?this.projects:["__ALL__"],a=[];for(let c of o)try{let u=c==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=a;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),o=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${o}/${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(o=>o.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 o;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")o=0;else try{let c=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(o=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${c.message}`)}let a={};n.title!==void 0&&(a.title=n.title),n.description!==void 0&&(a.description=n.description),n.labels!==void 0&&(a.labels=n.labels.join(",")),n.addLabels?.length&&(a.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(a.remove_labels=n.removeLabels.join(",")),s!==void 0&&(a.assignee_ids=s),o!==void 0&&(a.milestone_id=o);let l=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});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 o={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(o.assignee_ids=i),s!==void 0&&(o.milestone_id=s);let a=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(o)});return this.mapIssue(a,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:o}=this.parseId(e),a=o==="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)}/${a}/${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 Wc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new et(i.path,e,n);case"wiki":return new tt(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 a of r.agentMappings)a.gitlabUsernames.length&&(s[a.agentId]=a.gitlabUsernames);let o=i.projects.length?i.projects:r.routes.map(a=>a.project);return new nt(r.host,r.token,o,s,n)}}}var rt="unmapped";function it(t,e=[]){if(!t)return rt;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 lo(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,it(s.id,n)));let r=(s,o=new Set)=>{if(e.has(s))return e.get(s);if(o.has(s))return;o.add(s);let a=i[s]?.reportsTo;if(!a)return;let l=r(a,o);return l&&e.set(s,l),l};for(let s of Object.keys(i))r(s);return e}function co(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 Fc(t,e){let n=co(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return it(t.project,e.projects);if(t.agentId){let i=lo(e).get(t.agentId);if(i)return i}return rt}function Uc(t,e){let n=String(t||"").split(":");if(n.length<3)return{agentId:e};let[i,r,...s]=n,o=s.join(":"),a={agentId:e||i,channel:r};return r==="gitlab"||r==="github"?a.project=o.split(":")[0]:r==="cron"||r==="api"||(a.chatId=o.split("@")[0]),a}var uo=t=>t===rt?"internal":"client";function po(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??uo(t),respondWithinMinutes:go(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Vc(t){let e=new Set;for(let n of t.projects??[])e.add(it(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=>po(n,t))}function go(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 fo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,mo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function yr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(mo)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=ho(i);if(!r)return{cleanText:t};let s=n.index??0,o=n[1]??"";return{cleanText:(t.slice(0,s)+o+t.slice(s+n[0].length)).trim(),ui:r}}function Bc(t){if(!t||!t.includes("agentx:ui"))return t;let e=fo.exec(t);return e?t.slice(0,e.index).trimEnd():t}function ho(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 o of e.buttons)!o||typeof o.label!="string"||(typeof o.url=="string"&&/^https?:\/\//i.test(o.url)?i.push({label:o.label,url:o.url}):typeof o.reply=="string"&&o.reply.trim()?r.push({label:o.label,reply:o.reply.trim()}):o.action!=null&&s.push(o.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 zc(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 yo=5*6e4;function D(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var br=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 o=this.pendingKey(e,n),a=this.pending.get(o);if(a&&a.length){let l=Date.now(),c=a.filter(u=>u.expiresAt>l);for(let{signal:u}of c)this.deliverTo(r,u);this.pending.delete(o),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+
|
|
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+yo),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 bo,readFileSync as wr,renameSync as wo,rmSync as ko,writeFileSync as So}from"fs";import{homedir as xo}from"os";import{dirname as vo,join as $o}from"path";var kr=$o(xo(),".agentx","call.json");function Ao(t=kr,e=Date.now()){try{let n=JSON.parse(wr(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 Sr(t=Bt,e=Ao){let n=t();return n.active?n:e()}function Zc(t,e,n=kr,i=Date.now()){let r=null;try{r=JSON.parse(wr(n,"utf-8"))}catch{}if(r&&r.source&&r.source!=="daemon")return;if(!t){r&&ko(n,{force:!0});return}bo(vo(n),{recursive:!0});let s=`${n}.${process.pid}.tmp`;So(s,JSON.stringify({active:!0,source:"daemon",reason:t,until:new Date(i+e).toISOString()})+`
|
|
184
|
+
`),wo(s,n)}xe();Dt();var nu=["owner","agent","person"],Ro=36e5,_o=t=>Pt.includes(t.state);function xr(t){return e=>!t||t.get(e)?.state!=="active"?null:t.steps(e).find(n=>n.state==="active")?.agentId??null}function st(t,e){return t.state==="waiting_owner"?{group:"owner",who:te}:t.promise&&t.owedTo&&t.owedTo!==te&&!e.isAgent(t.owedTo)?{group:"person",who:t.owedTo}:t.state==="needs_attention"?{group:"owner",who:te}:{group:"agent",who:e.activeStepAgent?.(t.id)??t.agentId}}function ot(t,e,n){return _o(t)?t.state==="needs_attention"?t.attentionReason??"needs attention":t.dueAt!==null?n>t.dueAt?`past its due time (${Io(t.dueAt)})`:null:n-t.updatedAt>e*Ro?`no activity for ${e} h or more`:null:null}function ru(t,e,n,i){let r={owner:[],agent:[],person:[]};for(let s of t){let o=ot(s,e,n);if(!o)continue;let{group:a,who:l}=st(s,i);r[a].push({request:s,group:a,who:l,why:o})}return r}function iu(t,e){return t==="owner"?"you":t==="agent"?`agent ${e}`:`${e} (outside person)`}var Io=t=>new Date(t).toISOString().slice(0,16).replace("T"," ")+" UTC";function su(t){if(t==null||t==="")return;let e=typeof t=="number"?t:typeof t=="string"?Date.parse(t.trim()):NaN;return!Number.isFinite(e)||e<=0?"due must be an ISO date (2030-01-31T17:00:00Z) or epoch milliseconds":e}function ou(t){return e=>Tt(e,t())}var Eo=10;async function au(t,e,n){let i=t.dueForCheck(n.now-n.everyMinutes*6e4,Eo),r=0;return await Promise.all(i.map(async s=>{t.markChecked(s.id,s.verifyState,s.verifyDetail??"",n.now);let o=await e(s.closeWhen,s).catch(a=>({verdict:"unverifiable",detail:String(a?.message??a)}));if(o.verdict==="met"){t.closeVerified(s.id,o.detail,n.now)&&(r++,n.log(`[requests] ${s.id} closed by its check: ${o.detail}`));return}t.markChecked(s.id,o.verdict==="unverifiable"?"unverified":s.verifyState==="failed"?"failed":null,o.detail,n.now)})),{checked:i.length,closed:r}}var To={perClient:5,global:10,windowMs:10*60*1e3,lockoutMs:5*60*1e3},vr=class{constructor(e=To,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)}},Co="That code didn't work. Check it, or run agentx app pair for a new one.",Do=400;async function uu(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 o=null;try{o=(await on(t,1024)).code}catch{}let a=e.codes.redeem(o),l=a?e.verify(a.token):null;return await Po(n,e.minMs??Do),!a||!l?(e.limiter.fail(r),i(`[app] pair-code failed from ${r}`),{status:401,body:{error:Co}}):(e.limiter.succeed(r),i(`[app] pair-code paired ${a.tokenId} (${l}) from ${r}`),{status:200,body:{device:l},token:a.token})}async function Po(t,e){let n=t+e-Date.now();n>0&&await new Promise(i=>setTimeout(i,n))}Dt();var Lo=200,$r=4e3;function No(t){return t.replace(/```[\s\S]*?```/g," ").replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/^\s{0,3}(#{1,6}|>|[-*+]|\d+[.)])\s+/gm,"").replace(/[*_~`]+/g,"").replace(/\s+/g," ").trim()}function at(t,e=Lo){let n=No(t);if(n.length<=e)return n;let i=n.slice(0,e),r=Math.max(i.lastIndexOf(". "),i.lastIndexOf("? "),i.lastIndexOf("! "));return r>e/2?i.slice(0,r+1):`${i.slice(0,e-1).trimEnd()}\u2026`}function mu(t,e,n,i){let r=n?.get(t.id),s=i?ot(t,i.staleAfterHours,i.now):null,o=e.lastAnswer(t.id),a=o&&o.text.length>$r?`${o.text.slice(0,$r)}
|
|
184
185
|
|
|
185
|
-
\u2026`:o?.text;return{...t,summary:
|
|
186
|
+
\u2026`:o?.text;return{...t,summary:at(t.text),textHtml:re(t.text),why:t.state==="waiting_owner"?t.question:t.state==="needs_attention"?t.attentionReason:null,ownerNoteHtml:t.ownerNote?re(t.ownerNote):null,lastAnswer:o?{agentId:o.agentId,at:o.at,html:re(a)}:null,loop:t.promise||t.dueAt!==null||t.closeWhen?{owedTo:t.owedTo,promise:t.promise,dueAt:t.dueAt,check:t.closeWhen?Ct(t.closeWhen):null,verifyState:t.verifyState,verifyDetail:t.verifyDetail}:null,stall:i&&s?{...st(t,{isAgent:i.isAgent,activeStepAgent:xr(n)}),why:s}:null,plan:r?{state:r.state,steps:n.steps(t.id).map(l=>({idx:l.idx,name:l.name,kind:l.kind,agentId:l.agentId,state:l.state,approval:l.needsApproval?l.approval:null,evidence:l.evidence,note:l.note,nudges:l.nudges}))}:null}}import{execFile as Qo}from"child_process";import{mkdtempSync as zo,rmSync as Xo,writeFileSync as Go}from"fs";import{tmpdir as Ko}from"os";import{join as Er}from"path";import{randomBytes as Oo}from"crypto";var E={top:8,side:32,bottom:60},lt={height:56,keep:52},Ar=`
|
|
186
187
|
:root {
|
|
187
188
|
--ac-paper: #fafaf9; --ac-soft: #f4f4f2; --ac-edge: #e9e9e6;
|
|
188
189
|
--ac-text: #0b1413; --ac-muted: #4a5856; --ac-subtle: #7c8987;
|
|
@@ -311,16 +312,16 @@ button.primary:hover:not(:disabled) { transform: translateY(-1px); background: v
|
|
|
311
312
|
button.primary:disabled { opacity: .55; cursor: not-allowed; }
|
|
312
313
|
kbd { font: 11px var(--ac-mono); color: var(--ac-subtle); }
|
|
313
314
|
button.primary kbd { color: inherit; opacity: .7; }
|
|
314
|
-
`;var
|
|
315
|
+
`;var Rr=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),_r=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function Mo(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?Rr(n):_r(n)}`}function Wo(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[_r(n)],Rr(n)].join(" ")}function jo(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 Fo(t){let e=(t.recommend??"").trim(),n=e.toLowerCase(),i=t.choices??[],r=-1;if(i.forEach((o,a)=>{!n.startsWith(o.toLowerCase())||!/^\s*($|[:,.;–—-](\s|$))/.test(e.slice(o.length))||(r<0||o.length>i[r].length)&&(r=a)}),r<0)return{index:r,why:e};let s=e.slice(i[r].length).replace(/^[\s:,.;–—-]+/,"");return{index:r,why:s.slice(0,1).toUpperCase()+s.slice(1)}}function Uo(t){return t.origin?.kind==="request"?"Hand it back":t.draft?"Send":t.choices?.length?"Choose":"Yes"}var ct=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>`,Vo=ct('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),qo=ct('<path d="m6 15 6-6 6 6"/>'),Bo=ct('<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>');function Ir(t,e={}){let n=e.now??Date.now(),i=e.from||t.raised_by,r=Oo(12).toString("base64"),s=t.choices??[],o=t.origin?.kind==="reminder",a=t.origin?.kind==="request",l=Fo(t),c=s.map((p,g)=>`<button class="opt" role="radio" aria-checked="false" data-i="${g}"><span class="n">${g+1}</span><span class="t">${w(p)}</span>${g===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:Zt,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>
|
|
315
316
|
<html lang="en"><head><meta charset="utf-8">
|
|
316
317
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${r}'">
|
|
317
318
|
<title>AgentX</title>
|
|
318
|
-
<style>${
|
|
319
|
+
<style>${Ar}</style></head>
|
|
319
320
|
<body><div class="wrap"><main class="card${e.still?" still":""}">
|
|
320
|
-
<div class="head" title="Drag to move"><span class="avatar">${w(
|
|
321
|
-
<div class="who"><b>${w(i)}</b><span>${w(
|
|
321
|
+
<div class="head" title="Drag to move"><span class="avatar">${w(jo(i))}</span>
|
|
322
|
+
<div class="who"><b>${w(i)}</b><span>${w(Mo(t.created_at,n))}</span></div>
|
|
322
323
|
<span class="kind${o?"":" decision"}">${o?"Reminder":a?"Request":"Decision"}</span>
|
|
323
|
-
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${
|
|
324
|
+
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${qo}</button></div>
|
|
324
325
|
<div class="body"><h1 dir="auto">${w(t.title)}</h1>
|
|
325
326
|
${t.context?`<p class="context" dir="auto">${w(t.context)}</p>`:""}
|
|
326
327
|
<p class="ask" dir="auto">${w(t.ask)}</p>
|
|
@@ -329,15 +330,15 @@ ${c?`<div class="options" role="radiogroup">${c}</div>`:""}
|
|
|
329
330
|
${l.why?`<p class="why" dir="auto">${w(l.why)}</p>`:""}
|
|
330
331
|
${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>
|
|
331
332
|
<textarea id="text" dir="auto" rows="2" spellcheck="true"></textarea>`:""}
|
|
332
|
-
<div class="notes"><div>${
|
|
333
|
-
<div>${
|
|
333
|
+
<div class="notes"><div>${Vo}<span>${a?"It stays in Open requests on the Approvals page until you close it.":`If you don't answer by ${w(Wo(t.expires,n))}: ${w(t.if_silent)}.`}</span></div>
|
|
334
|
+
<div>${Bo}<span>Nothing goes out until you click.</span></div></div>
|
|
334
335
|
</div><div class="foot"><button class="btn later" id="later">Not now<kbd>esc</kbd></button>
|
|
335
336
|
<button class="btn" id="no">${a?"Drop":"No"}</button>
|
|
336
|
-
<button class="btn primary" id="yes">${
|
|
337
|
+
<button class="btn primary" id="yes">${Uo(t)}<kbd>\u2318\u21A9</kbd></button></div>
|
|
337
338
|
</main></div>
|
|
338
339
|
<script type="application/json" id="data">${JSON.stringify(d).replace(/</g,"\\u003c")}</script>
|
|
339
|
-
<script nonce="${r}">${
|
|
340
|
-
</body></html>`}var
|
|
340
|
+
<script nonce="${r}">${Ho}</script>
|
|
341
|
+
</body></html>`}var Ho=`
|
|
341
342
|
(function () {
|
|
342
343
|
var d = JSON.parse(document.getElementById("data").textContent);
|
|
343
344
|
var root = document.documentElement;
|
|
@@ -426,10 +427,10 @@ ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><sp
|
|
|
426
427
|
});
|
|
427
428
|
} catch (e) {}
|
|
428
429
|
})();
|
|
429
|
-
`;var
|
|
430
|
+
`;var Jo=440,Yo=`
|
|
430
431
|
ObjC.import("Cocoa"); ObjC.import("WebKit")
|
|
431
432
|
function run(argv) {
|
|
432
|
-
var path = argv[0], side = ${E.side}, gripTop = ${E.top}, gripEnd = ${E.top+
|
|
433
|
+
var path = argv[0], side = ${E.side}, gripTop = ${E.top}, gripEnd = ${E.top+lt.height}, keep = ${lt.keep}, w = Number(argv[1]) + 2 * side, h = 420, secs = Number(argv[2]), capture = argv[3] || ""
|
|
433
434
|
var app = $.NSApplication.sharedApplication
|
|
434
435
|
app.setActivationPolicy($.NSApplicationActivationPolicyAccessory)
|
|
435
436
|
ObjC.registerSubclass({ name: "AgentXCardView", superclass: "WKWebView", methods: {
|
|
@@ -437,7 +438,7 @@ function run(argv) {
|
|
|
437
438
|
} })
|
|
438
439
|
var vis = $.NSScreen.mainScreen.visibleFrame
|
|
439
440
|
var top = vis.origin.y + vis.size.height - 4, right = vis.origin.x + vis.size.width - 14 + side
|
|
440
|
-
var mask = $.NSWindowStyleMaskTitled | $.NSWindowStyleMaskClosable | $.NSWindowStyleMaskFullSizeContentView
|
|
441
|
+
var mask = $.NSWindowStyleMaskTitled | $.NSWindowStyleMaskClosable | $.NSWindowStyleMaskFullSizeContentView | $.NSWindowStyleMaskNonactivatingPanel
|
|
441
442
|
var win = $.NSPanel.alloc.initWithContentRectStyleMaskBackingDefer($.NSMakeRect(right - w, top - h, w, h), mask, $.NSBackingStoreBuffered, false)
|
|
442
443
|
win.titlebarAppearsTransparent = true
|
|
443
444
|
win.titleVisibility = $.NSWindowTitleHidden
|
|
@@ -458,8 +459,10 @@ function run(argv) {
|
|
|
458
459
|
win.contentView = web
|
|
459
460
|
var url = $.NSURL.fileURLWithPath(path)
|
|
460
461
|
web.loadFileURLAllowingReadAccessToURL(url, url.URLByDeletingLastPathComponent)
|
|
461
|
-
|
|
462
|
-
|
|
462
|
+
// No focus taken (#394): shown over the app in use, which keeps the keyboard.
|
|
463
|
+
// A click on the card still lands (acceptsFirstMouse); a click in its text
|
|
464
|
+
// box makes the panel key without bringing anything else forward.
|
|
465
|
+
win.orderFrontRegardless
|
|
463
466
|
var end = Date.now() + secs * 1000, sized = 0, shot = false, seen = "", asked = false, answer = null
|
|
464
467
|
// Every kind of event, as a number. JXA hands the AppKit constant for it over as text, and a
|
|
465
468
|
// loop asking with that gets no event at all: no click, no drag, no key.
|
|
@@ -499,21 +502,21 @@ function run(argv) {
|
|
|
499
502
|
}
|
|
500
503
|
function gone(why) { return JSON.stringify({ action: "dismiss", why: why }) }
|
|
501
504
|
function quoted(s) { return "'" + String(s).replace(/'/g, "'\\\\''") + "'" }
|
|
502
|
-
`;function
|
|
503
|
-
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&
|
|
504
|
-
`).trim():"",!o||o.length>
|
|
505
|
-
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function
|
|
506
|
-
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function
|
|
505
|
+
`;function Zo(t,e){let n=t.trim().split(`
|
|
506
|
+
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&Cr.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 o;return e.draft&&(o=typeof i.text=="string"?i.text.replace(/\r\n?/g,`
|
|
507
|
+
`).trim():"",!o||o.length>Yt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...o?{text:o}:{}}}async function Tr(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=zo(Er(Ko(),"agentx-card-"));try{let s=Er(r,"card.html");Go(s,Ir(t,{...e,still:!!e.capture}),{mode:384});let o=["-l","JavaScript","-e",Yo,s,String(Jo),String(i),...e.capture?[e.capture]:[]],a=await n("/usr/bin/osascript",o,(i+10)*1e3);return a.ok?Zo(a.stdout,t):null}finally{Xo(r,{recursive:!0,force:!0})}}var Cr=["not now","timed out","closed"],ea=(t,e,n)=>new Promise(i=>{try{Qo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),Dr=160,ut=15e3;function Pr(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>Dr?e.slice(0,Dr):e}async function ta(t,e,n,i,r){let s=e.sound==="chime"?i?"":"Glass":e.sound,o=s?sn(s):null;if(o&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),o],ut),!!e.speak)if(r){let a;await Promise.race([r(Pr(t)),new Promise(l=>{a=setTimeout(l,ut)})]),clearTimeout(a)}else{let a=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...a,"--",Pr(t)],ut)}}function Or(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function na(t,e,n){return Or(["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 Lr(t,e,n,i,r){return Or(["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(`
|
|
508
|
+
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function Nr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
|
|
509
|
+
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function dt(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
|
|
507
510
|
|
|
508
|
-
`)}async function
|
|
511
|
+
`)}async function Mr(t,e,n={}){let i=n.run??ea,r=(e.style??"card")==="card",s=ta(t,e,i,r,n.speak).catch(()=>{});if(r){let o=await Tr(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(o)return o}return await s,ra(t,e,i)}async function ra(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=(i+5)*1e3,s=`${t.raised_by}: ${t.title}`,o;if(t.choices?.length){let c=await n("/usr/bin/osascript",na(s,dt(t),t.choices),r);if(o=c.stdout.replace(/\n$/,""),!c.ok||!t.choices.includes(o))return{action:"dismiss"};if(!t.draft)return{action:"yes",choice:o}}if(t.draft){let c=o?`${o}
|
|
509
512
|
|
|
510
|
-
Message (edit it if you like):`:`${
|
|
513
|
+
Message (edit it if you like):`:`${dt(t)}
|
|
511
514
|
|
|
512
|
-
Message (edit it if you like):`,d=await n("/usr/bin/osascript",
|
|
513
|
-
`)[0]}); Siri voices will not switch`),null}}var
|
|
514
|
-
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as
|
|
515
|
-
`)[0].slice(0,200);l.push(`${c}: ${d}`),o.log(`[voice] phone transcription with ${c} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:l.join("; ")}]}function
|
|
516
|
-
`)[0].slice(0,160)}`),u("ElevenLabs could not speak this answer.",502)}}function
|
|
515
|
+
Message (edit it if you like):`,d=await n("/usr/bin/osascript",Lr(s,c,o?["Cancel","Send"]:["Not now","No","Send"],i,Qt(t.draft,o)),r),p=d.ok?Nr(d.stdout):null;if(p?.button==="Send"){let g=p.text.trim();return g?{action:"yes",...o?{choice:o}:{},text:g}:{action:"dismiss"}}return p?.button==="No"?{action:"no"}:{action:"dismiss"}}let a=await n("/usr/bin/osascript",Lr(s,dt(t),["Not now","No","Yes"],i),r),l=a.ok?Nr(a.stdout):null;return l?.button==="Yes"?{action:"yes"}:l?.button==="No"?{action:"no"}:{action:"dismiss"}}var ft=24*36e5,pt=!1,ia=10*6e4,Wr=-1/0;function jr(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=x(t.root),o=r?Date.parse(r):NaN,a=W(t.root,"pending").filter(c=>Date.parse(c.expires)>e),l=a.find(c=>s.includes(`card:${c.id}`));if(l)return l;for(let c of a){let u=`card:${c.id}`;if(n[u])continue;let d=i[u];if(d&&Date.parse(d)>e)continue;let p=Date.parse(c.created_at);if(!(e-p>ft&&!(p<=o)))return c}return null}function gt(t){try{return z(t)?.listByState("needs_attention")??[]}catch{return[]}}function sa(t){let e=t.now??Date.now(),{popped:n={},snoozed:i}=x(t.root);return gt(t).find(r=>{let s=`request:${r.id}`,o=i[s];return!n[s]&&!(o&&Date.parse(o)>e)&&e-r.updatedAt<=ft})??null}function oa(t,e){return{id:t.id,title:at(t.text,cn.title),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+ft).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(pt)return"busy";let r=jr(e)?null:sa(e),s=r?oa(r,e.now??Date.now()):jr(e);if(!s)return"none";let o=(t.focus??Sr)();if(o.active)return"held";let a=`${r?"request":"card"}:${s.id}`,l=(x(e.root).wanted??[]).includes(a)?null:an(s);if(l){let c=[...W(e.root,"pending").map(u=>`card:${u.id}`),...gt(e).map(u=>`request:${u.id}`)];return Te(e.root,a,c,e.now),i(`[approvals] popup: ${a} not shown, back to ${s.raised_by}: ${l}`),t.returnToAuthor?.(s,ln(s,l)),"returned"}pt=!0;try{let c=[...W(e.root,"pending").map(y=>`card:${y.id}`),...gt(e).map(y=>`request:${y.id}`)];Te(e.root,a,c,e.now),i(`[approvals] popup: showing ${a} from ${s.raised_by}`);let u=e.now??Date.now(),d=!!r&&u-Wr<ia;r&&n.speak&&(Wr=u);let p=t.agentName?.(s.raised_by)??(s.node?`${s.raised_by} on ${s.node}`:void 0),g=await(t.show??Mr)(s,d?{...n,speak:!1}:n,{from:p,speak:t.speak});if(g.action==="dismiss")return i(`[approvals] popup: ${a} left waiting: ${g.why??"no answer"} (${Ht(o)} when shown)`),"shown";if(!(r?z(e)?.get(r.id)?.state==="needs_attention":q(e.root,s.id)?.status==="pending"))return i(`[approvals] popup: ${a} was answered elsewhere; popup answer ignored`),"shown";let h=await Mn(e,a,g.action,{by:"operator (popup)",...g.action==="yes"?{choice:g.choice,text:g.text}:{}});return i(h.ok?`[approvals] popup: ${h.message}`:`[approvals] popup: ${a} not recorded: ${h.error}`),"shown"}catch(c){return i(`[approvals] popup failed for ${a}: ${c?.message??c}`),"shown"}finally{pt=!1}}function Hu(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}`}:(kn(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 K,createReadStream as aa,fstatSync as la,openSync as ca,realpathSync as Fr}from"fs";import{isAbsolute as ua,resolve as Ur,sep as Vr}from"path";var Yu="/app-files",da=/^[A-Za-z0-9_.:-]{1,64}$/;function pa(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 ${Re}/ first`};if(!Ae(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=Fr(Ur(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=Fr(ua(e)?e:Ur(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+Vr))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${Re}/ first`};let s=Ae(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function ga(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 fa(t,e,n){return{"Content-Type":t,"Content-Disposition":ga(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 ma(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 Zu(t,e,n,i){let r=(C,M)=>{e.writeHead(C,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(M))};if(t.method!=="GET"&&t.method!=="HEAD")return r(405,{error:"GET only"});let s=n.searchParams.get("agent")||"",o=n.searchParams.get("file")||"";if(!da.test(s))return r(400,{error:"bad agent id"});let a=i.workspaceOf(s);if(!a)return r(404,{error:`no agent "${s}" on this computer`});let l=pa(a,o,i.cwd);if(!l.ok)return i.log?.(`[app-files] refused ${JSON.stringify(o.slice(0,200))} from ${s}: ${l.error}`),r(l.status,{error:l.error});let c;try{c=ca(l.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let C=la(c);if(!C.isFile())return K(c),r(404,{error:"not a file"});u=C.size}catch{return K(c),r(404,{error:"file not found"})}if(u>ne.bytes)return K(c),r(413,{error:`the file is larger than ${ne.bytes/1024/1024} MB`});let d=l.path.split(Vr).pop()||"file",p=fa(l.mime,d,l.kind),g=ma(t.headers.range,u);if(g==="unsatisfiable"){K(c),e.writeHead(416,{...p,"Content-Range":`bytes */${u}`}),e.end();return}let{start:f,end:h}=g??{start:0,end:u-1};if(e.writeHead(g?206:200,{...p,"Content-Length":String(u?h-f+1:0),...g?{"Content-Range":`bytes ${f}-${h}/${u}`}:{}}),t.method==="HEAD"||u===0){K(c),e.end();return}let y=aa("",{fd:c,start:f,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as J}from"child_process";import{readFileSync as ha,writeFileSync as ya}from"fs";import{tmpdir as ba}from"os";import{join as wa}from"path";It();var qr=t=>t&&t!==1?Math.round(175*t):null,he=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function ka(){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=ha(t,"utf8").trim();if(e)return e}catch{}return null}function ad(t=ka()){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",...he(n.voice.rate)?{voice_settings:{speed:he(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=wa(ba(),`agentx-say-${process.pid}-${++e}.mp3`);return ya(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 Br(t,e){let n=t.languages&&ee(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var Sa=(t,e="")=>{let n=Br(t,e),i=qr(t.rate);return[...n&&!Bn(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function xa(t,e,n){if(!n)return["say",Sa(t,e)];let i=Br(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function ld(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function cd(t=mt()){if(t)try{J("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function ud(t=mt()){if(t)try{J("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function mt(t={},e){if(!Me(t))return null;try{return Xn(e)}catch(n){return N("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
|
|
516
|
+
`)[0]}); Siri voices will not switch`),null}}var dd=(t,e)=>{if(!t){let[n,i]=xa(e.voice,e.text,mt()),r=qr(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=J(n,i,{stdio:["pipe","ignore","ignore"],env:s});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?J("afplay",[t],{stdio:"ignore"}):J("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as Hr}from"child_process";import{accessSync as va,constants as $a,readFileSync as zr}from"fs";import{homedir as Aa}from"os";import{basename as U,delimiter as Xr,dirname as Ra,extname as _a,join as ht}from"path";var P={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function Gr(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:bt()}:null}var bt=()=>`The recording is longer than ${P.ms/6e4} minutes.`,Ia={"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 Kr(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return Ia[e]??null}function Jr(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 wt(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 yt(t,e,n=process.env.PATH??""){let i=Aa(),r=[ht(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(Xr).filter(Boolean)];for(let s of[e,...r.map(o=>ht(o,t))])if(s)try{return va(s,$a.X_OK),s}catch{}return null}function yd(t){return{key:t,mlx:yt("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:yt("whisper",process.env.AGENTX_WHISPER),ffmpeg:Ea()}}var Ea=()=>yt("ffmpeg",process.env.AGENTX_FFMPEG);async function Yr(t,e){return e?Ta(t,e):null}async function Ta(t,e){let n=String(P.ms/1e3+5);try{let r=[...(await Ca(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 Zr(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([zr(t)],{type:e}),U(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 o=await s.json();if(typeof o.text!="string")throw new Error("ElevenLabs returned no text");return o.text.trim()}async function Qr(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"],o={...process.env,PATH:`${Ra(i)}${Xr}${process.env.PATH??""}`};await Da(e,s,12e4,o);try{return zr(ht(r,U(n,_a(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function Ca(t,e,n){return new Promise((i,r)=>{let s=Hr(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${U(t)} took too long`))},n);s.stderr.on("data",l=>{o=(o+l).slice(-8192)}),s.on("error",l=>{clearTimeout(a),r(l)}),s.on("exit",l=>{clearTimeout(a),l===0?i(o):r(new Error(`${U(t)} exited ${l}`))})})}function Da(t,e,n,i=process.env){return new Promise((r,s)=>{let o=Hr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),a="",l="",c=setTimeout(()=>{o.kill("SIGKILL"),s(new Error(`${U(t)} took longer than ${n/1e3}s`))},n);o.stdout.on("data",u=>{a.length<4096&&(a+=u)}),o.stderr.on("data",u=>{l.length<4096&&(l+=u)}),o.on("error",u=>{clearTimeout(c),s(u)}),o.on("exit",u=>{clearTimeout(c),u===0?r(a):s(new Error(`${U(t)} exited ${u}: ${l.trim().split(`
|
|
517
|
+
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as Pa,rm as La,writeFile as Na}from"fs/promises";import{tmpdir as Oa}from"os";import{join as ei}from"path";ci();var Ma=64*1024,Wa=2,kt=0;function Id(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function Ed(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?ja(t,e,i):Va(t,e,i)}async function ja(t,e,n){let i=String(t.headers["content-type"]||""),r=Kr(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=Gr(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let o=await ti(t,P.bytes);if(!o)return b(e,413,{error:Ha()});if(!o.length)return b(e,400,{error:"The recording is empty."});if(kt>=Wa)return b(e,429,{error:"This computer is already writing down other recordings. Try again in a moment."});let a=n.stt(),l=n.host(),c=Jr(a,l);if(!l.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",p=c.length?"":" "+wt(a,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:wt(a,l),setup:!1});kt++;let u;try{let d=await Pa(ei(Oa(),"agentx-phone-voice-"));try{u=await Fa(d,`speech.${r}`,o,i,l,c,n)}finally{await La(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{kt--}b(e,u[0],u[1])}async function Fa(t,e,n,i,r,s,o){let a=ei(t,e);if(await Na(a,n,{mode:384}),r.ffmpeg){let c=await(o.measure??Yr)(a,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:bt()}]}let l=[];for(let c of s)try{let u=await Ua(c,a,i,r,t,o);return o.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(`
|
|
518
|
+
`)[0].slice(0,200);l.push(`${c}: ${d}`),o.log(`[voice] phone transcription with ${c} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:l.join("; ")}]}function Ua(t,e,n,i,r,s){let o=s.engines?.[t];if(o)return o(e,n,i,r);if(t==="elevenlabs")return Zr(e,n,i.key);let a=t==="mlx-whisper"?i.mlx:i.whisper;return Qr(t,a,e,i.ffmpeg,r)}async function Va(t,e,n){let i=await ti(t,Ma);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:"",o=typeof r?.peer=="string"&&r.peer?r.peer:void 0;if(!s)return b(e,400,{error:"agent is required"});let a=qa(typeof r?.text=="string"?r.text:"",n.spokenMaxChars?.());if(!a)return b(e,422,{error:"Nothing in this answer can be said aloud."});let l=n.pronounce?n.pronounce(a):a,c=n.voiceOf(s,o);if(!c)return b(e,404,{error:`Unknown agent: ${s}`});let u=(p,g=200)=>b(e,g,{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??Ba)(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(`
|
|
519
|
+
`)[0].slice(0,160)}`),u("ElevenLabs could not speak this answer.",502)}}function qa(t,e){let n=yr(qt(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return Et(n,e)}async function Ba(t,e,n){let i=he(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 Ha=()=>`The recording is larger than ${P.bytes/1024/1024} MB, more than ${P.ms/6e4} minutes of speech.`;function Td(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Xe(Be(t,r,n.voice)):null}function ti(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",o=>{if(!(s>e)){if(s+=o.length,s>e){r.length=0,n(null);return}r.push(o)}}),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 $t,writeFileSync as At,mkdirSync as ye,readdirSync as vt,rmSync as za,statSync as _}from"fs";import{resolve as ni,relative as Xa,dirname as Rt,join as O,extname as Y,basename as _t}from"path";var S=200*1024,ri=new Set([".md",".markdown",".txt"]),V=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"]),Ga=6,Ka=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=ni(t);if($(n)||ye(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=ni(n,e);if(Xa(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function ii(t){let e=Y(t).toLowerCase();if(!ri.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function St(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=vt(e)}catch{}for(let a of Ka){let l=O(e,a);if($(l)&&_(l).isFile()){let c=_(l).size,u=c>0&&c<S?xt(l):"";n.push({path:a,title:St(u,a),size:c,exists:!0}),i.add(a)}else n.push({path:a,title:a,size:0,exists:!1}),i.add(a)}for(let a of r){if(i.has(a))continue;let l=O(e,a);try{let c=_(l);if(!c.isFile()||!ri.has(Y(a).toLowerCase()))continue;let u=c.size>0&&c.size<S?xt(l):"";n.push({path:a,title:St(u,a),size:c.size,exists:!0})}catch{}}let s=[],o=O(e,".claude","skills");if($(o))try{for(let a of vt(o)){let l=O(o,a),c;try{c=_(l)}catch{continue}if(!c.isDirectory())continue;let u=O(l,"SKILL.md");if(!$(u))continue;let d=_(u),p=d.size<S?xt(u):"";s.push({slug:a,title:St(p,a),size:d.size,path:`.claude/skills/${a}/SKILL.md`})}}catch{}return s.sort((a,l)=>a.slug.localeCompare(l.slug)),{identity:n,skills:s,workspace:e}}function xt(t){try{return $t(t,"utf-8")}catch{return""}}function Nd(t,e){let n=T(t,e);if(ii(n),!$(n))return{path:e,content:""};if(_(n).size>S)throw new Error(`File is too large to edit in the admin panel (> ${S/1024} KB).`);return{path:e,content:$t(n,"utf-8")}}function Od(t,e,n){let i=T(t,e);ii(i);let r=Buffer.from(n,"utf-8");if(r.length>S)throw new Error(`File too large (${r.length} > ${S} bytes).`);return ye(Rt(i),{recursive:!0}),At(i,r),{path:e,bytes:r.length}}function Md(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.`);ye(Rt(r),{recursive:!0});let s=n.content?.trim()?n.content:Ja(e,n.title);return At(r,s),{slug:e,path:i}}function Wd(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(!_(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return za(n,{recursive:!0,force:!0}),{slug:e}}function jd(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,o)=>s.kind!==o.kind?s.kind==="dir"?-1:1:s.path.localeCompare(o.path)),i;function r(s,o,a,l){if(a>Ga)return;let c=[];try{c=vt(s)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let d=O(s,u),p=o?`${o}/${u}`:u,g;try{g=_(d)}catch{continue}if(g.isDirectory())l.push({path:`${p}/`,kind:"dir",size:0,editable:!1}),r(d,p,a+1,l);else if(g.isFile()){let f=Y(u).toLowerCase(),h=V.has(f)||V.has(u.toLowerCase());l.push({path:p,kind:"file",size:g.size,editable:h&&g.size<S})}}}}function Fd(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)||!_(i).isFile())throw new Error(`File not found: ${n}`);let r=Y(i).toLowerCase(),s=_t(i).toLowerCase();if(!V.has(r)&&!V.has(s))throw new Error(`File type not editable: ${n}`);if(_(i).size>S)throw new Error(`File too large to edit (> ${S/1024} KB): ${n}`);return{path:n,content:$t(i,"utf-8")}}function Ud(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=Y(r).toLowerCase(),o=_t(r).toLowerCase();if(!V.has(s)&&!V.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(i,"utf-8");if(a.length>S)throw new Error(`File too large (${a.length} > ${S} bytes).`);return ye(Rt(r),{recursive:!0}),At(r,a),{path:n,bytes:a.length}}function Vd(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=>$(O(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 Ja(t,e){return`# ${e?.trim()||t}
|
|
517
520
|
|
|
518
521
|
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.
|
|
519
522
|
|
|
@@ -526,7 +529,7 @@ Document the arguments, commands, or files the skill expects. Example:
|
|
|
526
529
|
|
|
527
530
|
\`\`\`bash
|
|
528
531
|
# Example invocation
|
|
529
|
-
claude-code ${
|
|
532
|
+
claude-code ${_t(t)} --arg value
|
|
530
533
|
\`\`\`
|
|
531
|
-
`}
|
|
532
|
-
//# sourceMappingURL=chunk-
|
|
534
|
+
`}jt();var si={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function oi(t){return{...si,...t??{},regions:{...t?.regions??{}},buffer:{...si.buffer,...t?.buffer??{}}}}function Hd(t){try{return oi(Wt(t).screen)}catch{return oi(void 0)}}var Ya=/^[a-z][\w-]*$/,ai=["window","screen","menubar","notifications"];function Z(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 be=(t,e)=>Z(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function li(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 zd(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=be(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=be(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=be(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Z(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Z(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,o]of Object.entries(e.regions)){if(!Ya.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);o===null?delete r[s]:r[s]=li(o)}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=Z(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Z(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=be(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&&!ai.includes(i)&&!n.regions?.[i])try{li(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...ai,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{dn as a,el as b,it as c,lo as d,co as e,Fc as f,Uc as g,Vc as h,yr as i,Bc as j,zc as k,D as l,br as m,k as n,il as o,Sr as p,Zc as q,gl as r,ji as s,wl as t,In as u,x as v,cl as w,ul as x,xl as y,ae as z,vl as A,Cn as B,El as C,z as D,Bl as E,Hl as F,Mn as G,nu as H,xr as I,st as J,ru as K,iu as L,Io as M,su as N,ou as O,au as P,vr as Q,uu as R,at as S,mu as T,Mr as U,Bu as V,Hu as W,Yu as X,fa as Y,Zu as Z,Xl as _,Gl as $,Kl as aa,Jl as ba,Yl as ca,Zl as da,ec as ea,tc as fa,uc as ga,Fe as ha,dc as ia,pc as ja,X as ka,G as la,ka as ma,ad as na,ld as oa,cd as pa,ud as qa,mt as ra,dd as sa,qe as ta,Be as ua,ge as va,Is as wa,Ts as xa,yc as ya,ze as za,Xe as Aa,Cs as Ba,Ds as Ca,rr as Da,ar as Ea,bc as Fa,Ns as Ga,wc as Ha,qs as Ia,zs as Ja,Ge as Ka,Gs as La,lr as Ma,P as Na,Gr as Oa,Kr as Pa,Jr as Qa,yd as Ra,Ea as Sa,Zr as Ta,Qr as Ua,Id as Va,Ed as Wa,Ha as Xa,Td as Ya,ti as Za,fe as _a,Cc as $a,fr as ab,Ke as bb,nt as cb,Wc as db,Ld as eb,Nd as fb,Od as gb,Md as hb,Wd as ib,jd as jb,Fd as kb,Ud as lb,Vd as mb,si as nb,oi as ob,Hd as pb,ai as qb,zd as rb};
|
|
535
|
+
//# sourceMappingURL=chunk-GWBBWYGM.js.map
|