agentix-cli 0.91.0 → 0.92.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-PBPYFVBE.js → App-NVYQSINX.js} +2 -2
- package/dist/{ChatApp-QC7QAQEW.js → ChatApp-CFJY5S7S.js} +2 -2
- package/dist/{agent-BQEENICU.js → agent-IKVCR32P.js} +2 -2
- package/dist/{board-dashboard-ZLDVYPZ4.js → board-dashboard-F2AY5XAU.js} +287 -227
- package/dist/board-dashboard-F2AY5XAU.js.map +1 -0
- package/dist/{chunk-NIQEKVWY.js → chunk-2I34WFIT.js} +2 -2
- package/dist/{chunk-AVA245WL.js → chunk-2IMQJS53.js} +2 -2
- package/dist/{chunk-4L244AW4.js → chunk-3Z5P2CWS.js} +2 -2
- package/dist/{chunk-ZVXKCXTP.js → chunk-4UXHHHYH.js} +2 -2
- package/dist/{chunk-SH5Y7N4W.js → chunk-5AAJ6BPY.js} +2 -2
- package/dist/{chunk-PJZ4ZHQS.js → chunk-7AJY3EMB.js} +2 -2
- package/dist/{chunk-HY6ILQ4T.js → chunk-BNUQFUAE.js} +2 -2
- package/dist/{chunk-HXM35HRM.js → chunk-D3PXRTOR.js} +57 -55
- package/dist/chunk-D3PXRTOR.js.map +1 -0
- package/dist/{chunk-3SZ4CU6G.js → chunk-DG5I6PPM.js} +16 -14
- package/dist/chunk-DG5I6PPM.js.map +1 -0
- package/dist/{chunk-XIYWXCNU.js → chunk-E5OV6RTG.js} +4 -4
- package/dist/chunk-E5OV6RTG.js.map +1 -0
- package/dist/{chunk-OS34M3FV.js → chunk-EBMU2RD6.js} +2 -2
- package/dist/{chunk-4TKGR3XF.js → chunk-EPP6BEUX.js} +2 -2
- package/dist/{chunk-24P6UR3L.js → chunk-GIJV3TMB.js} +19 -14
- package/dist/chunk-GIJV3TMB.js.map +1 -0
- package/dist/{chunk-L73YON3H.js → chunk-HVJ6LG43.js} +4 -4
- package/dist/{chunk-ES2NYGS2.js → chunk-I67L4ZXK.js} +2 -2
- package/dist/{chunk-EJPQPU5J.js → chunk-IXRAL4CW.js} +2 -2
- package/dist/{chunk-EBHHMJZX.js → chunk-KRW2M4RY.js} +2 -2
- package/dist/{chunk-4SHWIGTM.js → chunk-LLFQJUZ6.js} +5 -5
- package/dist/{chunk-OKT5RCXP.js → chunk-MDCAQYZW.js} +2 -2
- package/dist/{chunk-TGN7K7VG.js → chunk-N7HKIMMR.js} +36 -38
- package/dist/chunk-N7HKIMMR.js.map +1 -0
- package/dist/{chunk-BTTQZWYB.js → chunk-QAIYUMHW.js} +2 -2
- package/dist/{chunk-S4JD5FEE.js → chunk-QPRETJO4.js} +2 -2
- package/dist/{chunk-SQOBKSP3.js → chunk-ROOZIJOB.js} +2 -2
- package/dist/{chunk-RS6BNRVF.js → chunk-WO7HTHMB.js} +2 -2
- package/dist/{chunk-URVWZ5FM.js → chunk-XHGXAWV6.js} +2 -2
- package/dist/{chunk-7RDNVR5I.js → chunk-YXPJXBEI.js} +6 -6
- package/dist/{chunk-7RDNVR5I.js.map → chunk-YXPJXBEI.js.map} +1 -1
- package/dist/cli.js +1 -1
- package/dist/{client-WFEXHCNH.js → client-VDKYLOWU.js} +2 -2
- package/dist/{config-PPYPER75.js → config-STG62DJ3.js} +2 -2
- package/dist/config-mutator-MIU2D465.js +2 -0
- package/dist/{doctor-NRKGBTVD.js → doctor-FQNJDN4T.js} +2 -2
- package/dist/{grants-N7XC7NLS.js → grants-Y667GZAU.js} +2 -2
- package/dist/index.js +1 -1
- package/dist/processes-W5VHBP7T.js +2 -0
- package/dist/{program-7YKH5WTC.js → program-KUPJQVOT.js} +14 -14
- package/dist/{promote-PY73YR6C.js → promote-BSIVNB26.js} +2 -2
- package/dist/{query-F3R5KXA7.js → query-HGFJXEL7.js} +2 -2
- package/dist/{registry-YBMYCRQH.js → registry-YDCHLHWR.js} +2 -2
- package/dist/{request-planner-CVNEV6NJ.js → request-planner-XM3BUNKD.js} +2 -2
- package/dist/{review-candidates-5QTF5JRG.js → review-candidates-STJAWQ6H.js} +2 -2
- package/dist/{routing-BJLETKHZ.js → routing-ZWRKDDF2.js} +2 -2
- package/dist/schedule-tool-AGEAWU3E.js +2 -0
- package/dist/scheduler-PKQ5W7UW.js +2 -0
- package/dist/{seat-OORCKWER.js → seat-K54UKAY7.js} +2 -2
- package/dist/{select-OGMDS37Y.js → select-CQNVQYJI.js} +2 -2
- package/dist/{set-enabled-IKSHTUUF.js → set-enabled-3UTTNW3W.js} +2 -2
- package/dist/{tool-CKIO3NBX.js → tool-CA7EUQMY.js} +2 -2
- package/dist/{tool-6FVBXUTV.js → tool-HLPRU4ES.js} +2 -2
- package/dist/wiki-JKQJJLUX.js +2 -0
- package/package.json +2 -2
- package/dist/board-dashboard-ZLDVYPZ4.js.map +0 -1
- package/dist/chunk-24P6UR3L.js.map +0 -1
- package/dist/chunk-3SZ4CU6G.js.map +0 -1
- package/dist/chunk-HXM35HRM.js.map +0 -1
- package/dist/chunk-TGN7K7VG.js.map +0 -1
- package/dist/chunk-XIYWXCNU.js.map +0 -1
- package/dist/config-mutator-QQDBVKWM.js +0 -2
- package/dist/processes-MMAVAZAC.js +0 -2
- package/dist/schedule-tool-E2PRGDLW.js +0 -2
- package/dist/scheduler-53POJWDI.js +0 -2
- package/dist/wiki-4CPXUAPW.js +0 -2
- /package/dist/{App-PBPYFVBE.js.map → App-NVYQSINX.js.map} +0 -0
- /package/dist/{ChatApp-QC7QAQEW.js.map → ChatApp-CFJY5S7S.js.map} +0 -0
- /package/dist/{agent-BQEENICU.js.map → agent-IKVCR32P.js.map} +0 -0
- /package/dist/{chunk-NIQEKVWY.js.map → chunk-2I34WFIT.js.map} +0 -0
- /package/dist/{chunk-AVA245WL.js.map → chunk-2IMQJS53.js.map} +0 -0
- /package/dist/{chunk-4L244AW4.js.map → chunk-3Z5P2CWS.js.map} +0 -0
- /package/dist/{chunk-ZVXKCXTP.js.map → chunk-4UXHHHYH.js.map} +0 -0
- /package/dist/{chunk-SH5Y7N4W.js.map → chunk-5AAJ6BPY.js.map} +0 -0
- /package/dist/{chunk-PJZ4ZHQS.js.map → chunk-7AJY3EMB.js.map} +0 -0
- /package/dist/{chunk-HY6ILQ4T.js.map → chunk-BNUQFUAE.js.map} +0 -0
- /package/dist/{chunk-OS34M3FV.js.map → chunk-EBMU2RD6.js.map} +0 -0
- /package/dist/{chunk-4TKGR3XF.js.map → chunk-EPP6BEUX.js.map} +0 -0
- /package/dist/{chunk-L73YON3H.js.map → chunk-HVJ6LG43.js.map} +0 -0
- /package/dist/{chunk-ES2NYGS2.js.map → chunk-I67L4ZXK.js.map} +0 -0
- /package/dist/{chunk-EJPQPU5J.js.map → chunk-IXRAL4CW.js.map} +0 -0
- /package/dist/{chunk-EBHHMJZX.js.map → chunk-KRW2M4RY.js.map} +0 -0
- /package/dist/{chunk-4SHWIGTM.js.map → chunk-LLFQJUZ6.js.map} +0 -0
- /package/dist/{chunk-OKT5RCXP.js.map → chunk-MDCAQYZW.js.map} +0 -0
- /package/dist/{chunk-BTTQZWYB.js.map → chunk-QAIYUMHW.js.map} +0 -0
- /package/dist/{chunk-S4JD5FEE.js.map → chunk-QPRETJO4.js.map} +0 -0
- /package/dist/{chunk-SQOBKSP3.js.map → chunk-ROOZIJOB.js.map} +0 -0
- /package/dist/{chunk-RS6BNRVF.js.map → chunk-WO7HTHMB.js.map} +0 -0
- /package/dist/{chunk-URVWZ5FM.js.map → chunk-XHGXAWV6.js.map} +0 -0
- /package/dist/{client-WFEXHCNH.js.map → client-VDKYLOWU.js.map} +0 -0
- /package/dist/{config-PPYPER75.js.map → config-STG62DJ3.js.map} +0 -0
- /package/dist/{config-mutator-QQDBVKWM.js.map → config-mutator-MIU2D465.js.map} +0 -0
- /package/dist/{doctor-NRKGBTVD.js.map → doctor-FQNJDN4T.js.map} +0 -0
- /package/dist/{grants-N7XC7NLS.js.map → grants-Y667GZAU.js.map} +0 -0
- /package/dist/{processes-MMAVAZAC.js.map → processes-W5VHBP7T.js.map} +0 -0
- /package/dist/{program-7YKH5WTC.js.map → program-KUPJQVOT.js.map} +0 -0
- /package/dist/{promote-PY73YR6C.js.map → promote-BSIVNB26.js.map} +0 -0
- /package/dist/{query-F3R5KXA7.js.map → query-HGFJXEL7.js.map} +0 -0
- /package/dist/{registry-YBMYCRQH.js.map → registry-YDCHLHWR.js.map} +0 -0
- /package/dist/{request-planner-CVNEV6NJ.js.map → request-planner-XM3BUNKD.js.map} +0 -0
- /package/dist/{review-candidates-5QTF5JRG.js.map → review-candidates-STJAWQ6H.js.map} +0 -0
- /package/dist/{routing-BJLETKHZ.js.map → routing-ZWRKDDF2.js.map} +0 -0
- /package/dist/{schedule-tool-E2PRGDLW.js.map → schedule-tool-AGEAWU3E.js.map} +0 -0
- /package/dist/{scheduler-53POJWDI.js.map → scheduler-PKQ5W7UW.js.map} +0 -0
- /package/dist/{seat-OORCKWER.js.map → seat-K54UKAY7.js.map} +0 -0
- /package/dist/{select-OGMDS37Y.js.map → select-CQNVQYJI.js.map} +0 -0
- /package/dist/{set-enabled-IKSHTUUF.js.map → set-enabled-3UTTNW3W.js.map} +0 -0
- /package/dist/{tool-CKIO3NBX.js.map → tool-CA7EUQMY.js.map} +0 -0
- /package/dist/{tool-6FVBXUTV.js.map → tool-HLPRU4ES.js.map} +0 -0
- /package/dist/{wiki-4CPXUAPW.js.map → wiki-JKQJJLUX.js.map} +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{a as
|
|
2
|
-
`).filter(Boolean);if(!n.length)return null;let i=JSON.parse(n[0]),r=i.run?.workflowId;if(!r)return null;let s=i.run?.status??"unknown";for(let o=n.length-1;o>=0;o--){let a=JSON.parse(n[o]),c=a.status??a.run?.status;if(c){s=c;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var
|
|
3
|
-
`).pop()?.slice(0,300)||"no output";async function
|
|
4
|
-
`,{mode:384}),
|
|
5
|
-
`),ci(i,n)}function sn(t,e,n,i=Date.now()){let r=R(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),z(t,{...r,snoozed:s})}function xa(t,e){z(t,{...R(t),lastDigest:e})}function on(t,e,n,i=Date.now()){let r=R(t),s=new Set(n),o={};for(let[c,l]of Object.entries(r.popped??{}))s.has(c)&&(o[c]=l);o[e]=new Date(i).toISOString();let a=(r.wanted??[]).filter(c=>c!==e&&s.has(c));z(t,{...r,popped:o,wanted:a})}function an(t,e){let n=R(t);z(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function Sa(t,e=Date.now()){z(t,{...R(t),popped:{},passAt:new Date(e).toISOString()})}Lr();Mr();import{existsSync as di,readFileSync as pi}from"fs";xt();Pr();function cn(t){let e=St(t),n={};if(di(e))try{n=wt(JSON.parse(pi(e,"utf-8")))}catch{n={}}let i=ye.safeParse(n?.requests);return i.success?i.data:ye.parse(void 0)}async function _a(t,e={}){let n=(t.channels??[]).filter(i=>!he.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...he].join(", ")}`}:vt(i=>{let r=i.requests??={};for(let s of["enabled","channels","from","staleAfterHours","retentionDays"])t[s]!==void 0&&(r[s]=t[s])},{configPath:e.configPath,reload:e.reload})}var un=["card","schedule","memory","wiki","whatsapp","request"],mi=280;function L(t,e=mi){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Ae(t){if(t.configPath)return E(t.configPath);let e=[E(t.root,"agentx.json"),E(t.root,".agentx","config.json")];return e.find(n=>re(n))??e[0]}function Ie(t){return t.wikiDir?E(t.wikiDir):E(t.root,".agentx","wiki")}function hi(t){return U(t.root,"pending").map(yi)}function yi(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,created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.context||t.draft?{detail:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function bi(t){let e=Ae(t);if(!re(e))return[];let n;try{n=JSON.parse(gi(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 c=o.timezone||"UTC",l=o.schedule?_t(o.schedule):"",u=o.schedule?`${l.charAt(0).toLowerCase()}${l.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 ${Dt(Ct(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function dn(t){let e=E(t,".agentx","memory");return re(e)?fi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function wi(t){let e=dn(t.root);if(e.length===0)return[];let n=new be(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 ki(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function xi(t){return Nt(Ie(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(`${ki(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Si(t){return tn(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 pn(t){if(t.requests)return t.requests;if(E(t.root)!==process.cwd()||!re(E(t.root,".agentx","db.sqlite")))return null;let e=ht({quiet:!0});if(!e)return null;let n=ln.get(e);return!n&&!yt(e)?null:(n||ln.set(e,n=new bt(e)),n)}var ln=new WeakMap;function vi(t){let e=pn(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 fn={card:hi,schedule:bi,memory:wi,wiki:xi,whatsapp:Si,request:vi};function $i(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 Ba(t,e={}){let n=t.now??Date.now(),{snoozed:i}=R(t.root),r=[],s=[],o=0;for(let a of e.kinds??un){let c;try{c=fn[a](t)}catch(l){s.push({kind:a,error:String(l?.message??l).slice(0,200)});continue}for(let l of c){let u=i[l.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){o++;continue}l.snoozed_until=u}r.push(l)}}return r.sort($i),{items:r,snoozed:o,errors:s}}function Ai(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!un.includes(n)||!i?null:{kind:n,ref:i}}function Ii(t,e,n){switch(e){case"card":return B(t.root,n)?.status==="pending";case"wiki":return Ot(Ie(t),n)?.status==="pending";case"whatsapp":return ne(t.root,n)?.status==="pending";default:return fn[e](t).some(i=>i.key===`${e}:${n}`)}}async function gn(t,e,n,i={}){let r=Ai(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(),c=i.by??"operator";if(n==="later"){if(!Ii(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 sn(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let u=Ft(t.root,o,l?"yes":"no",{by:c,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 ${l?"yes":"no"}${u.card.choice?` (${u.card.choice})`:""}`}:u}case"schedule":{let u=await(l?Et:Tt)(o,{configPath:Ae(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 f=new be(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,l?"approved":"rejected",c),{ok:!0,message:`${e} ${l?"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=Ie(t),d=l?jt(u,o,{by:c,force:i.force,now:a}):Vt(u,o,{by:c,reason:i.note,now:a});return d.ok?{ok:!0,message:l?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await nn(t.root,o,l?"yes":"no",{by:c,now:a,send:t.sendWhatsApp});return u.ok?{ok:!0,message:l?`${e}: sent to ${u.draft.chat_name||u.draft.to}`:`${e}: dropped, nothing sent`}:u}case"request":{let u=pn(t),d=u?.get(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:l?cn(Ae(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 ${c}`,a),{ok:!0,message:`${e}: dropped`})}}}var mn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function za(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/requests"||t.startsWith("/requests/")||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/")}function Ha(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)}function qa(t){return mn.has(t)}function Ka(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(mn.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 Ga(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 Xa(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 ie(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Ri(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function _i(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Ya(t,e=_i()){let n=ie(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Ri(n),s=[ie(t.host),ie(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=ie(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Za(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as Wn,mkdirSync as rs,readFileSync as is,renameSync as ss,writeFileSync as os}from"fs";import{homedir as as}from"os";import{dirname as cs,join as ls}from"path";import{execFile as Vi,execFileSync as Wi}from"child_process";import{execFileSync as Ci}from"child_process";import{existsSync as yn,mkdirSync as Di,readdirSync as Ei,readFileSync as bn,renameSync as Ti,writeFileSync as Pi}from"fs";import{homedir as wn}from"os";import{join as _e}from"path";var S="siri:",kn="com.apple.ttsbundle.gryphon-neural_",xn=t=>!!t&&t.startsWith(kn),Li=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],Mi=()=>{try{return Ci("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Re;function Ce(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Re!==void 0)return Re;let{platform:n=process.platform,exists:i=yn,prefDomain:r=Mi}=t,s=n==="darwin"&&Li.every(o=>i(o))&&r();return e||(Re=s),s}var Sn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],vn={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"},De=t=>vn[t.toLowerCase()]??null;function se(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 Oi=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function Ni(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(Oi)){let o=`${i}-${r}`,a=`${kn}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:vn[s]??null,siri:!0})}return[...e.values()]}function oe(t=Sn,e={}){if(!Ce(e))return[];let n=[];for(let i of t){let r;try{r=Ei(i)}catch{continue}for(let s of r)try{n.push(bn(_e(i,s,"Info.plist"),"latin1"))}catch{}}return Ni(n)}var hn=`#!/bin/sh
|
|
1
|
+
import{a as $e}from"./chunk-GTJIKXDB.js";import{a as te,b as w}from"./chunk-DG5I6PPM.js";import{q as Ht}from"./chunk-S2GAEH2F.js";import{t as Bt,u as Ut}from"./chunk-IXRAL4CW.js";import{d as Wt,e as Ft}from"./chunk-AQASR6KR.js";import{b as zt,c as ve,e as B,f as U,h as qt}from"./chunk-E5OV6RTG.js";import{A as Se,b as xe,v as Ct,x as ee,y as ke}from"./chunk-5AAJ6BPY.js";import{a as Nt,b as jt,d as Vt}from"./chunk-Y4CYQV7G.js";import{a as Dt,b as Et}from"./chunk-SHEUCITK.js";import{g as Tt,h as Pt,i as Lt,k as Mt,l as Ot}from"./chunk-WO7HTHMB.js";import{q as _t}from"./chunk-QPRETJO4.js";import{a as At,b as It}from"./chunk-KRW2M4RY.js";import{Y as we,da as vt,ea as $t,ha as Rt,n as Q,o as bt,p as wt,q as Vr,v as kt,w as St,x as Br}from"./chunk-GIJV3TMB.js";import{a as xt,i as Fr}from"./chunk-RJ7DASOU.js";import{a as be,h as Wr}from"./chunk-BRK6M6LA.js";import{existsSync as Ur,readdirSync as Hr,readFileSync as zr,statSync as qr}from"fs";import{resolve as Kr}from"path";function Kt(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)??[],c=a.filter(g=>n-g.at<=r),l=a.filter(g=>n-g.at>r&&n-g.at<=r*2),u=c.filter(g=>g.status==="failed").length,d=a.filter(g=>g.status==="paused").length,p=a.length?Math.max(...a.map(g=>g.at)):null,f=a.length?l.length>0&&c.length===0?"dormant":c.length>0&&u*2>=c.length?"failing":c.length>0?"active":"quiet":"never";return{id:o.id,name:o.name||o.id,state:f,lastRunAt:p,recent:c.length,prior:l.length,failed:u,paused:d}}).sort((o,a)=>{let c={dormant:0,failing:1,active:2,quiet:3,never:4};return c[o.state]-c[a.state]||(a.lastRunAt??0)-(o.lastRunAt??0)})}var ne=new Map;function pa(t,e=1e3){if(!Ur(t))return[];let n=Hr(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let o=Kr(t,s);return{path:o,mtime:qr(o).mtimeMs}}).sort((s,o)=>o.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of ne.keys())i.has(s)||ne.delete(s);let r=[];for(let{path:s,mtime:o}of n){let a=ne.get(s);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let c=Gr(s,o);ne.set(s,{mtime:o,summary:c}),c&&r.push(c)}return r}function Gr(t,e){try{let n=zr(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]),c=a.status??a.run?.status;if(c){s=c;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var Xr={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},x={routines:200,summary:160,filters:6,filterValue:60,text:120},Jr=(t,e,n)=>{try{return _t(t,e,n)}catch{return null}},Gt=864e5;function ha(t){let e=t.now??Date.now(),n={...Xr,...t.thresholds},i=t.nextFire??Jr,r=[];for(let a of t.crons){let c=t.cronRuns.get(a.id)??[],l=a.timezone||"UTC",u=c.map(f=>({at:Date.parse(f.startedAt),status:f.status})),d=c[0],p={id:`cron:${a.id}`,source:"cron",kind:"schedule",name:$(a.id,x.text),trigger:{schedule:$(a.schedule,x.text),timezone:l},agent:a.agent||null,enabled:a.enabled,state:a.enabled?"enabled":"disabled",nextRunAt:a.enabled?Re(a.nextRun)??Re(i(a.schedule,new Date(e),l)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:ni(d.status==="success"?void 0:d.errorSummary,x.summary)}:null,lastSuccessAt:c.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:Xt(u),sampledRuns:c.length,flags:[],attention:null};p.flags=Jt(p,u,a.schedule,l,null,e,n,i),r.push(Yt(p))}let s=new Map(Kt(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 c=o.get(a.workflowId);c?c.push(a):o.set(a.workflowId,[a])}for(let a of t.workflows){let c=a.nodes.find(I=>I.type.startsWith("trigger."));if(!c||c.type!=="trigger.cron"&&c.type!=="trigger.hook")continue;let l=c.config??{},u=a.state||"active",d=u==="active",p=(o.get(a.id)??[]).slice().sort((I,ye)=>ye.at-I.at),f=p.map(I=>({at:I.at,status:Qr(I.status)})),g=f[0],h=c.type==="trigger.cron",y=typeof l.spec=="string"?l.spec:"",D=typeof l.timezone=="string"?l.timezone:"UTC",N={id:`workflow:${a.id}`,source:"workflow",kind:h?"schedule":"event",name:$(a.title||a.id,x.text),trigger:h?{schedule:$(y,x.text),timezone:D}:{event:$(typeof l.event=="string"?l.event:"",x.text),filters:ti(l.filter,a)},agent:ei(a),enabled:d,state:u,nextRunAt:h&&d&&y?Re(i(y,new Date(e),D)):null,lastRun:g?{at:new Date(g.at).toISOString(),status:g.status}:null,lastSuccessAt:(()=>{let I=f.find(ye=>ye.status==="success");return I?new Date(I.at).toISOString():null})(),consecutiveFailures:Xt(f),sampledRuns:p.length,flags:[],attention:null},Z=Date.parse(a.updated||a.created||"");N.flags=h?Jt(N,f,y,D,Number.isFinite(Z)?Z:null,e,n,i):Yr(N,s.get(a.id)?.state==="dormant",Number.isFinite(Z)?Z:null,e,n),r.push(Yt(N))}return r.sort(Zr).slice(0,x.routines)}function Xt(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 Jt(t,e,n,i,r,s,o,a){let c=[],l=e.length?e[0].at:null;if(!t.enabled){let p=Qt(l,r,s,o);return p&&c.push(p),c}if(t.consecutiveFailures>=o.failStreak&&c.push({reason:"failing",detail:`${t.consecutiveFailures} failed attempts in a row`}),l===null)return c.push({reason:"never-ran",detail:"No persisted attempt"}),c;let u=new Date(l),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&&c.push({reason:"overdue",detail:`No attempt since ${new Date(l).toISOString()}; ${o.missedFires} scheduled fires missed`}),c}function Yr(t,e,n,i,r){let s=[],o=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let a=Qt(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 Qt(t,e,n,i){let r=Math.max(t??0,e??0);return r&&n-r<i.disabledDays*Gt?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/Gt)} days`:"Disabled and never ran"}}function Yt(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 Zt={critical:0,warning:1,info:2};function Zr(t,e){let n=t.attention?Zt[t.attention]:3,i=e.attention?Zt[e.attention]:3;return n-i||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function Qr(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 ei(t){if(t.ownerAgent)return $(t.ownerAgent,x.text);let e=t.nodes.find(n=>n.type==="agent"&&typeof n.config?.agentId=="string"&&n.config.agentId);return e?$(String(e.config.agentId),x.text):null}function ti(t,e){let n=[],i=e?.project;if(i&&n.push($(`project=${i}`,x.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($(`${r}=${o.join(",")}`,x.filterValue))}return n.slice(0,x.filters)}function Re(t){if(!t)return null;let e=t instanceof Date?t:new Date(t);return Number.isFinite(e.getTime())?e.toISOString():null}function $(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function ni(t,e){return t===void 0?void 0:$(t,e)}import{existsSync as se,readdirSync as xi,readFileSync as ki}from"fs";import{resolve as E}from"path";import{randomBytes as nn}from"crypto";import{existsSync as ii,mkdirSync as si,readdirSync as oi,readFileSync as ai,renameSync as rn,unlinkSync as ci,writeFileSync as li}from"fs";import{resolve as sn}from"path";function en(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var ri=t=>t.trim().split(`
|
|
3
|
+
`).pop()?.slice(0,300)||"no output";async function tn(t,e,n,i=$e){let r=await i(t.bin,[...en(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${ri(r.stderr||r.stdout)}`}}async function wa(t,e,n,i,r=$e){return(await r(t.bin,[...en(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var ui=2e3,di=t=>tn(t.wacli,t.to,t.text);function Ae(t){return sn(t,".agentx","whatsapp-triage","drafts")}var pi=t=>/^[a-z0-9-]{8,64}$/.test(t),re=(t,e)=>sn(Ae(t),`${e}.json`);function on(t,e){si(Ae(t),{recursive:!0});let n=re(t,e.id),i=`${n}.${process.pid}.tmp`;li(i,JSON.stringify(e,null,2)+`
|
|
4
|
+
`,{mode:384}),rn(i,n)}function Ra(t,e,n=Date.now()){let i=e.text.trim().slice(0,ui);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${nn(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return on(t,r),r}function ie(t,e){if(!pi(e))return null;try{return JSON.parse(ai(re(t,e),"utf-8"))}catch{return null}}function an(t,e){let n=Ae(t);return ii(n)?oi(n).filter(i=>i.endsWith(".json")).map(i=>ie(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function cn(t,e,n,i={}){let r=ie(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${re(t,e)}.${process.pid}.${nn(3).toString("hex")}.claim`;try{rn(re(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??di)(r).catch(c=>({ok:!1,error:String(c?.message??c)}));a.ok?o.status="sent":(o.status="failed",o.error=a.error)}on(t,o);try{ci(s)}catch{}return o.status==="failed"?{ok:!1,error:o.error??"send failed"}:{ok:!0,draft:o}}import{mkdirSync as fi,readFileSync as gi,renameSync as mi,writeFileSync as hi}from"fs";import{resolve as yi}from"path";function ln(t){return yi(ve(t),"_state.json")}function R(t){try{let e=JSON.parse(gi(ln(t),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{},...e?.popped&&typeof e.popped=="object"?{popped:e.popped}:{},...typeof e?.passAt=="string"?{passAt:e.passAt}:{},...Array.isArray(e?.wanted)?{wanted:e.wanted.filter(n=>typeof n=="string")}:{}}}catch{return{snoozed:{}}}}function H(t,e){fi(ve(t),{recursive:!0});let n=ln(t),i=`${n}.${process.pid}.tmp`;hi(i,JSON.stringify(e,null,2)+`
|
|
5
|
+
`),mi(i,n)}function un(t,e,n,i=Date.now()){let r=R(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),H(t,{...r,snoozed:s})}function Da(t,e){H(t,{...R(t),lastDigest:e})}function dn(t,e,n,i=Date.now()){let r=R(t),s=new Set(n),o={};for(let[c,l]of Object.entries(r.popped??{}))s.has(c)&&(o[c]=l);o[e]=new Date(i).toISOString();let a=(r.wanted??[]).filter(c=>c!==e&&s.has(c));H(t,{...r,popped:o,wanted:a})}function pn(t,e){let n=R(t);H(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function Ea(t,e=Date.now()){H(t,{...R(t),popped:{},passAt:new Date(e).toISOString()})}Fr();Br();import{existsSync as bi,readFileSync as wi}from"fs";Rt();Wr();function fn(t){let e=At(t),n={};if(bi(e))try{n=vt(JSON.parse(wi(e,"utf-8")))}catch{n={}}let i=we.safeParse(n?.requests);return i.success?i.data:we.parse(void 0)}async function Na(t,e={}){let n=(t.channels??[]).filter(i=>!be.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...be].join(", ")}`}:It(i=>{let r=i.requests??={};for(let s of["enabled","channels","from","staleAfterHours","retentionDays"])t[s]!==void 0&&(r[s]=t[s])},{configPath:e.configPath,reload:e.reload})}var mn=["card","schedule","memory","wiki","whatsapp","request"],Si=280;function L(t,e=Si){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Ie(t){if(t.configPath)return E(t.configPath);let e=[E(t.root,"agentx.json"),E(t.root,".agentx","config.json")];return e.find(n=>se(n))??e[0]}function _e(t){return t.wikiDir?E(t.wikiDir):E(t.root,".agentx","wiki")}function vi(t){return U(t.root,"pending").map($i)}function $i(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,created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.context||t.draft?{detail:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Ri(t){let e=Ie(t);if(!se(e))return[];let n;try{n=JSON.parse(ki(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 c=o.timezone||"UTC",l=o.schedule?Tt(o.schedule):"",u=o.schedule?`${l.charAt(0).toLowerCase()}${l.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 ${Lt(Pt(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function hn(t){let e=E(t,".agentx","memory");return se(e)?xi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Ai(t){let e=hn(t.root);if(e.length===0)return[];let n=new xe(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:L(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Ii(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 _i(t){return Ft(_e(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(`${Ii(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Ci(t){return an(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(E(t.root)!==process.cwd()||!se(E(t.root,".agentx","db.sqlite")))return null;let e=xt({quiet:!0});if(!e)return null;let n=gn.get(e);return!n&&!kt(e)?null:(n||gn.set(e,n=new St(e)),n)}var gn=new WeakMap;function Di(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 yn={card:vi,schedule:Ri,memory:Ai,wiki:_i,whatsapp:Ci,request:Di};function Ei(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 Ya(t,e={}){let n=t.now??Date.now(),{snoozed:i}=R(t.root),r=[],s=[],o=0;for(let a of e.kinds??mn){let c;try{c=yn[a](t)}catch(l){s.push({kind:a,error:String(l?.message??l).slice(0,200)});continue}for(let l of c){let u=i[l.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){o++;continue}l.snoozed_until=u}r.push(l)}}return r.sort(Ei),{items:r,snoozed:o,errors:s}}function Ti(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!mn.includes(n)||!i?null:{kind:n,ref:i}}function Pi(t,e,n){switch(e){case"card":return B(t.root,n)?.status==="pending";case"wiki":return Wt(_e(t),n)?.status==="pending";case"whatsapp":return ie(t.root,n)?.status==="pending";default:return yn[e](t).some(i=>i.key===`${e}:${n}`)}}async function bn(t,e,n,i={}){let r=Ti(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(),c=i.by??"operator";if(n==="later"){if(!Pi(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 un(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let u=qt(t.root,o,l?"yes":"no",{by:c,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 ${l?"yes":"no"}${u.card.choice?` (${u.card.choice})`:""}`}:u}case"schedule":{let u=await(l?Mt:Ot)(o,{configPath:Ie(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(!hn(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new xe(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,l?"approved":"rejected",c),{ok:!0,message:`${e} ${l?"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=_e(t),d=l?Bt(u,o,{by:c,force:i.force,now:a}):Ut(u,o,{by:c,reason:i.note,now:a});return d.ok?{ok:!0,message:l?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await cn(t.root,o,l?"yes":"no",{by:c,now:a,send:t.sendWhatsApp});return u.ok?{ok:!0,message:l?`${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}"`}:l?fn(Ie(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 ${c}`,a),{ok:!0,message:`${e}: dropped`})}}}var wn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Qa(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/requests"||t.startsWith("/requests/")||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/")}function ec(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)}function tc(t){return wn.has(t)}function nc(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 rc(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 ic(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function oe(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Li(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function Mi(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function oc(t,e=Mi()){let n=oe(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Li(n),s=[oe(t.host),oe(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=oe(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function ac(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as Hn,mkdirSync as us,readFileSync as ds,renameSync as ps,writeFileSync as fs}from"fs";import{homedir as gs}from"os";import{dirname as ms,join as hs}from"path";import{execFile as qi,execFileSync as Ki}from"child_process";import{execFileSync as Oi}from"child_process";import{existsSync as kn,mkdirSync as Ni,readdirSync as ji,readFileSync as Sn,renameSync as Vi,writeFileSync as Wi}from"fs";import{homedir as vn}from"os";import{join as De}from"path";var S="siri:",$n="com.apple.ttsbundle.gryphon-neural_",Rn=t=>!!t&&t.startsWith($n),Fi=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],Bi=()=>{try{return Oi("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ce;function Ee(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Ce!==void 0)return Ce;let{platform:n=process.platform,exists:i=kn,prefDomain:r=Bi}=t,s=n==="darwin"&&Fi.every(o=>i(o))&&r();return e||(Ce=s),s}var An=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],In={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"},Te=t=>In[t.toLowerCase()]??null;function ae(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var Ui=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function Hi(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(Ui)){let o=`${i}-${r}`,a=`${$n}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:In[s]??null,siri:!0})}return[...e.values()]}function ce(t=An,e={}){if(!Ee(e))return[];let n=[];for(let i of t){let r;try{r=ji(i)}catch{continue}for(let s of r)try{n.push(Sn(De(i,s,"Info.plist"),"latin1"))}catch{}}return Hi(n)}var xn=`#!/bin/sh
|
|
6
6
|
# Written by agentx; shared by the daemon and AgentX Voice. Do not edit.
|
|
7
7
|
# siri-say.sh [voice] < text speak one line. A Siri voice id switches
|
|
8
8
|
# the OS default for it; any other id is
|
|
@@ -14,7 +14,7 @@ D=com.apple.Accessibility K=SpokenContentDefaultVoiceSelectionsByLanguage
|
|
|
14
14
|
dir="$HOME/.agentx/voice" lock="$HOME/.agentx/voice/siri.lock" saved="$HOME/.agentx/voice/siri-saved.plist"
|
|
15
15
|
stops="$dir/stop"
|
|
16
16
|
read_s=\${AGENTX_SAY_READ_S:-5} stale_s=\${AGENTX_SAY_STALE_S:-30} max_s=\${AGENTX_SAY_MAX_S:-300}
|
|
17
|
-
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${
|
|
17
|
+
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${An.join(" ")}"}
|
|
18
18
|
if [ "$1" = --stop ]; then
|
|
19
19
|
mkdir -p "$dir" || exit 1
|
|
20
20
|
# Queued lines see this change and drop. The owner's trap stops say,
|
|
@@ -107,30 +107,32 @@ wait "$say_pid"
|
|
|
107
107
|
status=$?
|
|
108
108
|
say_pid=
|
|
109
109
|
finish $status
|
|
110
|
-
`,
|
|
110
|
+
`,zi=(t=vn())=>De(t,".agentx","voice","siri-say.sh");function _n(t=vn()){let e=zi(t);return kn(e)&&Sn(e,"utf8")===xn||(Ni(De(t,".agentx","voice"),{recursive:!0}),Wi(`${e}.tmp`,xn,{mode:493}),Vi(`${e}.tmp`,e)),e}var Cn=`ObjC.import("AVFoundation")
|
|
111
111
|
const vs = $.AVSpeechSynthesisVoice.speechVoices, out = []
|
|
112
112
|
for (let i = 0; i < vs.count; i++) {
|
|
113
113
|
const v = vs.objectAtIndex(i)
|
|
114
114
|
out.push([v.identifier.js, v.name.js, v.language.js, Number(v.quality), Number(v.gender)].join("\\t"))
|
|
115
115
|
}
|
|
116
|
-
out.join("\\n")`,
|
|
117
|
-
`)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!
|
|
118
|
-
`)[0]}`),j={at:t,voices:
|
|
119
|
-
`),
|
|
120
|
-
${
|
|
116
|
+
out.join("\\n")`,Gi=new Set(["Fred","Kathy","Ralph","Junior"]),Xi={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 Dn(t){let e=[];for(let n of t.split(`
|
|
117
|
+
`)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!Gi.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":Xi[r]??null})}return e}var Ji=10*60*1e3,hc=60*1e3,j=null,Pe=!1;function Le(t=Date.now(),e=Ji){if(process.platform!=="darwin")return[];if(j)t-j.at>e&&!Pe&&(Pe=!0,qi("osascript",["-l","JavaScript","-e",Cn],{timeout:1e4},(n,i)=>{Pe=!1,n||(j={at:Date.now(),voices:[...Dn(String(i)),...ce()]})}));else try{j={at:t,voices:[...Dn(Ki("osascript",["-l","JavaScript","-e",Cn],{encoding:"utf8",timeout:1e4})),...ce()]}}catch(n){Me(`[voice] could not list system voices: ${String(n?.message??n).split(`
|
|
118
|
+
`)[0]}`),j={at:t,voices:ce()}}return j.voices}var Me=t=>process.stderr.write(t+`
|
|
119
|
+
`),le=new Set;function yc(t){Me=t}function M(t,e){le.has(t)||(le.add(t),Me(e))}function Pn(t){for(let e of le)t(e)&&le.delete(e)}var Ln=()=>{};function bc(t){Ln=t}function Mn(t){try{Ln(t)}catch(e){M("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var Yi={premium:3,enhanced:2,standard:1},Zi=new Set(["Grandma","Grandpa"]);function En(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!Zi.has(t.name)?1:0;return Yi[t.quality]*10+e}var V=t=>t.toLowerCase().split(/[-_]/)[0],Tn=t=>t.id.startsWith("com.apple.voice.");function Oe(t,e,n,i=new Set){let r=q(t.filter(a=>!a.siri&&V(a.locale)===V(e)),e);if(r.some(Tn)&&(r=r.filter(Tn)),n==="female"||n==="male"){let a=r.filter(c=>c.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 q(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=V(e),r=t.filter(s=>V(s.locale)===i);return(r.length?r:t).slice().sort((s,o)=>En(o)-En(s)||+(o.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(o.name)||s.locale.localeCompare(o.locale))}function K(t,e,n="en"){let i=t.trim();if(!i)return null;let r=e.find(l=>l.id===i);if(r)return r;if(i.toLowerCase().startsWith(S)){let l=i.slice(S.length).trim().toLowerCase(),u=q(e.filter(p=>p.siri&&p.name.toLowerCase()===l),n)[0];if(u||!l)return u??null;let d=K(l,e.filter(p=>V(p.locale)===V(n)),n);return d&&M(`siri:${l}`,`[voice] Siri voice "${l}" is not installed; speaking with ${d.name} (${d.locale}) instead.`),d}e=e.filter(l=>!l.siri);let s=/^(.+?)\s*\((premium|enhanced)\)$/i.exec(i),o=(s?s[1]:i.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),a=q(e.filter(l=>l.name.toLowerCase()===o),n);return(s?a.find(l=>l.quality===s[2].toLowerCase()):void 0)??a[0]??null}function On(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",c=a?o.gender:s,l=e.filter(d=>!r.has(d.name.toLowerCase())),u=l.find(d=>d.gender===c)??(a?e.find(d=>d.gender===c):void 0)??l[0]??e[i.size%e.length];i.set(o.id,u),r.add(u.name.toLowerCase()),a||(s=s==="female"?"male":"female")}return i}bt();var Ne="system",Qi=t=>t.trim().toLowerCase()===Ne,es="21m00Tcm4TlvDq8ikWAM";function je(t,e,n={},i=Le()){let r=e[t],s=r?.name||t,o=r?.voice,a=We(e,n,i).get(t)??null,c=is(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?de(a):null,systemByLanguage:c,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||os(s,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var de=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function ts(t,e,n,i){if(!e||!n.length)return null;let r=K(e,n,i);return r||(M(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),Mn(e)),r}function Wn(t,e){let n=t.trim();if(n.toLowerCase().startsWith(S))return{locale:e,gender:Te(n.slice(S.length).trim())};let i=ae(n);return i?{locale:i.locale,gender:Te(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var Fn=t=>t.toLowerCase().split(/[-_]/)[0],Nn=(t,e)=>typeof t=="string"?t:t?.[Fn(e)];function ue(t,e,n,i){if(e!==void 0)return Qi(e)?null:ts(t,e,n,i)??void 0}var Ve=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function ns(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,o=[],a=ue("voice.system",Nn(e.system,r),n,r),c=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=Nn(u.system,r),p=ue(u.id,d,n,r),f=p!==void 0?p:d!==void 0&&n.length?rs(u,d,r,a,n,c()):a!==void 0&&Ve(a,u.gender)?a:void 0;f!==void 0?s.set(u.id,f):o.push({id:u.id,gender:u.gender??null})}let l=c();for(let[u,d]of On(o,q(n.filter(p=>!p.siri),r),l))s.set(u,d);return s}function rs(t,e,n,i,r,s){for(let a of t.fallbacks??[]){let c=ue(`${t.id}.fallbacks`,a,r,n);if(c!==void 0)return c}if(i!==void 0&&Ve(i,t.gender))return i;let o=Wn(e,n);return Oe(r,o.locale,t.gender??o.gender,s)??void 0}function is(t,e,n,i,r){if(typeof e=="string")return{};let s={},o=(a,c,l)=>{if(!(!c||typeof c=="string"))for(let[u,d]of Object.entries(c)){let p=ue(`${a}.${u}`,d,r,u);p===void 0&&r.length&&(p=Oe(r,u,n??Wn(d,u).gender)??void 0),p!==void 0&&l(p)&&(s[Fn(u)]=p)}};return o("voice.system",i.system,a=>Ve(a,n)),o(t,e,()=>!0),s}function vc(t,e){let n=e?Q(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?de(i):null}}function We(t,e={},n=Le()){let i=Object.entries(t).map(([r,s])=>({id:r,system:s.voice?.system,gender:s.voice?.gender,fallbacks:s.voice?.fallbacks}));return ns(i,e,n)}function Fe(t,e){let n={provider:t.provider,elevenlabs:ss(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 ss(t,e){return t||e||process.env.AGENTX_VOICE_ID||es}function os(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 as=8*60*60*1e3,cs=500,jn=class{constructor(e=as){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(Vn(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=Vn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>cs&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},Vn=(t,e)=>`${t}\0${e}`;function Bn(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 $c(t,e,n,i={}){let r=e[t],s=je(t,e,i),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:Fe(s),persona:o||`You are ${s.name}.`,introLine:Bn(s,n)}}var ls="[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 Rc(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`${ls}
|
|
120
|
+
${Bn(r,e.voice.introduce===!0&&!!i)}`}var ys="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",zn=(t=gs())=>hs(t,".agentx","voice","health.json");function bs(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===Ne)return!0;if(i.toLowerCase().startsWith(S)){let r=i.slice(S.length).trim().toLowerCase();return e.some(s=>s.siri&&s.name.toLowerCase()===r)}return K(i,e,n)!==null}function ws(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 xs(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:o,perLanguage:a}of ws(t)){if(bs(s,e,o))continue;i??=We(t.agents,t.voice,e);let c=n.get(s)??{voice:s,agents:[],speaksWith:{}};c.agents.includes(r)||c.agents.push(r);let l=i.get(r);r!=="voice.system"&&!a&&(c.speaksWith[r]=l?de(l):"the OS default voice"),n.set(s,c)}return[...n.values()]}function Be(t){let e=ae(t);if(e)return`Siri ${e.name[0].toUpperCase()}${e.name.slice(1)} (${e.locale})`;if(t.toLowerCase().startsWith(S)){let n=t.slice(S.length).trim();return`Siri ${n[0]?.toUpperCase()??""}${n.slice(1)}`}return t}function ks(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${Be(n.voice)}: ${i}`});return{title:t.length===1?"AgentX: a voice is not installed":`AgentX: ${t.length} voices are not installed`,message:`${e.join(`
|
|
121
121
|
`)}
|
|
122
|
-
Reinstall in ${
|
|
123
|
-
`),
|
|
124
|
-
`),
|
|
125
|
-
`)}};function
|
|
126
|
-
`):[]}writeMd(e){let n=
|
|
127
|
-
`))}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(
|
|
128
|
-
`);for(let o=0;o<s.length;o++){let a=s[o].match(
|
|
129
|
-
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),
|
|
130
|
-
`)))}},Ge=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(l=>({name:l.name,color:l.color,text_color:l.text_color})),r=s.map(l=>l.name)):r=e.labels);let a=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(l=>({username:l.username,name:l.name,avatarUrl:l.avatar_url})),c=a[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:c?this.usernameToAgent(c)||c: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`,c=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,l=await this.api(c);for(let u of l){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)),c=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(c)}`,{method:"POST"})}catch(l){this.log(`[business] add_spent_time failed: ${l.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 l of o)try{let u=l==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(l)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,l))}catch(u){this.log(`[business] GitLab listAll failed on ${l}: ${u.message}`)}let c=a;if(e.notLabels?.length){let l=new Set(e.notLabels);c=c.filter(u=>!(u.labels||[]).some(d=>l.has(d)))}if(e.withoutScopedPrefix){let l=e.withoutScopedPrefix+"::";c=c.filter(u=>!(u.labels||[]).some(d=>d.startsWith(l)))}return c}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 l=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${l.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 c=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});return this.mapIssue(c,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 l=>{try{let u=await this.api(`/users?username=${encodeURIComponent(l)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${l}: ${u.message}`),null}}))).filter(l=>typeof l=="number"));let s;if(e.milestoneTitle)try{let c=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(s=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${c.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",c=new URLSearchParams;n.length&&c.set("add_labels",n.join(",")),i.length&&c.set("remove_labels",i.join(",")),c.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?${c.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 Mc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new qe(i.path,e,n);case"wiki":return new Ke(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 Ge(r.host,r.token,o,s,n)}}}var Xe="unmapped";function Je(t,e=[]){if(!t)return Xe;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 Cs(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,Je(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 c=r(a,o);return c&&e.set(s,c),c};for(let s of Object.keys(i))r(s);return e}function Ds(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 Nc(t,e){let n=Ds(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return Je(t.project,e.projects);if(t.agentId){let i=Cs(e).get(t.agentId);if(i)return i}return Xe}function jc(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 Es=t=>t===Xe?"internal":"client";function Ts(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??Es(t),respondWithinMinutes:Ps(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Vc(t){let e=new Set;for(let n of t.projects??[])e.add(Je(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=>Ts(n,t))}function Ps(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 Ls=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,Ms=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function Gn(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(Ms)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=Os(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 Fc(t){if(!t||!t.includes("agentx:ui"))return t;let e=Ls.exec(t);return e?t.slice(0,e.index).trimEnd():t}function Os(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 Uc(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 Ns=5*6e4;function T(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var Xn=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(T)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${T(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 c=Date.now(),l=a.filter(u=>u.expiresAt>c);for(let{signal:u}of l)this.deliverTo(r,u);this.pending.delete(o),l.length&&this.log(`flushed ${l.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
|
|
122
|
+
Reinstall in ${ys}. Agents switch back on their own once it is installed.`}}function Ss(t=zn()){if(!Hn(t))return null;try{let e=JSON.parse(ds(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function vs(t,e){us(ms(t),{recursive:!0}),fs(`${t}.tmp`,JSON.stringify(e,null,2)+`
|
|
123
|
+
`),ps(`${t}.tmp`,t)}var Un=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??zn(),s=new Map((Ss(r)?.missing??[]).map(d=>[d.voice,d])),o=xs(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}:{}})),c=[...s.keys()].filter(d=>!o.some(p=>p.voice===d));for(let d of c)this.deps.log(`[voice] ${Be(d)} is installed again; its agents speak with it again`);c.length&&Pn(d=>c.some(p=>d===p||d.endsWith(`:${p}`)));let l=a.filter(d=>!d.notifiedAt);if(l.length){let{title:d,message:p}=ks(l);try{await this.deps.notify(d,p);for(let f of l)f.notifiedAt=i.toISOString();this.deps.log(`[voice] told the owner: ${l.map(f=>Be(f.voice)).join(", ")} not installed`)}catch(f){this.deps.log(`[voice] could not send the missing-voice notice: ${f?.message??f}`)}}this.missingNow=a.length>0;let u={checkedAt:i.toISOString(),missing:a};return(!Hn(r)||JSON.stringify(a)!==JSON.stringify([...s.values()]))&&vs(r,u),u}finally{this.running=!1}}};import{readFileSync as He,writeFileSync as Yn,existsSync as ze,readdirSync as Ts,statSync as Ps}from"fs";import{resolve as qe,join as Ls}from"path";import{existsSync as qn,mkdirSync as $s,readFileSync as Rs,writeFileSync as Kn}from"fs";import{dirname as As,resolve as Gn}from"path";import{z as m}from"zod";var Is=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),_s=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:Is.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),Cs=m.object({version:m.literal(1),items:m.array(_s).default([])}),pe=class{constructor(e){this.path=e}jsonPath(){return Gn(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return Gn(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return qn(this.jsonPath())}load(){let e=this.jsonPath();if(!qn(e))return{version:1,items:[]};let n=Rs(e,"utf-8");try{return Cs.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();$s(As(n),{recursive:!0}),Kn(n,JSON.stringify(e,null,2)+`
|
|
124
|
+
`),Kn(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 c=s==="done"?"x":" ",l=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(`- [${c}] ${l}${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(`
|
|
125
|
+
`)}};function Nc(t){return`${t.type}:${t.project}:${t.iid}`}function Xn(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 Ue(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?Ds(t.source,e,n,i):t.source.type==="github"?Es(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function Ds(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=[],c=async(f,g={})=>fetch(`${o}/api/v4${f}`,{...g,headers:{"PRIVATE-TOKEN":s,"Content-Type":"application/json",...g.headers||{}}}),l=encodeURIComponent(t.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async g=>{try{let h=await fetch(`${o}/api/v4/users?username=${encodeURIComponent(g)}`,{headers:{"PRIVATE-TOKEN":s}});if(!h.ok)return null;let y=await h.json();return Array.isArray(y)&&y[0]?.id?y[0].id:null}catch{return null}}))).filter(g=>typeof g=="number"));let d;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")d=0;else try{let f=await c(`/projects/${l}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(f.ok){let g=await f.json();Array.isArray(g)&&g[0]?.id&&(d=g[0].id)}}catch(f){i(`[backlog-sync] milestone lookup failed: ${f.message}`)}let p={};if(e.title!==void 0&&(p.title=e.title),e.description!==void 0&&(p.description=e.description),e.labels!==void 0&&(p.labels=e.labels.join(",")),e.addLabels?.length&&(p.add_labels=e.addLabels.join(",")),e.removeLabels?.length&&(p.remove_labels=e.removeLabels.join(",")),u!==void 0&&(p.assignee_ids=u),d!==void 0&&(p.milestone_id=d),e.state&&(p.state_event=e.state==="closed"?"close":"reopen"),Object.keys(p).length)try{let f=await c(`/projects/${l}/issues/${t.iid}`,{method:"PUT",body:JSON.stringify(p)});if(a.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let g=await f.text().catch(()=>"");return{ok:!1,attempts:a,error:`PUT issue ${f.status}: ${g.slice(0,200)}`,url:t.url}}}catch(f){return a.push({kind:"PUT issue",ok:!1,error:f.message}),{ok:!1,attempts:a,error:f.message,url:t.url}}if(e.note)try{let f=await c(`/projects/${l}/issues/${t.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});a.push({kind:"POST note",ok:f.ok,status:f.status})}catch(f){a.push({kind:"POST note",ok:!1,error:f.message})}return{ok:a.every(f=>f.ok),attempts:a,url:t.url}}async function Es(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,f={})=>fetch(`https://api.github.com${p}`,{...f,headers:{Authorization:`Bearer ${s}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...f.headers||{}}}),c=t.project,l;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")l=null;else try{let p=await a(`/repos/${c}/milestones?state=all&per_page=100`);if(p.ok){let f=await p.json(),g=Array.isArray(f)?f.find(h=>h.title===e.milestoneTitle):null;g?.number&&(l=g.number)}}catch(p){i(`[backlog-sync] github milestone lookup failed: ${p.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let p=await a(`/repos/${c}/issues/${t.iid}`);if(p.ok){let f=await p.json(),g=Array.isArray(f.labels)?f.labels.map(y=>typeof y=="string"?y:y.name):[],h=new Set([...g,...e.addLabels??[]]);for(let y of e.removeLabels??[])h.delete(y);u=[...h]}}catch(p){i(`[backlog-sync] github label fetch failed: ${p.message}`)}let d={};if(e.title!==void 0&&(d.title=e.title),e.description!==void 0&&(d.body=e.description),u!==void 0&&(d.labels=u),e.assigneeUsernames!==void 0&&(d.assignees=e.assigneeUsernames),l!==void 0&&(d.milestone=l),e.state&&(d.state=e.state),Object.keys(d).length)try{let p=await a(`/repos/${c}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(o.push({kind:"PATCH issue",ok:p.ok,status:p.status}),!p.ok){let f=await p.text().catch(()=>"");return{ok:!1,attempts:o,error:`PATCH issue ${p.status}: ${f.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/${c}/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 Ke=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,fe=/@([a-z0-9_-]+)/i,Jn=/\[time:\s*([0-9hm\s]+)\]/i;function Ms(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 Ge=class{constructor(e,n,i=()=>{}){this.path=e;this.daemon=n;this.log=i;this.store=new pe(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=qe(process.cwd(),this.path);return ze(e)?He(e,"utf-8").split(`
|
|
126
|
+
`):[]}writeMd(e){let n=qe(process.cwd(),this.path);Yn(n,e.join(`
|
|
127
|
+
`))}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(Ke);if(!s||s[2].toLowerCase()==="x")continue;let a=s[3],c=a.match(fe);if(c&&c[1].toLowerCase()!==e.toLowerCase())continue;let l=a.match(Jn),u=a.replace(fe,"").replace(Jn,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:c?c[1]:void 0,estimatedSeconds:l?Ms(l[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=Xn([r.assignee||e],r.source,this.daemon);Ue(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 c=this.store.update(e,a);if(c.source&&this.daemon){let l={};n.status==="done"?(l.addLabels=["Done"],l.removeLabels=["Doing"]):n.status==="blocked"&&(l.addLabels=["Blocked"]),n.note&&(l.note=n.note),Object.keys(l).length&&Ue(c,l,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(Ke))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"}}},Xe=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(ze(e))for(let i of Ts(e)){let r=Ls(e,i);Ps(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(qe(process.cwd(),this.root),n);let i=[];for(let r of n){let s=He(r,"utf-8").split(`
|
|
128
|
+
`);for(let o=0;o<s.length;o++){let a=s[o].match(Ke);if(!a||a[2].toLowerCase()==="x")continue;let c=a[3].match(fe);!c||c[1].toLowerCase()!==e.toLowerCase()||i.push({id:`wiki:${r}:${o}`,title:a[3].replace(fe,"").trim(),assignee:c[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(!ze(s))return;let o=He(s,"utf-8").split(`
|
|
129
|
+
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),Yn(s,o.join(`
|
|
130
|
+
`)))}},Je=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(l=>({name:l.name,color:l.color,text_color:l.text_color})),r=s.map(l=>l.name)):r=e.labels);let a=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(l=>({username:l.username,name:l.name,avatarUrl:l.avatar_url})),c=a[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:c?this.usernameToAgent(c)||c: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`,c=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,l=await this.api(c);for(let u of l){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)),c=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(c)}`,{method:"POST"})}catch(l){this.log(`[business] add_spent_time failed: ${l.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 l of o)try{let u=l==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(l)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,l))}catch(u){this.log(`[business] GitLab listAll failed on ${l}: ${u.message}`)}let c=a;if(e.notLabels?.length){let l=new Set(e.notLabels);c=c.filter(u=>!(u.labels||[]).some(d=>l.has(d)))}if(e.withoutScopedPrefix){let l=e.withoutScopedPrefix+"::";c=c.filter(u=>!(u.labels||[]).some(d=>d.startsWith(l)))}return c}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 l=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${l.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 c=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});return this.mapIssue(c,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 l=>{try{let u=await this.api(`/users?username=${encodeURIComponent(l)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${l}: ${u.message}`),null}}))).filter(l=>typeof l=="number"));let s;if(e.milestoneTitle)try{let c=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(s=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${c.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",c=new URLSearchParams;n.length&&c.set("add_labels",n.join(",")),i.length&&c.set("remove_labels",i.join(",")),c.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?${c.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 Hc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Ge(i.path,e,n);case"wiki":return new Xe(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 Je(r.host,r.token,o,s,n)}}}var Ye="unmapped";function Ze(t,e=[]){if(!t)return Ye;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 Os(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,Ze(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 c=r(a,o);return c&&e.set(s,c),c};for(let s of Object.keys(i))r(s);return e}function Ns(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 qc(t,e){let n=Ns(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return Ze(t.project,e.projects);if(t.agentId){let i=Os(e).get(t.agentId);if(i)return i}return Ye}function Kc(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 js=t=>t===Ye?"internal":"client";function Vs(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??js(t),respondWithinMinutes:Ws(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Gc(t){let e=new Set;for(let n of t.projects??[])e.add(Ze(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=>Vs(n,t))}function Ws(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 Fs=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,Bs=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function Zn(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(Bs)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=Us(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 Jc(t){if(!t||!t.includes("agentx:ui"))return t;let e=Fs.exec(t);return e?t.slice(0,e.index).trimEnd():t}function Us(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 Hs=5*6e4;function T(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var Qn=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(T)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${T(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 c=Date.now(),l=a.filter(u=>u.expiresAt>c);for(let{signal:u}of l)this.deliverTo(r,u);this.pending.delete(o),l.length&&this.log(`flushed ${l.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
|
|
131
131
|
data: ${JSON.stringify(n)}
|
|
132
132
|
|
|
133
|
-
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=T(e.to);if(n===T(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&&T(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(T(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+
|
|
133
|
+
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=T(e.to);if(n===T(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&&T(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(T(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+Hs),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=T(e.to);for(let r of this.subs)r.callId===e.callId&&T(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()}};var zs=200,er=4e3;function qs(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 Qe(t,e=zs){let n=qs(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 tl(t,e){let n=e.lastAnswer(t.id),i=n&&n.text.length>er?`${n.text.slice(0,er)}
|
|
134
|
+
|
|
135
|
+
\u2026`:n?.text;return{...t,summary:Qe(t.text),textHtml:te(t.text),why:t.state==="waiting_owner"?t.question:t.state==="needs_attention"?t.attentionReason:null,ownerNoteHtml:t.ownerNote?te(t.ownerNote):null,lastAnswer:n?{agentId:n.agentId,at:n.at,html:te(i)}:null}}import{execFile as uo}from"child_process";import{mkdtempSync as ro,rmSync as io,writeFileSync as so}from"fs";import{tmpdir as oo}from"os";import{join as sr}from"path";import{randomBytes as Ks}from"crypto";var _={top:8,side:32,bottom:60},et={height:56,keep:52},tr=`
|
|
134
136
|
:root {
|
|
135
137
|
--ac-paper: #fafaf9; --ac-soft: #f4f4f2; --ac-edge: #e9e9e6;
|
|
136
138
|
--ac-text: #0b1413; --ac-muted: #4a5856; --ac-subtle: #7c8987;
|
|
@@ -259,33 +261,33 @@ button.primary:hover:not(:disabled) { transform: translateY(-1px); background: v
|
|
|
259
261
|
button.primary:disabled { opacity: .55; cursor: not-allowed; }
|
|
260
262
|
kbd { font: 11px var(--ac-mono); color: var(--ac-subtle); }
|
|
261
263
|
button.primary kbd { color: inherit; opacity: .7; }
|
|
262
|
-
`;var
|
|
264
|
+
`;var nr=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),rr=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function Gs(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?nr(n):rr(n)}`}function Xs(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[rr(n)],nr(n)].join(" ")}function Js(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 Ys(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 Zs(t){return t.origin?.kind==="request"?"Hand it back":t.draft?"Send":t.choices?.length?"Choose":"Yes"}var tt=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>`,Qs=tt('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),eo=tt('<path d="m6 15 6-6 6 6"/>'),to=tt('<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=Ks(12).toString("base64"),s=t.choices??[],o=t.origin?.kind==="reminder",a=t.origin?.kind==="request",c=Ys(t),l=s.map((p,f)=>`<button class="opt" role="radio" aria-checked="false" data-i="${f}"><span class="n">${f+1}</span><span class="t">${w(p)}</span>${f===c.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:jt,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:c.index};return`<!doctype html>
|
|
263
265
|
<html lang="en"><head><meta charset="utf-8">
|
|
264
266
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${r}'">
|
|
265
267
|
<title>AgentX</title>
|
|
266
|
-
<style>${
|
|
268
|
+
<style>${tr}</style></head>
|
|
267
269
|
<body><div class="wrap"><main class="card${e.still?" still":""}">
|
|
268
|
-
<div class="head" title="Drag to move"><span class="avatar">${w(
|
|
269
|
-
<div class="who"><b>${w(i)}</b><span>${w(
|
|
270
|
-
<span class="kind${o?"":" decision"}">${o?"Reminder":"Decision"}</span>
|
|
271
|
-
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${
|
|
270
|
+
<div class="head" title="Drag to move"><span class="avatar">${w(Js(i))}</span>
|
|
271
|
+
<div class="who"><b>${w(i)}</b><span>${w(Gs(t.created_at,n))}</span></div>
|
|
272
|
+
<span class="kind${o?"":" decision"}">${o?"Reminder":a?"Request":"Decision"}</span>
|
|
273
|
+
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${eo}</button></div>
|
|
272
274
|
<div class="body"><h1 dir="auto">${w(t.title)}</h1>
|
|
273
275
|
${t.context?`<p class="context" dir="auto">${w(t.context)}</p>`:""}
|
|
274
276
|
<p class="ask" dir="auto">${w(t.ask)}</p>
|
|
275
|
-
${
|
|
276
|
-
${
|
|
277
|
-
${
|
|
277
|
+
${l||u?`<div class="label-row">${l?'<span class="label">Pick one</span>':""}${u}</div>`:""}
|
|
278
|
+
${l?`<div class="options" role="radiogroup">${l}</div>`:""}
|
|
279
|
+
${c.why?`<p class="why" dir="auto">${w(c.why)}</p>`:""}
|
|
278
280
|
${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>
|
|
279
281
|
<textarea id="text" dir="auto" rows="2" spellcheck="true"></textarea>`:""}
|
|
280
|
-
<div class="notes"><div>${
|
|
281
|
-
<div>${
|
|
282
|
+
<div class="notes"><div>${Qs}<span>${a?"It stays in Open requests on the Approvals page until you close it.":`If you don't answer by ${w(Xs(t.expires,n))}: ${w(t.if_silent)}.`}</span></div>
|
|
283
|
+
<div>${to}<span>Nothing goes out until you click.</span></div></div>
|
|
282
284
|
</div><div class="foot"><button class="btn later" id="later">Not now<kbd>esc</kbd></button>
|
|
283
|
-
<button class="btn" id="no"
|
|
284
|
-
<button class="btn primary" id="yes">${
|
|
285
|
+
<button class="btn" id="no">${a?"Drop":"No"}</button>
|
|
286
|
+
<button class="btn primary" id="yes">${Zs(t)}<kbd>\u2318\u21A9</kbd></button></div>
|
|
285
287
|
</main></div>
|
|
286
|
-
<script type="application/json" id="data">${JSON.stringify(
|
|
287
|
-
<script nonce="${r}">${
|
|
288
|
-
</body></html>`}var
|
|
288
|
+
<script type="application/json" id="data">${JSON.stringify(d).replace(/</g,"\\u003c")}</script>
|
|
289
|
+
<script nonce="${r}">${no}</script>
|
|
290
|
+
</body></html>`}var no=`
|
|
289
291
|
(function () {
|
|
290
292
|
var d = JSON.parse(document.getElementById("data").textContent);
|
|
291
293
|
var root = document.documentElement;
|
|
@@ -374,10 +376,10 @@ ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><sp
|
|
|
374
376
|
});
|
|
375
377
|
} catch (e) {}
|
|
376
378
|
})();
|
|
377
|
-
`;var
|
|
379
|
+
`;var ao=440,co=`
|
|
378
380
|
ObjC.import("Cocoa"); ObjC.import("WebKit")
|
|
379
381
|
function run(argv) {
|
|
380
|
-
var path = argv[0], side = ${_.side}, gripTop = ${_.top}, gripEnd = ${_.top+
|
|
382
|
+
var path = argv[0], side = ${_.side}, gripTop = ${_.top}, gripEnd = ${_.top+et.height}, keep = ${et.keep}, w = Number(argv[1]) + 2 * side, h = 420, secs = Number(argv[2]), capture = argv[3] || ""
|
|
381
383
|
var app = $.NSApplication.sharedApplication
|
|
382
384
|
app.setActivationPolicy($.NSApplicationActivationPolicyAccessory)
|
|
383
385
|
ObjC.registerSubclass({ name: "AgentXCardView", superclass: "WKWebView", methods: {
|
|
@@ -447,21 +449,21 @@ function run(argv) {
|
|
|
447
449
|
}
|
|
448
450
|
function gone(why) { return JSON.stringify({ action: "dismiss", why: why }) }
|
|
449
451
|
function quoted(s) { return "'" + String(s).replace(/'/g, "'\\\\''") + "'" }
|
|
450
|
-
`;function
|
|
451
|
-
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&
|
|
452
|
-
`).trim():"",!o||o.length>
|
|
453
|
-
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function
|
|
454
|
-
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function
|
|
452
|
+
`;function lo(t,e){let n=t.trim().split(`
|
|
453
|
+
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&ar.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,`
|
|
454
|
+
`).trim():"",!o||o.length>Nt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...o?{text:o}:{}}}async function or(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=ro(sr(oo(),"agentx-card-"));try{let s=sr(r,"card.html");so(s,ir(t,{...e,still:!!e.capture}),{mode:384});let o=["-l","JavaScript","-e",co,s,String(ao),String(i),...e.capture?[e.capture]:[]],a=await n("/usr/bin/osascript",o,(i+10)*1e3);return a.ok?lo(a.stdout,t):null}finally{io(r,{recursive:!0,force:!0})}}var ar=["not now","timed out","closed"],po=(t,e,n)=>new Promise(i=>{try{uo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),cr=160,lr=15e3;function fo(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>cr?e.slice(0,cr):e}async function go(t,e,n,i){let r=e.sound==="chime"?i?"":"Glass":e.sound,s=r?Ht(r):null;if(s&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),s],lr),e.speak){let o=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...o,"--",fo(t)],lr)}}function pr(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function mo(t,e,n){return pr(["on run argv","activate","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 ur(t,e,n,i,r){return pr(["on run argv","activate","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(`
|
|
455
|
+
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function dr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
|
|
456
|
+
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function nt(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
|
|
455
457
|
|
|
456
|
-
`)}async function
|
|
458
|
+
`)}async function fr(t,e,n={}){let i=n.run??po,r=(e.style??"card")==="card",s=go(t,e,i,r).catch(()=>{});if(r){let o=await or(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,ho(t,e,i)}async function ho(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 l=await n("/usr/bin/osascript",mo(s,nt(t),t.choices),r);if(o=l.stdout.replace(/\n$/,""),!l.ok||!t.choices.includes(o))return{action:"dismiss"};if(!t.draft)return{action:"yes",choice:o}}if(t.draft){let l=o?`${o}
|
|
457
459
|
|
|
458
|
-
Message (edit it if you like):`:`${
|
|
460
|
+
Message (edit it if you like):`:`${nt(t)}
|
|
459
461
|
|
|
460
|
-
Message (edit it if you like):`,d=await n("/usr/bin/osascript",
|
|
461
|
-
`)[0]}); Siri voices will not switch`),null}}var
|
|
462
|
-
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as
|
|
463
|
-
`)[0].slice(0,200);c.push(`${l}: ${d}`),o.log(`[voice] phone transcription with ${l} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:c.join("; ")}]}function
|
|
464
|
-
`)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function
|
|
462
|
+
Message (edit it if you like):`,d=await n("/usr/bin/osascript",ur(s,l,o?["Cancel","Send"]:["Not now","No","Send"],i,Vt(t.draft,o)),r),p=d.ok?dr(d.stdout):null;if(p?.button==="Send"){let f=p.text.trim();return f?{action:"yes",...o?{choice:o}:{},text:f}:{action:"dismiss"}}return p?.button==="No"?{action:"no"}:{action:"dismiss"}}let a=await n("/usr/bin/osascript",ur(s,nt(t),["Not now","No","Yes"],i),r),c=a.ok?dr(a.stdout):null;return c?.button==="Yes"?{action:"yes"}:c?.button==="No"?{action:"no"}:{action:"dismiss"}}var it=24*36e5,rt=!1;function gr(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=R(t.root),o=r?Date.parse(r):NaN,a=U(t.root,"pending").filter(l=>Date.parse(l.expires)>e),c=a.find(l=>s.includes(`card:${l.id}`));if(c)return c;for(let l of a){let u=`card:${l.id}`;if(n[u])continue;let d=i[u];if(d&&Date.parse(d)>e)continue;let p=Date.parse(l.created_at);if(!(e-p>it&&!(p<=o)))return l}return null}function mr(t){try{return z(t)?.listByState("needs_attention")??[]}catch{return[]}}function yo(t){let e=t.now??Date.now(),{popped:n={},snoozed:i}=R(t.root);return mr(t).find(r=>{let s=`request:${r.id}`,o=i[s];return!n[s]&&!(o&&Date.parse(o)>e)&&e-r.updatedAt<=it})??null}function bo(t,e){return{id:t.id,title:Qe(t.text,zt.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+it).toISOString(),raised_by:t.agentId,created_at:new Date(t.createdAt).toISOString(),status:"pending",origin:{kind:"request",id:t.id}}}async function _l(t){let{ctx:e,settings:n,log:i}=t;if(!n.enabled||(t.platform??process.platform)!=="darwin")return"off";if(rt)return"busy";let r=gr(e)?null:yo(e),s=r?bo(r,e.now??Date.now()):gr(e);if(!s)return"none";let o=(t.focus??Dt)();if(o.active)return"held";rt=!0;let a=`${r?"request":"card"}:${s.id}`;try{let c=[...U(e.root,"pending").map(p=>`card:${p.id}`),...mr(e).map(p=>`request:${p.id}`)];dn(e.root,a,c,e.now),i(`[approvals] popup: showing ${a} from ${s.raised_by}`);let l=await(t.show??fr)(s,n,{from:t.agentName?.(s.raised_by)});if(l.action==="dismiss")return i(`[approvals] popup: ${a} left waiting: ${l.why??"no answer"} (${Et(o)} when shown)`),"shown";if(!(r?z(e)?.get(r.id)?.state==="needs_attention":B(e.root,s.id)?.status==="pending"))return i(`[approvals] popup: ${a} was answered elsewhere; popup answer ignored`),"shown";let d=await bn(e,a,l.action,{by:"operator (popup)",...l.action==="yes"?{choice:l.choice,text:l.text}:{}});return i(d.ok?`[approvals] popup: ${d.message}`:`[approvals] popup: ${a} not recorded: ${d.error}`),"shown"}catch(c){return i(`[approvals] popup failed for ${a}: ${c?.message??c}`),"shown"}finally{rt=!1}}function Cl(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:")?B(t.root,e.slice(5)):null;return i?i.status!=="pending"?{ok:!1,error:`${e} is already ${i.status}`}:(pn(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 G,createReadStream as wo,fstatSync as xo,openSync as ko,realpathSync as hr}from"fs";import{isAbsolute as So,resolve as yr,sep as br}from"path";var Ml="/app-files",vo=/^[A-Za-z0-9_.:-]{1,64}$/;function $o(t,e,n=process.cwd()){if(!e||e.length>ee.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 ${Se}/ first`};if(!ke(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=hr(yr(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=hr(So(e)?e:yr(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+br))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${Se}/ first`};let s=ke(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function Ro(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 Ao(t,e,n){return{"Content-Type":t,"Content-Disposition":Ro(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 Io(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 Ol(t,e,n,i){let r=(D,N)=>{e.writeHead(D,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(N))};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(!vo.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 c=$o(a,o,i.cwd);if(!c.ok)return i.log?.(`[app-files] refused ${JSON.stringify(o.slice(0,200))} from ${s}: ${c.error}`),r(c.status,{error:c.error});let l;try{l=ko(c.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let D=xo(l);if(!D.isFile())return G(l),r(404,{error:"not a file"});u=D.size}catch{return G(l),r(404,{error:"file not found"})}if(u>ee.bytes)return G(l),r(413,{error:`the file is larger than ${ee.bytes/1024/1024} MB`});let d=c.path.split(br).pop()||"file",p=Ao(c.mime,d,c.kind),f=Io(t.headers.range,u);if(f==="unsatisfiable"){G(l),e.writeHead(416,{...p,"Content-Range":`bytes */${u}`}),e.end();return}let{start:g,end:h}=f??{start:0,end:u-1};if(e.writeHead(f?206:200,{...p,"Content-Length":String(u?h-g+1:0),...f?{"Content-Range":`bytes ${g}-${h}/${u}`}:{}}),t.method==="HEAD"||u===0){G(l),e.end();return}let y=wo("",{fd:l,start:g,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as X}from"child_process";import{readFileSync as _o,writeFileSync as Co}from"fs";import{tmpdir as Do}from"os";import{join as Eo}from"path";bt();var wr=t=>t&&t!==1?Math.round(175*t):null,ge=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function To(){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=_o(t,"utf8").trim();if(e)return e}catch{}return null}function zl(t=To()){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",...ge(n.voice.rate)?{voice_settings:{speed:ge(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=Eo(Do(),`agentx-say-${process.pid}-${++e}.mp3`);return Co(s,Buffer.from(await r.arrayBuffer())),s}catch(r){if(i.aborted||!n.voice.fallback)throw r;return M(`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 xr(t,e){let n=t.languages&&Q(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var Po=(t,e="")=>{let n=xr(t,e),i=wr(t.rate);return[...n&&!Rn(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function Lo(t,e,n){if(!n)return["say",Po(t,e)];let i=xr(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function ql(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Kl(t=st()){if(t)try{X("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function Gl(t=st()){if(t)try{X("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function st(t={},e){if(!Ee(t))return null;try{return _n(e)}catch(n){return M("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
|
|
463
|
+
`)[0]}); Siri voices will not switch`),null}}var Xl=(t,e)=>{if(!t){let[n,i]=Lo(e.voice,e.text,st()),r=wr(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=X(n,i,{stdio:["pipe","ignore","ignore"],env:s});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?X("afplay",[t],{stdio:"ignore"}):X("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as kr}from"child_process";import{accessSync as Mo,constants as Oo,readFileSync as Sr}from"fs";import{homedir as No}from"os";import{basename as W,delimiter as vr,dirname as jo,extname as Vo,join as ot}from"path";var P={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function $r(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:ct()}:null}var ct=()=>`The recording is longer than ${P.ms/6e4} minutes.`,Wo={"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 Rr(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return Wo[e]??null}function Ar(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 lt(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 at(t,e,n=process.env.PATH??""){let i=No(),r=[ot(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(vr).filter(Boolean)];for(let s of[e,...r.map(o=>ot(o,t))])if(s)try{return Mo(s,Oo.X_OK),s}catch{}return null}function tu(t){return{key:t,mlx:at("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:at("whisper",process.env.AGENTX_WHISPER),ffmpeg:Fo()}}var Fo=()=>at("ffmpeg",process.env.AGENTX_FFMPEG);async function Ir(t,e){return e?Bo(t,e):null}async function Bo(t,e){let n=String(P.ms/1e3+5);try{let r=[...(await Uo(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 _r(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([Sr(t)],{type:e}),W(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 Cr(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:`${jo(i)}${vr}${process.env.PATH??""}`};await Ho(e,s,12e4,o);try{return Sr(ot(r,W(n,Vo(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function Uo(t,e,n){return new Promise((i,r)=>{let s=kr(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${W(t)} took too long`))},n);s.stderr.on("data",c=>{o=(o+c).slice(-8192)}),s.on("error",c=>{clearTimeout(a),r(c)}),s.on("exit",c=>{clearTimeout(a),c===0?i(o):r(new Error(`${W(t)} exited ${c}`))})})}function Ho(t,e,n,i=process.env){return new Promise((r,s)=>{let o=kr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),a="",c="",l=setTimeout(()=>{o.kill("SIGKILL"),s(new Error(`${W(t)} took longer than ${n/1e3}s`))},n);o.stdout.on("data",u=>{a.length<4096&&(a+=u)}),o.stderr.on("data",u=>{c.length<4096&&(c+=u)}),o.on("error",u=>{clearTimeout(l),s(u)}),o.on("exit",u=>{clearTimeout(l),u===0?r(a):s(new Error(`${W(t)} exited ${u}: ${c.trim().split(`
|
|
464
|
+
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as zo,rm as qo,writeFile as Ko}from"fs/promises";import{tmpdir as Go}from"os";import{join as Dr}from"path";Vr();var Xo=64*1024,Jo=2,ut=0;function pu(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function fu(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?Yo(t,e,i):ea(t,e,i)}async function Yo(t,e,n){let i=String(t.headers["content-type"]||""),r=Rr(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=$r(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let o=await Er(t,P.bytes);if(!o)return b(e,413,{error:ra()});if(!o.length)return b(e,400,{error:"The recording is empty."});if(ut>=Jo)return b(e,429,{error:"This computer is already writing down other recordings. Try again in a moment."});let a=n.stt(),c=n.host(),l=Ar(a,c);if(!c.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",p=l.length?"":" "+lt(a,c);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(!l.length)return b(e,503,{error:"Voice input isn't set up on this computer.",hint:lt(a,c),setup:!1});ut++;let u;try{let d=await zo(Dr(Go(),"agentx-phone-voice-"));try{u=await Zo(d,`speech.${r}`,o,i,c,l,n)}finally{await qo(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{ut--}b(e,u[0],u[1])}async function Zo(t,e,n,i,r,s,o){let a=Dr(t,e);if(await Ko(a,n,{mode:384}),r.ffmpeg){let l=await(o.measure??Ir)(a,r.ffmpeg);if(l==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(l*1e3>P.ms+2e3)return[413,{error:ct()}]}let c=[];for(let l of s)try{let u=await Qo(l,a,i,r,t,o);return o.log(`[voice] phone recording transcribed with ${l} (${Math.round(n.length/1024)} KB)`),u?[200,{text:u,engine:l}]:[422,{error:"No words were heard. Hold the orb and speak, then let go.",engine:l}]}catch(u){let d=String(u?.message??u).split(`
|
|
465
|
+
`)[0].slice(0,200);c.push(`${l}: ${d}`),o.log(`[voice] phone transcription with ${l} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:c.join("; ")}]}function Qo(t,e,n,i,r,s){let o=s.engines?.[t];if(o)return o(e,n,i,r);if(t==="elevenlabs")return _r(e,n,i.key);let a=t==="mlx-whisper"?i.mlx:i.whisper;return Cr(t,a,e,i.ffmpeg,r)}async function ea(t,e,n){let i=await Er(t,Xo);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=ta(typeof r?.text=="string"?r.text:"",n.spokenMaxChars?.());if(!a)return b(e,422,{error:"Nothing in this answer can be said aloud."});let c=n.voiceOf(s,o);if(!c)return b(e,404,{error:`Unknown agent: ${s}`});let l=(d,p=200)=>b(e,p,{fallback:"browser",reason:d,text:a});if(c.provider!=="elevenlabs")return l("This agent speaks with a system voice, which only plays on the computer.");let u=n.elevenLabsKey();if(!u)return l("No ElevenLabs key is set on this computer.");try{let d=await(n.synth??na)(u,c,a);e.writeHead(200,{"Content-Type":"audio/mpeg","Content-Length":d.length,"Cache-Control":"no-store","X-Spoken-Chars":String(a.length)}),e.end(d)}catch(d){return n.log(`[voice] phone answer synthesis failed: ${String(d?.message??d).split(`
|
|
466
|
+
`)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function ta(t,e){let n=Zn(Ct(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return wt(n,e)}async function na(t,e,n){let i=ge(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 ra=()=>`The recording is larger than ${P.bytes/1024/1024} MB, more than ${P.ms/6e4} minutes of speech.`;function gu(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Fe(je(t,r,n.voice)):null}function Er(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 v,readFileSync as gt,writeFileSync as mt,mkdirSync as me,readdirSync as ft,rmSync as ia,statSync as A}from"fs";import{resolve as Tr,relative as sa,dirname as ht,join as O,extname as J,basename as yt}from"path";var k=200*1024,Pr=new Set([".md",".markdown",".txt"]),F=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"]),oa=6,aa=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function C(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=Tr(t);if(v(n)||me(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=Tr(n,e);if(sa(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function Lr(t){let e=J(t).toLowerCase();if(!Pr.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function dt(t,e){let n=t.split(/\r?\n/).find(i=>i.trim().startsWith("#"));return n&&n.replace(/^#+\s*/,"").trim().slice(0,120)||e}function bu(t){let e=C(t,"."),n=[],i=new Set,r=[];try{r=ft(e)}catch{}for(let a of aa){let c=O(e,a);if(v(c)&&A(c).isFile()){let l=A(c).size,u=l>0&&l<k?pt(c):"";n.push({path:a,title:dt(u,a),size:l,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 c=O(e,a);try{let l=A(c);if(!l.isFile()||!Pr.has(J(a).toLowerCase()))continue;let u=l.size>0&&l.size<k?pt(c):"";n.push({path:a,title:dt(u,a),size:l.size,exists:!0})}catch{}}let s=[],o=O(e,".claude","skills");if(v(o))try{for(let a of ft(o)){let c=O(o,a),l;try{l=A(c)}catch{continue}if(!l.isDirectory())continue;let u=O(c,"SKILL.md");if(!v(u))continue;let d=A(u),p=d.size<k?pt(u):"";s.push({slug:a,title:dt(p,a),size:d.size,path:`.claude/skills/${a}/SKILL.md`})}}catch{}return s.sort((a,c)=>a.slug.localeCompare(c.slug)),{identity:n,skills:s,workspace:e}}function pt(t){try{return gt(t,"utf-8")}catch{return""}}function wu(t,e){let n=C(t,e);if(Lr(n),!v(n))return{path:e,content:""};if(A(n).size>k)throw new Error(`File is too large to edit in the admin panel (> ${k/1024} KB).`);return{path:e,content:gt(n,"utf-8")}}function xu(t,e,n){let i=C(t,e);Lr(i);let r=Buffer.from(n,"utf-8");if(r.length>k)throw new Error(`File too large (${r.length} > ${k} bytes).`);return me(ht(i),{recursive:!0}),mt(i,r),{path:e,bytes:r.length}}function ku(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=C(t,i);if(v(r))throw new Error(`Skill "${e}" already exists.`);me(ht(r),{recursive:!0});let s=n.content?.trim()?n.content:ca(e,n.title);return mt(r,s),{slug:e,path:i}}function Su(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);if(!A(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return ia(n,{recursive:!0,force:!0}),{slug:e}}function vu(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(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,c){if(a>oa)return;let l=[];try{l=ft(s)}catch{return}for(let u of l){if(u==="node_modules"||u===".git")continue;let d=O(s,u),p=o?`${o}/${u}`:u,f;try{f=A(d)}catch{continue}if(f.isDirectory())c.push({path:`${p}/`,kind:"dir",size:0,editable:!1}),r(d,p,a+1,c);else if(f.isFile()){let g=J(u).toLowerCase(),h=F.has(g)||F.has(u.toLowerCase());c.push({path:p,kind:"file",size:f.size,editable:h&&f.size<k})}}}}function $u(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=C(t,`.claude/skills/${e}/${n}`);if(!v(i)||!A(i).isFile())throw new Error(`File not found: ${n}`);let r=J(i).toLowerCase(),s=yt(i).toLowerCase();if(!F.has(r)&&!F.has(s))throw new Error(`File type not editable: ${n}`);if(A(i).size>k)throw new Error(`File too large to edit (> ${k/1024} KB): ${n}`);return{path:n,content:gt(i,"utf-8")}}function Ru(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=C(t,`.claude/skills/${e}/${n}`),s=J(r).toLowerCase(),o=yt(r).toLowerCase();if(!F.has(s)&&!F.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(i,"utf-8");if(a.length>k)throw new Error(`File too large (${a.length} > ${k} bytes).`);return me(ht(r),{recursive:!0}),mt(r,a),{path:n,bytes:a.length}}function Au(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);let i=r=>v(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 ca(t,e){return`# ${e?.trim()||t}
|
|
465
467
|
|
|
466
468
|
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.
|
|
467
469
|
|
|
@@ -474,7 +476,7 @@ Document the arguments, commands, or files the skill expects. Example:
|
|
|
474
476
|
|
|
475
477
|
\`\`\`bash
|
|
476
478
|
# Example invocation
|
|
477
|
-
claude-code ${
|
|
479
|
+
claude-code ${yt(t)} --arg value
|
|
478
480
|
\`\`\`
|
|
479
|
-
`}
|
|
480
|
-
//# sourceMappingURL=chunk-
|
|
481
|
+
`}Rt();var Mr={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function Or(t){return{...Mr,...t??{},regions:{...t?.regions??{}},buffer:{...Mr.buffer,...t?.buffer??{}}}}function Cu(t){try{return Or($t(t).screen)}catch{return Or(void 0)}}var la=/^[a-z][\w-]*$/,Nr=["window","screen","menubar","notifications"];function Y(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 he=(t,e)=>Y(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function jr(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 Du(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=he(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=he(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=he(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Y(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Y(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(!la.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);o===null?delete r[s]:r[s]=jr(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=Y(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Y(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=he(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&&!Nr.includes(i)&&!n.regions?.[i])try{jr(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...Nr,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{Kt as a,pa as b,Ze as c,Os as d,Ns as e,qc as f,Kc as g,Gc as h,Zn as i,Jc as j,Zc as k,T as l,Qn as m,x as n,ha as o,wa as p,di as q,Ra as r,cn as s,R as t,Da as u,Ea as v,fn as w,Na as x,z as y,Ya as z,bn as A,tl as B,fr as C,_l as D,Cl as E,Ml as F,Ao as G,Ol as H,Qa as I,ec as J,tc as K,nc as L,rc as M,ic as N,oc as O,ac as P,hc as Q,Le as R,yc as S,bc as T,q as U,K as V,To as W,zl as X,ql as Y,Kl as Z,Gl as _,st as $,Xl as aa,Ne as ba,je as ca,de as da,ns as ea,is as fa,vc as ga,We as ha,Fe as ia,ss as ja,os as ka,jn as la,Bn as ma,$c as na,ls as oa,Rc as pa,ys as qa,xs as ra,Be as sa,Ss as ta,Un as ua,P as va,$r as wa,Rr as xa,Ar as ya,tu as za,Fo as Aa,_r as Ba,Cr as Ca,pu as Da,fu as Ea,ra as Fa,gu as Ga,Er as Ha,pe as Ia,Nc as Ja,Xn as Ka,Ue as La,Je as Ma,Hc as Na,bu as Oa,wu as Pa,xu as Qa,ku as Ra,Su as Sa,vu as Ta,$u as Ua,Ru as Va,Au as Wa,Mr as Xa,Or as Ya,Cu as Za,Nr as _a,Du as $a};
|
|
482
|
+
//# sourceMappingURL=chunk-D3PXRTOR.js.map
|