agentix-cli 0.100.0 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/apps/mac-voice/Sources/AgentXVoice/SettingsWindow.swift +1 -1
  2. package/dist/{App-XLQDP26J.js → App-EYUDDF6K.js} +2 -2
  3. package/dist/{ChatApp-DRDUXZ66.js → ChatApp-F5LZLBI3.js} +2 -2
  4. package/dist/{agent-QHM3J2XS.js → agent-XF3BWMOB.js} +2 -2
  5. package/dist/{board-dashboard-R6ZTCTSI.js → board-dashboard-TVSOWW32.js} +4 -4
  6. package/dist/{chunk-DRUEPGLP.js → chunk-5UO6BBDG.js} +2 -2
  7. package/dist/{chunk-S2GPUSBU.js → chunk-AYNZAOJN.js} +2 -2
  8. package/dist/chunk-ECM2QEXF.js +54 -0
  9. package/dist/chunk-ECM2QEXF.js.map +1 -0
  10. package/dist/{chunk-J64VIHL5.js → chunk-EEZI2K7S.js} +2 -2
  11. package/dist/{chunk-BERHVF3T.js → chunk-EXPIKLUN.js} +2 -2
  12. package/dist/{chunk-Z4FY64BS.js → chunk-GSFB46YC.js} +2 -2
  13. package/dist/{chunk-OFVMUBIP.js → chunk-HMDM5MCR.js} +2 -2
  14. package/dist/{chunk-SJMOZY7Y.js → chunk-HQJW3BC5.js} +2 -2
  15. package/dist/{chunk-B32A6OOY.js → chunk-MWLX3QCD.js} +47 -47
  16. package/dist/chunk-MWLX3QCD.js.map +1 -0
  17. package/dist/{chunk-VBFXUZTY.js → chunk-N57ES35J.js} +2 -2
  18. package/dist/{chunk-GJ5EJVMZ.js → chunk-PYCTWI2I.js} +2 -2
  19. package/dist/{chunk-IQJ7UZVV.js → chunk-QRD3ZG27.js} +2 -2
  20. package/dist/{chunk-DXJRMPGH.js → chunk-RWSCQMLD.js} +2 -2
  21. package/dist/{chunk-YYCFI4VP.js → chunk-S337S2M7.js} +2 -2
  22. package/dist/{chunk-6BZMRVKJ.js → chunk-SRPQLIAL.js} +177 -177
  23. package/dist/chunk-SRPQLIAL.js.map +1 -0
  24. package/dist/{chunk-BHKWXFJD.js → chunk-TXFIMVVF.js} +5 -5
  25. package/dist/{chunk-LXJGLNVG.js → chunk-V6W3FFW7.js} +2 -2
  26. package/dist/{chunk-4BCAH7XI.js → chunk-XO55WKCX.js} +2 -2
  27. package/dist/{chunk-J4JVKVEK.js → chunk-Y6POV2X5.js} +2 -2
  28. package/dist/{chunk-BTLW2RML.js → chunk-YOCQ2MWL.js} +2 -2
  29. package/dist/{chunk-JZJ7AZJD.js → chunk-ZJXDBVBT.js} +2 -2
  30. package/dist/cli.js +1 -1
  31. package/dist/{client-BLUCLNIS.js → client-526OCGWD.js} +2 -2
  32. package/dist/config-HCJ5NZW5.js +2 -0
  33. package/dist/config-mutator-PGR2OGWC.js +2 -0
  34. package/dist/{doctor-XGQW5SMD.js → doctor-AC5ONEO2.js} +2 -2
  35. package/dist/index.d.ts +9 -9
  36. package/dist/index.js +1 -1
  37. package/dist/{program-CH5QSA7K.js → program-MPLZJQA5.js} +16 -16
  38. package/dist/program-MPLZJQA5.js.map +1 -0
  39. package/dist/{promote-K5LP5Q6Z.js → promote-CNKIINYK.js} +2 -2
  40. package/dist/{query-LHXSINM2.js → query-A2N2LIR7.js} +2 -2
  41. package/dist/{registry-OQUO6NCW.js → registry-REKWHOHS.js} +2 -2
  42. package/dist/{request-planner-TW5OCKTF.js → request-planner-MS5BS6HY.js} +2 -2
  43. package/dist/{review-candidates-EFELFOSY.js → review-candidates-2F4QK6QQ.js} +2 -2
  44. package/dist/{routing-TSRZLD7B.js → routing-SU5Q4IPM.js} +2 -2
  45. package/dist/schedule-tool-24KHZY2Z.js +2 -0
  46. package/dist/scheduler-ALDZOUKJ.js +2 -0
  47. package/dist/{seat-NIPWHLKC.js → seat-PZBFMYQL.js} +2 -2
  48. package/dist/{select-UAKDLN76.js → select-D3XOFXA5.js} +2 -2
  49. package/dist/{set-enabled-74DLXMSM.js → set-enabled-DNDRQ3CZ.js} +2 -2
  50. package/dist/{tool-TEGHFORD.js → tool-FB6SPVIS.js} +2 -2
  51. package/dist/{tool-CEBL57UW.js → tool-RRGOHJW6.js} +2 -2
  52. package/dist/wiki-3DH2QYTX.js +2 -0
  53. package/package.json +1 -1
  54. package/dist/chunk-6BZMRVKJ.js.map +0 -1
  55. package/dist/chunk-B32A6OOY.js.map +0 -1
  56. package/dist/chunk-JREA25GJ.js +0 -54
  57. package/dist/chunk-JREA25GJ.js.map +0 -1
  58. package/dist/config-ZUMI4IY4.js +0 -2
  59. package/dist/config-mutator-S3CD2IWQ.js +0 -2
  60. package/dist/program-CH5QSA7K.js.map +0 -1
  61. package/dist/schedule-tool-JUHRVU5D.js +0 -2
  62. package/dist/scheduler-EHJPTULN.js +0 -2
  63. package/dist/wiki-WOK4SCB7.js +0 -2
  64. /package/dist/{App-XLQDP26J.js.map → App-EYUDDF6K.js.map} +0 -0
  65. /package/dist/{ChatApp-DRDUXZ66.js.map → ChatApp-F5LZLBI3.js.map} +0 -0
  66. /package/dist/{agent-QHM3J2XS.js.map → agent-XF3BWMOB.js.map} +0 -0
  67. /package/dist/{board-dashboard-R6ZTCTSI.js.map → board-dashboard-TVSOWW32.js.map} +0 -0
  68. /package/dist/{chunk-DRUEPGLP.js.map → chunk-5UO6BBDG.js.map} +0 -0
  69. /package/dist/{chunk-S2GPUSBU.js.map → chunk-AYNZAOJN.js.map} +0 -0
  70. /package/dist/{chunk-J64VIHL5.js.map → chunk-EEZI2K7S.js.map} +0 -0
  71. /package/dist/{chunk-BERHVF3T.js.map → chunk-EXPIKLUN.js.map} +0 -0
  72. /package/dist/{chunk-Z4FY64BS.js.map → chunk-GSFB46YC.js.map} +0 -0
  73. /package/dist/{chunk-OFVMUBIP.js.map → chunk-HMDM5MCR.js.map} +0 -0
  74. /package/dist/{chunk-SJMOZY7Y.js.map → chunk-HQJW3BC5.js.map} +0 -0
  75. /package/dist/{chunk-VBFXUZTY.js.map → chunk-N57ES35J.js.map} +0 -0
  76. /package/dist/{chunk-GJ5EJVMZ.js.map → chunk-PYCTWI2I.js.map} +0 -0
  77. /package/dist/{chunk-IQJ7UZVV.js.map → chunk-QRD3ZG27.js.map} +0 -0
  78. /package/dist/{chunk-DXJRMPGH.js.map → chunk-RWSCQMLD.js.map} +0 -0
  79. /package/dist/{chunk-YYCFI4VP.js.map → chunk-S337S2M7.js.map} +0 -0
  80. /package/dist/{chunk-BHKWXFJD.js.map → chunk-TXFIMVVF.js.map} +0 -0
  81. /package/dist/{chunk-LXJGLNVG.js.map → chunk-V6W3FFW7.js.map} +0 -0
  82. /package/dist/{chunk-4BCAH7XI.js.map → chunk-XO55WKCX.js.map} +0 -0
  83. /package/dist/{chunk-J4JVKVEK.js.map → chunk-Y6POV2X5.js.map} +0 -0
  84. /package/dist/{chunk-BTLW2RML.js.map → chunk-YOCQ2MWL.js.map} +0 -0
  85. /package/dist/{chunk-JZJ7AZJD.js.map → chunk-ZJXDBVBT.js.map} +0 -0
  86. /package/dist/{client-BLUCLNIS.js.map → client-526OCGWD.js.map} +0 -0
  87. /package/dist/{config-ZUMI4IY4.js.map → config-HCJ5NZW5.js.map} +0 -0
  88. /package/dist/{config-mutator-S3CD2IWQ.js.map → config-mutator-PGR2OGWC.js.map} +0 -0
  89. /package/dist/{doctor-XGQW5SMD.js.map → doctor-AC5ONEO2.js.map} +0 -0
  90. /package/dist/{promote-K5LP5Q6Z.js.map → promote-CNKIINYK.js.map} +0 -0
  91. /package/dist/{query-LHXSINM2.js.map → query-A2N2LIR7.js.map} +0 -0
  92. /package/dist/{registry-OQUO6NCW.js.map → registry-REKWHOHS.js.map} +0 -0
  93. /package/dist/{request-planner-TW5OCKTF.js.map → request-planner-MS5BS6HY.js.map} +0 -0
  94. /package/dist/{review-candidates-EFELFOSY.js.map → review-candidates-2F4QK6QQ.js.map} +0 -0
  95. /package/dist/{routing-TSRZLD7B.js.map → routing-SU5Q4IPM.js.map} +0 -0
  96. /package/dist/{schedule-tool-JUHRVU5D.js.map → schedule-tool-24KHZY2Z.js.map} +0 -0
  97. /package/dist/{scheduler-EHJPTULN.js.map → scheduler-ALDZOUKJ.js.map} +0 -0
  98. /package/dist/{seat-NIPWHLKC.js.map → seat-PZBFMYQL.js.map} +0 -0
  99. /package/dist/{select-UAKDLN76.js.map → select-D3XOFXA5.js.map} +0 -0
  100. /package/dist/{set-enabled-74DLXMSM.js.map → set-enabled-DNDRQ3CZ.js.map} +0 -0
  101. /package/dist/{tool-TEGHFORD.js.map → tool-FB6SPVIS.js.map} +0 -0
  102. /package/dist/{tool-CEBL57UW.js.map → tool-RRGOHJW6.js.map} +0 -0
  103. /package/dist/{wiki-WOK4SCB7.js.map → wiki-3DH2QYTX.js.map} +0 -0
@@ -1,8 +1,8 @@
1
- import{a as $e}from"./chunk-GTJIKXDB.js";import{a as te,b as w}from"./chunk-DG5I6PPM.js";import{q as Ht}from"./chunk-S2GAEH2F.js";import{t as Bt,u as Ut}from"./chunk-YYCFI4VP.js";import{d as Wt,e as Ft}from"./chunk-AQASR6KR.js";import{b as zt,c as ve,e as B,f as U,h as qt}from"./chunk-E5OV6RTG.js";import{A as Se,b as xe,v as Ct,x as ee,y as ke}from"./chunk-BERHVF3T.js";import{a as Nt,b as jt,d as Vt}from"./chunk-Y4CYQV7G.js";import{a as Dt,b as Et}from"./chunk-SHEUCITK.js";import{g as Tt,h as Pt,i as Lt,k as Mt,l as Ot}from"./chunk-LXJGLNVG.js";import{q as _t}from"./chunk-J4JVKVEK.js";import{a as At,b as It}from"./chunk-DRUEPGLP.js";import{Y as we,da as vt,ea as $t,ha as Rt,n as Q,o as bt,p as wt,q as Vr,v as kt,w as St,x as Br}from"./chunk-JREA25GJ.js";import{a as xt,i as Fr}from"./chunk-RJ7DASOU.js";import{a as be,h as Wr}from"./chunk-BRK6M6LA.js";import{existsSync as Ur,readdirSync as Hr,readFileSync as zr,statSync as qr}from"fs";import{resolve as Kr}from"path";function Kt(t,e,n=Date.now(),i=7){let r=i*864e5,s=new Map;for(let o of e){let a=s.get(o.workflowId);a?a.push(o):s.set(o.workflowId,[o])}return t.map(o=>{let a=s.get(o.id)??[],c=a.filter(g=>n-g.at<=r),l=a.filter(g=>n-g.at>r&&n-g.at<=r*2),u=c.filter(g=>g.status==="failed").length,d=a.filter(g=>g.status==="paused").length,p=a.length?Math.max(...a.map(g=>g.at)):null,f=a.length?l.length>0&&c.length===0?"dormant":c.length>0&&u*2>=c.length?"failing":c.length>0?"active":"quiet":"never";return{id:o.id,name:o.name||o.id,state:f,lastRunAt:p,recent:c.length,prior:l.length,failed:u,paused:d}}).sort((o,a)=>{let c={dormant:0,failing:1,active:2,quiet:3,never:4};return c[o.state]-c[a.state]||(a.lastRunAt??0)-(o.lastRunAt??0)})}var ne=new Map;function pa(t,e=1e3){if(!Ur(t))return[];let n=Hr(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let o=Kr(t,s);return{path:o,mtime:qr(o).mtimeMs}}).sort((s,o)=>o.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of ne.keys())i.has(s)||ne.delete(s);let r=[];for(let{path:s,mtime:o}of n){let a=ne.get(s);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let c=Gr(s,o);ne.set(s,{mtime:o,summary:c}),c&&r.push(c)}return r}function Gr(t,e){try{let n=zr(t,"utf-8").split(`
2
- `).filter(Boolean);if(!n.length)return null;let i=JSON.parse(n[0]),r=i.run?.workflowId;if(!r)return null;let s=i.run?.status??"unknown";for(let o=n.length-1;o>=0;o--){let a=JSON.parse(n[o]),c=a.status??a.run?.status;if(c){s=c;break}}return{workflowId:r,status:s,at:e}}catch{return null}}var Xr={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},x={routines:200,summary:160,filters:6,filterValue:60,text:120},Jr=(t,e,n)=>{try{return _t(t,e,n)}catch{return null}},Gt=864e5;function ha(t){let e=t.now??Date.now(),n={...Xr,...t.thresholds},i=t.nextFire??Jr,r=[];for(let a of t.crons){let c=t.cronRuns.get(a.id)??[],l=a.timezone||"UTC",u=c.map(f=>({at:Date.parse(f.startedAt),status:f.status})),d=c[0],p={id:`cron:${a.id}`,source:"cron",kind:"schedule",name:$(a.id,x.text),trigger:{schedule:$(a.schedule,x.text),timezone:l},agent:a.agent||null,enabled:a.enabled,state:a.enabled?"enabled":"disabled",nextRunAt:a.enabled?Re(a.nextRun)??Re(i(a.schedule,new Date(e),l)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:ni(d.status==="success"?void 0:d.errorSummary,x.summary)}:null,lastSuccessAt:c.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:Xt(u),sampledRuns:c.length,flags:[],attention:null};p.flags=Jt(p,u,a.schedule,l,null,e,n,i),r.push(Yt(p))}let s=new Map(Kt(t.workflows.map(a=>({id:a.id,name:a.title})),t.workflowRuns,e).map(a=>[a.id,a])),o=new Map;for(let a of t.workflowRuns){let c=o.get(a.workflowId);c?c.push(a):o.set(a.workflowId,[a])}for(let a of t.workflows){let c=a.nodes.find(I=>I.type.startsWith("trigger."));if(!c||c.type!=="trigger.cron"&&c.type!=="trigger.hook")continue;let l=c.config??{},u=a.state||"active",d=u==="active",p=(o.get(a.id)??[]).slice().sort((I,ye)=>ye.at-I.at),f=p.map(I=>({at:I.at,status:Qr(I.status)})),g=f[0],h=c.type==="trigger.cron",y=typeof l.spec=="string"?l.spec:"",D=typeof l.timezone=="string"?l.timezone:"UTC",N={id:`workflow:${a.id}`,source:"workflow",kind:h?"schedule":"event",name:$(a.title||a.id,x.text),trigger:h?{schedule:$(y,x.text),timezone:D}:{event:$(typeof l.event=="string"?l.event:"",x.text),filters:ti(l.filter,a)},agent:ei(a),enabled:d,state:u,nextRunAt:h&&d&&y?Re(i(y,new Date(e),D)):null,lastRun:g?{at:new Date(g.at).toISOString(),status:g.status}:null,lastSuccessAt:(()=>{let I=f.find(ye=>ye.status==="success");return I?new Date(I.at).toISOString():null})(),consecutiveFailures:Xt(f),sampledRuns:p.length,flags:[],attention:null},Z=Date.parse(a.updated||a.created||"");N.flags=h?Jt(N,f,y,D,Number.isFinite(Z)?Z:null,e,n,i):Yr(N,s.get(a.id)?.state==="dormant",Number.isFinite(Z)?Z:null,e,n),r.push(Yt(N))}return r.sort(Zr).slice(0,x.routines)}function Xt(t){let e=0;for(let n of t)if(!(n.status==="running"||n.status==="paused"||n.status==="unknown"))if(n.status==="failed"||n.status==="timeout")e++;else break;return e}function Jt(t,e,n,i,r,s,o,a){let c=[],l=e.length?e[0].at:null;if(!t.enabled){let p=Qt(l,r,s,o);return p&&c.push(p),c}if(t.consecutiveFailures>=o.failStreak&&c.push({reason:"failing",detail:`${t.consecutiveFailures} failed attempts in a row`}),l===null)return c.push({reason:"never-ran",detail:"No persisted attempt"}),c;let u=new Date(l),d=null;for(let p=0;p<o.missedFires&&(d=a(n,u,i),!!d);p++)u=d;return d&&s>d.getTime()+o.graceMs&&c.push({reason:"overdue",detail:`No attempt since ${new Date(l).toISOString()}; ${o.missedFires} scheduled fires missed`}),c}function Yr(t,e,n,i,r){let s=[],o=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let a=Qt(o,n,i,r);return a&&s.push(a),s}return t.consecutiveFailures>=r.failStreak&&s.push({reason:"failing",detail:`${t.consecutiveFailures} failed runs in a row`}),o===null?s.push({reason:"never-ran",detail:"No run recorded for this trigger"}):e&&s.push({reason:"dormant",detail:"Fired in the prior week, silent in the last one"}),s}function Qt(t,e,n,i){let r=Math.max(t??0,e??0);return r&&n-r<i.disabledDays*Gt?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/Gt)} days`:"Disabled and never ran"}}function Yt(t){let e=new Set(t.flags.map(n=>n.reason));return t.attention=e.has("failing")?"critical":e.has("overdue")||e.has("dormant")||e.has("never-ran")?"warning":e.has("disabled-long")?"info":null,t}var Zt={critical:0,warning:1,info:2};function Zr(t,e){let n=t.attention?Zt[t.attention]:3,i=e.attention?Zt[e.attention]:3;return n-i||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function Qr(t){switch(t){case"completed":case"ok":return"success";case"failed":return"failed";case"timeout":return"timeout";case"canceled":return"canceled";case"running":return"running";case"paused":return"paused";default:return"unknown"}}function ei(t){if(t.ownerAgent)return $(t.ownerAgent,x.text);let e=t.nodes.find(n=>n.type==="agent"&&typeof n.config?.agentId=="string"&&n.config.agentId);return e?$(String(e.config.agentId),x.text):null}function ti(t,e){let n=[],i=e?.project;if(i&&n.push($(`project=${i}`,x.filterValue)),t&&typeof t=="object"&&!Array.isArray(t))for(let[r,s]of Object.entries(t)){let o=Array.isArray(s)?s.map(String):s==null?[]:[String(s)];o.length&&n.push($(`${r}=${o.join(",")}`,x.filterValue))}return n.slice(0,x.filters)}function Re(t){if(!t)return null;let e=t instanceof Date?t:new Date(t);return Number.isFinite(e.getTime())?e.toISOString():null}function $(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function ni(t,e){return t===void 0?void 0:$(t,e)}import{existsSync as se,readdirSync as xi,readFileSync as ki}from"fs";import{resolve as E}from"path";import{randomBytes as nn}from"crypto";import{existsSync as ii,mkdirSync as si,readdirSync as oi,readFileSync as ai,renameSync as rn,unlinkSync as ci,writeFileSync as li}from"fs";import{resolve as sn}from"path";function en(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var ri=t=>t.trim().split(`
3
- `).pop()?.slice(0,300)||"no output";async function tn(t,e,n,i=$e){let r=await i(t.bin,[...en(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${ri(r.stderr||r.stdout)}`}}async function wa(t,e,n,i,r=$e){return(await r(t.bin,[...en(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var ui=2e3,di=t=>tn(t.wacli,t.to,t.text);function Ae(t){return sn(t,".agentx","whatsapp-triage","drafts")}var pi=t=>/^[a-z0-9-]{8,64}$/.test(t),re=(t,e)=>sn(Ae(t),`${e}.json`);function on(t,e){si(Ae(t),{recursive:!0});let n=re(t,e.id),i=`${n}.${process.pid}.tmp`;li(i,JSON.stringify(e,null,2)+`
4
- `,{mode:384}),rn(i,n)}function Ra(t,e,n=Date.now()){let i=e.text.trim().slice(0,ui);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${nn(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return on(t,r),r}function ie(t,e){if(!pi(e))return null;try{return JSON.parse(ai(re(t,e),"utf-8"))}catch{return null}}function an(t,e){let n=Ae(t);return ii(n)?oi(n).filter(i=>i.endsWith(".json")).map(i=>ie(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function cn(t,e,n,i={}){let r=ie(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${re(t,e)}.${process.pid}.${nn(3).toString("hex")}.claim`;try{rn(re(t,e),s)}catch{return{ok:!1,error:`reply draft "${e}" is already being decided`}}let o={...r,decided_by:i.by??"operator",decided_at:new Date(i.now??Date.now()).toISOString()};if(n==="no")o.status="rejected";else{let a=await(i.send??di)(r).catch(c=>({ok:!1,error:String(c?.message??c)}));a.ok?o.status="sent":(o.status="failed",o.error=a.error)}on(t,o);try{ci(s)}catch{}return o.status==="failed"?{ok:!1,error:o.error??"send failed"}:{ok:!0,draft:o}}import{mkdirSync as fi,readFileSync as gi,renameSync as mi,writeFileSync as hi}from"fs";import{resolve as yi}from"path";function ln(t){return yi(ve(t),"_state.json")}function R(t){try{let e=JSON.parse(gi(ln(t),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{},...e?.popped&&typeof e.popped=="object"?{popped:e.popped}:{},...typeof e?.passAt=="string"?{passAt:e.passAt}:{},...Array.isArray(e?.wanted)?{wanted:e.wanted.filter(n=>typeof n=="string")}:{}}}catch{return{snoozed:{}}}}function H(t,e){fi(ve(t),{recursive:!0});let n=ln(t),i=`${n}.${process.pid}.tmp`;hi(i,JSON.stringify(e,null,2)+`
5
- `),mi(i,n)}function un(t,e,n,i=Date.now()){let r=R(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),H(t,{...r,snoozed:s})}function Da(t,e){H(t,{...R(t),lastDigest:e})}function dn(t,e,n,i=Date.now()){let r=R(t),s=new Set(n),o={};for(let[c,l]of Object.entries(r.popped??{}))s.has(c)&&(o[c]=l);o[e]=new Date(i).toISOString();let a=(r.wanted??[]).filter(c=>c!==e&&s.has(c));H(t,{...r,popped:o,wanted:a})}function pn(t,e){let n=R(t);H(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function Ea(t,e=Date.now()){H(t,{...R(t),popped:{},passAt:new Date(e).toISOString()})}Fr();Br();import{existsSync as bi,readFileSync as wi}from"fs";Rt();Wr();function fn(t){let e=At(t),n={};if(bi(e))try{n=vt(JSON.parse(wi(e,"utf-8")))}catch{n={}}let i=we.safeParse(n?.requests);return i.success?i.data:we.parse(void 0)}async function Na(t,e={}){let n=(t.channels??[]).filter(i=>!be.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...be].join(", ")}`}:It(i=>{let r=i.requests??={};for(let s of["enabled","channels","from","staleAfterHours","retentionDays"])t[s]!==void 0&&(r[s]=t[s])},{configPath:e.configPath,reload:e.reload})}var mn=["card","schedule","memory","wiki","whatsapp","request"],Si=280;function L(t,e=Si){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Ie(t){if(t.configPath)return E(t.configPath);let e=[E(t.root,"agentx.json"),E(t.root,".agentx","config.json")];return e.find(n=>se(n))??e[0]}function _e(t){return t.wikiDir?E(t.wikiDir):E(t.root,".agentx","wiki")}function vi(t){return U(t.root,"pending").map($i)}function $i(t){return{key:`card:${t.id}`,kind:"card",title:t.title,ask:t.ask,yes:`tell ${t.raised_by} yes`,no:`tell ${t.raised_by} no`,recommend:t.recommend,if_silent:t.if_silent,expires:t.expires,...t.source?{source:t.source}:{},raised_by:t.raised_by,created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.context||t.draft?{detail:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Ri(t){let e=Ie(t);if(!se(e))return[];let n;try{n=JSON.parse(ki(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,o]of Object.entries(n?.crons??{})){let a=o?.approval;if(!a||a.action!=="create"&&a.action!=="delete")continue;let c=o.timezone||"UTC",l=o.schedule?Tt(o.schedule):"",u=o.schedule?`${l.charAt(0).toLowerCase()}${l.slice(1)} (${o.schedule})`:"no schedule",d=String(o.prompt??o.command??""),p=a.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${o.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${o.agent??"the agent"} run this ${u}?`:`Remove the schedule "${s}" (${u})?`,yes:p?"enable it":"remove it",no:p?"drop the request":"keep the schedule",raised_by:String(a.requestedBy??"unknown"),created_at:String(a.requestedAt??""),detail:L(`${d}${p&&o.schedule?` \xB7 first run ${Lt(Pt(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function hn(t){let e=E(t,".agentx","memory");return se(e)?xi(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function Ai(t){let e=hn(t.root);if(e.length===0)return[];let n=new xe(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:L(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Ii(t){let e=t.sources.filter(n=>n.failure);return e.length?e.map(n=>`Recurring failure: ${n.agentId}'s ${n.failure.tool} fails with "${n.failure.errorClass}" in ${n.occurrences??1} sessions (${n.failure.runs} runs).`).join(" "):`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}.`}function _i(t){return Ft(_e(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:L(`${Ii(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Ci(t){return an(t.root,"pending").map(e=>({key:`whatsapp:${e.id}`,kind:"whatsapp",title:`WhatsApp reply to ${e.chat_name||e.to}`,ask:`Send this to ${e.chat_name||e.to}? "${e.text}"`,yes:"send it on WhatsApp",no:"drop the draft",raised_by:e.agent,created_at:e.created_at,detail:L(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function z(t){if(t.requests)return t.requests;if(E(t.root)!==process.cwd()||!se(E(t.root,".agentx","db.sqlite")))return null;let e=xt({quiet:!0});if(!e)return null;let n=gn.get(e);return!n&&!kt(e)?null:(n||gn.set(e,n=new St(e)),n)}var gn=new WeakMap;function Di(t){let e=z(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${L(n.text,80)}`,ask:`Ask ${n.agentId} to pick it up again?`,yes:`hand it back to ${n.agentId}`,no:"drop the request",raised_by:n.agentId,created_at:new Date(n.createdAt).toISOString(),detail:L(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var yn={card:vi,schedule:Ri,memory:Ai,wiki:_i,whatsapp:Ci,request:Di};function Ei(t,e){let n=t.expires?Date.parse(t.expires):1/0,i=e.expires?Date.parse(e.expires):1/0;return n!==i?n-i:(Date.parse(t.created_at)||0)-(Date.parse(e.created_at)||0)}function Ya(t,e={}){let n=t.now??Date.now(),{snoozed:i}=R(t.root),r=[],s=[],o=0;for(let a of e.kinds??mn){let c;try{c=yn[a](t)}catch(l){s.push({kind:a,error:String(l?.message??l).slice(0,200)});continue}for(let l of c){let u=i[l.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){o++;continue}l.snoozed_until=u}r.push(l)}}return r.sort(Ei),{items:r,snoozed:o,errors:s}}function Ti(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!mn.includes(n)||!i?null:{kind:n,ref:i}}function Pi(t,e,n){switch(e){case"card":return B(t.root,n)?.status==="pending";case"wiki":return Wt(_e(t),n)?.status==="pending";case"whatsapp":return ie(t.root,n)?.status==="pending";default:return yn[e](t).some(i=>i.key===`${e}:${n}`)}}async function bn(t,e,n,i={}){let r=Ti(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:s,ref:o}=r,a=t.now??Date.now(),c=i.by??"operator";if(n==="later"){if(!Pi(t,s,o))return{ok:!1,error:`nothing waiting for "${e}"`};let u=i.laterHours&&i.laterHours>0?i.laterHours:24,d=new Date(a+u*36e5);return un(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let u=qt(t.root,o,l?"yes":"no",{by:c,note:i.note,now:a,choice:i.choice,text:i.text});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${l?"yes":"no"}${u.card.choice?` (${u.card.choice})`:""}`}:u}case"schedule":{let u=await(l?Mt:Ot)(o,{configPath:Ie(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=o.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=o.slice(0,u),p=o.slice(u+1);if(!hn(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new xe(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,l?"approved":"rejected",c),{ok:!0,message:`${e} ${l?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${p}" isn't waiting for review`}}case"wiki":{let u=_e(t),d=l?Bt(u,o,{by:c,force:i.force,now:a}):Ut(u,o,{by:c,reason:i.note,now:a});return d.ok?{ok:!0,message:l?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}case"whatsapp":{let u=await cn(t.root,o,l?"yes":"no",{by:c,now:a,send:t.sendWhatsApp});return u.ok?{ok:!0,message:l?`${e}: sent to ${u.draft.chat_name||u.draft.to}`:`${e}: dropped, nothing sent`}:u}case"request":{let u=z(t),d=u?.get(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:l?fn(Ie(t)).enabled?(u.requestPickup(o,a),{ok:!0,message:`${e}: ${d.agentId} will be asked to pick it up again`}):{ok:!1,error:"Requests are off, so nothing would hand it back. Turn them on (agentx requests settings --enabled on), or answer no to drop it."}:(u.close(o,"dropped",i.note?.trim()||`dropped by ${c}`,a),{ok:!0,message:`${e}: dropped`})}}}var wn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Qa(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/requests"||t.startsWith("/requests/")||t==="/events/recent"||/^\/agents\/[^/]+\/events$/.test(t)||t==="/a2a/delegations"||t.startsWith("/a2a/delegations/")||t==="/traces"||t.startsWith("/traces/")||t==="/voice/history"||t.startsWith("/voice/history/")||t==="/voice/transcribe"||t==="/voice/speak"||t==="/app-files"||t==="/calls"||t.startsWith("/calls/")||t==="/webrtc/camera"||t.startsWith("/webrtc/camera/")||t==="/mesh/guests"||t.startsWith("/mesh/guests/")}function ec(t){return t==="/reload"||t==="/api/processes/kill"||t==="/send"||t==="/send/agent"||t==="/send/contact"||t==="/mesh/announce"||t==="/voice/settings"||t==="/voice/preview"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(t)||/^\/mesh\/guests\/[^/]+\/(pause|resume|end|update)$/.test(t)||/^\/crons\/[^/]+\/enabled$/.test(t)}function tc(t){return wn.has(t)}function nc(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(wn.has(t.remoteAddress))return{allowed:!0,reason:"loopback"};if(t.acceptedTokens.size===0)return{allowed:!0,reason:"no-tokens-configured"};let e=t.authorizationHeader||"",n=e.startsWith("Bearer ")?e.slice(7).trim():"";return n&&t.acceptedTokens.has(n)?{allowed:!0,reason:"token"}:{allowed:!1,reason:"missing-or-invalid-token"}}function rc(t,e=process.env){let n=new Set;e.MESH_TOKEN&&n.add(e.MESH_TOKEN);for(let i of t.mesh?.peers||[])i.token&&n.add(i.token);return n}function ic(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function oe(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Li(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function Mi(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function oc(t,e=Mi()){let n=oe(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Li(n),s=[oe(t.host),oe(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=oe(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function ac(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as Hn,mkdirSync as us,readFileSync as ds,renameSync as ps,writeFileSync as fs}from"fs";import{homedir as gs}from"os";import{dirname as ms,join as hs}from"path";import{execFile as qi,execFileSync as Ki}from"child_process";import{execFileSync as Oi}from"child_process";import{existsSync as kn,mkdirSync as Ni,readdirSync as ji,readFileSync as Sn,renameSync as Vi,writeFileSync as Wi}from"fs";import{homedir as vn}from"os";import{join as De}from"path";var S="siri:",$n="com.apple.ttsbundle.gryphon-neural_",Rn=t=>!!t&&t.startsWith($n),Fi=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],Bi=()=>{try{return Oi("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ce;function Ee(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Ce!==void 0)return Ce;let{platform:n=process.platform,exists:i=kn,prefDomain:r=Bi}=t,s=n==="darwin"&&Fi.every(o=>i(o))&&r();return e||(Ce=s),s}var An=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],In={aaron:"male",damon:"male",daniel:"male",pierre:"male",samer:"male",arthur:"male",gordon:"male",martin:"male",nora:"female",simone:"female",marie:"female",soha:"female",martha:"female",catherine:"female",helena:"female",nicky:"female"},Te=t=>In[t.toLowerCase()]??null;function ae(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var Ui=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function Hi(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(Ui)){let o=`${i}-${r}`,a=`${$n}${s}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:s[0].toUpperCase()+s.slice(1),locale:o,quality:"premium",gender:In[s]??null,siri:!0})}return[...e.values()]}function ce(t=An,e={}){if(!Ee(e))return[];let n=[];for(let i of t){let r;try{r=ji(i)}catch{continue}for(let s of r)try{n.push(Sn(De(i,s,"Info.plist"),"latin1"))}catch{}}return Hi(n)}var xn=`#!/bin/sh
1
+ import{a as $e}from"./chunk-GTJIKXDB.js";import{a as te,b as w}from"./chunk-DG5I6PPM.js";import{q as zt}from"./chunk-S2GAEH2F.js";import{t as Ut,u as Ht}from"./chunk-S337S2M7.js";import{d as Ft,e as Bt}from"./chunk-AQASR6KR.js";import{b as qt,c as ve,e as B,f as U,h as Kt}from"./chunk-E5OV6RTG.js";import{A as Se,b as ke,v as Dt,x as ee,y as xe}from"./chunk-EXPIKLUN.js";import{a as jt,b as Vt,d as Wt}from"./chunk-Y4CYQV7G.js";import{a as Et,b as Tt}from"./chunk-SHEUCITK.js";import{g as Pt,h as Lt,i as Mt,k as Ot,l as Nt}from"./chunk-V6W3FFW7.js";import{q as Ct}from"./chunk-Y6POV2X5.js";import{a as It,b as _t}from"./chunk-5UO6BBDG.js";import{X as we,ca as $t,da as Rt,ga as At,m as Q,n as wt,o as kt,p as Fr,u as St,v as vt,w as Hr}from"./chunk-ECM2QEXF.js";import{a as xt,i as Ur}from"./chunk-RJ7DASOU.js";import{a as be,h as Br}from"./chunk-BRK6M6LA.js";import{existsSync as zr,readdirSync as qr,readFileSync as Kr,statSync as Gr}from"fs";import{resolve as Xr}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 ne=new Map;function ga(t,e=1e3){if(!zr(t))return[];let n=qr(t).filter(s=>s.endsWith(".jsonl")).map(s=>{let o=Xr(t,s);return{path:o,mtime:Gr(o).mtimeMs}}).sort((s,o)=>o.mtime-s.mtime).slice(0,e),i=new Set(n.map(s=>s.path));for(let s of ne.keys())i.has(s)||ne.delete(s);let r=[];for(let{path:s,mtime:o}of n){let a=ne.get(s);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let c=Jr(s,o);ne.set(s,{mtime:o,summary:c}),c&&r.push(c)}return r}function Jr(t,e){try{let n=Kr(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 Yr={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},Zr=(t,e,n)=>{try{return Ct(t,e,n)}catch{return null}},Xt=864e5;function ba(t){let e=t.now??Date.now(),n={...Yr,...t.thresholds},i=t.nextFire??Zr,r=[];for(let a of t.crons){let c=t.cronRuns.get(a.id)??[],l=a.timezone||"UTC",u=c.map(f=>({at:Date.parse(f.startedAt),status:f.status})),d=c[0],p={id:`cron:${a.id}`,source:"cron",kind:"schedule",name:$(a.id,k.text),trigger:{schedule:$(a.schedule,k.text),timezone:l},agent:a.agent||null,enabled:a.enabled,state:a.enabled?"enabled":"disabled",nextRunAt:a.enabled?Re(a.nextRun)??Re(i(a.schedule,new Date(e),l)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:ii(d.status==="success"?void 0:d.errorSummary,k.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(I=>I.type.startsWith("trigger."));if(!c||c.type!=="trigger.cron"&&c.type!=="trigger.hook")continue;let l=c.config??{},u=a.state||"active",d=u==="active",p=(o.get(a.id)??[]).slice().sort((I,ye)=>ye.at-I.at),f=p.map(I=>({at:I.at,status:ti(I.status)})),g=f[0],h=c.type==="trigger.cron",y=typeof l.spec=="string"?l.spec:"",D=typeof l.timezone=="string"?l.timezone:"UTC",N={id:`workflow:${a.id}`,source:"workflow",kind:h?"schedule":"event",name:$(a.title||a.id,k.text),trigger:h?{schedule:$(y,k.text),timezone:D}:{event:$(typeof l.event=="string"?l.event:"",k.text),filters:ri(l.filter,a)},agent:ni(a),enabled:d,state:u,nextRunAt:h&&d&&y?Re(i(y,new Date(e),D)):null,lastRun:g?{at:new Date(g.at).toISOString(),status:g.status}:null,lastSuccessAt:(()=>{let I=f.find(ye=>ye.status==="success");return I?new Date(I.at).toISOString():null})(),consecutiveFailures:Jt(f),sampledRuns:p.length,flags:[],attention:null},Z=Date.parse(a.updated||a.created||"");N.flags=h?Yt(N,f,y,D,Number.isFinite(Z)?Z:null,e,n,i):Qr(N,s.get(a.id)?.state==="dormant",Number.isFinite(Z)?Z:null,e,n),r.push(Zt(N))}return r.sort(ei).slice(0,k.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 Qr(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 ei(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 ti(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 ni(t){if(t.ownerAgent)return $(t.ownerAgent,k.text);let e=t.nodes.find(n=>n.type==="agent"&&typeof n.config?.agentId=="string"&&n.config.agentId);return e?$(String(e.config.agentId),k.text):null}function ri(t,e){let n=[],i=e?.project;if(i&&n.push($(`project=${i}`,k.filterValue)),t&&typeof t=="object"&&!Array.isArray(t))for(let[r,s]of Object.entries(t)){let o=Array.isArray(s)?s.map(String):s==null?[]:[String(s)];o.length&&n.push($(`${r}=${o.join(",")}`,k.filterValue))}return n.slice(0,k.filters)}function Re(t){if(!t)return null;let e=t instanceof Date?t:new Date(t);return Number.isFinite(e.getTime())?e.toISOString():null}function $(t,e){return t.length<=e?t:t.slice(0,e-3)+"..."}function ii(t,e){return t===void 0?void 0:$(t,e)}import{existsSync as se,readdirSync as Si,readFileSync as vi}from"fs";import{resolve as E}from"path";import{randomBytes as rn}from"crypto";import{existsSync as oi,mkdirSync as ai,readdirSync as ci,readFileSync as li,renameSync as sn,unlinkSync as ui,writeFileSync as di}from"fs";import{resolve as on}from"path";function tn(t){return[...t.account?["--account",t.account]:[],...t.store?["--store",t.store]:[]]}var si=t=>t.trim().split(`
3
+ `).pop()?.slice(0,300)||"no output";async function nn(t,e,n,i=$e){let r=await i(t.bin,[...tn(t),"send","text","--to",e,"--message",n,"--no-preview"],{timeoutMs:6e4});return r.code===0?{ok:!0}:{ok:!1,error:`wacli send failed: ${si(r.stderr||r.stdout)}`}}async function xa(t,e,n,i,r=$e){return(await r(t.bin,[...tn(t),"--read-only","media","download","--chat",e,"--id",n,"--output",i],{timeoutMs:12e4})).code===0}var pi=2e3,fi=t=>nn(t.wacli,t.to,t.text);function Ae(t){return on(t,".agentx","whatsapp-triage","drafts")}var gi=t=>/^[a-z0-9-]{8,64}$/.test(t),re=(t,e)=>on(Ae(t),`${e}.json`);function an(t,e){ai(Ae(t),{recursive:!0});let n=re(t,e.id),i=`${n}.${process.pid}.tmp`;di(i,JSON.stringify(e,null,2)+`
4
+ `,{mode:384}),sn(i,n)}function Ia(t,e,n=Date.now()){let i=e.text.trim().slice(0,pi);if(!i)throw new Error("empty draft");let r={...e,text:i,id:`${n.toString(36)}-${rn(4).toString("hex")}`,status:"pending",created_at:new Date(n).toISOString()};return an(t,r),r}function ie(t,e){if(!gi(e))return null;try{return JSON.parse(li(re(t,e),"utf-8"))}catch{return null}}function cn(t,e){let n=Ae(t);return oi(n)?ci(n).filter(i=>i.endsWith(".json")).map(i=>ie(t,i.slice(0,-5))).filter(i=>!!i&&(!e||i.status===e)).sort((i,r)=>i.created_at.localeCompare(r.created_at)):[]}async function ln(t,e,n,i={}){let r=ie(t,e);if(!r||r.status!=="pending")return{ok:!1,error:`no reply draft "${e}" is waiting`};let s=`${re(t,e)}.${process.pid}.${rn(3).toString("hex")}.claim`;try{sn(re(t,e),s)}catch{return{ok:!1,error:`reply draft "${e}" is already being decided`}}let o={...r,decided_by:i.by??"operator",decided_at:new Date(i.now??Date.now()).toISOString()};if(n==="no")o.status="rejected";else{let a=await(i.send??fi)(r).catch(c=>({ok:!1,error:String(c?.message??c)}));a.ok?o.status="sent":(o.status="failed",o.error=a.error)}an(t,o);try{ui(s)}catch{}return o.status==="failed"?{ok:!1,error:o.error??"send failed"}:{ok:!0,draft:o}}import{mkdirSync as mi,readFileSync as hi,renameSync as yi,writeFileSync as bi}from"fs";import{resolve as wi}from"path";function un(t){return wi(ve(t),"_state.json")}function R(t){try{let e=JSON.parse(hi(un(t),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{},...e?.popped&&typeof e.popped=="object"?{popped:e.popped}:{},...typeof e?.passAt=="string"?{passAt:e.passAt}:{},...Array.isArray(e?.wanted)?{wanted:e.wanted.filter(n=>typeof n=="string")}:{}}}catch{return{snoozed:{}}}}function H(t,e){mi(ve(t),{recursive:!0});let n=un(t),i=`${n}.${process.pid}.tmp`;bi(i,JSON.stringify(e,null,2)+`
5
+ `),yi(i,n)}function dn(t,e,n,i=Date.now()){let r=R(t),s={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>i&&(s[o]=a);s[e]=n.toISOString(),H(t,{...r,snoozed:s})}function Ta(t,e){H(t,{...R(t),lastDigest:e})}function pn(t,e,n,i=Date.now()){let r=R(t),s=new Set(n),o={};for(let[c,l]of Object.entries(r.popped??{}))s.has(c)&&(o[c]=l);o[e]=new Date(i).toISOString();let a=(r.wanted??[]).filter(c=>c!==e&&s.has(c));H(t,{...r,popped:o,wanted:a})}function fn(t,e){let n=R(t);H(t,{...n,wanted:[...(n.wanted??[]).filter(i=>i!==e),e]})}function Pa(t,e=Date.now()){H(t,{...R(t),popped:{},passAt:new Date(e).toISOString()})}Ur();Hr();import{existsSync as ki,readFileSync as xi}from"fs";At();Br();function gn(t){let e=It(t),n={};if(ki(e))try{n=$t(JSON.parse(xi(e,"utf-8")))}catch{n={}}let i=we.safeParse(n?.requests);return i.success?i.data:we.parse(void 0)}async function Va(t,e={}){let n=(t.channels??[]).filter(i=>!be.has(i.toLowerCase().split("@")[0]));return n.length?{success:!1,error:`unknown channel ${n.map(i=>`"${i}"`).join(", ")}: use ${[...be].join(", ")}`}:_t(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 hn=["card","schedule","memory","wiki","whatsapp","request"],$i=280;function L(t,e=$i){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function Ie(t){if(t.configPath)return E(t.configPath);let e=[E(t.root,"agentx.json"),E(t.root,".agentx","config.json")];return e.find(n=>se(n))??e[0]}function _e(t){return t.wikiDir?E(t.wikiDir):E(t.root,".agentx","wiki")}function Ri(t){return U(t.root,"pending").map(Ai)}function Ai(t){return{key:`card:${t.id}`,kind:"card",title:t.title,ask:t.ask,yes:`tell ${t.raised_by} yes`,no:`tell ${t.raised_by} no`,recommend:t.recommend,if_silent:t.if_silent,expires:t.expires,...t.source?{source:t.source}:{},raised_by:t.raised_by,created_at:t.created_at,...t.choices?{choices:t.choices,more:`agentx approvals popup card:${t.id}`}:{},...t.context||t.draft?{detail:L([t.context,t.draft?`Suggested message: ${t.draft}`:""].filter(Boolean).join(" \xB7 "))}:{}}}function Ii(t){let e=Ie(t);if(!se(e))return[];let n;try{n=JSON.parse(vi(e,"utf-8"))}catch{return[]}let i=new Date(t.now??Date.now()),r=[];for(let[s,o]of Object.entries(n?.crons??{})){let a=o?.approval;if(!a||a.action!=="create"&&a.action!=="delete")continue;let c=o.timezone||"UTC",l=o.schedule?Pt(o.schedule):"",u=o.schedule?`${l.charAt(0).toLowerCase()}${l.slice(1)} (${o.schedule})`:"no schedule",d=String(o.prompt??o.command??""),p=a.action==="create";r.push({key:`schedule:${s}`,kind:"schedule",title:p?`New schedule "${s}" for ${o.agent??"an agent"}`:`Delete schedule "${s}"`,ask:p?`Let ${o.agent??"the agent"} run this ${u}?`:`Remove the schedule "${s}" (${u})?`,yes:p?"enable it":"remove it",no:p?"drop the request":"keep the schedule",raised_by:String(a.requestedBy??"unknown"),created_at:String(a.requestedAt??""),detail:L(`${d}${p&&o.schedule?` \xB7 first run ${Mt(Lt(o.schedule,c,i),c)}`:""}`),more:"agentx schedule list"})}return r}function yn(t){let e=E(t,".agentx","memory");return se(e)?Si(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function _i(t){let e=yn(t.root);if(e.length===0)return[];let n=new ke(t.root),i=[];for(let r of e)for(let s of n.held(r))i.push({key:`memory:${r}/${s.id}`,kind:"memory",title:`Fact ${r} learned from ${s.source.channel}`,ask:`Let ${r} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:r,created_at:s.createdAt,detail:L(s.content),more:`agentx memory facts held --agent ${r}`});return i}function Ci(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 Di(t){return Bt(_e(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:L(`${Ci(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}function Ei(t){return cn(t.root,"pending").map(e=>({key:`whatsapp:${e.id}`,kind:"whatsapp",title:`WhatsApp reply to ${e.chat_name||e.to}`,ask:`Send this to ${e.chat_name||e.to}? "${e.text}"`,yes:"send it on WhatsApp",no:"drop the draft",raised_by:e.agent,created_at:e.created_at,detail:L(`${e.triage}: ${e.summary}`),more:"agentx whatsapp triage log"}))}function z(t){if(t.requests)return t.requests;if(E(t.root)!==process.cwd()||!se(E(t.root,".agentx","db.sqlite")))return null;let e=xt({quiet:!0});if(!e)return null;let n=mn.get(e);return!n&&!St(e)?null:(n||mn.set(e,n=new vt(e)),n)}var mn=new WeakMap;function Ti(t){let e=z(t);return e?e.listByState("needs_attention").map(n=>({key:`request:${n.id}`,kind:"request",title:`Request not finished: ${L(n.text,80)}`,ask:`Ask ${n.agentId} to pick it up again?`,yes:`hand it back to ${n.agentId}`,no:"drop the request",raised_by:n.agentId,created_at:new Date(n.createdAt).toISOString(),detail:L(`${n.attentionReason??"It needs attention"}. Asked on ${n.channel}: ${n.text}`),more:`agentx requests show ${n.id}`})):[]}var bn={card:Ri,schedule:Ii,memory:_i,wiki:Di,whatsapp:Ei,request:Ti};function Pi(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 Qa(t,e={}){let n=t.now??Date.now(),{snoozed:i}=R(t.root),r=[],s=[],o=0;for(let a of e.kinds??hn){let c;try{c=bn[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(Pi),{items:r,snoozed:o,errors:s}}function Li(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),i=t.slice(e+1);return!hn.includes(n)||!i?null:{kind:n,ref:i}}function Mi(t,e,n){switch(e){case"card":return B(t.root,n)?.status==="pending";case"wiki":return Ft(_e(t),n)?.status==="pending";case"whatsapp":return ie(t.root,n)?.status==="pending";default:return bn[e](t).some(i=>i.key===`${e}:${n}`)}}async function wn(t,e,n,i={}){let r=Li(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(!Mi(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 dn(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(s){case"card":{let u=Kt(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:Ie(t),reload:t.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=o.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let d=o.slice(0,u),p=o.slice(u+1);if(!yn(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new ke(t.root);return f.held(d).some(g=>g.id===p)?(f.review(d,p,l?"approved":"rejected",c),{ok:!0,message:`${e} ${l?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${p}" isn't waiting for review`}}case"wiki":{let u=_e(t),d=l?Ut(u,o,{by:c,force:i.force,now:a}):Ht(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 ln(t.root,o,l?"yes":"no",{by:c,now:a,send:t.sendWhatsApp});return u.ok?{ok:!0,message:l?`${e}: sent to ${u.draft.chat_name||u.draft.to}`:`${e}: dropped, nothing sent`}:u}case"request":{let u=z(t),d=u?.get(o);return!u||!d||d.state!=="needs_attention"?{ok:!1,error:`nothing waiting for "${e}"`}:l?gn(Ie(t)).enabled?(u.requestPickup(o,a),{ok:!0,message:`${e}: ${d.agentId} will be asked to pick it up again`}):{ok:!1,error:"Requests are off, so nothing would hand it back. Turn them on (agentx requests settings --enabled on), or answer no to drop it."}:(u.close(o,"dropped",i.note?.trim()||`dropped by ${c}`,a),{ok:!0,message:`${e}: dropped`})}}}var kn=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function tc(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/requests"||t.startsWith("/requests/")||t==="/events/recent"||/^\/agents\/[^/]+\/events$/.test(t)||t==="/a2a/delegations"||t.startsWith("/a2a/delegations/")||t==="/traces"||t.startsWith("/traces/")||t==="/voice/history"||t.startsWith("/voice/history/")||t==="/voice/transcribe"||t==="/voice/speak"||t==="/app-files"||t==="/calls"||t.startsWith("/calls/")||t==="/webrtc/camera"||t.startsWith("/webrtc/camera/")||t==="/mesh/guests"||t.startsWith("/mesh/guests/")}function nc(t){return t==="/reload"||t==="/api/processes/kill"||t==="/send"||t==="/send/agent"||t==="/send/contact"||t==="/mesh/announce"||t==="/voice/settings"||t==="/voice/preview"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(t)||/^\/mesh\/guests\/[^/]+\/(pause|resume|end|update)$/.test(t)||/^\/crons\/[^/]+\/enabled$/.test(t)}function rc(t){return kn.has(t)}function ic(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(kn.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 sc(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 oc(t,e,n=process.env){let i=s=>s.replace(/\/+$/,"");return(e===i(t.daemonUrl)?t.token:t.daemons.find(s=>i(s.url)===e)?.token)||n.MESH_TOKEN||void 0}function oe(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function Oi(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function Ni(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function cc(t,e=Ni()){let n=oe(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=Oi(n),s=[oe(t.host),oe(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&s.includes(r)?"same-origin":"foreign"}let i=oe(t["sec-fetch-site"]).toLowerCase();return i==="cross-site"||i==="same-site"?"foreign":"none"}function lc(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{existsSync as zn,mkdirSync as ps,readFileSync as fs,renameSync as gs,writeFileSync as ms}from"fs";import{homedir as hs}from"os";import{dirname as ys,join as bs}from"path";import{execFile as Gi,execFileSync as Xi}from"child_process";import{execFileSync as ji}from"child_process";import{existsSync as Sn,mkdirSync as Vi,readdirSync as Wi,readFileSync as vn,renameSync as Fi,writeFileSync as Bi}from"fs";import{homedir as $n}from"os";import{join as De}from"path";var S="siri:",Rn="com.apple.ttsbundle.gryphon-neural_",An=t=>!!t&&t.startsWith(Rn),Ui=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],Hi=()=>{try{return ji("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},Ce;function Ee(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&Ce!==void 0)return Ce;let{platform:n=process.platform,exists:i=Sn,prefDomain:r=Hi}=t,s=n==="darwin"&&Ui.every(o=>i(o))&&r();return e||(Ce=s),s}var In=["/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"},Te=t=>_n[t.toLowerCase()]??null;function ae(t){let e=/^com\.apple\.ttsbundle\.gryphon-neural_([a-z]+)_([a-z]{2}-[A-Z]{2})_premium$/.exec(t);return e?{name:e[1],locale:e[2]}:null}var zi=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function qi(t){let e=new Map;for(let n of t)for(let[,i,r,s]of n.matchAll(zi)){let o=`${i}-${r}`,a=`${Rn}${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 ce(t=In,e={}){if(!Ee(e))return[];let n=[];for(let i of t){let r;try{r=Wi(i)}catch{continue}for(let s of r)try{n.push(vn(De(i,s,"Info.plist"),"latin1"))}catch{}}return qi(n)}var xn=`#!/bin/sh
6
6
  # Written by agentx; shared by the daemon and AgentX Voice. Do not edit.
7
7
  # siri-say.sh [voice] < text speak one line. A Siri voice id switches
8
8
  # the OS default for it; any other id is
@@ -14,7 +14,7 @@ D=com.apple.Accessibility K=SpokenContentDefaultVoiceSelectionsByLanguage
14
14
  dir="$HOME/.agentx/voice" lock="$HOME/.agentx/voice/siri.lock" saved="$HOME/.agentx/voice/siri-saved.plist"
15
15
  stops="$dir/stop"
16
16
  read_s=\${AGENTX_SAY_READ_S:-5} stale_s=\${AGENTX_SAY_STALE_S:-30} max_s=\${AGENTX_SAY_MAX_S:-300}
17
- assets=\${AGENTX_SIRI_ASSET_DIRS:-"${An.join(" ")}"}
17
+ assets=\${AGENTX_SIRI_ASSET_DIRS:-"${In.join(" ")}"}
18
18
  if [ "$1" = --stop ]; then
19
19
  mkdir -p "$dir" || exit 1
20
20
  # Queued lines see this change and drop. The owner's trap stops say,
@@ -107,32 +107,32 @@ wait "$say_pid"
107
107
  status=$?
108
108
  say_pid=
109
109
  finish $status
110
- `,zi=(t=vn())=>De(t,".agentx","voice","siri-say.sh");function _n(t=vn()){let e=zi(t);return kn(e)&&Sn(e,"utf8")===xn||(Ni(De(t,".agentx","voice"),{recursive:!0}),Wi(`${e}.tmp`,xn,{mode:493}),Vi(`${e}.tmp`,e)),e}var Cn=`ObjC.import("AVFoundation")
110
+ `,Ki=(t=$n())=>De(t,".agentx","voice","siri-say.sh");function Cn(t=$n()){let e=Ki(t);return Sn(e)&&vn(e,"utf8")===xn||(Vi(De(t,".agentx","voice"),{recursive:!0}),Bi(`${e}.tmp`,xn,{mode:493}),Fi(`${e}.tmp`,e)),e}var Dn=`ObjC.import("AVFoundation")
111
111
  const vs = $.AVSpeechSynthesisVoice.speechVoices, out = []
112
112
  for (let i = 0; i < vs.count; i++) {
113
113
  const v = vs.objectAtIndex(i)
114
114
  out.push([v.identifier.js, v.name.js, v.language.js, Number(v.quality), Number(v.gender)].join("\\t"))
115
115
  }
116
- out.join("\\n")`,Gi=new Set(["Fred","Kathy","Ralph","Junior"]),Xi={Flo:"female",Sandy:"female",Shelley:"female",Grandma:"female",Kathy:"female",Eddy:"male",Reed:"male",Rocko:"male",Grandpa:"male",Fred:"male",Ralph:"male",Junior:"male"};function Dn(t){let e=[];for(let n of t.split(`
117
- `)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!Gi.has(r)||e.push({id:i,name:r,locale:s,quality:o==="3"?"premium":o==="2"?"enhanced":"standard",gender:a==="1"?"male":a==="2"?"female":Xi[r]??null})}return e}var Ji=10*60*1e3,hc=60*1e3,j=null,Pe=!1;function Le(t=Date.now(),e=Ji){if(process.platform!=="darwin")return[];if(j)t-j.at>e&&!Pe&&(Pe=!0,qi("osascript",["-l","JavaScript","-e",Cn],{timeout:1e4},(n,i)=>{Pe=!1,n||(j={at:Date.now(),voices:[...Dn(String(i)),...ce()]})}));else try{j={at:t,voices:[...Dn(Ki("osascript",["-l","JavaScript","-e",Cn],{encoding:"utf8",timeout:1e4})),...ce()]}}catch(n){Me(`[voice] could not list system voices: ${String(n?.message??n).split(`
116
+ out.join("\\n")`,Ji=new Set(["Fred","Kathy","Ralph","Junior"]),Yi={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 En(t){let e=[];for(let n of t.split(`
117
+ `)){let[i,r,s,o,a]=n.split(" ");!i||!r||!s||i.includes(".siri_")||i.startsWith("com.apple.speech.synthesis.voice.")&&!Ji.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":Yi[r]??null})}return e}var Zi=10*60*1e3,bc=60*1e3,j=null,Pe=!1;function Le(t=Date.now(),e=Zi){if(process.platform!=="darwin")return[];if(j)t-j.at>e&&!Pe&&(Pe=!0,Gi("osascript",["-l","JavaScript","-e",Dn],{timeout:1e4},(n,i)=>{Pe=!1,n||(j={at:Date.now(),voices:[...En(String(i)),...ce()]})}));else try{j={at:t,voices:[...En(Xi("osascript",["-l","JavaScript","-e",Dn],{encoding:"utf8",timeout:1e4})),...ce()]}}catch(n){Me(`[voice] could not list system voices: ${String(n?.message??n).split(`
118
118
  `)[0]}`),j={at:t,voices:ce()}}return j.voices}var Me=t=>process.stderr.write(t+`
119
- `),le=new Set;function yc(t){Me=t}function M(t,e){le.has(t)||(le.add(t),Me(e))}function Pn(t){for(let e of le)t(e)&&le.delete(e)}var Ln=()=>{};function bc(t){Ln=t}function Mn(t){try{Ln(t)}catch(e){M("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var Yi={premium:3,enhanced:2,standard:1},Zi=new Set(["Grandma","Grandpa"]);function En(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!Zi.has(t.name)?1:0;return Yi[t.quality]*10+e}var V=t=>t.toLowerCase().split(/[-_]/)[0],Tn=t=>t.id.startsWith("com.apple.voice.");function Oe(t,e,n,i=new Set){let r=q(t.filter(a=>!a.siri&&V(a.locale)===V(e)),e);if(r.some(Tn)&&(r=r.filter(Tn)),n==="female"||n==="male"){let a=r.filter(c=>c.gender===n);a.length&&(r=a)}if(!r.length)return null;let s=r.filter(a=>a.quality===r[0].quality),o=new Set([...i].map(a=>a.toLowerCase()));return s.find(a=>!o.has(a.name.toLowerCase()))??s[0]}function q(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=V(e),r=t.filter(s=>V(s.locale)===i);return(r.length?r:t).slice().sort((s,o)=>En(o)-En(s)||+(o.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(o.name)||s.locale.localeCompare(o.locale))}function K(t,e,n="en"){let i=t.trim();if(!i)return null;let r=e.find(l=>l.id===i);if(r)return r;if(i.toLowerCase().startsWith(S)){let l=i.slice(S.length).trim().toLowerCase(),u=q(e.filter(p=>p.siri&&p.name.toLowerCase()===l),n)[0];if(u||!l)return u??null;let d=K(l,e.filter(p=>V(p.locale)===V(n)),n);return d&&M(`siri:${l}`,`[voice] Siri voice "${l}" is not installed; speaking with ${d.name} (${d.locale}) instead.`),d}e=e.filter(l=>!l.siri);let s=/^(.+?)\s*\((premium|enhanced)\)$/i.exec(i),o=(s?s[1]:i.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),a=q(e.filter(l=>l.name.toLowerCase()===o),n);return(s?a.find(l=>l.quality===s[2].toLowerCase()):void 0)??a[0]??null}function On(t,e,n=new Set){let i=new Map;if(!e.length)return i;let r=new Set([...n].map(o=>o.toLowerCase())),s="female";for(let o of t){let a=o.gender==="female"||o.gender==="male",c=a?o.gender:s,l=e.filter(d=>!r.has(d.name.toLowerCase())),u=l.find(d=>d.gender===c)??(a?e.find(d=>d.gender===c):void 0)??l[0]??e[i.size%e.length];i.set(o.id,u),r.add(u.name.toLowerCase()),a||(s=s==="female"?"male":"female")}return i}bt();var Ne="system",Qi=t=>t.trim().toLowerCase()===Ne,es="21m00Tcm4TlvDq8ikWAM";function je(t,e,n={},i=Le()){let r=e[t],s=r?.name||t,o=r?.voice,a=We(e,n,i).get(t)??null,c=is(t,o?.system,o?.gender,n,i);return{agentId:t,name:s,provider:o?.provider??n.provider??"system",elevenlabsVoiceId:o?.elevenlabsVoiceId||null,systemVoice:a?.id??null,systemVoiceName:a?de(a):null,systemByLanguage:c,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||os(s,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var de=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function ts(t,e,n,i){if(!e||!n.length)return null;let r=K(e,n,i);return r||(M(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),Mn(e)),r}function Wn(t,e){let n=t.trim();if(n.toLowerCase().startsWith(S))return{locale:e,gender:Te(n.slice(S.length).trim())};let i=ae(n);return i?{locale:i.locale,gender:Te(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var Fn=t=>t.toLowerCase().split(/[-_]/)[0],Nn=(t,e)=>typeof t=="string"?t:t?.[Fn(e)];function ue(t,e,n,i){if(e!==void 0)return Qi(e)?null:ts(t,e,n,i)??void 0}var Ve=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function ns(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,o=[],a=ue("voice.system",Nn(e.system,r),n,r),c=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=Nn(u.system,r),p=ue(u.id,d,n,r),f=p!==void 0?p:d!==void 0&&n.length?rs(u,d,r,a,n,c()):a!==void 0&&Ve(a,u.gender)?a:void 0;f!==void 0?s.set(u.id,f):o.push({id:u.id,gender:u.gender??null})}let l=c();for(let[u,d]of On(o,q(n.filter(p=>!p.siri),r),l))s.set(u,d);return s}function rs(t,e,n,i,r,s){for(let a of t.fallbacks??[]){let c=ue(`${t.id}.fallbacks`,a,r,n);if(c!==void 0)return c}if(i!==void 0&&Ve(i,t.gender))return i;let o=Wn(e,n);return Oe(r,o.locale,t.gender??o.gender,s)??void 0}function is(t,e,n,i,r){if(typeof e=="string")return{};let s={},o=(a,c,l)=>{if(!(!c||typeof c=="string"))for(let[u,d]of Object.entries(c)){let p=ue(`${a}.${u}`,d,r,u);p===void 0&&r.length&&(p=Oe(r,u,n??Wn(d,u).gender)??void 0),p!==void 0&&l(p)&&(s[Fn(u)]=p)}};return o("voice.system",i.system,a=>Ve(a,n)),o(t,e,()=>!0),s}function vc(t,e){let n=e?Q(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?de(i):null}}function We(t,e={},n=Le()){let i=Object.entries(t).map(([r,s])=>({id:r,system:s.voice?.system,gender:s.voice?.gender,fallbacks:s.voice?.fallbacks}));return ns(i,e,n)}function Fe(t,e){let n={provider:t.provider,elevenlabs:ss(e,t.elevenlabsVoiceId),system:t.systemVoice,fallback:t.fallback},i=Object.entries(t.systemByLanguage??{});return i.length&&(n.languages=Object.fromEntries(i.map(([r,s])=>[r,s?.id??null]))),t.rate&&t.rate!==1&&(n.rate=t.rate),t.priority&&t.priority!=="normal"&&(n.priority=t.priority),n}function ss(t,e){return t||e||process.env.AGENTX_VOICE_ID||es}function os(t,e){let n=(e??"").split(/(?<=\.)\s/)[0]??"",i=/^You are (.+?)\.?$/i.exec(n.trim());if(!i)return`Hello, this is ${t}.`;let r=i[1].replace(/\s*\([^)]*\)/g,"").trim(),[s,...o]=r.split(/,\s*/),a=o.join(", ");return a&&s.toLowerCase()===t.toLowerCase()?`Hello, this is ${t}, ${a}.`:!/^an? /i.test(r)&&r.toLowerCase().includes(t.toLowerCase())?`Hello, this is ${r}.`:`Hello, this is ${t}, ${r}.`}var as=8*60*60*1e3,cs=500,jn=class{constructor(e=as){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(Vn(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=Vn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>cs&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},Vn=(t,e)=>`${t}\0${e}`;function Bn(t,e){let n=t.style?` Your speaking manner: ${t.style}.`:"";return e?`[VOICE INTRO] This is your first spoken exchange with this person in a while. Open with one short sentence introducing yourself in your own manner, along the lines of "${t.intro}", then answer.${n}`:"[VOICE CASUAL] You have already introduced yourself in this voice conversation. Do not introduce yourself or greet again; talk casually, like a colleague in the same office."+n}function $c(t,e,n,i={}){let r=e[t],s=je(t,e,i),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:Fe(s),persona:o||`You are ${s.name}.`,introLine:Bn(s,n)}}var ls="[VOICE MODE] This question arrived by voice and your reply will be spoken aloud by a TTS engine. Answer in two or three short sentences. Plain language, no markdown, no code blocks, no bullet points, no URLs. Speak conversationally.";function Rc(t){let e=t;if(e?.channel!=="voice"||!e.voice||typeof e.voice!="object")return;let n=s=>typeof s=="string"?s.replace(/\s+/g," ").slice(0,200):"",i=n(e.voice.intro),r={agentId:"",name:"",provider:"system",elevenlabsVoiceId:null,systemVoice:null,systemVoiceName:null,systemByLanguage:{},fallback:!0,gender:null,style:n(e.voice.style)||null,intro:i||"Hello."};return`${ls}
120
- ${Bn(r,e.voice.introduce===!0&&!!i)}`}var ys="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",zn=(t=gs())=>hs(t,".agentx","voice","health.json");function bs(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===Ne)return!0;if(i.toLowerCase().startsWith(S)){let r=i.slice(S.length).trim().toLowerCase();return e.some(s=>s.siri&&s.name.toLowerCase()===r)}return K(i,e,n)!==null}function ws(t){let e=t.voice?.locale??"en",n=[],i=(r,s)=>{if(typeof s=="string")n.push({owner:r,name:s,locale:e,perLanguage:!1});else for(let[o,a]of Object.entries(s??{}))n.push({owner:r,name:a,locale:o,perLanguage:!0})};i("voice.system",t.voice?.system);for(let[r,s]of Object.entries(t.agents))(s.voice?.provider??t.voice?.provider??"system")!=="system"&&t.voice?.fallback==="none"||i(r,s.voice?.system);return n}function xs(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:o,perLanguage:a}of ws(t)){if(bs(s,e,o))continue;i??=We(t.agents,t.voice,e);let c=n.get(s)??{voice:s,agents:[],speaksWith:{}};c.agents.includes(r)||c.agents.push(r);let l=i.get(r);r!=="voice.system"&&!a&&(c.speaksWith[r]=l?de(l):"the OS default voice"),n.set(s,c)}return[...n.values()]}function Be(t){let e=ae(t);if(e)return`Siri ${e.name[0].toUpperCase()}${e.name.slice(1)} (${e.locale})`;if(t.toLowerCase().startsWith(S)){let n=t.slice(S.length).trim();return`Siri ${n[0]?.toUpperCase()??""}${n.slice(1)}`}return t}function ks(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${Be(n.voice)}: ${i}`});return{title:t.length===1?"AgentX: a voice is not installed":`AgentX: ${t.length} voices are not installed`,message:`${e.join(`
119
+ `),le=new Set;function wc(t){Me=t}function M(t,e){le.has(t)||(le.add(t),Me(e))}function Ln(t){for(let e of le)t(e)&&le.delete(e)}var Mn=()=>{};function kc(t){Mn=t}function On(t){try{Mn(t)}catch(e){M("missing-hook",`[voice] missing-voice check failed: ${e?.message??e}`)}}var Qi={premium:3,enhanced:2,standard:1},es=new Set(["Grandma","Grandpa"]);function Tn(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!es.has(t.name)?1:0;return Qi[t.quality]*10+e}var V=t=>t.toLowerCase().split(/[-_]/)[0],Pn=t=>t.id.startsWith("com.apple.voice.");function Oe(t,e,n,i=new Set){let r=q(t.filter(a=>!a.siri&&V(a.locale)===V(e)),e);if(r.some(Pn)&&(r=r.filter(Pn)),n==="female"||n==="male"){let a=r.filter(c=>c.gender===n);a.length&&(r=a)}if(!r.length)return null;let s=r.filter(a=>a.quality===r[0].quality),o=new Set([...i].map(a=>a.toLowerCase()));return s.find(a=>!o.has(a.name.toLowerCase()))??s[0]}function q(t,e="en"){let n=e.toLowerCase().replace("_","-"),i=V(e),r=t.filter(s=>V(s.locale)===i);return(r.length?r:t).slice().sort((s,o)=>Tn(o)-Tn(s)||+(o.locale.toLowerCase()===n)-+(s.locale.toLowerCase()===n)||s.name.localeCompare(o.name)||s.locale.localeCompare(o.locale))}function K(t,e,n="en"){let i=t.trim();if(!i)return null;let r=e.find(l=>l.id===i);if(r)return r;if(i.toLowerCase().startsWith(S)){let l=i.slice(S.length).trim().toLowerCase(),u=q(e.filter(p=>p.siri&&p.name.toLowerCase()===l),n)[0];if(u||!l)return u??null;let d=K(l,e.filter(p=>V(p.locale)===V(n)),n);return d&&M(`siri:${l}`,`[voice] Siri voice "${l}" is not installed; speaking with ${d.name} (${d.locale}) instead.`),d}e=e.filter(l=>!l.siri);let s=/^(.+?)\s*\((premium|enhanced)\)$/i.exec(i),o=(s?s[1]:i.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),a=q(e.filter(l=>l.name.toLowerCase()===o),n);return(s?a.find(l=>l.quality===s[2].toLowerCase()):void 0)??a[0]??null}function Nn(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}wt();var Ne="system",ts=t=>t.trim().toLowerCase()===Ne,ns="21m00Tcm4TlvDq8ikWAM";function je(t,e,n={},i=Le()){let r=e[t],s=r?.name||t,o=r?.voice,a=We(e,n,i).get(t)??null,c=os(t,o?.system,o?.gender,n,i);return{agentId:t,name:s,provider:o?.provider??n.provider??"system",elevenlabsVoiceId:o?.elevenlabsVoiceId||null,systemVoice:a?.id??null,systemVoiceName:a?de(a):null,systemByLanguage:c,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||cs(s,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var de=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function rs(t,e,n,i){if(!e||!n.length)return null;let r=K(e,n,i);return r||(M(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),On(e)),r}function Fn(t,e){let n=t.trim();if(n.toLowerCase().startsWith(S))return{locale:e,gender:Te(n.slice(S.length).trim())};let i=ae(n);return i?{locale:i.locale,gender:Te(i.name)}:{locale:/^com\.apple\.voice\.[a-z]+\.([a-z]{2}-[A-Z]{2})\./.exec(n)?.[1]??e,gender:null}}var Bn=t=>t.toLowerCase().split(/[-_]/)[0],jn=(t,e)=>typeof t=="string"?t:t?.[Bn(e)];function ue(t,e,n,i){if(e!==void 0)return ts(e)?null:rs(t,e,n,i)??void 0}var Ve=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function is(t,e,n,i=new Set){let r=e.locale??"en",s=new Map,o=[],a=ue("voice.system",jn(e.system,r),n,r),c=()=>new Set([...i,...[...s.values()].flatMap(u=>u?[u.name]:[])]);for(let u of t){let d=jn(u.system,r),p=ue(u.id,d,n,r),f=p!==void 0?p:d!==void 0&&n.length?ss(u,d,r,a,n,c()):a!==void 0&&Ve(a,u.gender)?a:void 0;f!==void 0?s.set(u.id,f):o.push({id:u.id,gender:u.gender??null})}let l=c();for(let[u,d]of Nn(o,q(n.filter(p=>!p.siri),r),l))s.set(u,d);return s}function ss(t,e,n,i,r,s){for(let a of t.fallbacks??[]){let c=ue(`${t.id}.fallbacks`,a,r,n);if(c!==void 0)return c}if(i!==void 0&&Ve(i,t.gender))return i;let o=Fn(e,n);return Oe(r,o.locale,t.gender??o.gender,s)??void 0}function os(t,e,n,i,r){if(typeof e=="string")return{};let s={},o=(a,c,l)=>{if(!(!c||typeof c=="string"))for(let[u,d]of Object.entries(c)){let p=ue(`${a}.${u}`,d,r,u);p===void 0&&r.length&&(p=Oe(r,u,n??Fn(d,u).gender)??void 0),p!==void 0&&l(p)&&(s[Bn(u)]=p)}};return o("voice.system",i.system,a=>Ve(a,n)),o(t,e,()=>!0),s}function Rc(t,e){let n=e?Q(e):null;if(!n||!(n in t.systemByLanguage))return t;let i=t.systemByLanguage[n];return{...t,systemVoice:i?.id??null,systemVoiceName:i?de(i):null}}function We(t,e={},n=Le()){let i=Object.entries(t).map(([r,s])=>({id:r,system:s.voice?.system,gender:s.voice?.gender,fallbacks:s.voice?.fallbacks}));return is(i,e,n)}function Fe(t,e){let n={provider:t.provider,elevenlabs:as(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 as(t,e){return t||e||process.env.AGENTX_VOICE_ID||ns}function cs(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 ls=8*60*60*1e3,us=500,Vn=class{constructor(e=ls){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,i=Date.now()){let r=this.lastSpoke.get(Wn(e,n));return r===void 0||i-r>this.gapMs}spoke(e,n,i=Date.now()){let r=Wn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,i),this.lastSpoke.size>us&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},Wn=(t,e)=>`${t}\0${e}`;function Un(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 Ac(t,e,n,i={}){let r=e[t],s=je(t,e,i),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:s.name,voice:Fe(s),persona:o||`You are ${s.name}.`,introLine:Un(s,n)}}var ds="[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 Ic(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`${ds}
120
+ ${Un(r,e.voice.introduce===!0&&!!i)}`}var ws="System Settings \u203A Accessibility \u203A Spoken Content \u203A System voice \u203A Manage Voices",qn=(t=hs())=>bs(t,".agentx","voice","health.json");function ks(t,e,n){let i=t.trim();if(!i||i.toLowerCase()===Ne)return!0;if(i.toLowerCase().startsWith(S)){let r=i.slice(S.length).trim().toLowerCase();return e.some(s=>s.siri&&s.name.toLowerCase()===r)}return K(i,e,n)!==null}function xs(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 Ss(t,e){if(!e.length)return[];let n=new Map,i;for(let{owner:r,name:s,locale:o,perLanguage:a}of xs(t)){if(ks(s,e,o))continue;i??=We(t.agents,t.voice,e);let c=n.get(s)??{voice:s,agents:[],speaksWith:{}};c.agents.includes(r)||c.agents.push(r);let l=i.get(r);r!=="voice.system"&&!a&&(c.speaksWith[r]=l?de(l):"the OS default voice"),n.set(s,c)}return[...n.values()]}function Be(t){let e=ae(t);if(e)return`Siri ${e.name[0].toUpperCase()}${e.name.slice(1)} (${e.locale})`;if(t.toLowerCase().startsWith(S)){let n=t.slice(S.length).trim();return`Siri ${n[0]?.toUpperCase()??""}${n.slice(1)}`}return t}function vs(t){let e=t.map(n=>{let i=n.agents.map(r=>n.speaksWith[r]?`${r} (now ${n.speaksWith[r]})`:r).join(", ");return`\u2022 ${Be(n.voice)}: ${i}`});return{title:t.length===1?"AgentX: a voice is not installed":`AgentX: ${t.length} voices are not installed`,message:`${e.join(`
121
121
  `)}
122
- Reinstall in ${ys}. Agents switch back on their own once it is installed.`}}function Ss(t=zn()){if(!Hn(t))return null;try{let e=JSON.parse(ds(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function vs(t,e){us(ms(t),{recursive:!0}),fs(`${t}.tmp`,JSON.stringify(e,null,2)+`
123
- `),ps(`${t}.tmp`,t)}var Un=class{constructor(e){this.deps=e}running=!1;missingNow=!1;hasMissing(){return this.missingNow}async check(e,n,i=new Date){if(this.running||!n.length)return null;this.running=!0;try{let r=this.deps.file??zn(),s=new Map((Ss(r)?.missing??[]).map(d=>[d.voice,d])),o=xs(e,n),a=o.map(d=>({...d,since:s.get(d.voice)?.since??i.toISOString(),...s.get(d.voice)?.notifiedAt?{notifiedAt:s.get(d.voice).notifiedAt}:{}})),c=[...s.keys()].filter(d=>!o.some(p=>p.voice===d));for(let d of c)this.deps.log(`[voice] ${Be(d)} is installed again; its agents speak with it again`);c.length&&Pn(d=>c.some(p=>d===p||d.endsWith(`:${p}`)));let l=a.filter(d=>!d.notifiedAt);if(l.length){let{title:d,message:p}=ks(l);try{await this.deps.notify(d,p);for(let f of l)f.notifiedAt=i.toISOString();this.deps.log(`[voice] told the owner: ${l.map(f=>Be(f.voice)).join(", ")} not installed`)}catch(f){this.deps.log(`[voice] could not send the missing-voice notice: ${f?.message??f}`)}}this.missingNow=a.length>0;let u={checkedAt:i.toISOString(),missing:a};return(!Hn(r)||JSON.stringify(a)!==JSON.stringify([...s.values()]))&&vs(r,u),u}finally{this.running=!1}}};import{readFileSync as He,writeFileSync as Yn,existsSync as ze,readdirSync as Ts,statSync as Ps}from"fs";import{resolve as qe,join as Ls}from"path";import{existsSync as qn,mkdirSync as $s,readFileSync as Rs,writeFileSync as Kn}from"fs";import{dirname as As,resolve as Gn}from"path";import{z as m}from"zod";var Is=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),_s=m.object({id:m.string(),title:m.string(),description:m.string().optional(),assignee:m.string().optional(),labels:m.array(m.string()).default([]),milestone:m.string().optional(),status:m.enum(["todo","doing","blocked","done"]).default("todo"),priority:m.number().int().optional(),estimatedSeconds:m.number().int().optional(),source:Is.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),Cs=m.object({version:m.literal(1),items:m.array(_s).default([])}),pe=class{constructor(e){this.path=e}jsonPath(){return Gn(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return Gn(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return qn(this.jsonPath())}load(){let e=this.jsonPath();if(!qn(e))return{version:1,items:[]};let n=Rs(e,"utf-8");try{return Cs.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();$s(As(n),{recursive:!0}),Kn(n,JSON.stringify(e,null,2)+`
124
- `),Kn(this.mdPath(),this.toMarkdown(e))}list(){return this.load().items}findById(e){return this.list().find(n=>n.id===e)}add(e){let n=this.load();if(n.items.some(s=>s.id===e.id))throw new Error(`backlog item ${e.id} already exists`);let i=new Date().toISOString(),r={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??i,updatedAt:i};return n.items.push(r),this.save(n),r}addMany(e){let n=this.load(),i=new Set(n.items.map(o=>o.id)),r=new Date().toISOString(),s=[];for(let o of e){if(i.has(o.id))continue;let a={...o,labels:o.labels??[],status:o.status??"todo",createdAt:o.createdAt??r,updatedAt:r};n.items.push(a),s.push(a),i.add(a.id)}return s.length&&this.save(n),s}update(e,n){let i=this.load(),r=i.items.findIndex(o=>o.id===e);if(r<0)throw new Error(`backlog item ${e} not found`);let s={...i.items[r],...n,id:i.items[r].id,createdAt:i.items[r].createdAt,updatedAt:new Date().toISOString()};return i.items[r]=s,this.save(i),s}remove(e){let n=this.load(),i=n.items.length;return n.items=n.items.filter(r=>r.id!==e),n.items.length===i?!1:(this.save(n),!0)}toMarkdown(e){let n=["# Backlog","","_Generated from `backlog.json`. Do not edit by hand \u2014 use `agentx backlog` commands._",""],i={doing:[],blocked:[],todo:[],done:[]};for(let s of e.items)i[s.status].push(s);let r=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[s,o]of r)if(i[s].length){n.push(`## ${o}`,"");for(let a of i[s]){let c=s==="done"?"x":" ",l=a.assignee?`@${a.assignee} `:"",u=a.estimatedSeconds?` [time: ${Math.round(a.estimatedSeconds/60)}m]`:"",d=a.source?` (${a.source.type}: ${a.source.project}#${a.source.iid})`:"";n.push(`- [${c}] ${l}${a.title}${u}${d}`),a.source?.url&&n.push(` - <${a.source.url}>`),a.labels.length&&n.push(` - labels: ${a.labels.join(", ")}`),a.milestone&&n.push(` - milestone: ${a.milestone}`),a.blocker&&n.push(` - BLOCKED: ${a.blocker}`)}n.push("")}return n.join(`
125
- `)}};function Nc(t){return`${t.type}:${t.project}:${t.iid}`}function Xn(t,e,n){let i=[];if(e.type==="gitlab"){let r=n.channels.gitlab?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.gitlabUsernames?.length?i.push(o.gitlabUsernames[0]):i.push(s)}}else if(e.type==="github"){let r=n.channels.github?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.githubUsernames?.length?i.push(o.githubUsernames[0]):i.push(s)}}return i}async function Ue(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?Ds(t.source,e,n,i):t.source.type==="github"?Es(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function Ds(t,e,n,i){let r=n.channels.gitlab,s=r?.token,o=r?.host||(t.host?`https://${t.host}`:void 0);if(!s||!o)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let a=[],c=async(f,g={})=>fetch(`${o}/api/v4${f}`,{...g,headers:{"PRIVATE-TOKEN":s,"Content-Type":"application/json",...g.headers||{}}}),l=encodeURIComponent(t.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async g=>{try{let h=await fetch(`${o}/api/v4/users?username=${encodeURIComponent(g)}`,{headers:{"PRIVATE-TOKEN":s}});if(!h.ok)return null;let y=await h.json();return Array.isArray(y)&&y[0]?.id?y[0].id:null}catch{return null}}))).filter(g=>typeof g=="number"));let d;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")d=0;else try{let f=await c(`/projects/${l}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(f.ok){let g=await f.json();Array.isArray(g)&&g[0]?.id&&(d=g[0].id)}}catch(f){i(`[backlog-sync] milestone lookup failed: ${f.message}`)}let p={};if(e.title!==void 0&&(p.title=e.title),e.description!==void 0&&(p.description=e.description),e.labels!==void 0&&(p.labels=e.labels.join(",")),e.addLabels?.length&&(p.add_labels=e.addLabels.join(",")),e.removeLabels?.length&&(p.remove_labels=e.removeLabels.join(",")),u!==void 0&&(p.assignee_ids=u),d!==void 0&&(p.milestone_id=d),e.state&&(p.state_event=e.state==="closed"?"close":"reopen"),Object.keys(p).length)try{let f=await c(`/projects/${l}/issues/${t.iid}`,{method:"PUT",body:JSON.stringify(p)});if(a.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let g=await f.text().catch(()=>"");return{ok:!1,attempts:a,error:`PUT issue ${f.status}: ${g.slice(0,200)}`,url:t.url}}}catch(f){return a.push({kind:"PUT issue",ok:!1,error:f.message}),{ok:!1,attempts:a,error:f.message,url:t.url}}if(e.note)try{let f=await c(`/projects/${l}/issues/${t.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});a.push({kind:"POST note",ok:f.ok,status:f.status})}catch(f){a.push({kind:"POST note",ok:!1,error:f.message})}return{ok:a.every(f=>f.ok),attempts:a,url:t.url}}async function Es(t,e,n,i){let s=n.channels.github?.token;if(!s)return{ok:!1,error:"github token not configured",attempts:[]};let o=[],a=async(p,f={})=>fetch(`https://api.github.com${p}`,{...f,headers:{Authorization:`Bearer ${s}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...f.headers||{}}}),c=t.project,l;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")l=null;else try{let p=await a(`/repos/${c}/milestones?state=all&per_page=100`);if(p.ok){let f=await p.json(),g=Array.isArray(f)?f.find(h=>h.title===e.milestoneTitle):null;g?.number&&(l=g.number)}}catch(p){i(`[backlog-sync] github milestone lookup failed: ${p.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let p=await a(`/repos/${c}/issues/${t.iid}`);if(p.ok){let f=await p.json(),g=Array.isArray(f.labels)?f.labels.map(y=>typeof y=="string"?y:y.name):[],h=new Set([...g,...e.addLabels??[]]);for(let y of e.removeLabels??[])h.delete(y);u=[...h]}}catch(p){i(`[backlog-sync] github label fetch failed: ${p.message}`)}let d={};if(e.title!==void 0&&(d.title=e.title),e.description!==void 0&&(d.body=e.description),u!==void 0&&(d.labels=u),e.assigneeUsernames!==void 0&&(d.assignees=e.assigneeUsernames),l!==void 0&&(d.milestone=l),e.state&&(d.state=e.state),Object.keys(d).length)try{let p=await a(`/repos/${c}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(o.push({kind:"PATCH issue",ok:p.ok,status:p.status}),!p.ok){let f=await p.text().catch(()=>"");return{ok:!1,attempts:o,error:`PATCH issue ${p.status}: ${f.slice(0,200)}`,url:t.url}}}catch(p){return o.push({kind:"PATCH issue",ok:!1,error:p.message}),{ok:!1,attempts:o,error:p.message,url:t.url}}if(e.note)try{let p=await a(`/repos/${c}/issues/${t.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});o.push({kind:"POST comment",ok:p.ok,status:p.status})}catch(p){o.push({kind:"POST comment",ok:!1,error:p.message})}return{ok:o.every(p=>p.ok),attempts:o,url:t.url}}var Ke=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,fe=/@([a-z0-9_-]+)/i,Jn=/\[time:\s*([0-9hm\s]+)\]/i;function Ms(t){let e=t.match(/(\d+)\s*h/i),n=t.match(/(\d+)\s*m/i);return(e?parseInt(e[1],10)*3600:0)+(n?parseInt(n[1],10)*60:0)}var Ge=class{constructor(e,n,i=()=>{}){this.path=e;this.daemon=n;this.log=i;this.store=new pe(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=qe(process.cwd(),this.path);return ze(e)?He(e,"utf-8").split(`
126
- `):[]}writeMd(e){let n=qe(process.cwd(),this.path);Yn(n,e.join(`
127
- `))}async listOpen(e){if(this.store.exists())return this.store.list().filter(s=>s.status!=="done"&&(!s.assignee||s.assignee.toLowerCase()===e.toLowerCase())).map(s=>this.toWorkItem(s));let n=this.readMd(),i=[];for(let r=0;r<n.length;r++){let s=n[r].match(Ke);if(!s||s[2].toLowerCase()==="x")continue;let a=s[3],c=a.match(fe);if(c&&c[1].toLowerCase()!==e.toLowerCase())continue;let l=a.match(Jn),u=a.replace(fe,"").replace(Jn,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:c?c[1]:void 0,estimatedSeconds:l?Ms(l[1]):void 0,priority:r})}return i}async listAll(e={}){return this.store.exists()?this.store.list().map(n=>this.toWorkItem(n)):[]}async claim(e,n){if(!this.store.exists())return;let i=this.store.findById(n);if(!i)return;let r=this.store.update(n,{assignee:i.assignee||e,status:"doing"});if(r.source&&this.daemon){let s=Xn([r.assignee||e],r.source,this.daemon);Ue(r,{assigneeUsernames:s,addLabels:["Doing"],removeLabels:["To Do"]},this.daemon,this.log).catch(o=>this.log(`[backlog-sync] claim failed for ${n}: ${o?.message??o}`))}}async report(e,n){if(this.store.exists()&&this.store.findById(e)){let a={};n.status==="done"?a.status="done":n.status==="blocked"?(a.status="blocked",a.blocker=n.blocker||n.note||void 0):n.status==="in-progress"&&(a.status="doing"),n.timeSeconds&&(a.estimatedSeconds=n.timeSeconds);let c=this.store.update(e,a);if(c.source&&this.daemon){let l={};n.status==="done"?(l.addLabels=["Done"],l.removeLabels=["Doing"]):n.status==="blocked"&&(l.addLabels=["Blocked"]),n.note&&(l.note=n.note),Object.keys(l).length&&Ue(c,l,this.daemon,this.log).catch(u=>this.log(`[backlog-sync] report failed for ${e}: ${u?.message??u}`))}return}if(!e.startsWith("backlog:"))throw new Error(`not a backlog id: ${e}`);let i=parseInt(e.slice(8),10),r=this.readMd(),s=r[i];if(!s)throw new Error(`backlog line ${i} missing`);if(!s.match(Ke))throw new Error(`backlog line ${i} not a checkbox`);if(n.status==="done"){r[i]=s.replace(/- \[ \]/,"- [x]");let a=n.timeSeconds?` <!-- done by agent, ${Math.round(n.timeSeconds/60)}m -->`:" <!-- done by agent -->";r.splice(i+1,0,a)}else n.status==="blocked"?r.splice(i+1,0,` <!-- BLOCKED: ${n.blocker||n.note||"?"} -->`):n.note&&r.splice(i+1,0,` <!-- ${n.note.replace(/-->/g,"\u2014 >")} -->`);this.writeMd(r)}toWorkItem(e){let n={todo:"todo",doing:"doing",blocked:"onhold",done:"done"}[e.status];return{id:e.id,title:e.title,description:e.description,assignee:e.assignee,estimatedSeconds:e.estimatedSeconds,priority:e.priority,labels:e.labels,stage:n,milestone:e.milestone,url:e.source?.url,updatedAt:e.updatedAt,state:e.status==="done"?"closed":"opened"}}},Xe=class{constructor(e,n){this.root=e;this.glob=n}type="wiki";capabilities={listAll:!1,create:!1,transition:!1,labels:!1,search:!1};walk(e,n){if(ze(e))for(let i of Ts(e)){let r=Ls(e,i);Ps(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(qe(process.cwd(),this.root),n);let i=[];for(let r of n){let s=He(r,"utf-8").split(`
122
+ Reinstall in ${ws}. Agents switch back on their own once it is installed.`}}function $s(t=qn()){if(!zn(t))return null;try{let e=JSON.parse(fs(t,"utf8"));return e&&Array.isArray(e.missing)?e:null}catch{return null}}function Rs(t,e){ps(ys(t),{recursive:!0}),ms(`${t}.tmp`,JSON.stringify(e,null,2)+`
123
+ `),gs(`${t}.tmp`,t)}var Hn=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??qn(),s=new Map(($s(r)?.missing??[]).map(d=>[d.voice,d])),o=Ss(e,n),a=o.map(d=>({...d,since:s.get(d.voice)?.since??i.toISOString(),...s.get(d.voice)?.notifiedAt?{notifiedAt:s.get(d.voice).notifiedAt}:{}})),c=[...s.keys()].filter(d=>!o.some(p=>p.voice===d));for(let d of c)this.deps.log(`[voice] ${Be(d)} is installed again; its agents speak with it again`);c.length&&Ln(d=>c.some(p=>d===p||d.endsWith(`:${p}`)));let l=a.filter(d=>!d.notifiedAt);if(l.length){let{title:d,message:p}=vs(l);try{await this.deps.notify(d,p);for(let f of l)f.notifiedAt=i.toISOString();this.deps.log(`[voice] told the owner: ${l.map(f=>Be(f.voice)).join(", ")} not installed`)}catch(f){this.deps.log(`[voice] could not send the missing-voice notice: ${f?.message??f}`)}}this.missingNow=a.length>0;let u={checkedAt:i.toISOString(),missing:a};return(!zn(r)||JSON.stringify(a)!==JSON.stringify([...s.values()]))&&Rs(r,u),u}finally{this.running=!1}}};import{readFileSync as He,writeFileSync as Zn,existsSync as ze,readdirSync as Ls,statSync as Ms}from"fs";import{resolve as qe,join as Os}from"path";import{existsSync as Kn,mkdirSync as As,readFileSync as Is,writeFileSync as Gn}from"fs";import{dirname as _s,resolve as Xn}from"path";import{z as m}from"zod";var Cs=m.object({type:m.enum(["gitlab","github"]),host:m.string().optional(),project:m.string(),iid:m.number().int().positive(),url:m.string()}),Ds=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:Cs.optional(),importedAt:m.string().optional(),createdAt:m.string(),updatedAt:m.string(),blocker:m.string().optional(),doneNote:m.string().optional()}),Es=m.object({version:m.literal(1),items:m.array(Ds).default([])}),pe=class{constructor(e){this.path=e}jsonPath(){return Xn(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return Xn(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return Kn(this.jsonPath())}load(){let e=this.jsonPath();if(!Kn(e))return{version:1,items:[]};let n=Is(e,"utf-8");try{return Es.parse(JSON.parse(n))}catch(i){throw new Error(`Backlog file invalid (${e}): ${i.message}`)}}save(e){let n=this.jsonPath();As(_s(n),{recursive:!0}),Gn(n,JSON.stringify(e,null,2)+`
124
+ `),Gn(this.mdPath(),this.toMarkdown(e))}list(){return this.load().items}findById(e){return this.list().find(n=>n.id===e)}add(e){let n=this.load();if(n.items.some(s=>s.id===e.id))throw new Error(`backlog item ${e.id} already exists`);let i=new Date().toISOString(),r={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??i,updatedAt:i};return n.items.push(r),this.save(n),r}addMany(e){let n=this.load(),i=new Set(n.items.map(o=>o.id)),r=new Date().toISOString(),s=[];for(let o of e){if(i.has(o.id))continue;let a={...o,labels:o.labels??[],status:o.status??"todo",createdAt:o.createdAt??r,updatedAt:r};n.items.push(a),s.push(a),i.add(a.id)}return s.length&&this.save(n),s}update(e,n){let i=this.load(),r=i.items.findIndex(o=>o.id===e);if(r<0)throw new Error(`backlog item ${e} not found`);let s={...i.items[r],...n,id:i.items[r].id,createdAt:i.items[r].createdAt,updatedAt:new Date().toISOString()};return i.items[r]=s,this.save(i),s}remove(e){let n=this.load(),i=n.items.length;return n.items=n.items.filter(r=>r.id!==e),n.items.length===i?!1:(this.save(n),!0)}toMarkdown(e){let n=["# Backlog","","_Generated from `backlog.json`. Do not edit by hand \u2014 use `agentx backlog` commands._",""],i={doing:[],blocked:[],todo:[],done:[]};for(let s of e.items)i[s.status].push(s);let r=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[s,o]of r)if(i[s].length){n.push(`## ${o}`,"");for(let a of i[s]){let c=s==="done"?"x":" ",l=a.assignee?`@${a.assignee} `:"",u=a.estimatedSeconds?` [time: ${Math.round(a.estimatedSeconds/60)}m]`:"",d=a.source?` (${a.source.type}: ${a.source.project}#${a.source.iid})`:"";n.push(`- [${c}] ${l}${a.title}${u}${d}`),a.source?.url&&n.push(` - <${a.source.url}>`),a.labels.length&&n.push(` - labels: ${a.labels.join(", ")}`),a.milestone&&n.push(` - milestone: ${a.milestone}`),a.blocker&&n.push(` - BLOCKED: ${a.blocker}`)}n.push("")}return n.join(`
125
+ `)}};function Vc(t){return`${t.type}:${t.project}:${t.iid}`}function Jn(t,e,n){let i=[];if(e.type==="gitlab"){let r=n.channels.gitlab?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.gitlabUsernames?.length?i.push(o.gitlabUsernames[0]):i.push(s)}}else if(e.type==="github"){let r=n.channels.github?.agentMappings??[];for(let s of t){let o=r.find(a=>a.agentId===s);o?.githubUsernames?.length?i.push(o.githubUsernames[0]):i.push(s)}}return i}async function Ue(t,e,n,i=()=>{}){return t.source?t.source.type==="gitlab"?Ts(t.source,e,n,i):t.source.type==="github"?Ps(t.source,e,n,i):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function Ts(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 Ps(t,e,n,i){let s=n.channels.github?.token;if(!s)return{ok:!1,error:"github token not configured",attempts:[]};let o=[],a=async(p,f={})=>fetch(`https://api.github.com${p}`,{...f,headers:{Authorization:`Bearer ${s}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...f.headers||{}}}),c=t.project,l;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")l=null;else try{let p=await a(`/repos/${c}/milestones?state=all&per_page=100`);if(p.ok){let f=await p.json(),g=Array.isArray(f)?f.find(h=>h.title===e.milestoneTitle):null;g?.number&&(l=g.number)}}catch(p){i(`[backlog-sync] github milestone lookup failed: ${p.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let p=await a(`/repos/${c}/issues/${t.iid}`);if(p.ok){let f=await p.json(),g=Array.isArray(f.labels)?f.labels.map(y=>typeof y=="string"?y:y.name):[],h=new Set([...g,...e.addLabels??[]]);for(let y of e.removeLabels??[])h.delete(y);u=[...h]}}catch(p){i(`[backlog-sync] github label fetch failed: ${p.message}`)}let d={};if(e.title!==void 0&&(d.title=e.title),e.description!==void 0&&(d.body=e.description),u!==void 0&&(d.labels=u),e.assigneeUsernames!==void 0&&(d.assignees=e.assigneeUsernames),l!==void 0&&(d.milestone=l),e.state&&(d.state=e.state),Object.keys(d).length)try{let p=await a(`/repos/${c}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(o.push({kind:"PATCH issue",ok:p.ok,status:p.status}),!p.ok){let f=await p.text().catch(()=>"");return{ok:!1,attempts:o,error:`PATCH issue ${p.status}: ${f.slice(0,200)}`,url:t.url}}}catch(p){return o.push({kind:"PATCH issue",ok:!1,error:p.message}),{ok:!1,attempts:o,error:p.message,url:t.url}}if(e.note)try{let p=await a(`/repos/${c}/issues/${t.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});o.push({kind:"POST comment",ok:p.ok,status:p.status})}catch(p){o.push({kind:"POST comment",ok:!1,error:p.message})}return{ok:o.every(p=>p.ok),attempts:o,url:t.url}}var Ke=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,fe=/@([a-z0-9_-]+)/i,Yn=/\[time:\s*([0-9hm\s]+)\]/i;function Ns(t){let e=t.match(/(\d+)\s*h/i),n=t.match(/(\d+)\s*m/i);return(e?parseInt(e[1],10)*3600:0)+(n?parseInt(n[1],10)*60:0)}var Ge=class{constructor(e,n,i=()=>{}){this.path=e;this.daemon=n;this.log=i;this.store=new pe(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=qe(process.cwd(),this.path);return ze(e)?He(e,"utf-8").split(`
126
+ `):[]}writeMd(e){let n=qe(process.cwd(),this.path);Zn(n,e.join(`
127
+ `))}async listOpen(e){if(this.store.exists())return this.store.list().filter(s=>s.status!=="done"&&(!s.assignee||s.assignee.toLowerCase()===e.toLowerCase())).map(s=>this.toWorkItem(s));let n=this.readMd(),i=[];for(let r=0;r<n.length;r++){let s=n[r].match(Ke);if(!s||s[2].toLowerCase()==="x")continue;let a=s[3],c=a.match(fe);if(c&&c[1].toLowerCase()!==e.toLowerCase())continue;let l=a.match(Yn),u=a.replace(fe,"").replace(Yn,"").trim();i.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:c?c[1]:void 0,estimatedSeconds:l?Ns(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=Jn([r.assignee||e],r.source,this.daemon);Ue(r,{assigneeUsernames:s,addLabels:["Doing"],removeLabels:["To Do"]},this.daemon,this.log).catch(o=>this.log(`[backlog-sync] claim failed for ${n}: ${o?.message??o}`))}}async report(e,n){if(this.store.exists()&&this.store.findById(e)){let a={};n.status==="done"?a.status="done":n.status==="blocked"?(a.status="blocked",a.blocker=n.blocker||n.note||void 0):n.status==="in-progress"&&(a.status="doing"),n.timeSeconds&&(a.estimatedSeconds=n.timeSeconds);let c=this.store.update(e,a);if(c.source&&this.daemon){let l={};n.status==="done"?(l.addLabels=["Done"],l.removeLabels=["Doing"]):n.status==="blocked"&&(l.addLabels=["Blocked"]),n.note&&(l.note=n.note),Object.keys(l).length&&Ue(c,l,this.daemon,this.log).catch(u=>this.log(`[backlog-sync] report failed for ${e}: ${u?.message??u}`))}return}if(!e.startsWith("backlog:"))throw new Error(`not a backlog id: ${e}`);let i=parseInt(e.slice(8),10),r=this.readMd(),s=r[i];if(!s)throw new Error(`backlog line ${i} missing`);if(!s.match(Ke))throw new Error(`backlog line ${i} not a checkbox`);if(n.status==="done"){r[i]=s.replace(/- \[ \]/,"- [x]");let a=n.timeSeconds?` <!-- done by agent, ${Math.round(n.timeSeconds/60)}m -->`:" <!-- done by agent -->";r.splice(i+1,0,a)}else n.status==="blocked"?r.splice(i+1,0,` <!-- BLOCKED: ${n.blocker||n.note||"?"} -->`):n.note&&r.splice(i+1,0,` <!-- ${n.note.replace(/-->/g,"\u2014 >")} -->`);this.writeMd(r)}toWorkItem(e){let n={todo:"todo",doing:"doing",blocked:"onhold",done:"done"}[e.status];return{id:e.id,title:e.title,description:e.description,assignee:e.assignee,estimatedSeconds:e.estimatedSeconds,priority:e.priority,labels:e.labels,stage:n,milestone:e.milestone,url:e.source?.url,updatedAt:e.updatedAt,state:e.status==="done"?"closed":"opened"}}},Xe=class{constructor(e,n){this.root=e;this.glob=n}type="wiki";capabilities={listAll:!1,create:!1,transition:!1,labels:!1,search:!1};walk(e,n){if(ze(e))for(let i of Ls(e)){let r=Os(e,i);Ms(r).isDirectory()?this.walk(r,n):i.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(qe(process.cwd(),this.root),n);let i=[];for(let r of n){let s=He(r,"utf-8").split(`
128
128
  `);for(let o=0;o<s.length;o++){let a=s[o].match(Ke);if(!a||a[2].toLowerCase()==="x")continue;let c=a[3].match(fe);!c||c[1].toLowerCase()!==e.toLowerCase()||i.push({id:`wiki:${r}:${o}`,title:a[3].replace(fe,"").trim(),assignee:c[1],priority:o})}}return i}async claim(){}async report(e,n){let i=e.split(":"),r=parseInt(i[i.length-1],10),s=i.slice(1,-1).join(":");if(!ze(s))return;let o=He(s,"utf-8").split(`
129
- `);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),Yn(s,o.join(`
130
- `)))}},Je=class{constructor(e,n,i,r,s){this.host=e;this.token=n;this.projects=i;this.agentUsernames=r;this.log=s}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[n,i]of Object.entries(this.agentUsernames))if(i.some(r=>r.toLowerCase()===e.toLowerCase()))return n}mapIssue(e,n){let i=e.references?.full?.split("#")[0]||n,r=[],s;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(s=e.labels.map(l=>({name:l.name,color:l.color,text_color:l.text_color})),r=s.map(l=>l.name)):r=e.labels);let a=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(l=>({username:l.username,name:l.name,avatarUrl:l.avatar_url})),c=a[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:c?this.usernameToAgent(c)||c:void 0,assignees:a,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:r,labelDetails:s,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,n={}){let i=await fetch(`${this.host}/api/v4${e}`,{...n,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...n.headers||{}}});if(!i.ok)throw new Error(`GitLab ${i.status}: ${await i.text().catch(()=>"")}`);return i.json()}async listOpen(e){let n=this.agentUsernames[e]||[];if(!n.length)return[];let i=[],r=this.projects.length?this.projects:["__ALL__"];for(let s of n)for(let o of r)try{let a=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,c=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,l=await this.api(c);for(let u of l){let d=this.mapIssue(u,o);d.assignee=e,i.push(d)}}catch(a){this.log(`[business] GitLab listOpen failed for ${s} on ${o}: ${a.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),o=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(o,{method:"PUT"})}catch(a){this.log(`[business] claim label update failed: ${a.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let a=Math.max(1,Math.round(n.timeSeconds/60)),c=a>=60?`${Math.floor(a/60)}h${a%60?` ${a%60}m`:""}`:`${a}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/add_spent_time?duration=${encodeURIComponent(c)}`,{method:"POST"})}catch(l){this.log(`[business] add_spent_time failed: ${l.message}`)}}if(n.status==="done")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(a){this.log(`[business] done label update failed: ${a.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(a){this.log(`[business] blocked label update failed: ${a.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(a){this.log(`[business] report note failed: ${a.message}`)}}async listAll(e={}){let n=e.sinceDays??30,i=new Date(Date.now()-n*24*36e5).toISOString(),r=new URLSearchParams,s=e.state??"opened";r.set("state",s),r.set("updated_after",i),r.set("scope","all"),r.set("per_page","100"),r.set("with_labels_details","true"),r.set("order_by","updated_at"),r.set("sort","desc"),e.labels?.length&&r.set("labels",e.labels.join(",")),e.milestone&&r.set("milestone",e.milestone),e.search&&r.set("search",e.search);let o=this.projects.length?this.projects:["__ALL__"],a=[];for(let l of o)try{let u=l==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(l)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,l))}catch(u){this.log(`[business] GitLab listAll failed on ${l}: ${u.message}`)}let c=a;if(e.notLabels?.length){let l=new Set(e.notLabels);c=c.filter(u=>!(u.labels||[]).some(d=>l.has(d)))}if(e.withoutScopedPrefix){let l=e.withoutScopedPrefix+"::";c=c.filter(u=>!(u.labels||[]).some(d=>d.startsWith(l)))}return c}async setState(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?state_event=${n}`,{method:"PUT"})}async getItem(e){let{project:n,iid:i}=this.parseId(e);try{let r=await this.api(`/projects/${encodeURIComponent(n)}/issues/${i}?with_labels_details=true`);return{...this.mapIssue(r,n),descriptionHtml:r.description_html||void 0,createdAt:r.created_at,author:r.author?{username:r.author.username,name:r.author.name,avatarUrl:r.author.avatar_url}:void 0,allLabels:Array.isArray(r.labels)?typeof r.labels[0]=="object"?r.labels.map(o=>o.name):r.labels:[]}}catch(r){return this.log(`[board] GitLab getItem failed for ${e}: ${r.message}`),null}}async updateItem(e,n){let{project:i,iid:r}=this.parseId(e),s;n.assigneeUsernames&&(s=(await Promise.all(n.assigneeUsernames.map(async u=>{try{let d=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(d)&&d[0]?.id?d[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let o;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")o=0;else try{let l=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${l.message}`)}let a={};n.title!==void 0&&(a.title=n.title),n.description!==void 0&&(a.description=n.description),n.labels!==void 0&&(a.labels=n.labels.join(",")),n.addLabels?.length&&(a.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(a.remove_labels=n.removeLabels.join(",")),s!==void 0&&(a.assignee_ids=s),o!==void 0&&(a.milestone_id=o);let c=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});return this.mapIssue(c,i)}async listMembers(){let e=new Map;for(let n of this.projects)try{let i=await this.api(`/projects/${encodeURIComponent(n)}/members/all?per_page=100`);for(let r of i)r.username&&!e.has(r.username)&&e.set(r.username,{username:r.username,name:r.name,avatarUrl:r.avatar_url})}catch(i){this.log(`[board] listMembers failed for ${n}: ${i.message}`)}return[...e.values()].sort((n,i)=>n.username.localeCompare(i.username))}async listMilestones(){let e=new Map;for(let i of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(i)}/milestones?per_page=100`);for(let s of r)s.title&&!e.has(s.title)&&e.set(s.title,{id:s.id,title:s.title,state:s.state,dueDate:s.due_date})}catch(r){this.log(`[board] listMilestones failed for ${i}: ${r.message}`)}let n=[...e.values()];return n.sort((i,r)=>i.state!==r.state?i.state==="active"?-1:1:i.title.localeCompare(r.title)),n}async create(e){let n=e.projectHint||this.projects[0];if(!n)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let i,r=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];r.length&&(i=(await Promise.all(r.map(async l=>{try{let u=await this.api(`/users?username=${encodeURIComponent(l)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${l}: ${u.message}`),null}}))).filter(l=>typeof l=="number"));let s;if(e.milestoneTitle)try{let c=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(s=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${c.message}`)}let o={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(o.assignee_ids=i),s!==void 0&&(o.milestone_id=s);let a=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(o)});return this.mapIssue(a,n)}async transition(e,n,i){await this.transitionMany(e,n?[n]:[],i?[i]:[])}async transitionMany(e,n,i){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests",c=new URLSearchParams;n.length&&c.set("add_labels",n.join(",")),i.length&&c.set("remove_labels",i.join(",")),c.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?${c.toString()}`,{method:"PUT"})}parseId(e){let i=e.replace(/^gitlab:/,"").split(":"),r=i.pop(),s=i.pop()==="mr"?"mr":"issue";return{project:i.join(":"),type:s,iid:r}}};function Hc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Ge(i.path,e,n);case"wiki":return new Xe(i.path,i.glob);case"gitlab":{let r=e.channels.gitlab;if(!r?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let s={};for(let a of r.agentMappings)a.gitlabUsernames.length&&(s[a.agentId]=a.gitlabUsernames);let o=i.projects.length?i.projects:r.routes.map(a=>a.project);return new Je(r.host,r.token,o,s,n)}}}var Ye="unmapped";function Ze(t,e=[]){if(!t)return Ye;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let i=t.indexOf("/");return i>0?t.slice(0,i):t}function Os(t){let e=new Map,n=t.projects??[],i=t.orgChart??{};for(let s of n)s.pm&&(e.has(s.pm)||e.set(s.pm,Ze(s.id,n)));let r=(s,o=new Set)=>{if(e.has(s))return e.get(s);if(o.has(s))return;o.add(s);let a=i[s]?.reportsTo;if(!a)return;let c=r(a,o);return c&&e.set(s,c),c};for(let s of Object.keys(i))r(s);return e}function Ns(t,e,n=[]){if(!n.length)return;let i=n.filter(r=>!r.channel||r.channel===t);return i.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??i.find(r=>r.username&&e.username&&r.username===e.username)??i.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??i.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function qc(t,e){let n=Ns(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return Ze(t.project,e.projects);if(t.agentId){let i=Os(e).get(t.agentId);if(i)return i}return Ye}function Kc(t,e){let n=String(t||"").split(":");if(n.length<3)return{agentId:e};let[i,r,...s]=n,o=s.join(":"),a={agentId:e||i,channel:r};return r==="gitlab"||r==="github"?a.project=o.split(":")[0]:r==="cron"||r==="api"||(a.chatId=o.split("@")[0]),a}var js=t=>t===Ye?"internal":"client";function Vs(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??js(t),respondWithinMinutes:Ws(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Gc(t){let e=new Set;for(let n of t.projects??[])e.add(Ze(n.id,t.projects));for(let n of t.contactMap??[])e.add(n.client);for(let n of Object.keys(t.clients??{}))e.add(n);return[...e].sort().map(n=>Vs(n,t))}function Ws(t){let e=/^(\d+)\s*([mhd])$/.exec(String(t??"").trim());if(!e)return;let n=Number(e[1]);return e[2]==="m"?n:e[2]==="h"?n*60:n*1440}var Fs=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,Bs=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function Zn(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(Bs)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=Us(i);if(!r)return{cleanText:t};let s=n.index??0,o=n[1]??"";return{cleanText:(t.slice(0,s)+o+t.slice(s+n[0].length)).trim(),ui:r}}function Jc(t){if(!t||!t.includes("agentx:ui"))return t;let e=Fs.exec(t);return e?t.slice(0,e.index).trimEnd():t}function Us(t){let e;try{e=JSON.parse(t)}catch{return null}if(!e||typeof e!="object")return null;let n={};if(Array.isArray(e.buttons)){let i=[],r=[],s=[];for(let o of e.buttons)!o||typeof o.label!="string"||(typeof o.url=="string"&&/^https?:\/\//i.test(o.url)?i.push({label:o.label,url:o.url}):typeof o.reply=="string"&&o.reply.trim()?r.push({label:o.label,reply:o.reply.trim()}):o.action!=null&&s.push(o.label));i.length&&(n.buttons=i),r.length&&(n.replies=r),s.length&&(n.skippedActions=s)}if(e.poll&&typeof e.poll=="object"){let i=e.poll.question,r=e.poll.options;typeof i=="string"&&i.trim()&&Array.isArray(r)&&r.filter(s=>typeof s=="string").length>=2&&(n.poll={question:i,options:r.filter(s=>typeof s=="string"),multiple:e.poll.multiple===!0})}if(e.media&&typeof e.media=="object"){let{type:i,url:r,caption:s}=e.media;["image","document","audio","video"].includes(i)&&typeof r=="string"&&r&&(n.media={type:i,url:r,...typeof s=="string"?{caption:s}:{}})}if(Array.isArray(e.quickReplies)){let i=e.quickReplies.filter(r=>typeof r=="string"&&r.trim()).map(r=>r.trim());i.length&&(n.quickReplies=i)}return!n.buttons&&!n.poll&&!n.media&&!n.quickReplies&&!n.replies&&!n.skippedActions?null:n}function Zc(t,e){let n=`${e}/call?to=${encodeURIComponent(t.from)}&callId=${encodeURIComponent(t.callId)}`;return t.reason==="camera"?`\u{1F4F7} ${t.from} is sharing a phone camera \u2014 tap to watch: ${n}&watch=1`:`\u{1F4DE} ${t.from} is calling \u2014 tap to join: ${n}`}var Hs=5*6e4;function T(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var Qn=class{subs=new Set;log;forwarder;localName;allowedCallers;pending=new Map;cleanupTimer;ringHandler;recentRings=new Map;constructor(e,n=[],i=console.error.bind(console,"[webrtc]")){this.localName=e,this.allowedCallers=new Set(n.map(T)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${T(n)}`}cleanupExpired(){let e=Date.now();for(let[n,i]of this.pending){let r=i.filter(s=>s.expiresAt>e);r.length===0?this.pending.delete(n):r.length!==i.length&&this.pending.set(n,r)}for(let[n,i]of this.recentRings)i<=e&&this.recentRings.delete(n)}setForwarder(e){this.forwarder=e}setRingHandler(e){this.ringHandler=e}subscribe(e,n,i){return this.addSubscriber(e,n,{kind:"sse",res:i})}subscribeInternal(e,n,i){return this.addSubscriber(e,n,{kind:"callback",deliver:i})}addSubscriber(e,n,i){let r={callId:e,recipient:n,sink:i};this.subs.add(r);let s=i.kind==="sse"?"sse":"internal";this.log(`subscribe[${s}] call=${e} as=${n} (${this.subs.size} total)`);let o=this.pendingKey(e,n),a=this.pending.get(o);if(a&&a.length){let c=Date.now(),l=a.filter(u=>u.expiresAt>c);for(let{signal:u}of l)this.deliverTo(r,u);this.pending.delete(o),l.length&&this.log(`flushed ${l.length} buffered signal(s) to new subscriber call=${e} as=${n}`)}return()=>{this.subs.delete(r),this.log(`unsubscribe[${s}] call=${e} as=${n} (${this.subs.size} remaining)`)}}deliverTo(e,n){try{return e.sink.kind==="sse"?e.sink.res.write(`event: signal
129
+ `);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),Zn(s,o.join(`
130
+ `)))}},Je=class{constructor(e,n,i,r,s){this.host=e;this.token=n;this.projects=i;this.agentUsernames=r;this.log=s}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[n,i]of Object.entries(this.agentUsernames))if(i.some(r=>r.toLowerCase()===e.toLowerCase()))return n}mapIssue(e,n){let i=e.references?.full?.split("#")[0]||n,r=[],s;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(s=e.labels.map(l=>({name:l.name,color:l.color,text_color:l.text_color})),r=s.map(l=>l.name)):r=e.labels);let a=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(l=>({username:l.username,name:l.name,avatarUrl:l.avatar_url})),c=a[0]?.username;return{id:`gitlab:${i}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:c?this.usernameToAgent(c)||c:void 0,assignees:a,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:r,labelDetails:s,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,n={}){let i=await fetch(`${this.host}/api/v4${e}`,{...n,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...n.headers||{}}});if(!i.ok)throw new Error(`GitLab ${i.status}: ${await i.text().catch(()=>"")}`);return i.json()}async listOpen(e){let n=this.agentUsernames[e]||[];if(!n.length)return[];let i=[],r=this.projects.length?this.projects:["__ALL__"];for(let s of n)for(let o of r)try{let a=`assignee_username=${encodeURIComponent(s)}&state=opened&scope=all&per_page=20`,c=o==="__ALL__"?`/issues?${a}`:`/projects/${encodeURIComponent(o)}/issues?${a}`,l=await this.api(c);for(let u of l){let d=this.mapIssue(u,o);d.assignee=e,i.push(d)}}catch(a){this.log(`[business] GitLab listOpen failed for ${s} on ${o}: ${a.message}`)}return i}async claim(e,n){let{project:i,iid:r,type:s}=this.parseId(n),o=`/projects/${encodeURIComponent(i)}/${s==="issue"?"issues":"merge_requests"}/${r}?add_labels=Doing&remove_labels=To Do`;try{await this.api(o,{method:"PUT"})}catch(a){this.log(`[business] claim label update failed: ${a.message}`)}}async report(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";if(n.timeSeconds&&n.timeSeconds>0){let a=Math.max(1,Math.round(n.timeSeconds/60)),c=a>=60?`${Math.floor(a/60)}h${a%60?` ${a%60}m`:""}`:`${a}m`;try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/add_spent_time?duration=${encodeURIComponent(c)}`,{method:"POST"})}catch(l){this.log(`[business] add_spent_time failed: ${l.message}`)}}if(n.status==="done")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(a){this.log(`[business] done label update failed: ${a.message}`)}else if(n.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?add_labels=Blocked`,{method:"PUT"})}catch(a){this.log(`[business] blocked label update failed: ${a.message}`)}if(n.note)try{await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}/notes`,{method:"POST",body:JSON.stringify({body:n.note})})}catch(a){this.log(`[business] report note failed: ${a.message}`)}}async listAll(e={}){let n=e.sinceDays??30,i=new Date(Date.now()-n*24*36e5).toISOString(),r=new URLSearchParams,s=e.state??"opened";r.set("state",s),r.set("updated_after",i),r.set("scope","all"),r.set("per_page","100"),r.set("with_labels_details","true"),r.set("order_by","updated_at"),r.set("sort","desc"),e.labels?.length&&r.set("labels",e.labels.join(",")),e.milestone&&r.set("milestone",e.milestone),e.search&&r.set("search",e.search);let o=this.projects.length?this.projects:["__ALL__"],a=[];for(let l of o)try{let u=l==="__ALL__"?`/issues?${r.toString()}`:`/projects/${encodeURIComponent(l)}/issues?${r.toString()}`,d=await this.api(u);for(let p of d)a.push(this.mapIssue(p,l))}catch(u){this.log(`[business] GitLab listAll failed on ${l}: ${u.message}`)}let c=a;if(e.notLabels?.length){let l=new Set(e.notLabels);c=c.filter(u=>!(u.labels||[]).some(d=>l.has(d)))}if(e.withoutScopedPrefix){let l=e.withoutScopedPrefix+"::";c=c.filter(u=>!(u.labels||[]).some(d=>d.startsWith(l)))}return c}async setState(e,n){let{project:i,iid:r,type:s}=this.parseId(e),o=s==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(i)}/${o}/${r}?state_event=${n}`,{method:"PUT"})}async getItem(e){let{project:n,iid:i}=this.parseId(e);try{let r=await this.api(`/projects/${encodeURIComponent(n)}/issues/${i}?with_labels_details=true`);return{...this.mapIssue(r,n),descriptionHtml:r.description_html||void 0,createdAt:r.created_at,author:r.author?{username:r.author.username,name:r.author.name,avatarUrl:r.author.avatar_url}:void 0,allLabels:Array.isArray(r.labels)?typeof r.labels[0]=="object"?r.labels.map(o=>o.name):r.labels:[]}}catch(r){return this.log(`[board] GitLab getItem failed for ${e}: ${r.message}`),null}}async updateItem(e,n){let{project:i,iid:r}=this.parseId(e),s;n.assigneeUsernames&&(s=(await Promise.all(n.assigneeUsernames.map(async u=>{try{let d=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(d)&&d[0]?.id?d[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let o;if(n.milestoneTitle!==void 0)if(n.milestoneTitle===null||n.milestoneTitle==="")o=0;else try{let l=await this.api(`/projects/${encodeURIComponent(i)}/milestones?title=${encodeURIComponent(n.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${n.milestoneTitle}": ${l.message}`)}let a={};n.title!==void 0&&(a.title=n.title),n.description!==void 0&&(a.description=n.description),n.labels!==void 0&&(a.labels=n.labels.join(",")),n.addLabels?.length&&(a.add_labels=n.addLabels.join(",")),n.removeLabels?.length&&(a.remove_labels=n.removeLabels.join(",")),s!==void 0&&(a.assignee_ids=s),o!==void 0&&(a.milestone_id=o);let c=await this.api(`/projects/${encodeURIComponent(i)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});return this.mapIssue(c,i)}async listMembers(){let e=new Map;for(let n of this.projects)try{let i=await this.api(`/projects/${encodeURIComponent(n)}/members/all?per_page=100`);for(let r of i)r.username&&!e.has(r.username)&&e.set(r.username,{username:r.username,name:r.name,avatarUrl:r.avatar_url})}catch(i){this.log(`[board] listMembers failed for ${n}: ${i.message}`)}return[...e.values()].sort((n,i)=>n.username.localeCompare(i.username))}async listMilestones(){let e=new Map;for(let i of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(i)}/milestones?per_page=100`);for(let s of r)s.title&&!e.has(s.title)&&e.set(s.title,{id:s.id,title:s.title,state:s.state,dueDate:s.due_date})}catch(r){this.log(`[board] listMilestones failed for ${i}: ${r.message}`)}let n=[...e.values()];return n.sort((i,r)=>i.state!==r.state?i.state==="active"?-1:1:i.title.localeCompare(r.title)),n}async create(e){let n=e.projectHint||this.projects[0];if(!n)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let i,r=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];r.length&&(i=(await Promise.all(r.map(async l=>{try{let u=await this.api(`/users?username=${encodeURIComponent(l)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${l}: ${u.message}`),null}}))).filter(l=>typeof l=="number"));let s;if(e.milestoneTitle)try{let c=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(s=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${c.message}`)}let o={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};i?.length&&(o.assignee_ids=i),s!==void 0&&(o.milestone_id=s);let a=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(o)});return this.mapIssue(a,n)}async transition(e,n,i){await this.transitionMany(e,n?[n]:[],i?[i]:[])}async transitionMany(e,n,i){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests",c=new URLSearchParams;n.length&&c.set("add_labels",n.join(",")),i.length&&c.set("remove_labels",i.join(",")),c.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?${c.toString()}`,{method:"PUT"})}parseId(e){let i=e.replace(/^gitlab:/,"").split(":"),r=i.pop(),s=i.pop()==="mr"?"mr":"issue";return{project:i.join(":"),type:s,iid:r}}};function qc(t,e,n){let i=t.workSource;switch(i.type){case"backlog":return new Ge(i.path,e,n);case"wiki":return new Xe(i.path,i.glob);case"gitlab":{let r=e.channels.gitlab;if(!r?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let s={};for(let a of r.agentMappings)a.gitlabUsernames.length&&(s[a.agentId]=a.gitlabUsernames);let o=i.projects.length?i.projects:r.routes.map(a=>a.project);return new Je(r.host,r.token,o,s,n)}}}var Ye="unmapped";function Ze(t,e=[]){if(!t)return Ye;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let i=t.indexOf("/");return i>0?t.slice(0,i):t}function js(t){let e=new Map,n=t.projects??[],i=t.orgChart??{};for(let s of n)s.pm&&(e.has(s.pm)||e.set(s.pm,Ze(s.id,n)));let r=(s,o=new Set)=>{if(e.has(s))return e.get(s);if(o.has(s))return;o.add(s);let a=i[s]?.reportsTo;if(!a)return;let c=r(a,o);return c&&e.set(s,c),c};for(let s of Object.keys(i))r(s);return e}function Vs(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 Gc(t,e){let n=Vs(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return Ze(t.project,e.projects);if(t.agentId){let i=js(e).get(t.agentId);if(i)return i}return Ye}function Xc(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 Ws=t=>t===Ye?"internal":"client";function Fs(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??Ws(t),respondWithinMinutes:Bs(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function Jc(t){let e=new Set;for(let n of t.projects??[])e.add(Ze(n.id,t.projects));for(let n of t.contactMap??[])e.add(n.client);for(let n of Object.keys(t.clients??{}))e.add(n);return[...e].sort().map(n=>Fs(n,t))}function Bs(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 Us=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,Hs=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function Qn(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(Hs)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],i=n[2],r=zs(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 Zc(t){if(!t||!t.includes("agentx:ui"))return t;let e=Us.exec(t);return e?t.slice(0,e.index).trimEnd():t}function zs(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 el(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 qs=5*6e4;function T(t){return t.toLowerCase().replace(/[^a-z0-9]/g,"")}var er=class{subs=new Set;log;forwarder;localName;allowedCallers;pending=new Map;cleanupTimer;ringHandler;recentRings=new Map;constructor(e,n=[],i=console.error.bind(console,"[webrtc]")){this.localName=e,this.allowedCallers=new Set(n.map(T)),this.log=i,this.cleanupTimer=setInterval(()=>this.cleanupExpired(),1e4)}pendingKey(e,n){return`${e}|${T(n)}`}cleanupExpired(){let e=Date.now();for(let[n,i]of this.pending){let r=i.filter(s=>s.expiresAt>e);r.length===0?this.pending.delete(n):r.length!==i.length&&this.pending.set(n,r)}for(let[n,i]of this.recentRings)i<=e&&this.recentRings.delete(n)}setForwarder(e){this.forwarder=e}setRingHandler(e){this.ringHandler=e}subscribe(e,n,i){return this.addSubscriber(e,n,{kind:"sse",res:i})}subscribeInternal(e,n,i){return this.addSubscriber(e,n,{kind:"callback",deliver:i})}addSubscriber(e,n,i){let r={callId:e,recipient:n,sink:i};this.subs.add(r);let s=i.kind==="sse"?"sse":"internal";this.log(`subscribe[${s}] call=${e} as=${n} (${this.subs.size} total)`);let o=this.pendingKey(e,n),a=this.pending.get(o);if(a&&a.length){let c=Date.now(),l=a.filter(u=>u.expiresAt>c);for(let{signal:u}of l)this.deliverTo(r,u);this.pending.delete(o),l.length&&this.log(`flushed ${l.length} buffered signal(s) to new subscriber call=${e} as=${n}`)}return()=>{this.subs.delete(r),this.log(`unsubscribe[${s}] call=${e} as=${n} (${this.subs.size} remaining)`)}}deliverTo(e,n){try{return e.sink.kind==="sse"?e.sink.res.write(`event: signal
131
131
  data: ${JSON.stringify(n)}
132
132
 
133
- `):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=T(e.to);if(n===T(this.localName)||this.hasSubscriberFor(e.callId,n))return this.fanOut(e),{ok:!0};if(!this.forwarder)return{ok:!1,error:"mesh forwarder not wired"};let r=await this.forwarder(e.to,e);return r?{ok:r}:{ok:!1,error:`forward to "${e.to}" failed`}}hasSubscriberFor(e,n){for(let i of this.subs)if(i.callId===e&&T(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(T(e.from)))return this.log(`reject inbound ${e.kind} from "${e.from}": not in allowedCallers`),{ok:!1,error:"caller not allowed"};if(e.kind==="ring"){let i=Date.now(),r=this.recentRings.get(e.callId);if(r&&r>i)return this.log(`dedup ring for call=${e.callId} (already notified)`),{ok:!0};if(this.recentRings.set(e.callId,i+Hs),this.ringHandler)try{this.ringHandler(e)}catch(s){this.log(`ringHandler threw: ${s.message}`)}else this.log(`ring received for call=${e.callId} but no handler wired`);return{ok:!0}}if(this.fanOut(e)===0){let i=this.pendingKey(e.callId,e.to),r=this.pending.get(i)||[];r.push({signal:e,expiresAt:Date.now()+3e4}),this.pending.set(i,r),this.log(`buffered ${e.kind} for call=${e.callId} to=${e.to} (no subscriber yet, ${r.length} pending)`)}return{ok:!0}}fanOut(e){let n=0,i=T(e.to);for(let r of this.subs)r.callId===e.callId&&T(r.recipient)===i&&(this.deliverTo(r,e)?n++:this.subs.delete(r));return n}get subscriberCount(){return this.subs.size}shutdown(){this.cleanupTimer&&clearInterval(this.cleanupTimer);for(let e of this.subs)if(e.sink.kind==="sse")try{e.sink.res.end()}catch{}this.subs.clear(),this.pending.clear()}};var zs=200,er=4e3;function qs(t){return t.replace(/```[\s\S]*?```/g," ").replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/^\s{0,3}(#{1,6}|>|[-*+]|\d+[.)])\s+/gm,"").replace(/[*_~`]+/g,"").replace(/\s+/g," ").trim()}function Qe(t,e=zs){let n=qs(t);if(n.length<=e)return n;let i=n.slice(0,e),r=Math.max(i.lastIndexOf(". "),i.lastIndexOf("? "),i.lastIndexOf("! "));return r>e/2?i.slice(0,r+1):`${i.slice(0,e-1).trimEnd()}\u2026`}function tl(t,e){let n=e.lastAnswer(t.id),i=n&&n.text.length>er?`${n.text.slice(0,er)}
133
+ `):e.sink.deliver(n),!0}catch{return!1}}async handleOutgoing(e){let n=T(e.to);if(n===T(this.localName)||this.hasSubscriberFor(e.callId,n))return this.fanOut(e),{ok:!0};if(!this.forwarder)return{ok:!1,error:"mesh forwarder not wired"};let r=await this.forwarder(e.to,e);return r?{ok:r}:{ok:!1,error:`forward to "${e.to}" failed`}}hasSubscriberFor(e,n){for(let i of this.subs)if(i.callId===e&&T(i.recipient)===n)return!0;return!1}handleIncoming(e){if((e.kind==="offer"||e.kind==="ring")&&this.allowedCallers.size>0&&!this.allowedCallers.has(T(e.from)))return this.log(`reject inbound ${e.kind} from "${e.from}": not in allowedCallers`),{ok:!1,error:"caller not allowed"};if(e.kind==="ring"){let i=Date.now(),r=this.recentRings.get(e.callId);if(r&&r>i)return this.log(`dedup ring for call=${e.callId} (already notified)`),{ok:!0};if(this.recentRings.set(e.callId,i+qs),this.ringHandler)try{this.ringHandler(e)}catch(s){this.log(`ringHandler threw: ${s.message}`)}else this.log(`ring received for call=${e.callId} but no handler wired`);return{ok:!0}}if(this.fanOut(e)===0){let i=this.pendingKey(e.callId,e.to),r=this.pending.get(i)||[];r.push({signal:e,expiresAt:Date.now()+3e4}),this.pending.set(i,r),this.log(`buffered ${e.kind} for call=${e.callId} to=${e.to} (no subscriber yet, ${r.length} pending)`)}return{ok:!0}}fanOut(e){let n=0,i=T(e.to);for(let r of this.subs)r.callId===e.callId&&T(r.recipient)===i&&(this.deliverTo(r,e)?n++:this.subs.delete(r));return n}get subscriberCount(){return this.subs.size}shutdown(){this.cleanupTimer&&clearInterval(this.cleanupTimer);for(let e of this.subs)if(e.sink.kind==="sse")try{e.sink.res.end()}catch{}this.subs.clear(),this.pending.clear()}};var Ks=200,tr=4e3;function Gs(t){return t.replace(/```[\s\S]*?```/g," ").replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/^\s{0,3}(#{1,6}|>|[-*+]|\d+[.)])\s+/gm,"").replace(/[*_~`]+/g,"").replace(/\s+/g," ").trim()}function Qe(t,e=Ks){let n=Gs(t);if(n.length<=e)return n;let i=n.slice(0,e),r=Math.max(i.lastIndexOf(". "),i.lastIndexOf("? "),i.lastIndexOf("! "));return r>e/2?i.slice(0,r+1):`${i.slice(0,e-1).trimEnd()}\u2026`}function rl(t,e){let n=e.lastAnswer(t.id),i=n&&n.text.length>tr?`${n.text.slice(0,tr)}
134
134
 
135
- \u2026`:n?.text;return{...t,summary:Qe(t.text),textHtml:te(t.text),why:t.state==="waiting_owner"?t.question:t.state==="needs_attention"?t.attentionReason:null,ownerNoteHtml:t.ownerNote?te(t.ownerNote):null,lastAnswer:n?{agentId:n.agentId,at:n.at,html:te(i)}:null}}import{execFile as uo}from"child_process";import{mkdtempSync as ro,rmSync as io,writeFileSync as so}from"fs";import{tmpdir as oo}from"os";import{join as sr}from"path";import{randomBytes as Ks}from"crypto";var _={top:8,side:32,bottom:60},et={height:56,keep:52},tr=`
135
+ \u2026`:n?.text;return{...t,summary:Qe(t.text),textHtml:te(t.text),why:t.state==="waiting_owner"?t.question:t.state==="needs_attention"?t.attentionReason:null,ownerNoteHtml:t.ownerNote?te(t.ownerNote):null,lastAnswer:n?{agentId:n.agentId,at:n.at,html:te(i)}:null}}import{execFile as fo}from"child_process";import{mkdtempSync as so,rmSync as oo,writeFileSync as ao}from"fs";import{tmpdir as co}from"os";import{join as or}from"path";import{randomBytes as Xs}from"crypto";var _={top:8,side:32,bottom:60},et={height:56,keep:52},nr=`
136
136
  :root {
137
137
  --ac-paper: #fafaf9; --ac-soft: #f4f4f2; --ac-edge: #e9e9e6;
138
138
  --ac-text: #0b1413; --ac-muted: #4a5856; --ac-subtle: #7c8987;
@@ -261,16 +261,16 @@ button.primary:hover:not(:disabled) { transform: translateY(-1px); background: v
261
261
  button.primary:disabled { opacity: .55; cursor: not-allowed; }
262
262
  kbd { font: 11px var(--ac-mono); color: var(--ac-subtle); }
263
263
  button.primary kbd { color: inherit; opacity: .7; }
264
- `;var nr=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),rr=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function Gs(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?nr(n):rr(n)}`}function Xs(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[rr(n)],nr(n)].join(" ")}function Js(t){let e=t.trim().split(/[\s_-]+/).filter(Boolean);return(e.length>1?e[0][0]+e[1][0]:t.trim().slice(0,1)).toUpperCase()}function Ys(t){let e=(t.recommend??"").trim(),n=e.toLowerCase(),i=t.choices??[],r=-1;if(i.forEach((o,a)=>{!n.startsWith(o.toLowerCase())||!/^\s*($|[:,.;–—-](\s|$))/.test(e.slice(o.length))||(r<0||o.length>i[r].length)&&(r=a)}),r<0)return{index:r,why:e};let s=e.slice(i[r].length).replace(/^[\s:,.;–—-]+/,"");return{index:r,why:s.slice(0,1).toUpperCase()+s.slice(1)}}function Zs(t){return t.origin?.kind==="request"?"Hand it back":t.draft?"Send":t.choices?.length?"Choose":"Yes"}var tt=t=>`<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${t}</svg>`,Qs=tt('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),eo=tt('<path d="m6 15 6-6 6 6"/>'),to=tt('<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>');function ir(t,e={}){let n=e.now??Date.now(),i=e.from||t.raised_by,r=Ks(12).toString("base64"),s=t.choices??[],o=t.origin?.kind==="reminder",a=t.origin?.kind==="request",c=Ys(t),l=s.map((p,f)=>`<button class="opt" role="radio" aria-checked="false" data-i="${f}"><span class="n">${f+1}</span><span class="t">${w(p)}</span>${f===c.index?'<i class="dot"></i>':""}</button>`).join(""),u=t.recommend?`<span class="rec"><i class="dot"></i>${w(i)} recommends</span>`:"",d={choices:s,draft:t.draft??"",placeholder:jt,chime:e.sound==="chime",volume:Math.min(1,Math.max(0,e.volume??.4)),theme:e.theme??"system",pick:e.pick&&e.pick<=s.length?e.pick-1:c.index};return`<!doctype html>
264
+ `;var rr=t=>t.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit"}),ir=t=>`${t.getDate()} ${t.toLocaleDateString("en-US",{month:"short"})}`;function Js(t,e){let n=new Date(t);return Number.isNaN(n.getTime())?"":`since ${n.toDateString()===new Date(e).toDateString()?rr(n):ir(n)}`}function Ys(t,e){let n=new Date(t),i=n.getTime()-e<6*864e5;return[n.toLocaleDateString("en-US",{weekday:"short"}),...i?[]:[ir(n)],rr(n)].join(" ")}function Zs(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 Qs(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 eo(t){return t.origin?.kind==="request"?"Hand it back":t.draft?"Send":t.choices?.length?"Choose":"Yes"}var tt=t=>`<svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${t}</svg>`,to=tt('<circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/>'),no=tt('<path d="m6 15 6-6 6 6"/>'),ro=tt('<rect x="5" y="11" width="14" height="10" rx="2"/><path d="M8 11V7a4 4 0 0 1 8 0v4"/>');function sr(t,e={}){let n=e.now??Date.now(),i=e.from||t.raised_by,r=Xs(12).toString("base64"),s=t.choices??[],o=t.origin?.kind==="reminder",a=t.origin?.kind==="request",c=Qs(t),l=s.map((p,f)=>`<button class="opt" role="radio" aria-checked="false" data-i="${f}"><span class="n">${f+1}</span><span class="t">${w(p)}</span>${f===c.index?'<i class="dot"></i>':""}</button>`).join(""),u=t.recommend?`<span class="rec"><i class="dot"></i>${w(i)} recommends</span>`:"",d={choices:s,draft:t.draft??"",placeholder:Vt,chime:e.sound==="chime",volume:Math.min(1,Math.max(0,e.volume??.4)),theme:e.theme??"system",pick:e.pick&&e.pick<=s.length?e.pick-1:c.index};return`<!doctype html>
265
265
  <html lang="en"><head><meta charset="utf-8">
266
266
  <meta http-equiv="Content-Security-Policy" content="default-src 'none'; style-src 'unsafe-inline'; script-src 'nonce-${r}'">
267
267
  <title>AgentX</title>
268
- <style>${tr}</style></head>
268
+ <style>${nr}</style></head>
269
269
  <body><div class="wrap"><main class="card${e.still?" still":""}">
270
- <div class="head" title="Drag to move"><span class="avatar">${w(Js(i))}</span>
271
- <div class="who"><b>${w(i)}</b><span>${w(Gs(t.created_at,n))}</span></div>
270
+ <div class="head" title="Drag to move"><span class="avatar">${w(Zs(i))}</span>
271
+ <div class="who"><b>${w(i)}</b><span>${w(Js(t.created_at,n))}</span></div>
272
272
  <span class="kind${o?"":" decision"}">${o?"Reminder":a?"Request":"Decision"}</span>
273
- <button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${eo}</button></div>
273
+ <button class="fold" id="fold" title="Shrink" aria-label="Shrink the card" aria-expanded="true">${no}</button></div>
274
274
  <div class="body"><h1 dir="auto">${w(t.title)}</h1>
275
275
  ${t.context?`<p class="context" dir="auto">${w(t.context)}</p>`:""}
276
276
  <p class="ask" dir="auto">${w(t.ask)}</p>
@@ -279,15 +279,15 @@ ${l?`<div class="options" role="radiogroup">${l}</div>`:""}
279
279
  ${c.why?`<p class="why" dir="auto">${w(c.why)}</p>`:""}
280
280
  ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><span class="edited"><i class="dot"></i>Edited</span><button class="reset" id="reset">Reset</button></div>
281
281
  <textarea id="text" dir="auto" rows="2" spellcheck="true"></textarea>`:""}
282
- <div class="notes"><div>${Qs}<span>${a?"It stays in Open requests on the Approvals page until you close it.":`If you don't answer by ${w(Xs(t.expires,n))}: ${w(t.if_silent)}.`}</span></div>
283
- <div>${to}<span>Nothing goes out until you click.</span></div></div>
282
+ <div class="notes"><div>${to}<span>${a?"It stays in Open requests on the Approvals page until you close it.":`If you don't answer by ${w(Ys(t.expires,n))}: ${w(t.if_silent)}.`}</span></div>
283
+ <div>${ro}<span>Nothing goes out until you click.</span></div></div>
284
284
  </div><div class="foot"><button class="btn later" id="later">Not now<kbd>esc</kbd></button>
285
285
  <button class="btn" id="no">${a?"Drop":"No"}</button>
286
- <button class="btn primary" id="yes">${Zs(t)}<kbd>\u2318\u21A9</kbd></button></div>
286
+ <button class="btn primary" id="yes">${eo(t)}<kbd>\u2318\u21A9</kbd></button></div>
287
287
  </main></div>
288
288
  <script type="application/json" id="data">${JSON.stringify(d).replace(/</g,"\\u003c")}</script>
289
- <script nonce="${r}">${no}</script>
290
- </body></html>`}var no=`
289
+ <script nonce="${r}">${io}</script>
290
+ </body></html>`}var io=`
291
291
  (function () {
292
292
  var d = JSON.parse(document.getElementById("data").textContent);
293
293
  var root = document.documentElement;
@@ -376,7 +376,7 @@ ${t.draft?`<div class="label-row" id="msg"><span class="label">Message</span><sp
376
376
  });
377
377
  } catch (e) {}
378
378
  })();
379
- `;var ao=440,co=`
379
+ `;var lo=440,uo=`
380
380
  ObjC.import("Cocoa"); ObjC.import("WebKit")
381
381
  function run(argv) {
382
382
  var path = argv[0], side = ${_.side}, gripTop = ${_.top}, gripEnd = ${_.top+et.height}, keep = ${et.keep}, w = Number(argv[1]) + 2 * side, h = 420, secs = Number(argv[2]), capture = argv[3] || ""
@@ -449,21 +449,21 @@ function run(argv) {
449
449
  }
450
450
  function gone(why) { return JSON.stringify({ action: "dismiss", why: why }) }
451
451
  function quoted(s) { return "'" + String(s).replace(/'/g, "'\\\\''") + "'" }
452
- `;function lo(t,e){let n=t.trim().split(`
453
- `).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&ar.includes(i.why))return{action:"dismiss",why:i.why};if(i?.action!=="yes")return{action:"dismiss"};let r=e.choices??[],s;if(r.length){if(typeof i.choice!="string"||!r.includes(i.choice))return{action:"dismiss"};s=i.choice}let o;return e.draft&&(o=typeof i.text=="string"?i.text.replace(/\r\n?/g,`
454
- `).trim():"",!o||o.length>Nt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...o?{text:o}:{}}}async function or(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=ro(sr(oo(),"agentx-card-"));try{let s=sr(r,"card.html");so(s,ir(t,{...e,still:!!e.capture}),{mode:384});let o=["-l","JavaScript","-e",co,s,String(ao),String(i),...e.capture?[e.capture]:[]],a=await n("/usr/bin/osascript",o,(i+10)*1e3);return a.ok?lo(a.stdout,t):null}finally{io(r,{recursive:!0,force:!0})}}var ar=["not now","timed out","closed"],po=(t,e,n)=>new Promise(i=>{try{uo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),cr=160,lr=15e3;function fo(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>cr?e.slice(0,cr):e}async function go(t,e,n,i){let r=e.sound==="chime"?i?"":"Glass":e.sound,s=r?Ht(r):null;if(s&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),s],lr),e.speak){let o=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...o,"--",fo(t)],lr)}}function pr(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function mo(t,e,n){return pr(["on run argv","activate","set opts to items 3 thru -1 of argv",'set pick to choose from list opts with title (item 1 of argv) with prompt (item 2 of argv) OK button name "Next" cancel button name "Not now"','if pick is false then return ""',"return item 1 of pick","end run"],[t,e,...n])}function ur(t,e,n,i,r){return pr(["on run argv","activate","set AppleScript's text item delimiters to linefeed","set btns to text items of (item 3 of argv)","set secs to (item 5 of argv) as integer","if (count of argv) > 5 then","set r to display dialog (item 2 of argv) with title (item 1 of argv) default answer (item 6 of argv) buttons btns default button (item 4 of argv) giving up after secs","else","set r to display dialog (item 2 of argv) with title (item 1 of argv) buttons btns default button (item 4 of argv) giving up after secs","end if",'if gave up of r then return ""',"if (count of argv) > 5 then return (button returned of r) & linefeed & (text returned of r)","return button returned of r","end run"],[t,e,n.join(`
455
- `),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function dr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
456
- `);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function nt(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
452
+ `;function po(t,e){let n=t.trim().split(`
453
+ `).pop()??"",i;try{i=JSON.parse(n)}catch{return{action:"dismiss"}}if(i?.action==="no")return{action:"no"};if(i?.action==="dismiss"&&cr.includes(i.why))return{action:"dismiss",why:i.why};if(i?.action!=="yes")return{action:"dismiss"};let r=e.choices??[],s;if(r.length){if(typeof i.choice!="string"||!r.includes(i.choice))return{action:"dismiss"};s=i.choice}let o;return e.draft&&(o=typeof i.text=="string"?i.text.replace(/\r\n?/g,`
454
+ `).trim():"",!o||o.length>jt.text)?{action:"dismiss"}:{action:"yes",...s?{choice:s}:{},...o?{text:o}:{}}}async function ar(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=so(or(co(),"agentx-card-"));try{let s=or(r,"card.html");ao(s,sr(t,{...e,still:!!e.capture}),{mode:384});let o=["-l","JavaScript","-e",uo,s,String(lo),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{oo(r,{recursive:!0,force:!0})}}var cr=["not now","timed out","closed"],go=(t,e,n)=>new Promise(i=>{try{fo(t,e,{timeout:n},(r,s)=>i({ok:!r,stdout:String(s??"")}))}catch{i({ok:!1,stdout:""})}}),lr=160,nt=15e3;function ur(t){let e=(t.say||t.title).replace(/\s+/g," ").trim();return e.length>lr?e.slice(0,lr):e}async function mo(t,e,n,i,r){let s=e.sound==="chime"?i?"":"Glass":e.sound,o=s?zt(s):null;if(o&&await n("/usr/bin/afplay",["-v",String(Math.min(1,Math.max(0,e.volume))),o],nt),!!e.speak)if(r){let a;await Promise.race([r(ur(t)),new Promise(c=>{a=setTimeout(c,nt)})]),clearTimeout(a)}else{let a=e.voice&&/^[\w .()-]+$/.test(e.voice)?["-v",e.voice]:[];await n("/usr/bin/say",[...a,"--",ur(t)],nt)}}function fr(t,e){return[...t.flatMap(n=>["-e",n]),...e]}function ho(t,e,n){return fr(["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 dr(t,e,n,i,r){return fr(["on run argv","activate","set AppleScript's text item delimiters to linefeed","set btns to text items of (item 3 of argv)","set secs to (item 5 of argv) as integer","if (count of argv) > 5 then","set r to display dialog (item 2 of argv) with title (item 1 of argv) default answer (item 6 of argv) buttons btns default button (item 4 of argv) giving up after secs","else","set r to display dialog (item 2 of argv) with title (item 1 of argv) buttons btns default button (item 4 of argv) giving up after secs","end if",'if gave up of r then return ""',"if (count of argv) > 5 then return (button returned of r) & linefeed & (text returned of r)","return button returned of r","end run"],[t,e,n.join(`
455
+ `),n[n.length-1],String(i),...r!==void 0?[r]:[]])}function pr(t){let e=t.replace(/\n$/,"");if(!e)return null;let n=e.indexOf(`
456
+ `);return n<0?{button:e,text:""}:{button:e.slice(0,n),text:e.slice(n+1)}}function rt(t){return[t.ask,t.recommend?`Recommended: ${t.recommend}`:"",`From ${t.raised_by}`].filter(Boolean).join(`
457
457
 
458
- `)}async function fr(t,e,n={}){let i=n.run??po,r=(e.style??"card")==="card",s=go(t,e,i,r).catch(()=>{});if(r){let o=await or(t,{timeoutSeconds:e.timeoutSeconds,sound:e.sound,volume:e.volume,theme:e.theme,from:n.from,capture:n.capture,pick:n.pick},i).catch(()=>null);if(o)return o}return await s,ho(t,e,i)}async function ho(t,e,n){let i=Math.max(10,Math.round(e.timeoutSeconds)),r=(i+5)*1e3,s=`${t.raised_by}: ${t.title}`,o;if(t.choices?.length){let l=await n("/usr/bin/osascript",mo(s,nt(t),t.choices),r);if(o=l.stdout.replace(/\n$/,""),!l.ok||!t.choices.includes(o))return{action:"dismiss"};if(!t.draft)return{action:"yes",choice:o}}if(t.draft){let l=o?`${o}
458
+ `)}async function gr(t,e,n={}){let i=n.run??go,r=(e.style??"card")==="card",s=mo(t,e,i,r,n.speak).catch(()=>{});if(r){let o=await ar(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,yo(t,e,i)}async function yo(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",ho(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}
459
459
 
460
- Message (edit it if you like):`:`${nt(t)}
460
+ Message (edit it if you like):`:`${rt(t)}
461
461
 
462
- Message (edit it if you like):`,d=await n("/usr/bin/osascript",ur(s,l,o?["Cancel","Send"]:["Not now","No","Send"],i,Vt(t.draft,o)),r),p=d.ok?dr(d.stdout):null;if(p?.button==="Send"){let f=p.text.trim();return f?{action:"yes",...o?{choice:o}:{},text:f}:{action:"dismiss"}}return p?.button==="No"?{action:"no"}:{action:"dismiss"}}let a=await n("/usr/bin/osascript",ur(s,nt(t),["Not now","No","Yes"],i),r),c=a.ok?dr(a.stdout):null;return c?.button==="Yes"?{action:"yes"}:c?.button==="No"?{action:"no"}:{action:"dismiss"}}var it=24*36e5,rt=!1;function gr(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=R(t.root),o=r?Date.parse(r):NaN,a=U(t.root,"pending").filter(l=>Date.parse(l.expires)>e),c=a.find(l=>s.includes(`card:${l.id}`));if(c)return c;for(let l of a){let u=`card:${l.id}`;if(n[u])continue;let d=i[u];if(d&&Date.parse(d)>e)continue;let p=Date.parse(l.created_at);if(!(e-p>it&&!(p<=o)))return l}return null}function mr(t){try{return z(t)?.listByState("needs_attention")??[]}catch{return[]}}function yo(t){let e=t.now??Date.now(),{popped:n={},snoozed:i}=R(t.root);return mr(t).find(r=>{let s=`request:${r.id}`,o=i[s];return!n[s]&&!(o&&Date.parse(o)>e)&&e-r.updatedAt<=it})??null}function bo(t,e){return{id:t.id,title:Qe(t.text,zt.title),context:t.attentionReason??"It is not finished and nothing is retrying it.",ask:`Hand it back to ${t.agentId}, or drop it?`,say:"A request you made is not finished.",recommend:"",if_silent:"keep",expires:new Date(e+it).toISOString(),raised_by:t.agentId,created_at:new Date(t.createdAt).toISOString(),status:"pending",origin:{kind:"request",id:t.id}}}async function _l(t){let{ctx:e,settings:n,log:i}=t;if(!n.enabled||(t.platform??process.platform)!=="darwin")return"off";if(rt)return"busy";let r=gr(e)?null:yo(e),s=r?bo(r,e.now??Date.now()):gr(e);if(!s)return"none";let o=(t.focus??Dt)();if(o.active)return"held";rt=!0;let a=`${r?"request":"card"}:${s.id}`;try{let c=[...U(e.root,"pending").map(p=>`card:${p.id}`),...mr(e).map(p=>`request:${p.id}`)];dn(e.root,a,c,e.now),i(`[approvals] popup: showing ${a} from ${s.raised_by}`);let l=await(t.show??fr)(s,n,{from:t.agentName?.(s.raised_by)});if(l.action==="dismiss")return i(`[approvals] popup: ${a} left waiting: ${l.why??"no answer"} (${Et(o)} when shown)`),"shown";if(!(r?z(e)?.get(r.id)?.state==="needs_attention":B(e.root,s.id)?.status==="pending"))return i(`[approvals] popup: ${a} was answered elsewhere; popup answer ignored`),"shown";let d=await bn(e,a,l.action,{by:"operator (popup)",...l.action==="yes"?{choice:l.choice,text:l.text}:{}});return i(d.ok?`[approvals] popup: ${d.message}`:`[approvals] popup: ${a} not recorded: ${d.error}`),"shown"}catch(c){return i(`[approvals] popup failed for ${a}: ${c?.message??c}`),"shown"}finally{rt=!1}}function Cl(t,e,n){if(!n)return{ok:!1,error:"the Mac popup is off; turn it on with `agentx approvals settings --popup on`"};let i=e.startsWith("card:")?B(t.root,e.slice(5)):null;return i?i.status!=="pending"?{ok:!1,error:`${e} is already ${i.status}`}:(pn(t.root,e),{ok:!0,message:`${e} will show on the Mac within a minute`}):{ok:!1,error:`no card "${e}"; the popup shows decision cards only`}}import{closeSync as G,createReadStream as wo,fstatSync as xo,openSync as ko,realpathSync as hr}from"fs";import{isAbsolute as So,resolve as yr,sep as br}from"path";var Ml="/app-files",vo=/^[A-Za-z0-9_.:-]{1,64}$/;function $o(t,e,n=process.cwd()){if(!e||e.length>ee.pathChars||e.includes("\0"))return{ok:!1,status:400,error:"bad file path"};if(e.split(/[\\/]/).includes(".."))return{ok:!1,status:403,error:`the path leaves the workspace: copy the file into ${Se}/ first`};if(!ke(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=hr(yr(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=hr(So(e)?e:yr(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+br))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${Se}/ first`};let s=ke(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function Ro(t,e){let n=t.replace(/[^\x20-\x7e]/g,"_").replace(/["\\;]/g,"_").slice(0,120)||"file";return`${e==="file"?"attachment":"inline"}; filename="${n}"; filename*=UTF-8''${encodeURIComponent(t.slice(0,120))}`}function Ao(t,e,n){return{"Content-Type":t,"Content-Disposition":Ro(e,n),"X-Content-Type-Options":"nosniff","Content-Security-Policy":"default-src 'none'; img-src 'self'; media-src 'self'; sandbox","Cache-Control":"private, max-age=3600","Accept-Ranges":"bytes"}}function Io(t,e){let n=/^bytes=(\d*)-(\d*)$/.exec(String(t||"").trim());if(!n||!n[1]&&!n[2])return null;let i,r;return n[1]?(i=Number(n[1]),r=n[2]?Math.min(Number(n[2]),e-1):e-1):(i=Math.max(0,e-Number(n[2])),r=e-1),i>r||i>=e?"unsatisfiable":{start:i,end:r}}function Ol(t,e,n,i){let r=(D,N)=>{e.writeHead(D,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(N))};if(t.method!=="GET"&&t.method!=="HEAD")return r(405,{error:"GET only"});let s=n.searchParams.get("agent")||"",o=n.searchParams.get("file")||"";if(!vo.test(s))return r(400,{error:"bad agent id"});let a=i.workspaceOf(s);if(!a)return r(404,{error:`no agent "${s}" on this computer`});let c=$o(a,o,i.cwd);if(!c.ok)return i.log?.(`[app-files] refused ${JSON.stringify(o.slice(0,200))} from ${s}: ${c.error}`),r(c.status,{error:c.error});let l;try{l=ko(c.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let D=xo(l);if(!D.isFile())return G(l),r(404,{error:"not a file"});u=D.size}catch{return G(l),r(404,{error:"file not found"})}if(u>ee.bytes)return G(l),r(413,{error:`the file is larger than ${ee.bytes/1024/1024} MB`});let d=c.path.split(br).pop()||"file",p=Ao(c.mime,d,c.kind),f=Io(t.headers.range,u);if(f==="unsatisfiable"){G(l),e.writeHead(416,{...p,"Content-Range":`bytes */${u}`}),e.end();return}let{start:g,end:h}=f??{start:0,end:u-1};if(e.writeHead(f?206:200,{...p,"Content-Length":String(u?h-g+1:0),...f?{"Content-Range":`bytes ${g}-${h}/${u}`}:{}}),t.method==="HEAD"||u===0){G(l),e.end();return}let y=wo("",{fd:l,start:g,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as X}from"child_process";import{readFileSync as _o,writeFileSync as Co}from"fs";import{tmpdir as Do}from"os";import{join as Eo}from"path";bt();var wr=t=>t&&t!==1?Math.round(175*t):null,ge=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function To(){if(process.env.ELEVENLABS_API_KEY)return process.env.ELEVENLABS_API_KEY;for(let t of[`${process.env.HOME}/.elevenlabs/key`,`${process.env.HOME}/.agentx/elevenlabs-key.txt`])try{let e=_o(t,"utf8").trim();if(e)return e}catch{}return null}function zl(t=To()){let e=0;return async(n,i)=>{if(n.voice.provider==="system")return null;if(!t){if(n.voice.fallback)return null;throw new Error("ElevenLabs is the voice provider but no key is set")}try{let r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${n.voice.elevenlabs}/stream?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n.text,model_id:"eleven_flash_v2_5",...ge(n.voice.rate)?{voice_settings:{speed:ge(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=Eo(Do(),`agentx-say-${process.pid}-${++e}.mp3`);return Co(s,Buffer.from(await r.arrayBuffer())),s}catch(r){if(i.aborted||!n.voice.fallback)throw r;return M(`elevenlabs:${String(r?.message??r).slice(0,40)}`,`[voice] ElevenLabs failed (${String(r?.message??r).slice(0,160)}); speaking with the system voice`),null}}}function xr(t,e){let n=t.languages&&Q(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var Po=(t,e="")=>{let n=xr(t,e),i=wr(t.rate);return[...n&&!Rn(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function Lo(t,e,n){if(!n)return["say",Po(t,e)];let i=xr(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function ql(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Kl(t=st()){if(t)try{X("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function Gl(t=st()){if(t)try{X("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function st(t={},e){if(!Ee(t))return null;try{return _n(e)}catch(n){return M("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
463
- `)[0]}); Siri voices will not switch`),null}}var Xl=(t,e)=>{if(!t){let[n,i]=Lo(e.voice,e.text,st()),r=wr(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=X(n,i,{stdio:["pipe","ignore","ignore"],env:s});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?X("afplay",[t],{stdio:"ignore"}):X("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as kr}from"child_process";import{accessSync as Mo,constants as Oo,readFileSync as Sr}from"fs";import{homedir as No}from"os";import{basename as W,delimiter as vr,dirname as jo,extname as Vo,join as ot}from"path";var P={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function $r(t){let e=Array.isArray(t)?t[0]:t;return!e||!/^\d{1,9}$/.test(e.trim())?{status:400,error:"Say how long the recording is (X-Audio-Duration-Ms)."}:Number(e)>P.ms+2e3?{status:413,error:ct()}:null}var ct=()=>`The recording is longer than ${P.ms/6e4} minutes.`,Wo={"audio/webm":"webm","video/webm":"webm","audio/ogg":"ogg","audio/mp4":"m4a","video/mp4":"m4a","audio/x-m4a":"m4a","audio/aac":"aac","audio/mpeg":"mp3","audio/wav":"wav","audio/x-wav":"wav","audio/wave":"wav"};function Rr(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return Wo[e]??null}function Ar(t,e){let n=[];return t!=="local"&&e.key&&n.push("elevenlabs"),e.ffmpeg&&(e.mlx?n.push("mlx-whisper"):e.whisper&&n.push("whisper")),n}function lt(t,e){return t==="local"&&e.key&&!e.ffmpeg?"Speech to text is set to local, and this computer has no ffmpeg.":(e.mlx||e.whisper)&&!e.ffmpeg?"This computer has Whisper but no ffmpeg to read the recording.":"Add an ElevenLabs key on this computer, or install mlx-whisper and ffmpeg."}function at(t,e,n=process.env.PATH??""){let i=No(),r=[ot(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(vr).filter(Boolean)];for(let s of[e,...r.map(o=>ot(o,t))])if(s)try{return Mo(s,Oo.X_OK),s}catch{}return null}function tu(t){return{key:t,mlx:at("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:at("whisper",process.env.AGENTX_WHISPER),ffmpeg:Fo()}}var Fo=()=>at("ffmpeg",process.env.AGENTX_FFMPEG);async function Ir(t,e){return e?Bo(t,e):null}async function Bo(t,e){let n=String(P.ms/1e3+5);try{let r=[...(await Uo(e,["-nostdin","-hide_banner","-t",n,"-i",t,"-f","null","-"],3e4)).matchAll(/time=(\d+):(\d+):(\d+(?:\.\d+)?)/g)],s=r[r.length-1];return s?Number(s[1])*3600+Number(s[2])*60+Number(s[3]):null}catch{return null}}async function _r(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([Sr(t)],{type:e}),W(t));let s=await fetch("https://api.elevenlabs.io/v1/speech-to-text",{method:"POST",headers:{"xi-api-key":n},body:r,signal:i??AbortSignal.timeout(6e4)});if(!s.ok)throw new Error(`ElevenLabs ${s.status}: ${(await s.text().catch(()=>"")).slice(0,160)}`);let o=await s.json();if(typeof o.text!="string")throw new Error("ElevenLabs returned no text");return o.text.trim()}async function Cr(t,e,n,i,r){let s=t==="mlx-whisper"?["--model",process.env.AGENTX_MLX_MODEL||"mlx-community/whisper-large-v3-turbo","--output-format","txt","--output-dir",r,n]:[n,"--model",process.env.AGENTX_WHISPER_MODEL||"base","--output_format","txt","--output_dir",r,"--fp16","False"],o={...process.env,PATH:`${jo(i)}${vr}${process.env.PATH??""}`};await Ho(e,s,12e4,o);try{return Sr(ot(r,W(n,Vo(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function Uo(t,e,n){return new Promise((i,r)=>{let s=kr(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${W(t)} took too long`))},n);s.stderr.on("data",c=>{o=(o+c).slice(-8192)}),s.on("error",c=>{clearTimeout(a),r(c)}),s.on("exit",c=>{clearTimeout(a),c===0?i(o):r(new Error(`${W(t)} exited ${c}`))})})}function Ho(t,e,n,i=process.env){return new Promise((r,s)=>{let o=kr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),a="",c="",l=setTimeout(()=>{o.kill("SIGKILL"),s(new Error(`${W(t)} took longer than ${n/1e3}s`))},n);o.stdout.on("data",u=>{a.length<4096&&(a+=u)}),o.stderr.on("data",u=>{c.length<4096&&(c+=u)}),o.on("error",u=>{clearTimeout(l),s(u)}),o.on("exit",u=>{clearTimeout(l),u===0?r(a):s(new Error(`${W(t)} exited ${u}: ${c.trim().split(`
464
- `).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as zo,rm as qo,writeFile as Ko}from"fs/promises";import{tmpdir as Go}from"os";import{join as Dr}from"path";Vr();var Xo=64*1024,Jo=2,ut=0;function pu(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function fu(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?Yo(t,e,i):ea(t,e,i)}async function Yo(t,e,n){let i=String(t.headers["content-type"]||""),r=Rr(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=$r(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let o=await Er(t,P.bytes);if(!o)return b(e,413,{error:ra()});if(!o.length)return b(e,400,{error:"The recording is empty."});if(ut>=Jo)return b(e,429,{error:"This computer is already writing down other recordings. Try again in a moment."});let a=n.stt(),c=n.host(),l=Ar(a,c);if(!c.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",p=l.length?"":" "+lt(a,c);return b(e,503,{error:"Voice input isn't set up on this computer.",hint:`Install ffmpeg ${d} for voice input from the phone.${p}`,setup:!1})}if(!l.length)return b(e,503,{error:"Voice input isn't set up on this computer.",hint:lt(a,c),setup:!1});ut++;let u;try{let d=await zo(Dr(Go(),"agentx-phone-voice-"));try{u=await Zo(d,`speech.${r}`,o,i,c,l,n)}finally{await qo(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{ut--}b(e,u[0],u[1])}async function Zo(t,e,n,i,r,s,o){let a=Dr(t,e);if(await Ko(a,n,{mode:384}),r.ffmpeg){let l=await(o.measure??Ir)(a,r.ffmpeg);if(l==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(l*1e3>P.ms+2e3)return[413,{error:ct()}]}let c=[];for(let l of s)try{let u=await Qo(l,a,i,r,t,o);return o.log(`[voice] phone recording transcribed with ${l} (${Math.round(n.length/1024)} KB)`),u?[200,{text:u,engine:l}]:[422,{error:"No words were heard. Hold the orb and speak, then let go.",engine:l}]}catch(u){let d=String(u?.message??u).split(`
465
- `)[0].slice(0,200);c.push(`${l}: ${d}`),o.log(`[voice] phone transcription with ${l} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:c.join("; ")}]}function Qo(t,e,n,i,r,s){let o=s.engines?.[t];if(o)return o(e,n,i,r);if(t==="elevenlabs")return _r(e,n,i.key);let a=t==="mlx-whisper"?i.mlx:i.whisper;return Cr(t,a,e,i.ffmpeg,r)}async function ea(t,e,n){let i=await Er(t,Xo);if(!i)return b(e,413,{error:"request too large"});let r;try{r=JSON.parse(i.toString("utf8")||"{}")}catch{return b(e,400,{error:"expected JSON"})}let s=typeof r?.agent=="string"?r.agent:"",o=typeof r?.peer=="string"&&r.peer?r.peer:void 0;if(!s)return b(e,400,{error:"agent is required"});let a=ta(typeof r?.text=="string"?r.text:"",n.spokenMaxChars?.());if(!a)return b(e,422,{error:"Nothing in this answer can be said aloud."});let c=n.voiceOf(s,o);if(!c)return b(e,404,{error:`Unknown agent: ${s}`});let l=(d,p=200)=>b(e,p,{fallback:"browser",reason:d,text:a});if(c.provider!=="elevenlabs")return l("This agent speaks with a system voice, which only plays on the computer.");let u=n.elevenLabsKey();if(!u)return l("No ElevenLabs key is set on this computer.");try{let d=await(n.synth??na)(u,c,a);e.writeHead(200,{"Content-Type":"audio/mpeg","Content-Length":d.length,"Cache-Control":"no-store","X-Spoken-Chars":String(a.length)}),e.end(d)}catch(d){return n.log(`[voice] phone answer synthesis failed: ${String(d?.message??d).split(`
466
- `)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function ta(t,e){let n=Zn(Ct(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return wt(n,e)}async function na(t,e,n){let i=ge(e.rate),r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(e.elevenlabs)}?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n,model_id:"eleven_flash_v2_5",...i?{voice_settings:{speed:i}}:{}}),signal:AbortSignal.timeout(6e4)});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text().catch(()=>"")).slice(0,160)}`);return Buffer.from(await r.arrayBuffer())}var ra=()=>`The recording is larger than ${P.bytes/1024/1024} MB, more than ${P.ms/6e4} minutes of speech.`;function gu(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Fe(je(t,r,n.voice)):null}function Er(t,e){return Number(t.headers["content-length"])>e?(t.resume(),Promise.resolve(null)):new Promise((n,i)=>{let r=[],s=0;t.on("data",o=>{if(!(s>e)){if(s+=o.length,s>e){r.length=0,n(null);return}r.push(o)}}),t.on("end",()=>{s<=e&&n(Buffer.concat(r))}),t.on("error",i)})}function b(t,e,n){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}import{existsSync as v,readFileSync as gt,writeFileSync as mt,mkdirSync as me,readdirSync as ft,rmSync as ia,statSync as A}from"fs";import{resolve as Tr,relative as sa,dirname as ht,join as O,extname as J,basename as yt}from"path";var k=200*1024,Pr=new Set([".md",".markdown",".txt"]),F=new Set([".md",".markdown",".txt",".json",".jsonc",".yaml",".yml",".toml",".sh",".bash",".zsh",".py",".js",".mjs",".ts",".tsx",".jsx",".css",".html",".lock",".cfg",".ini",".env",".gitignore"]),oa=6,aa=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function C(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=Tr(t);if(v(n)||me(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=Tr(n,e);if(sa(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function Lr(t){let e=J(t).toLowerCase();if(!Pr.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function dt(t,e){let n=t.split(/\r?\n/).find(i=>i.trim().startsWith("#"));return n&&n.replace(/^#+\s*/,"").trim().slice(0,120)||e}function bu(t){let e=C(t,"."),n=[],i=new Set,r=[];try{r=ft(e)}catch{}for(let a of aa){let c=O(e,a);if(v(c)&&A(c).isFile()){let l=A(c).size,u=l>0&&l<k?pt(c):"";n.push({path:a,title:dt(u,a),size:l,exists:!0}),i.add(a)}else n.push({path:a,title:a,size:0,exists:!1}),i.add(a)}for(let a of r){if(i.has(a))continue;let c=O(e,a);try{let l=A(c);if(!l.isFile()||!Pr.has(J(a).toLowerCase()))continue;let u=l.size>0&&l.size<k?pt(c):"";n.push({path:a,title:dt(u,a),size:l.size,exists:!0})}catch{}}let s=[],o=O(e,".claude","skills");if(v(o))try{for(let a of ft(o)){let c=O(o,a),l;try{l=A(c)}catch{continue}if(!l.isDirectory())continue;let u=O(c,"SKILL.md");if(!v(u))continue;let d=A(u),p=d.size<k?pt(u):"";s.push({slug:a,title:dt(p,a),size:d.size,path:`.claude/skills/${a}/SKILL.md`})}}catch{}return s.sort((a,c)=>a.slug.localeCompare(c.slug)),{identity:n,skills:s,workspace:e}}function pt(t){try{return gt(t,"utf-8")}catch{return""}}function wu(t,e){let n=C(t,e);if(Lr(n),!v(n))return{path:e,content:""};if(A(n).size>k)throw new Error(`File is too large to edit in the admin panel (> ${k/1024} KB).`);return{path:e,content:gt(n,"utf-8")}}function xu(t,e,n){let i=C(t,e);Lr(i);let r=Buffer.from(n,"utf-8");if(r.length>k)throw new Error(`File too large (${r.length} > ${k} bytes).`);return me(ht(i),{recursive:!0}),mt(i,r),{path:e,bytes:r.length}}function ku(t,e,n={}){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Skill slug must be lowercase (letters, digits, -, _) and start with a letter or digit.");let i=`.claude/skills/${e}/SKILL.md`,r=C(t,i);if(v(r))throw new Error(`Skill "${e}" already exists.`);me(ht(r),{recursive:!0});let s=n.content?.trim()?n.content:ca(e,n.title);return mt(r,s),{slug:e,path:i}}function Su(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);if(!A(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return ia(n,{recursive:!0,force:!0}),{slug:e}}function vu(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);let i=[];return r(n,"",0,i),i.sort((s,o)=>s.kind!==o.kind?s.kind==="dir"?-1:1:s.path.localeCompare(o.path)),i;function r(s,o,a,c){if(a>oa)return;let l=[];try{l=ft(s)}catch{return}for(let u of l){if(u==="node_modules"||u===".git")continue;let d=O(s,u),p=o?`${o}/${u}`:u,f;try{f=A(d)}catch{continue}if(f.isDirectory())c.push({path:`${p}/`,kind:"dir",size:0,editable:!1}),r(d,p,a+1,c);else if(f.isFile()){let g=J(u).toLowerCase(),h=F.has(g)||F.has(u.toLowerCase());c.push({path:p,kind:"file",size:f.size,editable:h&&f.size<k})}}}}function $u(t,e,n){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let i=C(t,`.claude/skills/${e}/${n}`);if(!v(i)||!A(i).isFile())throw new Error(`File not found: ${n}`);let r=J(i).toLowerCase(),s=yt(i).toLowerCase();if(!F.has(r)&&!F.has(s))throw new Error(`File type not editable: ${n}`);if(A(i).size>k)throw new Error(`File too large to edit (> ${k/1024} KB): ${n}`);return{path:n,content:gt(i,"utf-8")}}function Ru(t,e,n,i){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let r=C(t,`.claude/skills/${e}/${n}`),s=J(r).toLowerCase(),o=yt(r).toLowerCase();if(!F.has(s)&&!F.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(i,"utf-8");if(a.length>k)throw new Error(`File too large (${a.length} > ${k} bytes).`);return me(ht(r),{recursive:!0}),mt(r,a),{path:n,bytes:a.length}}function Au(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);let i=r=>v(O(n,r));return i("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:i("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:i("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:i("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:i("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function ca(t,e){return`# ${e?.trim()||t}
462
+ Message (edit it if you like):`,d=await n("/usr/bin/osascript",dr(s,l,o?["Cancel","Send"]:["Not now","No","Send"],i,Wt(t.draft,o)),r),p=d.ok?pr(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",dr(s,rt(t),["Not now","No","Yes"],i),r),c=a.ok?pr(a.stdout):null;return c?.button==="Yes"?{action:"yes"}:c?.button==="No"?{action:"no"}:{action:"dismiss"}}var st=24*36e5,it=!1,bo=10*6e4,mr=-1/0;function hr(t){let e=t.now??Date.now(),{popped:n={},snoozed:i,passAt:r,wanted:s=[]}=R(t.root),o=r?Date.parse(r):NaN,a=U(t.root,"pending").filter(l=>Date.parse(l.expires)>e),c=a.find(l=>s.includes(`card:${l.id}`));if(c)return c;for(let l of a){let u=`card:${l.id}`;if(n[u])continue;let d=i[u];if(d&&Date.parse(d)>e)continue;let p=Date.parse(l.created_at);if(!(e-p>st&&!(p<=o)))return l}return null}function yr(t){try{return z(t)?.listByState("needs_attention")??[]}catch{return[]}}function wo(t){let e=t.now??Date.now(),{popped:n={},snoozed:i}=R(t.root);return yr(t).find(r=>{let s=`request:${r.id}`,o=i[s];return!n[s]&&!(o&&Date.parse(o)>e)&&e-r.updatedAt<=st})??null}function ko(t,e){return{id:t.id,title:Qe(t.text,qt.title),context:t.attentionReason??"It is not finished and nothing is retrying it.",ask:`Hand it back to ${t.agentId}, or drop it?`,say:"A request you made is not finished.",recommend:"",if_silent:"keep",expires:new Date(e+st).toISOString(),raised_by:t.agentId,created_at:new Date(t.createdAt).toISOString(),status:"pending",origin:{kind:"request",id:t.id}}}async function Dl(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=hr(e)?null:wo(e),s=r?ko(r,e.now??Date.now()):hr(e);if(!s)return"none";let o=(t.focus??Et)();if(o.active)return"held";it=!0;let a=`${r?"request":"card"}:${s.id}`;try{let c=[...U(e.root,"pending").map(g=>`card:${g.id}`),...yr(e).map(g=>`request:${g.id}`)];pn(e.root,a,c,e.now),i(`[approvals] popup: showing ${a} from ${s.raised_by}`);let l=e.now??Date.now(),u=!!r&&l-mr<bo;r&&n.speak&&(mr=l);let d=await(t.show??gr)(s,u?{...n,speak:!1}:n,{from:t.agentName?.(s.raised_by),speak:t.speak});if(d.action==="dismiss")return i(`[approvals] popup: ${a} left waiting: ${d.why??"no answer"} (${Tt(o)} when shown)`),"shown";if(!(r?z(e)?.get(r.id)?.state==="needs_attention":B(e.root,s.id)?.status==="pending"))return i(`[approvals] popup: ${a} was answered elsewhere; popup answer ignored`),"shown";let f=await wn(e,a,d.action,{by:"operator (popup)",...d.action==="yes"?{choice:d.choice,text:d.text}:{}});return i(f.ok?`[approvals] popup: ${f.message}`:`[approvals] popup: ${a} not recorded: ${f.error}`),"shown"}catch(c){return i(`[approvals] popup failed for ${a}: ${c?.message??c}`),"shown"}finally{it=!1}}function El(t,e,n){if(!n)return{ok:!1,error:"the Mac popup is off; turn it on with `agentx approvals settings --popup on`"};let i=e.startsWith("card:")?B(t.root,e.slice(5)):null;return i?i.status!=="pending"?{ok:!1,error:`${e} is already ${i.status}`}:(fn(t.root,e),{ok:!0,message:`${e} will show on the Mac within a minute`}):{ok:!1,error:`no card "${e}"; the popup shows decision cards only`}}import{closeSync as G,createReadStream as xo,fstatSync as So,openSync as vo,realpathSync as br}from"fs";import{isAbsolute as $o,resolve as wr,sep as kr}from"path";var Nl="/app-files",Ro=/^[A-Za-z0-9_.:-]{1,64}$/;function Ao(t,e,n=process.cwd()){if(!e||e.length>ee.pathChars||e.includes("\0"))return{ok:!1,status:400,error:"bad file path"};if(e.split(/[\\/]/).includes(".."))return{ok:!1,status:403,error:`the path leaves the workspace: copy the file into ${Se}/ first`};if(!xe(e))return{ok:!1,status:415,error:"this type of file is not served"};let i;try{i=br(wr(n,t))}catch{return{ok:!1,status:404,error:"the agent's workspace is missing"}}let r;try{r=br($o(e)?e:wr(i,e))}catch{return{ok:!1,status:404,error:"file not found"}}if(!r.startsWith(i+kr))return{ok:!1,status:403,error:`the file is outside the agent's workspace: copy it into ${Se}/ first`};let s=xe(r);return s?{ok:!0,path:r,...s}:{ok:!1,status:415,error:"this type of file is not served"}}function Io(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 _o(t,e,n){return{"Content-Type":t,"Content-Disposition":Io(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 Co(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 jl(t,e,n,i){let r=(D,N)=>{e.writeHead(D,{"Content-Type":"application/json","Cache-Control":"no-store","X-Content-Type-Options":"nosniff"}),e.end(JSON.stringify(N))};if(t.method!=="GET"&&t.method!=="HEAD")return r(405,{error:"GET only"});let s=n.searchParams.get("agent")||"",o=n.searchParams.get("file")||"";if(!Ro.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=Ao(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=vo(c.path,"r")}catch{return r(404,{error:"file not found"})}let u;try{let D=So(l);if(!D.isFile())return G(l),r(404,{error:"not a file"});u=D.size}catch{return G(l),r(404,{error:"file not found"})}if(u>ee.bytes)return G(l),r(413,{error:`the file is larger than ${ee.bytes/1024/1024} MB`});let d=c.path.split(kr).pop()||"file",p=_o(c.mime,d,c.kind),f=Co(t.headers.range,u);if(f==="unsatisfiable"){G(l),e.writeHead(416,{...p,"Content-Range":`bytes */${u}`}),e.end();return}let{start:g,end:h}=f??{start:0,end:u-1};if(e.writeHead(f?206:200,{...p,"Content-Length":String(u?h-g+1:0),...f?{"Content-Range":`bytes ${g}-${h}/${u}`}:{}}),t.method==="HEAD"||u===0){G(l),e.end();return}let y=xo("",{fd:l,start:g,end:h,autoClose:!0});y.on("error",()=>e.destroy()),e.on("close",()=>y.destroy()),y.pipe(e)}import{spawn as X}from"child_process";import{readFileSync as Do,writeFileSync as Eo}from"fs";import{tmpdir as To}from"os";import{join as Po}from"path";wt();var xr=t=>t&&t!==1?Math.round(175*t):null,ge=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function Lo(){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=Do(t,"utf8").trim();if(e)return e}catch{}return null}function Kl(t=Lo()){let e=0;return async(n,i)=>{if(n.voice.provider==="system")return null;if(!t){if(n.voice.fallback)return null;throw new Error("ElevenLabs is the voice provider but no key is set")}try{let r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${n.voice.elevenlabs}/stream?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n.text,model_id:"eleven_flash_v2_5",...ge(n.voice.rate)?{voice_settings:{speed:ge(n.voice.rate)}}:{}}),signal:i});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let s=Po(To(),`agentx-say-${process.pid}-${++e}.mp3`);return Eo(s,Buffer.from(await r.arrayBuffer())),s}catch(r){if(i.aborted||!n.voice.fallback)throw r;return M(`elevenlabs:${String(r?.message??r).slice(0,40)}`,`[voice] ElevenLabs failed (${String(r?.message??r).slice(0,160)}); speaking with the system voice`),null}}}function Sr(t,e){let n=t.languages&&Q(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var Mo=(t,e="")=>{let n=Sr(t,e),i=xr(t.rate);return[...n&&!An(n)?["-v",n]:[],...i?["-r",String(i)]:[]]};function Oo(t,e,n){if(!n)return["say",Mo(t,e)];let i=Sr(t,e);return["/bin/sh",[n,...i?[i]:[]]]}function Gl(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Xl(t=ot()){if(t)try{X("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function Jl(t=ot()){if(t)try{X("/bin/sh",[t,"--restore"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function ot(t={},e){if(!Ee(t))return null;try{return Cn(e)}catch(n){return M("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
463
+ `)[0]}); Siri voices will not switch`),null}}var Yl=(t,e)=>{if(!t){let[n,i]=Oo(e.voice,e.text,ot()),r=xr(e.voice.rate),s=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=X(n,i,{stdio:["pipe","ignore","ignore"],env:s});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?X("afplay",[t],{stdio:"ignore"}):X("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as vr}from"child_process";import{accessSync as No,constants as jo,readFileSync as $r}from"fs";import{homedir as Vo}from"os";import{basename as W,delimiter as Rr,dirname as Wo,extname as Fo,join as at}from"path";var P={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function Ar(t){let e=Array.isArray(t)?t[0]:t;return!e||!/^\d{1,9}$/.test(e.trim())?{status:400,error:"Say how long the recording is (X-Audio-Duration-Ms)."}:Number(e)>P.ms+2e3?{status:413,error:lt()}:null}var lt=()=>`The recording is longer than ${P.ms/6e4} minutes.`,Bo={"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 Ir(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return Bo[e]??null}function _r(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 ut(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 ct(t,e,n=process.env.PATH??""){let i=Vo(),r=[at(i,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(Rr).filter(Boolean)];for(let s of[e,...r.map(o=>at(o,t))])if(s)try{return No(s,jo.X_OK),s}catch{}return null}function ru(t){return{key:t,mlx:ct("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:ct("whisper",process.env.AGENTX_WHISPER),ffmpeg:Uo()}}var Uo=()=>ct("ffmpeg",process.env.AGENTX_FFMPEG);async function Cr(t,e){return e?Ho(t,e):null}async function Ho(t,e){let n=String(P.ms/1e3+5);try{let r=[...(await zo(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 Dr(t,e,n,i){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([$r(t)],{type:e}),W(t));let s=await fetch("https://api.elevenlabs.io/v1/speech-to-text",{method:"POST",headers:{"xi-api-key":n},body:r,signal:i??AbortSignal.timeout(6e4)});if(!s.ok)throw new Error(`ElevenLabs ${s.status}: ${(await s.text().catch(()=>"")).slice(0,160)}`);let o=await s.json();if(typeof o.text!="string")throw new Error("ElevenLabs returned no text");return o.text.trim()}async function Er(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:`${Wo(i)}${Rr}${process.env.PATH??""}`};await qo(e,s,12e4,o);try{return $r(at(r,W(n,Fo(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function zo(t,e,n){return new Promise((i,r)=>{let s=vr(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{s.kill("SIGKILL"),r(new Error(`${W(t)} took too long`))},n);s.stderr.on("data",c=>{o=(o+c).slice(-8192)}),s.on("error",c=>{clearTimeout(a),r(c)}),s.on("exit",c=>{clearTimeout(a),c===0?i(o):r(new Error(`${W(t)} exited ${c}`))})})}function qo(t,e,n,i=process.env){return new Promise((r,s)=>{let o=vr(t,e,{stdio:["ignore","pipe","pipe"],env:i}),a="",c="",l=setTimeout(()=>{o.kill("SIGKILL"),s(new Error(`${W(t)} took longer than ${n/1e3}s`))},n);o.stdout.on("data",u=>{a.length<4096&&(a+=u)}),o.stderr.on("data",u=>{c.length<4096&&(c+=u)}),o.on("error",u=>{clearTimeout(l),s(u)}),o.on("exit",u=>{clearTimeout(l),u===0?r(a):s(new Error(`${W(t)} exited ${u}: ${c.trim().split(`
464
+ `).pop()?.slice(0,160)??""}`))})})}import{mkdtemp as Ko,rm as Go,writeFile as Xo}from"fs/promises";import{tmpdir as Jo}from"os";import{join as Tr}from"path";Fr();var Yo=64*1024,Zo=2,dt=0;function gu(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function mu(t,e,n,i){return t.method!=="POST"?b(e,405,{error:"POST"}):n==="/voice/transcribe"?Qo(t,e,i):na(t,e,i)}async function Qo(t,e,n){let i=String(t.headers["content-type"]||""),r=Ir(i);if(!r)return b(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let s=Ar(t.headers["x-audio-duration-ms"]);if(s)return t.resume(),b(e,s.status,{error:s.error});let o=await Pr(t,P.bytes);if(!o)return b(e,413,{error:sa()});if(!o.length)return b(e,400,{error:"The recording is empty."});if(dt>=Zo)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=_r(a,c);if(!c.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",p=l.length?"":" "+ut(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:ut(a,c),setup:!1});dt++;let u;try{let d=await Ko(Tr(Jo(),"agentx-phone-voice-"));try{u=await ea(d,`speech.${r}`,o,i,c,l,n)}finally{await Go(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{dt--}b(e,u[0],u[1])}async function ea(t,e,n,i,r,s,o){let a=Tr(t,e);if(await Xo(a,n,{mode:384}),r.ffmpeg){let l=await(o.measure??Cr)(a,r.ffmpeg);if(l==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(l*1e3>P.ms+2e3)return[413,{error:lt()}]}let c=[];for(let l of s)try{let u=await ta(l,a,i,r,t,o);return o.log(`[voice] phone recording transcribed with ${l} (${Math.round(n.length/1024)} KB)`),u?[200,{text:u,engine:l}]:[422,{error:"No words were heard. Hold the orb and speak, then let go.",engine:l}]}catch(u){let d=String(u?.message??u).split(`
465
+ `)[0].slice(0,200);c.push(`${l}: ${d}`),o.log(`[voice] phone transcription with ${l} failed: ${d}`)}return[502,{error:"Speech to text failed on this computer.",detail:c.join("; ")}]}function ta(t,e,n,i,r,s){let o=s.engines?.[t];if(o)return o(e,n,i,r);if(t==="elevenlabs")return Dr(e,n,i.key);let a=t==="mlx-whisper"?i.mlx:i.whisper;return Er(t,a,e,i.ffmpeg,r)}async function na(t,e,n){let i=await Pr(t,Yo);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=ra(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(`
466
+ `)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function ra(t,e){let n=Qn(Dt(t).text).cleanText.replace(/!\[[^\]\n]*\]\([^)\n]*\)/g,"");return kt(n,e)}async function ia(t,e,n){let i=ge(e.rate),r=await fetch(`https://api.elevenlabs.io/v1/text-to-speech/${encodeURIComponent(e.elevenlabs)}?output_format=mp3_44100_128`,{method:"POST",headers:{"xi-api-key":t,"Content-Type":"application/json"},body:JSON.stringify({text:n,model_id:"eleven_flash_v2_5",...i?{voice_settings:{speed:i}}:{}}),signal:AbortSignal.timeout(6e4)});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text().catch(()=>"")).slice(0,160)}`);return Buffer.from(await r.arrayBuffer())}var sa=()=>`The recording is larger than ${P.bytes/1024/1024} MB, more than ${P.ms/6e4} minutes of speech.`;function hu(t,e,n,i){if(e)return i.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Fe(je(t,r,n.voice)):null}function Pr(t,e){return Number(t.headers["content-length"])>e?(t.resume(),Promise.resolve(null)):new Promise((n,i)=>{let r=[],s=0;t.on("data",o=>{if(!(s>e)){if(s+=o.length,s>e){r.length=0,n(null);return}r.push(o)}}),t.on("end",()=>{s<=e&&n(Buffer.concat(r))}),t.on("error",i)})}function b(t,e,n){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}import{existsSync as v,readFileSync as mt,writeFileSync as ht,mkdirSync as me,readdirSync as gt,rmSync as oa,statSync as A}from"fs";import{resolve as Lr,relative as aa,dirname as yt,join as O,extname as J,basename as bt}from"path";var x=200*1024,Mr=new Set([".md",".markdown",".txt"]),F=new Set([".md",".markdown",".txt",".json",".jsonc",".yaml",".yml",".toml",".sh",".bash",".zsh",".py",".js",".mjs",".ts",".tsx",".jsx",".css",".html",".lock",".cfg",".ini",".env",".gitignore"]),ca=6,la=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function C(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=Lr(t);if(v(n)||me(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let i=Lr(n,e);if(aa(n,i).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return i}function Or(t){let e=J(t).toLowerCase();if(!Mr.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function pt(t,e){let n=t.split(/\r?\n/).find(i=>i.trim().startsWith("#"));return n&&n.replace(/^#+\s*/,"").trim().slice(0,120)||e}function ku(t){let e=C(t,"."),n=[],i=new Set,r=[];try{r=gt(e)}catch{}for(let a of la){let c=O(e,a);if(v(c)&&A(c).isFile()){let l=A(c).size,u=l>0&&l<x?ft(c):"";n.push({path:a,title:pt(u,a),size:l,exists:!0}),i.add(a)}else n.push({path:a,title:a,size:0,exists:!1}),i.add(a)}for(let a of r){if(i.has(a))continue;let c=O(e,a);try{let l=A(c);if(!l.isFile()||!Mr.has(J(a).toLowerCase()))continue;let u=l.size>0&&l.size<x?ft(c):"";n.push({path:a,title:pt(u,a),size:l.size,exists:!0})}catch{}}let s=[],o=O(e,".claude","skills");if(v(o))try{for(let a of gt(o)){let c=O(o,a),l;try{l=A(c)}catch{continue}if(!l.isDirectory())continue;let u=O(c,"SKILL.md");if(!v(u))continue;let d=A(u),p=d.size<x?ft(u):"";s.push({slug:a,title:pt(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 ft(t){try{return mt(t,"utf-8")}catch{return""}}function xu(t,e){let n=C(t,e);if(Or(n),!v(n))return{path:e,content:""};if(A(n).size>x)throw new Error(`File is too large to edit in the admin panel (> ${x/1024} KB).`);return{path:e,content:mt(n,"utf-8")}}function Su(t,e,n){let i=C(t,e);Or(i);let r=Buffer.from(n,"utf-8");if(r.length>x)throw new Error(`File too large (${r.length} > ${x} bytes).`);return me(yt(i),{recursive:!0}),ht(i,r),{path:e,bytes:r.length}}function vu(t,e,n={}){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error("Skill slug must be lowercase (letters, digits, -, _) and start with a letter or digit.");let i=`.claude/skills/${e}/SKILL.md`,r=C(t,i);if(v(r))throw new Error(`Skill "${e}" already exists.`);me(yt(r),{recursive:!0});let s=n.content?.trim()?n.content:ua(e,n.title);return ht(r,s),{slug:e,path:i}}function $u(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);if(!A(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return oa(n,{recursive:!0,force:!0}),{slug:e}}function Ru(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);let i=[];return r(n,"",0,i),i.sort((s,o)=>s.kind!==o.kind?s.kind==="dir"?-1:1:s.path.localeCompare(o.path)),i;function r(s,o,a,c){if(a>ca)return;let l=[];try{l=gt(s)}catch{return}for(let u of l){if(u==="node_modules"||u===".git")continue;let d=O(s,u),p=o?`${o}/${u}`:u,f;try{f=A(d)}catch{continue}if(f.isDirectory())c.push({path:`${p}/`,kind:"dir",size:0,editable:!1}),r(d,p,a+1,c);else if(f.isFile()){let g=J(u).toLowerCase(),h=F.has(g)||F.has(u.toLowerCase());c.push({path:p,kind:"file",size:f.size,editable:h&&f.size<x})}}}}function Au(t,e,n){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let i=C(t,`.claude/skills/${e}/${n}`);if(!v(i)||!A(i).isFile())throw new Error(`File not found: ${n}`);let r=J(i).toLowerCase(),s=bt(i).toLowerCase();if(!F.has(r)&&!F.has(s))throw new Error(`File type not editable: ${n}`);if(A(i).size>x)throw new Error(`File too large to edit (> ${x/1024} KB): ${n}`);return{path:n,content:mt(i,"utf-8")}}function Iu(t,e,n,i){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!n||n.includes(".."))throw new Error(`Invalid file path: ${n}`);let r=C(t,`.claude/skills/${e}/${n}`),s=J(r).toLowerCase(),o=bt(r).toLowerCase();if(!F.has(s)&&!F.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(i,"utf-8");if(a.length>x)throw new Error(`File too large (${a.length} > ${x} bytes).`);return me(yt(r),{recursive:!0}),ht(r,a),{path:n,bytes:a.length}}function _u(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=C(t,`.claude/skills/${e}`);if(!v(n))throw new Error(`Skill "${e}" not found.`);let i=r=>v(O(n,r));return i("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:i("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:i("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:i("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:i("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function ua(t,e){return`# ${e?.trim()||t}
467
467
 
468
468
  Describe what this skill does and when the agent should use it. Keep it under ~5 lines \u2014 the agent reads this to decide whether to invoke the skill.
469
469
 
@@ -476,7 +476,7 @@ Document the arguments, commands, or files the skill expects. Example:
476
476
 
477
477
  \`\`\`bash
478
478
  # Example invocation
479
- claude-code ${yt(t)} --arg value
479
+ claude-code ${bt(t)} --arg value
480
480
  \`\`\`
481
- `}Rt();var Mr={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function Or(t){return{...Mr,...t??{},regions:{...t?.regions??{}},buffer:{...Mr.buffer,...t?.buffer??{}}}}function Cu(t){try{return Or($t(t).screen)}catch{return Or(void 0)}}var la=/^[a-z][\w-]*$/,Nr=["window","screen","menubar","notifications"];function Y(t,e,n,i){let r=Number(t);if(t===""||t===null||!Number.isFinite(r)||!n(r))throw new Error(`${e} must be ${i}`);return r}var he=(t,e)=>Y(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function jr(t){let e=typeof t=="string"?t.split(",").map(Number):[t?.x,t?.y,t?.width,t?.height].map(Number);if(e.length!==4||!e.every(Number.isFinite)||e[2]<=0||e[3]<=0)throw new Error("a region is x,y,width,height in screen points, with width and height above 0");return{x:e[0],y:e[1],width:e[2],height:e[3]}}function Du(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=he(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=he(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=he(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Y(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Y(e.changeThreshold,"changeThreshold",r=>r>=0&&r<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let r={...n.regions??{}};for(let[s,o]of Object.entries(e.regions)){if(!la.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);o===null?delete r[s]:r[s]=jr(o)}n.regions=r}if(e.buffer&&typeof e.buffer=="object"){let r=e.buffer,s={...n.buffer??{}};"enabled"in r&&(s.enabled=!!r.enabled),"seconds"in r&&(s.seconds=Y(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Y(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=he(r.maxPixels,"buffer.maxPixels")),"region"in r&&(s.region=String(r.region).trim()),n.buffer=s}let i=n.buffer?.region;if(i!==void 0&&!Nr.includes(i)&&!n.regions?.[i])try{jr(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...Nr,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{Kt as a,pa as b,Ze as c,Os as d,Ns as e,qc as f,Kc as g,Gc as h,Zn as i,Jc as j,Zc as k,T as l,Qn as m,x as n,ha as o,wa as p,di as q,Ra as r,cn as s,R as t,Da as u,Ea as v,fn as w,Na as x,z as y,Ya as z,bn as A,tl as B,fr as C,_l as D,Cl as E,Ml as F,Ao as G,Ol as H,Qa as I,ec as J,tc as K,nc as L,rc as M,ic as N,oc as O,ac as P,hc as Q,Le as R,yc as S,bc as T,q as U,K as V,To as W,zl as X,ql as Y,Kl as Z,Gl as _,st as $,Xl as aa,Ne as ba,je as ca,de as da,ns as ea,is as fa,vc as ga,We as ha,Fe as ia,ss as ja,os as ka,jn as la,Bn as ma,$c as na,ls as oa,Rc as pa,ys as qa,xs as ra,Be as sa,Ss as ta,Un as ua,P as va,$r as wa,Rr as xa,Ar as ya,tu as za,Fo as Aa,_r as Ba,Cr as Ca,pu as Da,fu as Ea,ra as Fa,gu as Ga,Er as Ha,pe as Ia,Nc as Ja,Xn as Ka,Ue as La,Je as Ma,Hc as Na,bu as Oa,wu as Pa,xu as Qa,ku as Ra,Su as Sa,vu as Ta,$u as Ua,Ru as Va,Au as Wa,Mr as Xa,Or as Ya,Cu as Za,Nr as _a,Du as $a};
482
- //# sourceMappingURL=chunk-B32A6OOY.js.map
481
+ `}At();var Nr={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function jr(t){return{...Nr,...t??{},regions:{...t?.regions??{}},buffer:{...Nr.buffer,...t?.buffer??{}}}}function Eu(t){try{return jr(Rt(t).screen)}catch{return jr(void 0)}}var da=/^[a-z][\w-]*$/,Vr=["window","screen","menubar","notifications"];function Y(t,e,n,i){let r=Number(t);if(t===""||t===null||!Number.isFinite(r)||!n(r))throw new Error(`${e} must be ${i}`);return r}var he=(t,e)=>Y(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function Wr(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 Tu(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=he(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=he(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=he(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=Y(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=Y(e.changeThreshold,"changeThreshold",r=>r>=0&&r<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let r={...n.regions??{}};for(let[s,o]of Object.entries(e.regions)){if(!da.test(s))throw new Error(`region name "${s}" must be lowercase letters, digits, - or _`);o===null?delete r[s]:r[s]=Wr(o)}n.regions=r}if(e.buffer&&typeof e.buffer=="object"){let r=e.buffer,s={...n.buffer??{}};"enabled"in r&&(s.enabled=!!r.enabled),"seconds"in r&&(s.seconds=Y(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(s.fps=Y(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(s.maxPixels=he(r.maxPixels,"buffer.maxPixels")),"region"in r&&(s.region=String(r.region).trim()),n.buffer=s}let i=n.buffer?.region;if(i!==void 0&&!Vr.includes(i)&&!n.regions?.[i])try{Wr(i)}catch{throw new Error(`buffer.region "${i}" is not a region \u2014 use ${[...Vr,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{Gt as a,ga as b,Ze as c,js as d,Vs as e,Gc as f,Xc as g,Jc as h,Qn as i,Zc as j,el as k,T as l,er as m,k as n,ba as o,xa as p,fi as q,Ia as r,ln as s,R as t,Ta as u,Pa as v,gn as w,Va as x,z as y,Qa as z,wn as A,rl as B,gr as C,Dl as D,El as E,Nl as F,_o as G,jl as H,tc as I,nc as J,rc as K,ic as L,sc as M,oc as N,cc as O,lc as P,bc as Q,Le as R,wc as S,kc as T,q as U,K as V,Lo as W,Kl as X,Gl as Y,Xl as Z,Jl as _,ot as $,Yl as aa,Ne as ba,je as ca,de as da,is as ea,os as fa,Rc as ga,We as ha,Fe as ia,as as ja,cs as ka,Vn as la,Un as ma,Ac as na,ds as oa,Ic as pa,ws as qa,Ss as ra,Be as sa,$s as ta,Hn as ua,P as va,Ar as wa,Ir as xa,_r as ya,ru as za,Uo as Aa,Dr as Ba,Er as Ca,gu as Da,mu as Ea,sa as Fa,hu as Ga,Pr as Ha,pe as Ia,Vc as Ja,Jn as Ka,Ue as La,Je as Ma,qc as Na,ku as Oa,xu as Pa,Su as Qa,vu as Ra,$u as Sa,Ru as Ta,Au as Ua,Iu as Va,_u as Wa,Nr as Xa,jr as Ya,Eu as Za,Vr as _a,Tu as $a};
482
+ //# sourceMappingURL=chunk-MWLX3QCD.js.map