agentix-cli 0.79.4 → 0.80.1
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-PFMTQ7J5.js → App-KVH5POXZ.js} +2 -2
- package/dist/{ChatApp-ZBSU2F6J.js → ChatApp-LD4TXJWP.js} +2 -2
- package/dist/{agent-AMU6E27Z.js → agent-FUMJM6OW.js} +2 -2
- package/dist/{board-dashboard-OJSOA4OL.js → board-dashboard-OS5J3F73.js} +340 -215
- package/dist/board-dashboard-OS5J3F73.js.map +1 -0
- package/dist/{chunk-LPDQ2KK4.js → chunk-3UN6CXRL.js} +2 -2
- package/dist/chunk-42Y3BXXS.js +15 -0
- package/dist/{chunk-YKPISR5J.js.map → chunk-42Y3BXXS.js.map} +1 -1
- package/dist/chunk-6JJ3GODZ.js +57 -0
- package/dist/chunk-6JJ3GODZ.js.map +1 -0
- package/dist/{chunk-LNQOJC57.js → chunk-7IGSJGXI.js} +2 -2
- package/dist/{chunk-ROIPXJ6L.js → chunk-AF46YOLU.js} +192 -191
- package/dist/chunk-AF46YOLU.js.map +1 -0
- package/dist/chunk-API4IZZG.js +2 -0
- package/dist/chunk-API4IZZG.js.map +1 -0
- package/dist/{chunk-T7GFKM63.js → chunk-BEHC3X42.js} +191 -195
- package/dist/chunk-BEHC3X42.js.map +1 -0
- package/dist/{chunk-EAYHYAF3.js → chunk-BJPIRNP6.js} +2 -2
- package/dist/{chunk-2ZQ42Q4L.js → chunk-BVZFYBBP.js} +2 -2
- package/dist/chunk-GTJIKXDB.js +2 -0
- package/dist/chunk-GTJIKXDB.js.map +1 -0
- package/dist/{chunk-M4XUZA3O.js → chunk-H7253EHW.js} +2 -2
- package/dist/{chunk-EUVMKZUC.js → chunk-MOQNLS5Z.js} +2 -2
- package/dist/{chunk-XFCSJUGY.js → chunk-MYRSNJJ4.js} +2 -2
- package/dist/{chunk-X6WZ54UJ.js → chunk-NOAAK2XI.js} +79 -79
- package/dist/chunk-NOAAK2XI.js.map +1 -0
- package/dist/chunk-OVN5LVJY.js +11 -0
- package/dist/chunk-OVN5LVJY.js.map +1 -0
- package/dist/{chunk-7QRCAHPX.js → chunk-PE55MMLK.js} +2 -2
- package/dist/{chunk-6SJTBTDG.js → chunk-R42S57G6.js} +2 -2
- package/dist/chunk-SHEUCITK.js +2 -0
- package/dist/chunk-SHEUCITK.js.map +1 -0
- package/dist/{chunk-WVYOXM45.js → chunk-TEFMZY6B.js} +2 -2
- package/dist/{chunk-WNI2P7S6.js → chunk-UB63NQQL.js} +2 -2
- package/dist/{chunk-HTKSZZXK.js → chunk-UR3ZIDMA.js} +2 -2
- package/dist/{chunk-MGCTX2BB.js → chunk-UXSYVMPK.js} +2 -2
- package/dist/{chunk-5RRORS5S.js → chunk-XESESMKN.js} +57 -57
- package/dist/chunk-XESESMKN.js.map +1 -0
- package/dist/{chunk-CNSPC4BZ.js → chunk-YCI3KUYF.js} +2 -2
- package/dist/{chunk-R7WZUUYO.js → chunk-Z3XUGXPD.js} +2 -2
- package/dist/{chunk-RD5EKHGZ.js → chunk-ZR3NZLJL.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/client-TJ5YZOEE.js +2 -0
- package/dist/config-4WZ7Y34V.js +2 -0
- package/dist/config-mutator-5Z7EEB5N.js +2 -0
- package/dist/{doctor-DST4SVW4.js → doctor-7K3NRBNN.js} +2 -2
- package/dist/{facts-2K6UX5GD.js → facts-U7BUYRXN.js} +2 -2
- package/dist/{facts-2K6UX5GD.js.map → facts-U7BUYRXN.js.map} +1 -1
- package/dist/index.d.ts +82 -12
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/program-KMQNX6YK.js +2 -0
- package/dist/{promote-CQCRZCYB.js → promote-NDC3X54P.js} +2 -2
- package/dist/query-F7BD3JPE.js +2 -0
- package/dist/registry-5NBHBVY3.js +2 -0
- package/dist/{request-planner-TNDIQMHS.js → request-planner-H74KHFGJ.js} +2 -2
- package/dist/{review-candidates-SXVIYCVE.js → review-candidates-IPJWEXR2.js} +2 -2
- package/dist/routing-3RSG7SKW.js +2 -0
- package/dist/schedule-tool-7NYAK43U.js +2 -0
- package/dist/scheduler-24O7PADJ.js +2 -0
- package/dist/seat-TOM2WHQR.js +2 -0
- package/dist/{select-WKMMUWLU.js → select-BUWOD47K.js} +2 -2
- package/dist/{set-enabled-RIE3PLNJ.js → set-enabled-XWSFTICB.js} +2 -2
- package/dist/tool-GUINJ2BQ.js +4 -0
- package/dist/tool-GUINJ2BQ.js.map +1 -0
- package/dist/tool-VOA4HSVP.js +4 -0
- package/dist/tool-VOA4HSVP.js.map +1 -0
- package/dist/wiki-VFME4T2H.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-OJSOA4OL.js.map +0 -1
- package/dist/chunk-2ACZWM7F.js +0 -22
- package/dist/chunk-2ACZWM7F.js.map +0 -1
- package/dist/chunk-5RRORS5S.js.map +0 -1
- package/dist/chunk-7XB2CVC3.js +0 -2
- package/dist/chunk-7XB2CVC3.js.map +0 -1
- package/dist/chunk-ROIPXJ6L.js.map +0 -1
- package/dist/chunk-T7GFKM63.js.map +0 -1
- package/dist/chunk-X6WZ54UJ.js.map +0 -1
- package/dist/chunk-YKPISR5J.js +0 -15
- package/dist/client-XAE7NLE2.js +0 -2
- package/dist/config-5HAWFIEL.js +0 -2
- package/dist/config-mutator-Y7KAC4AC.js +0 -2
- package/dist/program-SSCPEHTW.js +0 -2
- package/dist/query-WSLKGCQN.js +0 -2
- package/dist/registry-6HKQKIBD.js +0 -2
- package/dist/routing-GQWG65DQ.js +0 -2
- package/dist/schedule-tool-WXRMJMW6.js +0 -2
- package/dist/scheduler-YW6JFH3Z.js +0 -2
- package/dist/seat-K2JSQIZ4.js +0 -2
- package/dist/tool-TAMRBONN.js +0 -4
- package/dist/tool-TAMRBONN.js.map +0 -1
- package/dist/wiki-WBRXHY7J.js +0 -2
- /package/dist/{App-PFMTQ7J5.js.map → App-KVH5POXZ.js.map} +0 -0
- /package/dist/{ChatApp-ZBSU2F6J.js.map → ChatApp-LD4TXJWP.js.map} +0 -0
- /package/dist/{agent-AMU6E27Z.js.map → agent-FUMJM6OW.js.map} +0 -0
- /package/dist/{chunk-LPDQ2KK4.js.map → chunk-3UN6CXRL.js.map} +0 -0
- /package/dist/{chunk-LNQOJC57.js.map → chunk-7IGSJGXI.js.map} +0 -0
- /package/dist/{chunk-EAYHYAF3.js.map → chunk-BJPIRNP6.js.map} +0 -0
- /package/dist/{chunk-2ZQ42Q4L.js.map → chunk-BVZFYBBP.js.map} +0 -0
- /package/dist/{chunk-M4XUZA3O.js.map → chunk-H7253EHW.js.map} +0 -0
- /package/dist/{chunk-EUVMKZUC.js.map → chunk-MOQNLS5Z.js.map} +0 -0
- /package/dist/{chunk-XFCSJUGY.js.map → chunk-MYRSNJJ4.js.map} +0 -0
- /package/dist/{chunk-7QRCAHPX.js.map → chunk-PE55MMLK.js.map} +0 -0
- /package/dist/{chunk-6SJTBTDG.js.map → chunk-R42S57G6.js.map} +0 -0
- /package/dist/{chunk-WVYOXM45.js.map → chunk-TEFMZY6B.js.map} +0 -0
- /package/dist/{chunk-WNI2P7S6.js.map → chunk-UB63NQQL.js.map} +0 -0
- /package/dist/{chunk-HTKSZZXK.js.map → chunk-UR3ZIDMA.js.map} +0 -0
- /package/dist/{chunk-MGCTX2BB.js.map → chunk-UXSYVMPK.js.map} +0 -0
- /package/dist/{chunk-CNSPC4BZ.js.map → chunk-YCI3KUYF.js.map} +0 -0
- /package/dist/{chunk-R7WZUUYO.js.map → chunk-Z3XUGXPD.js.map} +0 -0
- /package/dist/{chunk-RD5EKHGZ.js.map → chunk-ZR3NZLJL.js.map} +0 -0
- /package/dist/{client-XAE7NLE2.js.map → client-TJ5YZOEE.js.map} +0 -0
- /package/dist/{config-5HAWFIEL.js.map → config-4WZ7Y34V.js.map} +0 -0
- /package/dist/{config-mutator-Y7KAC4AC.js.map → config-mutator-5Z7EEB5N.js.map} +0 -0
- /package/dist/{doctor-DST4SVW4.js.map → doctor-7K3NRBNN.js.map} +0 -0
- /package/dist/{program-SSCPEHTW.js.map → program-KMQNX6YK.js.map} +0 -0
- /package/dist/{promote-CQCRZCYB.js.map → promote-NDC3X54P.js.map} +0 -0
- /package/dist/{query-WSLKGCQN.js.map → query-F7BD3JPE.js.map} +0 -0
- /package/dist/{registry-6HKQKIBD.js.map → registry-5NBHBVY3.js.map} +0 -0
- /package/dist/{request-planner-TNDIQMHS.js.map → request-planner-H74KHFGJ.js.map} +0 -0
- /package/dist/{review-candidates-SXVIYCVE.js.map → review-candidates-IPJWEXR2.js.map} +0 -0
- /package/dist/{routing-GQWG65DQ.js.map → routing-3RSG7SKW.js.map} +0 -0
- /package/dist/{schedule-tool-WXRMJMW6.js.map → schedule-tool-7NYAK43U.js.map} +0 -0
- /package/dist/{scheduler-YW6JFH3Z.js.map → scheduler-24O7PADJ.js.map} +0 -0
- /package/dist/{seat-K2JSQIZ4.js.map → seat-TOM2WHQR.js.map} +0 -0
- /package/dist/{select-WKMMUWLU.js.map → select-BUWOD47K.js.map} +0 -0
- /package/dist/{set-enabled-RIE3PLNJ.js.map → set-enabled-XWSFTICB.js.map} +0 -0
- /package/dist/{wiki-WBRXHY7J.js.map → wiki-VFME4T2H.js.map} +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import{
|
|
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
|
-
`,"utf-8")}create(e){if(!e.name?.trim())throw new Error("Token name is required.");if(!Array.isArray(e.scopes)||e.scopes.length===0)throw new Error("At least one scope is required.");for(let o of e.scopes)if(!
|
|
4
|
-
`).pop()?.slice(0,300)||"no output";async function
|
|
5
|
-
`,{mode:384}),
|
|
6
|
-
`),
|
|
7
|
-
`)}import{mkdirSync as
|
|
8
|
-
`),Pi(i,n)}function cn(t,e,n,i=Date.now()){let r=C(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),K(t,{...r,snoozed:s})}function lc(t,e){K(t,{...C(t),lastDigest:e})}function ln(t,e,n,i=Date.now()){let r=C(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));K(t,{...r,popped:o,wanted:a})}function dn(t,e){let n=C(t);K(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function dc(t,e=Date.now()){K(t,{...C(t),popped:{},passAt:new Date(e).toISOString()})}var un=["card","schedule","memory","wiki","whatsapp"],Vi=280;function G(t,e=Vi){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function pn(t){if(t.configPath)return W(t.configPath);let e=[W(t.root,"agentx.json"),W(t.root,".agentx","config.json")];return e.find(n=>Ie(n))??e[0]}function Re(t){return t.wikiDir?W(t.wikiDir):W(t.root,".agentx","wiki")}function Fi(t){return P(t.root,"pending").map(Wi)}function Wi(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:G([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Ui(t){let e=pn(t);if(!Ie(e))return[];let n;try{n=JSON.parse(ji(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?xt(o.schedule):"",d=o.schedule?`${l.charAt(0).toLowerCase()}${l.slice(1)} (${o.schedule})`:"no schedule",u=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 ${d}?`:`Remove the schedule "${s}" (${d})?`,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:G(`${u}${p&&o.schedule?` \xB7 first run ${St(kt(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function fn(t){let e=W(t,".agentx","memory");return Ie(e)?Mi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Bi(t){let e=fn(t.root);if(e.length===0)return[];let n=new we(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:G(s.content),more:`agentx memory facts held --agent ${r}`});return i}function zi(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function Hi(t){return Tt(Re(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:G(`${zi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Ki(t){return Zt(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:G(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}var gn={card:Fi,schedule:Ui,memory:Bi,wiki:Hi,whatsapp:Ki};function Gi(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 kc(t,e={}){let n=t.now??Date.now(),{snoozed:i}=C(t.root),r=[],s=[],o=0;for(let a of e.kinds??un){let c;try{c=gn[a](t)}catch(l){s.push({kind:a,error:String(l?.message??l).slice(0,200)});continue}for(let l of c){let d=i[l.key];if(d&&Date.parse(d)>n){if(!e.includeSnoozed){o++;continue}l.snoozed_until=d}r.push(l)}}return r.sort(Gi),{items:r,snoozed:o,errors:s}}function qi(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!un.includes(n)||!i?null:{kind:n,ref:i}}function Xi(t,e,n){switch(e){case"card":return L(t.root,n)?.status==="pending";case"wiki":return Et(Re(t),n)?.status==="pending";case"whatsapp":return se(t.root,n)?.status==="pending";default:return gn[e](t).some(i=>i.key===`${e}:${n}`)}}async function mn(t,e,n,i={}){let r=qi(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:o}=r,a=t.now??Date.now(),c=i.by??"operator";if(n==="later"){if(!Xi(t,s,o))return{ok:!1,error:`nothing waiting for "${e}"`};let d=i.laterHours&&i.laterHours>0?i.laterHours:24,u=new Date(a+d*36e5);return cn(t.root,e,u,a),{ok:!0,message:`${e} put off until ${u.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let d=on(t.root,o,l?"yes":"no",{by:c,note:i.note,now:a,choice:i.choice,text:i.text});return d.ok?{ok:!0,message:`${e}: ${d.card.raised_by} will be told ${l?"yes":"no"}${d.card.choice?` (${d.card.choice})`:""}`}:d}case"schedule":{let d=await(l?vt:$t)(o,{configPath:pn(t),reload:t.reload});return d.success?{ok:!0,message:d.message}:{ok:!1,error:d.message}}case"memory":{let d=o.indexOf("/");if(d<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let u=o.slice(0,d),p=o.slice(d+1);if(!fn(t.root).includes(u))return{ok:!1,error:`no memory for agent "${u}"`};let f=new we(t.root);return f.held(u).some(g=>g.id===p)?(f.review(u,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 d=Re(t),u=l?Lt(d,o,{by:c,force:i.force,now:a}):Pt(d,o,{by:c,reason:i.note,now:a});return u.ok?{ok:!0,message:l?`${u.proposal.article.path} written to the shared wiki`:`${e} rejected`}:u}case"whatsapp":{let d=await Qt(t.root,o,l?"yes":"no",{by:c,now:a,send:t.sendWhatsApp});return d.ok?{ok:!0,message:l?`${e}: sent to ${d.draft.chat_name||d.draft.to}`:`${e}: dropped, nothing sent`}:d}}}var hn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function vc(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||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/")}function $c(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)||/^\/crons\/[^/]+\/enabled$/.test(t)}function Ac(t){return hn.has(t)}function Ic(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(hn.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 _c(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function ae(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Ji(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function Yi(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Dc(t,e=Yi()){let n=ae(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Ji(n),s=[ae(t.host),ae(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=ae(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Ec(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as Wn,mkdirSync as Is,readFileSync as Rs,renameSync as _s,writeFileSync as Cs}from"fs";import{homedir as Ds}from"os";import{dirname as Es,join as Ts}from"path";import{execFile as cs,execFileSync as ls}from"child_process";import{execFileSync as Zi}from"child_process";import{existsSync as bn,mkdirSync as Qi,readdirSync as es,readFileSync as wn,renameSync as ts,writeFileSync as ns}from"fs";import{homedir as xn}from"os";import{join as Ce}from"path";var v="siri:",kn="com.apple.ttsbundle.gryphon-neural_",Sn=t=>!!t&&t.startsWith(kn),rs=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],is=()=>{try{return Zi("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},_e;function De(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&_e!==void 0)return _e;let{platform:n=process.platform,exists:i=bn,prefDomain:r=is}=t,s=n==="darwin"&&rs.every(o=>i(o))&&r();return e||(_e=s),s}var vn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],$n={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"},Ee=t=>$n[t.toLowerCase()]??null;function ce(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var ss=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function os(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(ss)){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:$n[s]??null,siri:!0})}return[...e.values()]}function le(t=vn,e={}){if(!De(e))return[];let n=[];for(let i of t){let r;try{r=es(i)}catch{continue}for(let s of r)try{n.push(wn(Ce(i,s,"Info.plist"),"latin1"))}catch{}}return os(n)}var yn=`#!/bin/sh
|
|
1
|
+
import{a as Ie}from"./chunk-GTJIKXDB.js";import{q as Kt}from"./chunk-S2GAEH2F.js";import{a as k}from"./chunk-CL53UVOF.js";import{t as Ht,u as qt}from"./chunk-BVZFYBBP.js";import{d as Bt,e as zt}from"./chunk-AQASR6KR.js";import{A as ve,C as $e,b as xe,v as Rt,w as _t,x as Ct,z as ne}from"./chunk-6JJ3GODZ.js";import{a as Se}from"./chunk-API4IZZG.js";import{a as vt}from"./chunk-N6EWZGIX.js";import{a as Mt,b as jt,c as Vt,d as Wt,e as Ft,f as Ut}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 Ot,l as Nt}from"./chunk-TEFMZY6B.js";import{q as At}from"./chunk-R42S57G6.js";import{a as $t,b as It}from"./chunk-UR3ZIDMA.js";import{B as ke,E as kt,F as xt,I as St,r as te,s as bt,t as wt,u as Kr}from"./chunk-42Y3BXXS.js";import{existsSync as Gr,readdirSync as Xr,readFileSync as Jr,statSync as Yr}from"fs";import{resolve as Zr}from"path";function Gt(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 re=new Map;function Oa(t,e=1e3){if(!Gr(t))return[];let n=Xr(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let o=Zr(t,s);return{path:o,mtime:Yr(o).mtimeMs}}).sort((s,o)=>o.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of re.keys())i.has(s)||re.delete(s);let r=[];for(let{path:s,mtime:o}of n){let a=re.get(s);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let c=Qr(s,o);re.set(s,{mtime:o,summary:c}),c&&r.push(c)}return r}function Qr(t,e){try{let n=Jr(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 ei={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},x={routines:200,summary:160,filters:6,filterValue:60,text:120},ti=(t,e,n)=>{try{return At(t,e,n)}catch{return null}},Xt=864e5;function Va(t){let e=t.now??Date.now(),n={...ei,...t.thresholds},i=t.nextFire??ti,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:I(a.id,x.text),trigger:{schedule:I(a.schedule,x.text),timezone:l},agent:a.agent||null,enabled:a.enabled,state:a.enabled?"enabled":"disabled",nextRunAt:a.enabled?Ae(a.nextRun)??Ae(i(a.schedule,new Date(e),l)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:ai(d.status==="success"?void 0:d.errorSummary,x.summary)}:null,lastSuccessAt:c.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:Jt(u),sampledRuns:c.length,flags:[],attention:null};p.flags=Yt(p,u,a.schedule,l,null,e,n,i),r.push(Zt(p))}let s=new Map(Gt(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(_=>_.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((_,we)=>we.at-_.at),f=p.map(_=>({at:_.at,status:ii(_.status)})),g=f[0],h=c.type==="trigger.cron",y=typeof l.spec=="string"?l.spec:"",T=typeof l.timezone=="string"?l.timezone:"UTC",F={id:`workflow:${a.id}`,source:"workflow",kind:h?"schedule":"event",name:I(a.title||a.id,x.text),trigger:h?{schedule:I(y,x.text),timezone:T}:{event:I(typeof l.event=="string"?l.event:"",x.text),filters:oi(l.filter,a)},agent:si(a),enabled:d,state:u,nextRunAt:h&&d&&y?Ae(i(y,new Date(e),T)):null,lastRun:g?{at:new Date(g.at).toISOString(),status:g.status}:null,lastSuccessAt:(()=>{let _=f.find(we=>we.status==="success");return _?new Date(_.at).toISOString():null})(),consecutiveFailures:Jt(f),sampledRuns:p.length,flags:[],attention:null},ee=Date.parse(a.updated||a.created||"");F.flags=h?Yt(F,f,y,T,Number.isFinite(ee)?ee:null,e,n,i):ni(F,s.get(a.id)?.state==="dormant",Number.isFinite(ee)?ee:null,e,n),r.push(Zt(F))}return r.sort(ri).slice(0,x.routines)}function Jt(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 Yt(t,e,n,i,r,s,o,a){let c=[],l=e.length?e[0].at:null;if(!t.enabled){let p=en(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 ni(t,e,n,i,r){let s=[],o=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let a=en(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 en(t,e,n,i){let r=Math.max(t??0,e??0);return r&&n-r<i.disabledDays*Xt?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/Xt)} days`:"Disabled and never ran"}}function Zt(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 Qt={critical:0,warning:1,info:2};function ri(t,e){let n=t.attention?Qt[t.attention]:3,i=e.attention?Qt[e.attention]:3;return n-i||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function ii(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 si(t){if(t.ownerAgent)return I(t.ownerAgent,x.text);let e=t.nodes.find(n=>n.type==="agent"&&typeof n.config?.agentId=="string"&&n.config.agentId);return e?I(String(e.config.agentId),x.text):null}function oi(t,e){let n=[],i=e?.project;if(i&&n.push(I(`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(I(`${r}=${o.join(",")}`,x.filterValue))}return n.slice(0,x.filters)}function Ae(t){if(!t)return null;let e=t instanceof Date?t:new Date(t);return Number.isFinite(e.getTime())?e.toISOString():null}function I(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function ai(t,e){return t===void 0?void 0:I(t,e)}import{createHash as ci,randomBytes as tn}from"crypto";import{existsSync as li,mkdirSync as ui,readFileSync as di,writeFileSync as pi}from"fs";import{resolve as fi,dirname as gi}from"path";var Re="agx_live_",mi=".agentx/tokens.json",nn=class{file;constructor(e=process.cwd(),n=mi){this.file=fi(e,n)}load(){if(!li(this.file))return[];try{return JSON.parse(di(this.file,"utf-8"))}catch{return[]}}save(e){ui(gi(this.file),{recursive:!0}),pi(this.file,JSON.stringify(e,null,2)+`
|
|
3
|
+
`,"utf-8")}create(e){if(!e.name?.trim())throw new Error("Token name is required.");if(!Array.isArray(e.scopes)||e.scopes.length===0)throw new Error("At least one scope is required.");for(let o of e.scopes)if(!hi(o))throw new Error(`Invalid scope: ${o}`);let n=tn(32).toString("hex"),i=Re+n,r={id:"tok_"+tn(4).toString("hex"),name:e.name.trim(),prefix:Re+n.slice(0,4),hash:rn(i),scopes:[...e.scopes],createdAt:new Date().toISOString(),expiresAt:e.expiresInDays?new Date(Date.now()+e.expiresInDays*86400*1e3).toISOString():void 0},s=this.load();return s.push(r),this.save(s),{token:i,record:r}}list(){return this.load()}revoke(e){let n=this.load(),i=n.find(r=>r.id===e);return i?(i.revokedAt=new Date().toISOString(),this.save(n),i):null}isActive(e){let n=this.load().find(i=>i.id===e);return!!n&&!n.revokedAt&&!(n.expiresAt&&Date.parse(n.expiresAt)<Date.now())}verify(e){if(!e||!e.startsWith(Re))return null;let n=rn(e),i=this.load(),r=i.find(a=>a.hash===n);if(!r||r.revokedAt||r.expiresAt&&Date.parse(r.expiresAt)<Date.now())return null;let s=Date.now(),o=r.lastUsedAt?Date.parse(r.lastUsedAt):0;if(s-o>6e4){r.lastUsedAt=new Date(s).toISOString();try{this.save(i)}catch{}}return r}};function za(t,e){return!!(t.scopes.includes(e)||e.startsWith("agent:")&&t.scopes.includes("agent:*")||e==="dashboard:read"&&t.scopes.includes("dashboard:write"))}function hi(t){return t==="dashboard:read"||t==="dashboard:write"||t==="agent:*"||/^agent:[a-z0-9][a-z0-9_-]*$/.test(t)||t==="mesh:peer"||t==="app"}function rn(t){return"sha256:"+ci("sha256").update(t).digest("hex")}function Ha(t){let e=t.headers.authorization,n=Array.isArray(e)?e[0]:e;if(n&&n.toLowerCase().startsWith("bearer "))return n.slice(7).trim();if(t.url)try{let r=new URL(t.url,"http://localhost").searchParams.get("token");if(r)return r}catch{}return null}import{existsSync as ae,readdirSync as Hi,readFileSync as qi}from"fs";import{resolve as O}from"path";import{randomBytes as an}from"crypto";import{existsSync as bi,mkdirSync as wi,readdirSync as ki,readFileSync as xi,renameSync as cn,unlinkSync as Si,writeFileSync as vi}from"fs";import{resolve as ln}from"path";function sn(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var yi=t=>t.trim().split(`
|
|
4
|
+
`).pop()?.slice(0,300)||"no output";async function on(t,e,n,i=Ie){let r=await i(t.bin,[...sn(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${yi(r.stderr||r.stdout)}`}}async function Ga(t,e,n,i,r=Ie){return(await r(t.bin,[...sn(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var $i=2e3,Ii=t=>on(t.wacli,t.to,t.text);function _e(t){return ln(t,".agentx","whatsapp-triage","drafts")}var Ai=t=>/^[a-z0-9-]{8,64}$/.test(t),ie=(t,e)=>ln(_e(t),`${e}.json`);function un(t,e){wi(_e(t),{recursive:!0});let n=ie(t,e.id),i=`${n}.${process.pid}.tmp`;vi(i,JSON.stringify(e,null,2)+`
|
|
5
|
+
`,{mode:384}),cn(i,n)}function ec(t,e,n=Date.now()){let i=e.text.trim().slice(0,$i);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${an(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return un(t,r),r}function se(t,e){if(!Ai(e))return null;try{return JSON.parse(xi(ie(t,e),"utf-8"))}catch{return null}}function dn(t,e){let n=_e(t);return bi(n)?ki(n).filter(i=>i.endsWith(".json")).map(i=>se(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function pn(t,e,n,i={}){let r=se(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${ie(t,e)}.${process.pid}.${an(3).toString("hex")}.claim`;try{cn(ie(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??Ii)(r).catch(c=>({ok:!1,error:String(c?.message??c)}));a.ok?o.status="sent":(o.status="failed",o.error=a.error)}un(t,o);try{Si(s)}catch{}return o.status==="failed"?{ok:!1,error:o.error??"send failed"}:{ok:!0,draft:o}}import{existsSync as Ri,mkdirSync as _i,readdirSync as Ci,readFileSync as Di,renameSync as Ei,writeFileSync as Ti}from"fs";import{resolve as mn}from"path";function fn(t,e){let n=t.list?` in the "${t.list}" list`:"",i=[`This card came from the operator's reminder "${t.title}"${n} (id ${t.id}).`];return i.push(e?`Do what the operator chose, then tick the reminder off: remindctl complete ${t.id}`:"Leave the reminder open; it will come back at a later check-in."),i}var gn=["discard","keep","pause","approve"],A={title:120,ask:300,recommend:300,source:500,note:500,pendingPerAgent:25},Pi={defaultExpiryDays:3,maxExpiryDays:30};function U(t){return mn(t,".agentx","approvals")}var Li=/^[a-z0-9][a-z0-9-]{0,80}$/;function hn(t){return Li.test(t)}function yn(t,e){if(!hn(e))throw new Error(`invalid card id: ${e}`);return mn(U(t),`${e}.json`)}function Oi(t,e){let n=new Date(t).toISOString().slice(0,10),i=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return`${n}-${i||"card"}-${Math.random().toString(36).slice(2,6)}`}function oe(t,e){_i(U(t),{recursive:!0});let n=yn(t,e.id),i=`${n}.${process.pid}.tmp`;Ti(i,JSON.stringify(e,null,2)+`
|
|
6
|
+
`),Ei(i,n)}function P(t,e){if(!hn(e))return null;try{return JSON.parse(Di(yn(t,e),"utf-8"))}catch{return null}}function L(t,e){let n=U(t);if(!Ri(n))return[];let i=[];for(let r of Ci(n).filter(s=>s.endsWith(".json")&&!s.startsWith("_")).sort()){let s=P(t,r.slice(0,-5));s&&(!e||s.status===e)&&i.push(s)}return i}function w(t){return typeof t=="string"?t.replace(/\s+/g," ").trim():""}function Ni(t,e,n){let i=e+n.maxExpiryDays*864e5,r,s=w(t);if(!s)r=e+n.defaultExpiryDays*864e5;else{let o=/^(\d+)\s*([hd])$/i.exec(s);if(o)r=e+Number(o[1])*(o[2].toLowerCase()==="d"?864e5:36e5);else if(r=Date.parse(s),Number.isNaN(r))return{ok:!1,error:`expires must be an ISO date or time, or like "12h" / "3d" (got "${s}")`}}return r<=e?{ok:!1,error:"expires must be in the future"}:{ok:!0,at:new Date(Math.min(r,i)).toISOString()}}function Mi(t,e={}){let n=e.now??Date.now(),i=e.settings??Pi,r=w(t.title),s=w(t.ask),o=w(t.recommend),a=w(t.raised_by);if(!r)return{ok:!1,error:"title is required"};if(!s)return{ok:!1,error:"ask is required: the yes/no question"};if(!o)return{ok:!1,error:"recommend is required: your advice and why, in one line"};if(!a)return{ok:!1,error:"raised_by is required: the agent id"};if(r.length>A.title)return{ok:!1,error:`title is longer than ${A.title} characters`};if(s.length>A.ask)return{ok:!1,error:`ask is longer than ${A.ask} characters`};if(o.length>A.recommend)return{ok:!1,error:`recommend is longer than ${A.recommend} characters`};let c=w(t.if_silent).toLowerCase();if(!gn.includes(c))return{ok:!1,error:`if_silent must be one of ${gn.join(", ")}`};let l=Ni(t.expires,n,i);if(!l.ok)return l;let u=w(t.source);if(u.length>A.source)return{ok:!1,error:`source is longer than ${A.source} characters`};if(u&&/^[a-z][a-z0-9+.-]*:/i.test(u)&&!/^https?:\/\//i.test(u))return{ok:!1,error:"source must be an http(s) link or a plain reference"};let d=Vt(t);if(!d.ok)return d;let p,f=t.reply;return f&&typeof f=="object"&&w(f.channel)&&w(f.chatId)&&(p={channel:w(f.channel),chatId:w(f.chatId),...w(f.accountId)?{accountId:w(f.accountId)}:{}}),{ok:!0,card:{id:Oi(n,r),title:r,ask:s,recommend:o,if_silent:c,expires:l.at,...u?{source:u}:{},raised_by:a,created_at:new Date(n).toISOString(),...p?{reply:p}:{},...d.value,...e.origin?{origin:e.origin}:{},status:"pending"}}}function ac(t,e,n={}){let i=Mi(e,n);if(!i.ok)return i;let r=L(t,"pending").filter(s=>s.raised_by===i.card.raised_by).length;return r>=A.pendingPerAgent?{ok:!1,error:`${i.card.raised_by} already has ${r} cards waiting; wait for decisions before raising more`}:(oe(t,i.card),i)}function bn(t,e,n,i={}){let r=P(t,e);if(!r)return{ok:!1,error:`no card "${e}"`};if(r.status!=="pending")return{ok:!1,error:`card "${e}" is already ${r.status}`};let s=Ft(r,n,i);if(!s.ok)return s;let o=w(i.note).slice(0,A.note),a={...r,status:"decided",verdict:n,decided_by:i.by??"operator",decided_at:new Date(i.now??Date.now()).toISOString(),...o?{note:o}:{},...s.choice?{choice:s.choice}:{},...s.text?{text:s.text}:{}};return oe(t,a),{ok:!0,card:a}}function cc(t,e=Date.now()){let n=[];for(let i of L(t,"pending")){if(Date.parse(i.expires)>e)continue;let r={...i,status:"expired",outcome:i.if_silent,decided_by:"expiry",decided_at:new Date(e).toISOString()};oe(t,r),n.push(r)}return n}function lc(t){return L(t).filter(e=>e.status!=="pending"&&!e.agent_notified_at)}function uc(t,e,n=Date.now()){let i=P(t,e);!i||i.agent_notified_at||oe(t,{...i,agent_notified_at:new Date(n).toISOString()})}function dc(t){let e=t.status==="decided"?t.verdict==="yes"?"The operator said YES.":"The operator said NO.":`Nobody answered before it expired, so the default applied: ${t.outcome??t.if_silent}.`,n=[`[Approval result] Your decision card "${t.title}" (${t.id}) is closed.`,`Question: ${t.ask}`,e];return t.status==="decided"&&t.verdict==="yes"&&n.push(...Ut(t)),t.note&&n.push(`Operator note: ${t.note}`),t.source&&n.push(`Source: ${t.source}`),t.origin&&n.push(...fn(t.origin,t.status==="decided"&&t.verdict==="yes")),t.reply&&n.push(`You raised it from ${t.reply.channel} chat ${t.reply.chatId}; reply there if the requester should know.`),n.push("Act on this result now. Do not raise the same card again."),n.join(`
|
|
7
|
+
`)}import{mkdirSync as ji,readFileSync as Vi,renameSync as Wi,writeFileSync as Fi}from"fs";import{resolve as Ui}from"path";function wn(t){return Ui(U(t),"_state.json")}function C(t){try{let e=JSON.parse(Vi(wn(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 K(t,e){ji(U(t),{recursive:!0});let n=wn(t),i=`${n}.${process.pid}.tmp`;Fi(i,JSON.stringify(e,null,2)+`
|
|
8
|
+
`),Wi(i,n)}function kn(t,e,n,i=Date.now()){let r=C(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),K(t,{...r,snoozed:s})}function hc(t,e){K(t,{...C(t),lastDigest:e})}function xn(t,e,n,i=Date.now()){let r=C(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));K(t,{...r,popped:o,wanted:a})}function Sn(t,e){let n=C(t);K(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function yc(t,e=Date.now()){K(t,{...C(t),popped:{},passAt:new Date(e).toISOString()})}import{existsSync as Bi,readFileSync as zi}from"fs";St();function vn(t){let e=$t(t),n={};if(Bi(e))try{n=kt(JSON.parse(zi(e,"utf-8")))}catch{n={}}let i=ke.safeParse(n?.requests);return i.success?i.data:ke.parse(void 0)}async function vc(t,e={}){let n=(t.channels??[]).filter(i=>!Se.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...Se].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 In=["card","schedule","memory","wiki","whatsapp","request"],Ki=280;function j(t,e=Ki){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Ce(t){if(t.configPath)return O(t.configPath);let e=[O(t.root,"agentx.json"),O(t.root,".agentx","config.json")];return e.find(n=>ae(n))??e[0]}function De(t){return t.wikiDir?O(t.wikiDir):O(t.root,".agentx","wiki")}function Gi(t){return L(t.root,"pending").map(Xi)}function Xi(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:j([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Ji(t){let e=Ce(t);if(!ae(e))return[];let n;try{n=JSON.parse(qi(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:j(`${d}${p&&o.schedule?` \xB7 first run ${Lt(Pt(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function An(t){let e=O(t,".agentx","memory");return ae(e)?Hi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Yi(t){let e=An(t.root);if(e.length===0)return[];let n=new xe(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:j(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Zi(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function Qi(t){return zt(De(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:j(`${Zi(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function es(t){return dn(t.root,"pending").map(e=>({key:`whatsapp:${e.id}`,kind:"whatsapp",title:`WhatsApp reply to ${e.chat_name||e.to}`,ask:`Send this to ${e.chat_name||e.to}? "${e.text}"`,yes:"send it on WhatsApp",no:"drop the draft",raised_by:e.agent,created_at:e.created_at,detail:j(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function Rn(t){if(t.requests)return t.requests;if(O(t.root)!==process.cwd()||!ae(O(t.root,".agentx","db.sqlite")))return null;let e=vt({quiet:!0});if(!e)return null;let n=$n.get(e);return!n&&!Rt(e)?null:(n||$n.set(e,n=new _t(e)),n)}var $n=new WeakMap;function ts(t){let e=Rn(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${j(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:j(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var _n={card:Gi,schedule:Ji,memory:Yi,wiki:Qi,whatsapp:es,request:ts};function ns(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 Mc(t,e={}){let n=t.now??Date.now(),{snoozed:i}=C(t.root),r=[],s=[],o=0;for(let a of e.kinds??In){let c;try{c=_n[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(ns),{items:r,snoozed:o,errors:s}}function rs(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!In.includes(n)||!i?null:{kind:n,ref:i}}function is(t,e,n){switch(e){case"card":return P(t.root,n)?.status==="pending";case"wiki":return Bt(De(t),n)?.status==="pending";case"whatsapp":return se(t.root,n)?.status==="pending";default:return _n[e](t).some(i=>i.key===`${e}:${n}`)}}async function Cn(t,e,n,i={}){let r=rs(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(!is(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 kn(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let u=bn(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?Ot:Nt)(o,{configPath:Ce(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(!An(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=De(t),d=l?Ht(u,o,{by:c,force:i.force,now:a}):qt(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 pn(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=Rn(t),d=u?.get(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:l?vn(Ce(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 Dn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Vc(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/")}function Wc(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)||/^\/crons\/[^/]+\/enabled$/.test(t)}function Fc(t){return Dn.has(t)}function Uc(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Dn.has(t.remoteAddress))return{allowed:!0,reason:"loopback"};if(t.acceptedTokens.size===0)return{allowed:!0,reason:"no-tokens-configured"};let e=t.authorizationHeader||"",n=e.startsWith("Bearer ")?e.slice(7).trim():"";return n&&t.acceptedTokens.has(n)?{allowed:!0,reason:"token"}:{allowed:!1,reason:"missing-or-invalid-token"}}function Bc(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 zc(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 ce(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function ss(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function os(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function qc(t,e=os()){let n=ce(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=ss(n),s=[ce(t.host),ce(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=ce(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function Kc(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as tr,mkdirSync as Os,readFileSync as Ns,renameSync as Ms,writeFileSync as js}from"fs";import{homedir as Vs}from"os";import{dirname as Ws,join as Fs}from"path";import{execFile as ys,execFileSync as bs}from"child_process";import{execFileSync as as}from"child_process";import{existsSync as Tn,mkdirSync as cs,readdirSync as ls,readFileSync as Pn,renameSync as us,writeFileSync as ds}from"fs";import{homedir as Ln}from"os";import{join as Te}from"path";var v="siri:",On="com.apple.ttsbundle.gryphon-neural_",Nn=t=>!!t&&t.startsWith(On),ps=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],fs=()=>{try{return as("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ee;function Pe(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Ee!==void 0)return Ee;let{platform:n=process.platform,exists:i=Tn,prefDomain:r=fs}=t,s=n==="darwin"&&ps.every(o=>i(o))&&r();return e||(Ee=s),s}var Mn=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],jn={aaron:"male",damon:"male",daniel:"male",pierre:"male",samer:"male",arthur:"male",gordon:"male",martin:"male",nora:"female",simone:"female",marie:"female",soha:"female",martha:"female",catherine:"female",helena:"female",nicky:"female"},Le=t=>jn[t.toLowerCase()]??null;function le(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var gs=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function ms(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(gs)){let o=`${i}-${r}`,a=`${On}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:jn[s]??null,siri:!0})}return[...e.values()]}function ue(t=Mn,e={}){if(!Pe(e))return[];let n=[];for(let i of t){let r;try{r=ls(i)}catch{continue}for(let s of r)try{n.push(Pn(Te(i,s,"Info.plist"),"latin1"))}catch{}}return ms(n)}var En=`#!/bin/sh
|
|
9
9
|
# Written by agentx; shared by the daemon and AgentX Voice. Do not edit.
|
|
10
10
|
# siri-say.sh [voice] < text speak one line. A Siri voice id switches
|
|
11
11
|
# the OS default for it; any other id is
|
|
@@ -17,7 +17,7 @@ D=com.apple.Accessibility K=SpokenContentDefaultVoiceSelectionsByLanguage
|
|
|
17
17
|
dir="$HOME/.agentx/voice" lock="$HOME/.agentx/voice/siri.lock" saved="$HOME/.agentx/voice/siri-saved.plist"
|
|
18
18
|
stops="$dir/stop"
|
|
19
19
|
read_s=\${AGENTX_SAY_READ_S:-5} stale_s=\${AGENTX_SAY_STALE_S:-30} max_s=\${AGENTX_SAY_MAX_S:-300}
|
|
20
|
-
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${
|
|
20
|
+
assets=\${AGENTX_SIRI_ASSET_DIRS:-"${Mn.join(" ")}"}
|
|
21
21
|
if [ "$1" = --stop ]; then
|
|
22
22
|
mkdir -p "$dir" || exit 1
|
|
23
23
|
# Queued lines see this change and drop. The owner's trap stops say,
|
|
@@ -110,30 +110,30 @@ wait "$say_pid"
|
|
|
110
110
|
status=$?
|
|
111
111
|
say_pid=
|
|
112
112
|
finish $status
|
|
113
|
-
`,
|
|
113
|
+
`,hs=(t=Ln())=>Te(t,".agentx","voice","siri-say.sh");function Vn(t=Ln()){let e=hs(t);return Tn(e)&&Pn(e,"utf8")===En||(cs(Te(t,".agentx","voice"),{recursive:!0}),ds(`${e}.tmp`,En,{mode:493}),us(`${e}.tmp`,e)),e}var Wn=`ObjC.import("AVFoundation")
|
|
114
114
|
const vs = $.AVSpeechSynthesisVoice.speechVoices, out = []
|
|
115
115
|
for (let i = 0; i < vs.count; i++) {
|
|
116
116
|
const v = vs.objectAtIndex(i)
|
|
117
117
|
out.push([v.identifier.js, v.name.js, v.language.js, Number(v.quality), Number(v.gender)].join("\\t"))
|
|
118
118
|
}
|
|
119
|
-
out.join("\\n")`,
|
|
120
|
-
`)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!
|
|
121
|
-
`)[0]}`),
|
|
122
|
-
`),de=new Set;function
|
|
123
|
-
${
|
|
119
|
+
out.join("\\n")`,ws=new Set(["Fred","Kathy","Ralph","Junior"]),ks={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 Fn(t){let e=[];for(let n of t.split(`
|
|
120
|
+
`)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!ws.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":ks[r]??null})}return e}var xs=10*60*1e3,nl=60*1e3,B=null,Oe=!1;function Ne(t=Date.now(),e=xs){if(process.platform!=="darwin")return[];if(B)t-B.at>e&&!Oe&&(Oe=!0,ys("osascript",["-l","JavaScript","-e",Wn],{timeout:1e4},(n,i)=>{Oe=!1,n||(B={at:Date.now(),voices:[...Fn(String(i)),...ue()]})}));else try{B={at:t,voices:[...Fn(bs("osascript",["-l","JavaScript","-e",Wn],{encoding:"utf8",timeout:1e4})),...ue()]}}catch(n){Me(`[voice] could not list system voices: ${String(n?.message??n).split(`
|
|
121
|
+
`)[0]}`),B={at:t,voices:ue()}}return B.voices}var Me=t=>process.stderr.write(t+`
|
|
122
|
+
`),de=new Set;function rl(t){Me=t}function V(t,e){de.has(t)||(de.add(t),Me(e))}function zn(t){for(let e of de)t(e)&&de.delete(e)}var Hn=()=>{};function il(t){Hn=t}function qn(t){try{Hn(t)}catch(e){V("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var Ss={premium:3,enhanced:2,standard:1},vs=new Set(["Grandma","Grandpa"]);function Un(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!vs.has(t.name)?1:0;return Ss[t.quality]*10+e}var z=t=>t.toLowerCase().split(/[-_]/)[0],Bn=t=>t.id.startsWith("com.apple.voice.");function je(t,e,n,i=new Set){let r=G(t.filter(a=>!a.siri&&z(a.locale)===z(e)),e);if(r.some(Bn)&&(r=r.filter(Bn)),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 G(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=z(e),r=t.filter(s=>z(s.locale)===i);return(r.length?r:t).slice().sort((s,o)=>Un(o)-Un(s)||+(o.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(o.name)||s.locale.localeCompare(o.locale))}function X(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(v)){let l=i.slice(v.length).trim().toLowerCase(),u=G(e.filter(p=>p.siri&&p.name.toLowerCase()===l),n)[0];if(u||!l)return u??null;let d=X(l,e.filter(p=>z(p.locale)===z(n)),n);return d&&V(`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=G(e.filter(l=>l.name.toLowerCase()===o),n);return(s?a.find(l=>l.quality===s[2].toLowerCase()):void 0)??a[0]??null}function Kn(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 Ve="system",$s=t=>t.trim().toLowerCase()===Ve,Is="21m00Tcm4TlvDq8ikWAM";function We(t,e,n={},i=Ne()){let r=e[t],s=r?.name||t,o=r?.voice,a=Ue(e,n,i).get(t)??null,c=Cs(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?fe(a):null,systemByLanguage:c,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||Es(s,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var fe=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function As(t,e,n,i){if(!e||!n.length)return null;let r=X(e,n,i);return r||(V(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),qn(e)),r}function Yn(t,e){let n=t.trim();if(n.toLowerCase().startsWith(v))return{locale:e,gender:Le(n.slice(v.length).trim())};let i=le(n);return i?{locale:i.locale,gender:Le(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var Zn=t=>t.toLowerCase().split(/[-_]/)[0],Gn=(t,e)=>typeof t=="string"?t:t?.[Zn(e)];function pe(t,e,n,i){if(e!==void 0)return $s(e)?null:As(t,e,n,i)??void 0}var Fe=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function Rs(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,o=[],a=pe("voice.system",Gn(e.system,r),n,r),c=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=Gn(u.system,r),p=pe(u.id,d,n,r),f=p!==void 0?p:d!==void 0&&n.length?_s(u,d,r,a,n,c()):a!==void 0&&Fe(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 Kn(o,G(n.filter(p=>!p.siri),r),l))s.set(u,d);return s}function _s(t,e,n,i,r,s){for(let a of t.fallbacks??[]){let c=pe(`${t.id}.fallbacks`,a,r,n);if(c!==void 0)return c}if(i!==void 0&&Fe(i,t.gender))return i;let o=Yn(e,n);return je(r,o.locale,t.gender??o.gender,s)??void 0}function Cs(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=pe(`${a}.${u}`,d,r,u);p===void 0&&r.length&&(p=je(r,u,n??Yn(d,u).gender)??void 0),p!==void 0&&l(p)&&(s[Zn(u)]=p)}};return o("voice.system",i.system,a=>Fe(a,n)),o(t,e,()=>!0),s}function ll(t,e){let n=e?te(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?fe(i):null}}function Ue(t,e={},n=Ne()){let i=Object.entries(t).map(([r,s])=>({id:r,system:s.voice?.system,gender:s.voice?.gender,fallbacks:s.voice?.fallbacks}));return Rs(i,e,n)}function Be(t,e){let n={provider:t.provider,elevenlabs:Ds(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 Ds(t,e){return t||e||process.env.AGENTX_VOICE_ID||Is}function Es(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 Ts=8*60*60*1e3,Ps=500,Xn=class{constructor(e=Ts){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(Jn(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=Jn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>Ps&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},Jn=(t,e)=>`${t}\0${e}`;function Qn(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 ul(t,e,n,i={}){let r=e[t],s=We(t,e,i),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:Be(s),persona:o||`You are ${s.name}.`,introLine:Qn(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 dl(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}
|
|
123
|
+
${Qn(r,e.voice.introduce===!0&&!!i)}`}var Us="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",nr=(t=Vs())=>Fs(t,".agentx","voice","health.json");function Bs(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===Ve)return!0;if(i.toLowerCase().startsWith(v)){let r=i.slice(v.length).trim().toLowerCase();return e.some(s=>s.siri&&s.name.toLowerCase()===r)}return X(i,e,n)!==null}function zs(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 Hs(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:o,perLanguage:a}of zs(t)){if(Bs(s,e,o))continue;i??=Ue(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?fe(l):"the OS default voice"),n.set(s,c)}return[...n.values()]}function ze(t){let e=le(t);if(e)return`Siri ${e.name[0].toUpperCase()}${e.name.slice(1)} (${e.locale})`;if(t.toLowerCase().startsWith(v)){let n=t.slice(v.length).trim();return`Siri ${n[0]?.toUpperCase()??""}${n.slice(1)}`}return t}function qs(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${ze(n.voice)}: ${i}`});return{title:t.length===1?"AgentX: a voice is not installed":`AgentX: ${t.length} voices are not installed`,message:`${e.join(`
|
|
124
124
|
`)}
|
|
125
|
-
Reinstall in ${
|
|
126
|
-
`),
|
|
127
|
-
`),
|
|
128
|
-
`)}};function
|
|
129
|
-
`):[]}writeMd(e){let n=
|
|
130
|
-
`))}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(
|
|
131
|
-
`);for(let o=0;o<s.length;o++){let a=s[o].match(
|
|
132
|
-
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),
|
|
133
|
-
`)))}},Xe=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 d of l){let u=this.mapIssue(d,o);u.assignee=e,i.push(u)}}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 d=l==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(l)}/issues?${r.toString()}`,u=await this.api(d);for(let p of u)a.push(this.mapIssue(p,l))}catch(d){this.log(`[business] GitLab listAll failed on ${l}: ${d.message}`)}let c=a;if(e.notLabels?.length){let l=new Set(e.notLabels);c=c.filter(d=>!(d.labels||[]).some(u=>l.has(u)))}if(e.withoutScopedPrefix){let l=e.withoutScopedPrefix+"::";c=c.filter(d=>!(d.labels||[]).some(u=>u.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 d=>{try{let u=await this.api(`/users?username=${encodeURIComponent(d)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch{return null}}))).filter(d=>typeof d=="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 d=await this.api(`/users?username=${encodeURIComponent(l)}`);return Array.isArray(d)&&d[0]?.id?d[0].id:null}catch(d){return this.log(`[board] user lookup failed for ${l}: ${d.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 gl(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Ge(i.path,e,n);case"wiki":return new qe(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 Xe(r.host,r.token,o,s,n)}}}import{readFileSync as Xn}from"fs";import{homedir as Jn}from"os";import{join as Yn}from"path";var Zn=Yn(Jn(),"Library","DoNotDisturb","DB","Assertions.json"),Qn=Yn(Jn(),".agentx","focus.json");function er(t=Zn,e=Qn){let n=Zs(e);return n.active?n:Qs(t)}function Zs(t=Qn){try{if(JSON.parse(Xn(t,"utf-8"))?.active===!0)return{active:!0,mode:"widget",reason:"holding \u2014 switched on from the widget"}}catch{}return{active:!1,mode:null,reason:"widget hold is off"}}function Qs(t=Zn){let e;try{e=Xn(t,"utf-8")}catch(a){return a?.code==="EPERM"||a?.code==="EACCES"?{active:!1,mode:null,reason:"Focus database not readable \u2014 grant Full Disk Access to the app running agentx"}:{active:!1,mode:null,reason:"no Focus database on this machine"}}let n;try{n=JSON.parse(e)}catch{return{active:!1,mode:null,reason:"Focus database was not readable JSON"}}let r=(Array.isArray(n?.data)?n.data[0]:null)?.storeAssertionRecords;if(!Array.isArray(r)||r.length===0)return{active:!1,mode:null,reason:"no active Focus assertion"};let s=r[0],o=s?.assertionDetails?.assertionDetailsModeIdentifier??s?.assertionDetails?.assertionDetailsModeID??null;return{active:!0,mode:typeof o=="string"?o:null,reason:`Focus assertion present${o?` (${o})`:""}`}}function tr(t){return t.active?t.mode==="widget"?"holding (widget)":t.mode?`in ${(t.mode.split(".").pop()??t.mode).replace(/-/g," ")}`:"in Focus":"not in Focus"}var Je="unmapped";function Ye(t,e=[]){if(!t)return Je;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let i=t.indexOf("/");return i>0?t.slice(0,i):t}function eo(t){let e=new Map,n=t.projects??[],i=t.orgChart??{};for(let s of n)s.pm&&(e.has(s.pm)||e.set(s.pm,Ye(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 to(t,e,n=[]){if(!n.length)return;let i=n.filter(r=>!r.channel||r.channel===t);return i.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??i.find(r=>r.username&&e.username&&r.username===e.username)??i.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??i.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function xl(t,e){let n=to(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return Ye(t.project,e.projects);if(t.agentId){let i=eo(e).get(t.agentId);if(i)return i}return Je}function kl(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 no=t=>t===Je?"internal":"client";function ro(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??no(t),respondWithinMinutes:io(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Sl(t){let e=new Set;for(let n of t.projects??[])e.add(Ye(n.id,t.projects));for(let n of t.contactMap??[])e.add(n.client);for(let n of Object.keys(t.clients??{}))e.add(n);return[...e].sort().map(n=>ro(n,t))}function io(t){let e=/^(\d+)\s*([mhd])$/.exec(String(t??"").trim());if(!e)return;let n=Number(e[1]);return e[2]==="m"?n:e[2]==="h"?n*60:n*1440}var so=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,oo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function nr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(oo)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=ao(i);if(!r)return{cleanText:t};let s=n.index??0,o=n[1]??"";return{cleanText:(t.slice(0,s)+o+t.slice(s+n[0].length)).trim(),ui:r}}function $l(t){if(!t||!t.includes("agentx:ui"))return t;let e=so.exec(t);return e?t.slice(0,e.index).trimEnd():t}function ao(t){let e;try{e=JSON.parse(t)}catch{return null}if(!e||typeof e!="object")return null;let n={};if(Array.isArray(e.buttons)){let i=[],r=[],s=[];for(let 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 Il(t,e){let n=`${e}/call?to=${encodeURIComponent(t.from)}&callId=${encodeURIComponent(t.callId)}`;return t.reason==="camera"?`\u{1F4F7} ${t.from} is sharing a phone camera \u2014 tap to watch: ${n}&watch=1`:`\u{1F4DE} ${t.from} is calling \u2014 tap to join: ${n}`}var co=5*6e4;function O(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var rr=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(O)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${O(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(d=>d.expiresAt>c);for(let{signal:d}of l)this.deliverTo(r,d);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
|
|
125
|
+
Reinstall in ${Us}. Agents switch back on their own once it is installed.`}}function Ks(t=nr()){if(!tr(t))return null;try{let e=JSON.parse(Ns(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function Gs(t,e){Os(Ws(t),{recursive:!0}),js(`${t}.tmp`,JSON.stringify(e,null,2)+`
|
|
126
|
+
`),Ms(`${t}.tmp`,t)}var er=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??nr(),s=new Map((Ks(r)?.missing??[]).map(d=>[d.voice,d])),o=Hs(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] ${ze(d)} is installed again; its agents speak with it again`);c.length&&zn(d=>c.some(p=>d===p||d.endsWith(`:${p}`)));let l=a.filter(d=>!d.notifiedAt);if(l.length){let{title:d,message:p}=qs(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=>ze(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(!tr(r)||JSON.stringify(a)!==JSON.stringify([...s.values()]))&&Gs(r,u),u}finally{this.running=!1}}};import{readFileSync as qe,writeFileSync as cr,existsSync as Ke,readdirSync as ro,statSync as io}from"fs";import{resolve as Ge,join as so}from"path";import{existsSync as rr,mkdirSync as Xs,readFileSync as Js,writeFileSync as ir}from"fs";import{dirname as Ys,resolve as sr}from"path";import{z as m}from"zod";var Zs=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),Qs=m.object({id:m.string(),title:m.string(),description:m.string().optional(),assignee:m.string().optional(),labels:m.array(m.string()).default([]),milestone:m.string().optional(),status:m.enum(["todo","doing","blocked","done"]).default("todo"),priority:m.number().int().optional(),estimatedSeconds:m.number().int().optional(),source:Zs.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),eo=m.object({version:m.literal(1),items:m.array(Qs).default([])}),ge=class{constructor(e){this.path=e}jsonPath(){return sr(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return sr(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return rr(this.jsonPath())}load(){let e=this.jsonPath();if(!rr(e))return{version:1,items:[]};let n=Js(e,"utf-8");try{return eo.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();Xs(Ys(n),{recursive:!0}),ir(n,JSON.stringify(e,null,2)+`
|
|
127
|
+
`),ir(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(`
|
|
128
|
+
`)}};function vl(t){return`${t.type}:${t.project}:${t.iid}`}function or(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 He(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?to(t.source,e,n,i):t.source.type==="github"?no(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function to(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 no(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 Xe=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,me=/@([a-z0-9_-]+)/i,ar=/\[time:\s*([0-9hm\s]+)\]/i;function oo(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 Je=class{constructor(e,n,i=()=>{}){this.path=e;this.daemon=n;this.log=i;this.store=new ge(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=Ge(process.cwd(),this.path);return Ke(e)?qe(e,"utf-8").split(`
|
|
129
|
+
`):[]}writeMd(e){let n=Ge(process.cwd(),this.path);cr(n,e.join(`
|
|
130
|
+
`))}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(Xe);if(!s||s[2].toLowerCase()==="x")continue;let a=s[3],c=a.match(me);if(c&&c[1].toLowerCase()!==e.toLowerCase())continue;let l=a.match(ar),u=a.replace(me,"").replace(ar,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:c?c[1]:void 0,estimatedSeconds:l?oo(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=or([r.assignee||e],r.source,this.daemon);He(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&&He(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(Xe))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"}}},Ye=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(Ke(e))for(let i of ro(e)){let r=so(e,i);io(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(Ge(process.cwd(),this.root),n);let i=[];for(let r of n){let s=qe(r,"utf-8").split(`
|
|
131
|
+
`);for(let o=0;o<s.length;o++){let a=s[o].match(Xe);if(!a||a[2].toLowerCase()==="x")continue;let c=a[3].match(me);!c||c[1].toLowerCase()!==e.toLowerCase()||i.push({id:`wiki:${r}:${o}`,title:a[3].replace(me,"").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(!Ke(s))return;let o=qe(s,"utf-8").split(`
|
|
132
|
+
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),cr(s,o.join(`
|
|
133
|
+
`)))}},Ze=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 Dl(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Je(i.path,e,n);case"wiki":return new Ye(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 Ze(r.host,r.token,o,s,n)}}}var Qe="unmapped";function et(t,e=[]){if(!t)return Qe;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 ao(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,et(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 co(t,e,n=[]){if(!n.length)return;let i=n.filter(r=>!r.channel||r.channel===t);return i.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??i.find(r=>r.username&&e.username&&r.username===e.username)??i.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??i.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function Tl(t,e){let n=co(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return et(t.project,e.projects);if(t.agentId){let i=ao(e).get(t.agentId);if(i)return i}return Qe}function Pl(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 lo=t=>t===Qe?"internal":"client";function uo(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??lo(t),respondWithinMinutes:po(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Ll(t){let e=new Set;for(let n of t.projects??[])e.add(et(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=>uo(n,t))}function po(t){let e=/^(\d+)\s*([mhd])$/.exec(String(t??"").trim());if(!e)return;let n=Number(e[1]);return e[2]==="m"?n:e[2]==="h"?n*60:n*1440}var fo=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,go=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function lr(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(go)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=mo(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 Nl(t){if(!t||!t.includes("agentx:ui"))return t;let e=fo.exec(t);return e?t.slice(0,e.index).trimEnd():t}function mo(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 jl(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 ho=5*6e4;function N(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var ur=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(N)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${N(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
|
|
134
134
|
data: ${JSON.stringify(n)}
|
|
135
135
|
|
|
136
|
-
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=
|
|
136
|
+
`):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=N(e.to);if(n===N(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&&N(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(N(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+ho),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=N(e.to);for(let r of this.subs)r.callId===e.callId&&N(r.recipient)===i&&(this.deliverTo(r,e)?n++:this.subs.delete(r));return n}get subscriberCount(){return this.subs.size}shutdown(){this.cleanupTimer&&clearInterval(this.cleanupTimer);for(let e of this.subs)if(e.sink.kind==="sse")try{e.sink.res.end()}catch{}this.subs.clear(),this.pending.clear()}};import{execFile as Lo}from"child_process";import{mkdtempSync as Ro,rmSync as _o,writeFileSync as Co}from"fs";import{tmpdir as Do}from"os";import{join as mr}from"path";import{randomBytes as yo}from"crypto";var D={top:8,side:32,bottom:60},tt={height:56,keep:52},dr=`
|
|
137
137
|
:root {
|
|
138
138
|
--ac-paper: #fafaf9; --ac-soft: #f4f4f2; --ac-edge: #e9e9e6;
|
|
139
139
|
--ac-text: #0b1413; --ac-muted: #4a5856; --ac-subtle: #7c8987;
|
|
@@ -262,33 +262,33 @@ button.primary:hover:not(:disabled) { transform: translateY(-1px); background: v
|
|
|
262
262
|
button.primary:disabled { opacity: .55; cursor: not-allowed; }
|
|
263
263
|
kbd { font: 11px var(--ac-mono); color: var(--ac-subtle); }
|
|
264
264
|
button.primary kbd { color: inherit; opacity: .7; }
|
|
265
|
-
`;var
|
|
265
|
+
`;var pr=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),fr=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function bo(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?pr(n):fr(n)}`}function wo(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[fr(n)],pr(n)].join(" ")}function ko(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 xo(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 So(t){return t.draft?"Send":t.choices?.length?"Choose":"Yes"}var nt=t=>`<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${t}</svg>`,vo=nt('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),$o=nt('<path d="m6 15 6-6 6 6"/>'),Io=nt('<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>');function gr(t,e={}){let n=e.now??Date.now(),i=e.from||t.raised_by,r=yo(12).toString("base64"),s=t.choices??[],o=t.origin?.kind==="reminder",a=xo(t),c=s.map((d,p)=>`<button class="opt" role="radio" aria-checked="false" data-i="${p}"><span class="n">${p+1}</span><span class="t">${k(d)}</span>${p===a.index?'<i class="dot"></i>':""}</button>`).join(""),l=t.recommend?`<span class="rec"><i class="dot"></i>${k(i)} recommends</span>`:"",u={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:a.index};return`<!doctype html>
|
|
266
266
|
<html lang="en"><head><meta charset="utf-8">
|
|
267
267
|
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${r}'">
|
|
268
268
|
<title>AgentX</title>
|
|
269
|
-
<style>${
|
|
269
|
+
<style>${dr}</style></head>
|
|
270
270
|
<body><div class="wrap"><main class="card${e.still?" still":""}">
|
|
271
|
-
<div class="head" title="Drag to move"><span class="avatar">${
|
|
272
|
-
<div class="who"><b>${
|
|
271
|
+
<div class="head" title="Drag to move"><span class="avatar">${k(ko(i))}</span>
|
|
272
|
+
<div class="who"><b>${k(i)}</b><span>${k(bo(t.created_at,n))}</span></div>
|
|
273
273
|
<span class="kind${o?"":" decision"}">${o?"Reminder":"Decision"}</span>
|
|
274
|
-
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${
|
|
275
|
-
<div class="body"><h1 dir="auto">${
|
|
276
|
-
${t.context?`<p class="context" dir="auto">${
|
|
277
|
-
<p class="ask" dir="auto">${
|
|
274
|
+
<button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${$o}</button></div>
|
|
275
|
+
<div class="body"><h1 dir="auto">${k(t.title)}</h1>
|
|
276
|
+
${t.context?`<p class="context" dir="auto">${k(t.context)}</p>`:""}
|
|
277
|
+
<p class="ask" dir="auto">${k(t.ask)}</p>
|
|
278
278
|
${c||l?`<div class="label-row">${c?'<span class="label">Pick one</span>':""}${l}</div>`:""}
|
|
279
279
|
${c?`<div class="options" role="radiogroup">${c}</div>`:""}
|
|
280
|
-
${a.why?`<p class="why" dir="auto">${
|
|
280
|
+
${a.why?`<p class="why" dir="auto">${k(a.why)}</p>`:""}
|
|
281
281
|
${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>
|
|
282
282
|
<textarea id="text" dir="auto" rows="2" spellcheck="true"></textarea>`:""}
|
|
283
|
-
<div class="notes"><div>${
|
|
284
|
-
<div>${
|
|
283
|
+
<div class="notes"><div>${vo}<span>If you don't answer by ${k(wo(t.expires,n))}: ${k(t.if_silent)}.</span></div>
|
|
284
|
+
<div>${Io}<span>Nothing goes out until you click.</span></div></div>
|
|
285
285
|
</div><div class="foot"><button class="btn later" id="later">Not now<kbd>esc</kbd></button>
|
|
286
286
|
<button class="btn" id="no">No</button>
|
|
287
|
-
<button class="btn primary" id="yes">${
|
|
287
|
+
<button class="btn primary" id="yes">${So(t)}<kbd>\u2318\u21A9</kbd></button></div>
|
|
288
288
|
</main></div>
|
|
289
|
-
<script type="application/json" id="data">${JSON.stringify(
|
|
290
|
-
<script nonce="${r}">${
|
|
291
|
-
</body></html>`}var
|
|
289
|
+
<script type="application/json" id="data">${JSON.stringify(u).replace(/</g,"\\u003c")}</script>
|
|
290
|
+
<script nonce="${r}">${Ao}</script>
|
|
291
|
+
</body></html>`}var Ao=`
|
|
292
292
|
(function () {
|
|
293
293
|
var d = JSON.parse(document.getElementById("data").textContent);
|
|
294
294
|
var root = document.documentElement;
|
|
@@ -377,10 +377,10 @@ ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><sp
|
|
|
377
377
|
});
|
|
378
378
|
} catch (e) {}
|
|
379
379
|
})();
|
|
380
|
-
`;var
|
|
380
|
+
`;var Eo=440,To=`
|
|
381
381
|
ObjC.import("Cocoa"); ObjC.import("WebKit")
|
|
382
382
|
function run(argv) {
|
|
383
|
-
var path = argv[0], side = ${D.side}, gripTop = ${D.top}, gripEnd = ${D.top+
|
|
383
|
+
var path = argv[0], side = ${D.side}, gripTop = ${D.top}, gripEnd = ${D.top+tt.height}, keep = ${tt.keep}, w = Number(argv[1]) + 2 * side, h = 420, secs = Number(argv[2]), capture = argv[3] || ""
|
|
384
384
|
var app = $.NSApplication.sharedApplication
|
|
385
385
|
app.setActivationPolicy($.NSApplicationActivationPolicyAccessory)
|
|
386
386
|
ObjC.registerSubclass({ name: "AgentXCardView", superclass: "WKWebView", methods: {
|
|
@@ -450,21 +450,21 @@ function run(argv) {
|
|
|
450
450
|
}
|
|
451
451
|
function gone(why) { return JSON.stringify({ action: "dismiss", why: why }) }
|
|
452
452
|
function quoted(s) { return "'" + String(s).replace(/'/g, "'\\\\''") + "'" }
|
|
453
|
-
`;function
|
|
454
|
-
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&
|
|
455
|
-
`).trim():"",!o||o.length>
|
|
456
|
-
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function
|
|
457
|
-
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function
|
|
453
|
+
`;function Po(t,e){let n=t.trim().split(`
|
|
454
|
+
`).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&yr.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,`
|
|
455
|
+
`).trim():"",!o||o.length>Mt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...o?{text:o}:{}}}async function hr(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=Ro(mr(Do(),"agentx-card-"));try{let s=mr(r,"card.html");Co(s,gr(t,{...e,still:!!e.capture}),{mode:384});let o=["-l","JavaScript","-e",To,s,String(Eo),String(i),...e.capture?[e.capture]:[]],a=await n("/usr/bin/osascript",o,(i+10)*1e3);return a.ok?Po(a.stdout,t):null}finally{_o(r,{recursive:!0,force:!0})}}var yr=["not now","timed out","closed"],Oo=(t,e,n)=>new Promise(i=>{try{Lo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),br=160,wr=15e3;function No(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>br?e.slice(0,br):e}async function Mo(t,e,n,i){let r=e.sound==="chime"?i?"":"Glass":e.sound,s=r?Kt(r):null;if(s&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),s],wr),e.speak){let o=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...o,"--",No(t)],wr)}}function Sr(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function jo(t,e,n){return Sr(["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 kr(t,e,n,i,r){return Sr(["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(`
|
|
456
|
+
`),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function xr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
|
|
457
|
+
`);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function rt(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
|
|
458
458
|
|
|
459
|
-
`)}async function
|
|
459
|
+
`)}async function vr(t,e,n={}){let i=n.run??Oo,r=(e.style??"card")==="card",s=Mo(t,e,i,r).catch(()=>{});if(r){let o=await hr(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,Vo(t,e,i)}async function Vo(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",jo(s,rt(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}
|
|
460
460
|
|
|
461
|
-
Message (edit it if you like):`:`${
|
|
461
|
+
Message (edit it if you like):`:`${rt(t)}
|
|
462
462
|
|
|
463
|
-
Message (edit it if you like):`,
|
|
464
|
-
`)[0]}); Siri voices will not switch`),null}}var
|
|
465
|
-
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as
|
|
466
|
-
`)[0].slice(0,200);c.push(`${l}: ${
|
|
467
|
-
`)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function
|
|
463
|
+
Message (edit it if you like):`,d=await n("/usr/bin/osascript",kr(s,l,o?["Cancel","Send"]:["Not now","No","Send"],i,Wt(t.draft,o)),r),p=d.ok?xr(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",kr(s,rt(t),["Not now","No","Yes"],i),r),c=a.ok?xr(a.stdout):null;return c?.button==="Yes"?{action:"yes"}:c?.button==="No"?{action:"no"}:{action:"dismiss"}}var Wo=24*36e5,it=!1;function Fo(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=C(t.root),o=r?Date.parse(r):NaN,a=L(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>Wo&&!(p<=o)))return l}return null}async function uu(t){let{ctx:e,settings:n,log:i}=t;if(!n.enabled||(t.platform??process.platform)!=="darwin")return"off";if(it)return"busy";let r=Fo(e);if(!r)return"none";let s=(t.focus??Dt)();if(s.active)return"held";it=!0;let o=`card:${r.id}`;try{let a=L(e.root,"pending").map(u=>`card:${u.id}`);xn(e.root,o,a,e.now),i(`[approvals] popup: showing ${o} from ${r.raised_by}`);let c=await(t.show??vr)(r,n,{from:t.agentName?.(r.raised_by)});if(c.action==="dismiss")return i(`[approvals] popup: ${o} left waiting: ${c.why??"no answer"} (${Et(s)} when shown)`),"shown";if(P(e.root,r.id)?.status!=="pending")return i(`[approvals] popup: ${o} was answered elsewhere; popup answer ignored`),"shown";let l=await Cn(e,o,c.action,{by:"operator (popup)",...c.action==="yes"?{choice:c.choice,text:c.text}:{}});return i(l.ok?`[approvals] popup: ${l.message}`:`[approvals] popup: ${o} not recorded: ${l.error}`),"shown"}catch(a){return i(`[approvals] popup failed for ${o}: ${a?.message??a}`),"shown"}finally{it=!1}}function du(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:")?P(t.root,e.slice(5)):null;return i?i.status!=="pending"?{ok:!1,error:`${e} is already ${i.status}`}:(Sn(t.root,e),{ok:!0,message:`${e} will show on the Mac within a minute`}):{ok:!1,error:`no card "${e}"; the popup shows decision cards only`}}import{closeSync as J,createReadStream as Uo,fstatSync as Bo,openSync as zo,realpathSync as $r}from"fs";import{isAbsolute as Ho,resolve as Ir,sep as Ar}from"path";var yu="/app-files",qo=/^[A-Za-z0-9_.:-]{1,64}$/;function Ko(t,e,n=process.cwd()){if(!e||e.length>ne.pathChars||e.includes("\0"))return{ok:!1,status:400,error:"bad file path"};if(e.split(/[\\/]/).includes(".."))return{ok:!1,status:403,error:`the path leaves the workspace: copy the file into ${$e}/ first`};if(!ve(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=$r(Ir(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=$r(Ho(e)?e:Ir(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+Ar))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${$e}/ first`};let s=ve(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function Go(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 Xo(t,e,n){return{"Content-Type":t,"Content-Disposition":Go(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 Jo(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 bu(t,e,n,i){let r=(T,F)=>{e.writeHead(T,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(F))};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(!qo.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=Ko(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=zo(c.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let T=Bo(l);if(!T.isFile())return J(l),r(404,{error:"not a file"});u=T.size}catch{return J(l),r(404,{error:"file not found"})}if(u>ne.bytes)return J(l),r(413,{error:`the file is larger than ${ne.bytes/1024/1024} MB`});let d=c.path.split(Ar).pop()||"file",p=Xo(c.mime,d,c.kind),f=Jo(t.headers.range,u);if(f==="unsatisfiable"){J(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){J(l),e.end();return}let y=Uo("",{fd:l,start:g,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as Y}from"child_process";import{readFileSync as Yo,writeFileSync as Zo}from"fs";import{tmpdir as Qo}from"os";import{join as ea}from"path";bt();var Rr=t=>t&&t!==1?Math.round(175*t):null,he=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function ta(){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=Yo(t,"utf8").trim();if(e)return e}catch{}return null}function Ru(t=ta()){let e=0;return async(n,i)=>{if(n.voice.provider==="system")return null;if(!t){if(n.voice.fallback)return null;throw new Error("ElevenLabs is the voice provider but no key is set")}try{let r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${n.voice.elevenlabs}/stream?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n.text,model_id:"eleven_flash_v2_5",...he(n.voice.rate)?{voice_settings:{speed:he(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=ea(Qo(),`agentx-say-${process.pid}-${++e}.mp3`);return Zo(s,Buffer.from(await r.arrayBuffer())),s}catch(r){if(i.aborted||!n.voice.fallback)throw r;return V(`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 _r(t,e){let n=t.languages&&te(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var na=(t,e="")=>{let n=_r(t,e),i=Rr(t.rate);return[...n&&!Nn(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function ra(t,e,n){if(!n)return["say",na(t,e)];let i=_r(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function _u(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Cu(t=st()){if(t)try{Y("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function Du(t=st()){if(t)try{Y("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function st(t={},e){if(!Pe(t))return null;try{return Vn(e)}catch(n){return V("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
|
|
464
|
+
`)[0]}); Siri voices will not switch`),null}}var Eu=(t,e)=>{if(!t){let[n,i]=ra(e.voice,e.text,st()),r=Rr(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=Y(n,i,{stdio:["pipe","ignore","ignore"],env:s});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?Y("afplay",[t],{stdio:"ignore"}):Y("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as Cr}from"child_process";import{accessSync as ia,constants as sa,readFileSync as Dr}from"fs";import{homedir as oa}from"os";import{basename as H,delimiter as Er,dirname as aa,extname as ca,join as ot}from"path";var M={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function Tr(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)>M.ms+2e3?{status:413,error:ct()}:null}var ct=()=>`The recording is longer than ${M.ms/6e4} minutes.`,la={"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 Pr(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return la[e]??null}function Lr(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=oa(),r=[ot(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(Er).filter(Boolean)];for(let s of[e,...r.map(o=>ot(o,t))])if(s)try{return ia(s,sa.X_OK),s}catch{}return null}function Mu(t){return{key:t,mlx:at("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:at("whisper",process.env.AGENTX_WHISPER),ffmpeg:ua()}}var ua=()=>at("ffmpeg",process.env.AGENTX_FFMPEG);async function Or(t,e){return e?da(t,e):null}async function da(t,e){let n=String(M.ms/1e3+5);try{let r=[...(await pa(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 Nr(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([Dr(t)],{type:e}),H(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 Mr(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:`${aa(i)}${Er}${process.env.PATH??""}`};await fa(e,s,12e4,o);try{return Dr(ot(r,H(n,ca(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function pa(t,e,n){return new Promise((i,r)=>{let s=Cr(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${H(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(`${H(t)} exited ${c}`))})})}function fa(t,e,n,i=process.env){return new Promise((r,s)=>{let o=Cr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),a="",c="",l=setTimeout(()=>{o.kill("SIGKILL"),s(new Error(`${H(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(`${H(t)} exited ${u}: ${c.trim().split(`
|
|
465
|
+
`).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as ga,rm as ma,writeFile as ha}from"fs/promises";import{tmpdir as ya}from"os";import{join as jr}from"path";Kr();var ba=64*1024,wa=2,ut=0;function Gu(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function Xu(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?ka(t,e,i):va(t,e,i)}async function ka(t,e,n){let i=String(t.headers["content-type"]||""),r=Pr(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=Tr(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let o=await Vr(t,M.bytes);if(!o)return b(e,413,{error:Aa()});if(!o.length)return b(e,400,{error:"The recording is empty."});if(ut>=wa)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=Lr(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 ga(jr(ya(),"agentx-phone-voice-"));try{u=await xa(d,`speech.${r}`,o,i,c,l,n)}finally{await ma(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{ut--}b(e,u[0],u[1])}async function xa(t,e,n,i,r,s,o){let a=jr(t,e);if(await ha(a,n,{mode:384}),r.ffmpeg){let l=await(o.measure??Or)(a,r.ffmpeg);if(l==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(l*1e3>M.ms+2e3)return[413,{error:ct()}]}let c=[];for(let l of s)try{let u=await Sa(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(`
|
|
466
|
+
`)[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 Sa(t,e,n,i,r,s){let o=s.engines?.[t];if(o)return o(e,n,i,r);if(t==="elevenlabs")return Nr(e,n,i.key);let a=t==="mlx-whisper"?i.mlx:i.whisper;return Mr(t,a,e,i.ffmpeg,r)}async function va(t,e,n){let i=await Vr(t,ba);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=$a(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??Ia)(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(`
|
|
467
|
+
`)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function $a(t,e){let n=lr(Ct(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return wt(n,e)}async function Ia(t,e,n){let i=he(e.rate),r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(e.elevenlabs)}?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n,model_id:"eleven_flash_v2_5",...i?{voice_settings:{speed:i}}:{}}),signal:AbortSignal.timeout(6e4)});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text().catch(()=>"")).slice(0,160)}`);return Buffer.from(await r.arrayBuffer())}var Aa=()=>`The recording is larger than ${M.bytes/1024/1024} MB, more than ${M.ms/6e4} minutes of speech.`;function Ju(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Be(We(t,r,n.voice)):null}function Vr(t,e){return Number(t.headers["content-length"])>e?(t.resume(),Promise.resolve(null)):new Promise((n,i)=>{let r=[],s=0;t.on("data",o=>{if(!(s>e)){if(s+=o.length,s>e){r.length=0,n(null);return}r.push(o)}}),t.on("end",()=>{s<=e&&n(Buffer.concat(r))}),t.on("error",i)})}function b(t,e,n){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}import{existsSync as $,readFileSync as gt,writeFileSync as mt,mkdirSync as ye,readdirSync as ft,rmSync as Ra,statSync as R}from"fs";import{resolve as Wr,relative as _a,dirname as ht,join as W,extname as Z,basename as yt}from"path";var S=200*1024,Fr=new Set([".md",".markdown",".txt"]),q=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"]),Ca=6,Da=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function E(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=Wr(t);if($(n)||ye(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=Wr(n,e);if(_a(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function Ur(t){let e=Z(t).toLowerCase();if(!Fr.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 ed(t){let e=E(t,"."),n=[],i=new Set,r=[];try{r=ft(e)}catch{}for(let a of Da){let c=W(e,a);if($(c)&&R(c).isFile()){let l=R(c).size,u=l>0&&l<S?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=W(e,a);try{let l=R(c);if(!l.isFile()||!Fr.has(Z(a).toLowerCase()))continue;let u=l.size>0&&l.size<S?pt(c):"";n.push({path:a,title:dt(u,a),size:l.size,exists:!0})}catch{}}let s=[],o=W(e,".claude","skills");if($(o))try{for(let a of ft(o)){let c=W(o,a),l;try{l=R(c)}catch{continue}if(!l.isDirectory())continue;let u=W(c,"SKILL.md");if(!$(u))continue;let d=R(u),p=d.size<S?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 td(t,e){let n=E(t,e);if(Ur(n),!$(n))return{path:e,content:""};if(R(n).size>S)throw new Error(`File is too large to edit in the admin panel (> ${S/1024} KB).`);return{path:e,content:gt(n,"utf-8")}}function nd(t,e,n){let i=E(t,e);Ur(i);let r=Buffer.from(n,"utf-8");if(r.length>S)throw new Error(`File too large (${r.length} > ${S} bytes).`);return ye(ht(i),{recursive:!0}),mt(i,r),{path:e,bytes:r.length}}function rd(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=E(t,i);if($(r))throw new Error(`Skill "${e}" already exists.`);ye(ht(r),{recursive:!0});let s=n.content?.trim()?n.content:Ea(e,n.title);return mt(r,s),{slug:e,path:i}}function id(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=E(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);if(!R(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return Ra(n,{recursive:!0,force:!0}),{slug:e}}function sd(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=E(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);let i=[];return r(n,"",0,i),i.sort((s,o)=>s.kind!==o.kind?s.kind==="dir"?-1:1:s.path.localeCompare(o.path)),i;function r(s,o,a,c){if(a>Ca)return;let l=[];try{l=ft(s)}catch{return}for(let u of l){if(u==="node_modules"||u===".git")continue;let d=W(s,u),p=o?`${o}/${u}`:u,f;try{f=R(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=Z(u).toLowerCase(),h=q.has(g)||q.has(u.toLowerCase());c.push({path:p,kind:"file",size:f.size,editable:h&&f.size<S})}}}}function od(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=E(t,`.claude/skills/${e}/${n}`);if(!$(i)||!R(i).isFile())throw new Error(`File not found: ${n}`);let r=Z(i).toLowerCase(),s=yt(i).toLowerCase();if(!q.has(r)&&!q.has(s))throw new Error(`File type not editable: ${n}`);if(R(i).size>S)throw new Error(`File too large to edit (> ${S/1024} KB): ${n}`);return{path:n,content:gt(i,"utf-8")}}function ad(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=E(t,`.claude/skills/${e}/${n}`),s=Z(r).toLowerCase(),o=yt(r).toLowerCase();if(!q.has(s)&&!q.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(i,"utf-8");if(a.length>S)throw new Error(`File too large (${a.length} > ${S} bytes).`);return ye(ht(r),{recursive:!0}),mt(r,a),{path:n,bytes:a.length}}function cd(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=E(t,`.claude/skills/${e}`);if(!$(n))throw new Error(`Skill "${e}" not found.`);let i=r=>$(W(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 Ea(t,e){return`# ${e?.trim()||t}
|
|
468
468
|
|
|
469
469
|
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.
|
|
470
470
|
|
|
@@ -477,7 +477,7 @@ Document the arguments, commands, or files the skill expects. Example:
|
|
|
477
477
|
|
|
478
478
|
\`\`\`bash
|
|
479
479
|
# Example invocation
|
|
480
|
-
claude-code ${
|
|
480
|
+
claude-code ${yt(t)} --arg value
|
|
481
481
|
\`\`\`
|
|
482
|
-
`}
|
|
483
|
-
//# sourceMappingURL=chunk-
|
|
482
|
+
`}St();var Br={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function zr(t){return{...Br,...t??{},regions:{...t?.regions??{}},buffer:{...Br.buffer,...t?.buffer??{}}}}function dd(t){try{return zr(xt(t).screen)}catch{return zr(void 0)}}var Ta=/^[a-z][\w-]*$/,Hr=["window","screen","menubar","notifications"];function Q(t,e,n,i){let r=Number(t);if(t===""||t===null||!Number.isFinite(r)||!n(r))throw new Error(`${e} must be ${i}`);return r}var be=(t,e)=>Q(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function qr(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 pd(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=be(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=be(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=be(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Q(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Q(e.changeThreshold,"changeThreshold",r=>r>=0&&r<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let r={...n.regions??{}};for(let[s,o]of Object.entries(e.regions)){if(!Ta.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);o===null?delete r[s]:r[s]=qr(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=Q(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Q(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=be(r.maxPixels,"buffer.maxPixels")),"region"in r&&(s.region=String(r.region).trim()),n.buffer=s}let i=n.buffer?.region;if(i!==void 0&&!Hr.includes(i)&&!n.regions?.[i])try{qr(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...Hr,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{Gt as a,Oa as b,et as c,ao as d,co as e,Tl as f,Pl as g,Ll as h,lr as i,Nl as j,jl as k,N as l,ur as m,x as n,Va as o,nn as p,za as q,rn as r,Ha as s,gn as t,A as u,U as v,hn as w,P as x,ac as y,cc as z,lc as A,uc as B,dc as C,Ga as D,Ii as E,ec as F,pn as G,C as H,hc as I,yc as J,vn as K,vc as L,Rn as M,Mc as N,Cn as O,vr as P,uu as Q,du as R,yu as S,Xo as T,bu as U,Vc as V,Wc as W,Fc as X,Uc as Y,Bc as Z,zc as _,qc as $,Kc as aa,nl as ba,Ne as ca,rl as da,il as ea,G as fa,X as ga,ta as ha,Ru as ia,_u as ja,Cu as ka,Du as la,st as ma,Eu as na,Ve as oa,We as pa,fe as qa,Rs as ra,Cs as sa,ll as ta,Ue as ua,Be as va,Ds as wa,Es as xa,Xn as ya,Qn as za,ul as Aa,Ls as Ba,dl as Ca,Us as Da,Hs as Ea,ze as Fa,Ks as Ga,er as Ha,M as Ia,Tr as Ja,Pr as Ka,Lr as La,Mu as Ma,ua as Na,Nr as Oa,Mr as Pa,Gu as Qa,Xu as Ra,Aa as Sa,Ju as Ta,Vr as Ua,ge as Va,vl as Wa,or as Xa,He as Ya,Ze as Za,Dl as _a,ed as $a,td as ab,nd as bb,rd as cb,id as db,sd as eb,od as fb,ad as gb,cd as hb,Br as ib,zr as jb,dd as kb,Hr as lb,pd as mb};
|
|
483
|
+
//# sourceMappingURL=chunk-XESESMKN.js.map
|