agentix-cli 0.63.0 → 0.65.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{agent-D2BHFDUA.js → agent-HUKCS3AK.js} +2 -2
- package/dist/{board-dashboard-SMCZBJKO.js → board-dashboard-S4V4WR2N.js} +382 -213
- package/dist/board-dashboard-S4V4WR2N.js.map +1 -0
- package/dist/{chunk-GUJB53QU.js → chunk-62EJKQFX.js} +2 -2
- package/dist/{chunk-TX3ZOO22.js → chunk-AVDWFQZ5.js} +2 -2
- package/dist/{chunk-KAFO5QZR.js → chunk-C4CDVE2E.js} +28 -28
- package/dist/chunk-C4CDVE2E.js.map +1 -0
- package/dist/chunk-ECBKTFTL.js +20 -0
- package/dist/chunk-ECBKTFTL.js.map +1 -0
- package/dist/chunk-EOKOGQZG.js +131 -0
- package/dist/chunk-EOKOGQZG.js.map +1 -0
- package/dist/{chunk-ZGWW6FZF.js → chunk-HSJRI3NW.js} +184 -184
- package/dist/chunk-HSJRI3NW.js.map +1 -0
- package/dist/{chunk-7LETLAIH.js → chunk-LEFRNHZF.js} +4 -4
- package/dist/{chunk-7LETLAIH.js.map → chunk-LEFRNHZF.js.map} +1 -1
- package/dist/{chunk-JZMKKDT3.js → chunk-OTTAKMGC.js} +54 -54
- package/dist/chunk-OTTAKMGC.js.map +1 -0
- package/dist/{chunk-33YJIUYL.js → chunk-WMDDQVCI.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/processes-TGFDGQYY.js +2 -0
- package/dist/{program-NPPLJAQ7.js → program-DZCKFNHD.js} +2 -2
- package/dist/registry-P7IAAFCX.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-SMCZBJKO.js.map +0 -1
- package/dist/chunk-5UYXEO3I.js +0 -131
- package/dist/chunk-5UYXEO3I.js.map +0 -1
- package/dist/chunk-JZMKKDT3.js.map +0 -1
- package/dist/chunk-KAFO5QZR.js.map +0 -1
- package/dist/chunk-PMGPGMBZ.js +0 -19
- package/dist/chunk-PMGPGMBZ.js.map +0 -1
- package/dist/chunk-ZGWW6FZF.js.map +0 -1
- package/dist/processes-NNXSRQSV.js +0 -2
- package/dist/registry-MRMQBYE4.js +0 -2
- /package/dist/{agent-D2BHFDUA.js.map → agent-HUKCS3AK.js.map} +0 -0
- /package/dist/{chunk-GUJB53QU.js.map → chunk-62EJKQFX.js.map} +0 -0
- /package/dist/{chunk-TX3ZOO22.js.map → chunk-AVDWFQZ5.js.map} +0 -0
- /package/dist/{chunk-33YJIUYL.js.map → chunk-WMDDQVCI.js.map} +0 -0
- /package/dist/{processes-NNXSRQSV.js.map → processes-TGFDGQYY.js.map} +0 -0
- /package/dist/{program-NPPLJAQ7.js.map → program-DZCKFNHD.js.map} +0 -0
- /package/dist/{registry-MRMQBYE4.js.map → registry-P7IAAFCX.js.map} +0 -0
package/dist/chunk-5UYXEO3I.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import{g as ze,h as He,i as Ke,k as Ge,l as Xe}from"./chunk-I2SD4XZ6.js";import{t as Ye,u as Ze}from"./chunk-XT3E5MLX.js";import{d as qe,e as Je}from"./chunk-AQASR6KR.js";import{b as re}from"./chunk-PMGPGMBZ.js";import{q as We}from"./chunk-BHE5TJSN.js";import{w as Be,z as bn}from"./chunk-OVF37EXJ.js";import{existsSync as wn,readdirSync as kn,readFileSync as Sn,statSync as xn}from"fs";import{resolve as $n}from"path";function Qe(t,e,n=Date.now(),s=7){let r=s*864e5,i=new Map;for(let o of e){let a=i.get(o.workflowId);a?a.push(o):i.set(o.workflowId,[o])}return t.map(o=>{let a=i.get(o.id)??[],c=a.filter(m=>n-m.at<=r),l=a.filter(m=>n-m.at>r&&n-m.at<=r*2),u=c.filter(m=>m.status==="failed").length,d=a.filter(m=>m.status==="paused").length,g=a.length?Math.max(...a.map(m=>m.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:g,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 B=new Map;function ri(t,e=1e3){if(!wn(t))return[];let n=kn(t).filter(i=>i.endsWith(".jsonl")).map(i=>{let o=$n(t,i);return{path:o,mtime:xn(o).mtimeMs}}).sort((i,o)=>o.mtime-i.mtime).slice(0,e),s=new Set(n.map(i=>i.path));for(let i of B.keys())s.has(i)||B.delete(i);let r=[];for(let{path:i,mtime:o}of n){let a=B.get(i);if(a&&a.mtime===o){a.summary&&r.push(a.summary);continue}let c=vn(i,o);B.set(i,{mtime:o,summary:c}),c&&r.push(c)}return r}function vn(t,e){try{let n=Sn(t,"utf-8").split(`
|
|
2
|
-
`).filter(Boolean);if(!n.length)return null;let s=JSON.parse(n[0]),r=s.run?.workflowId;if(!r)return null;let i=s.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){i=c;break}}return{workflowId:r,status:i,at:e}}catch{return null}}var In={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},_n=(t,e,n)=>{try{return We(t,e,n)}catch{return null}},et=864e5;function ai(t){let e=t.now??Date.now(),n={...In,...t.thresholds},s=t.nextFire??_n,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],g={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?se(a.nextRun)??se(s(a.schedule,new Date(e),l)):null,lastRun:d?{at:d.startedAt,status:d.status,summary:Dn(d.status==="success"?void 0:d.errorSummary,k.summary)}:null,lastSuccessAt:c.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:tt(u),sampledRuns:c.length,flags:[],attention:null};g.flags=nt(g,u,a.schedule,l,null,e,n,s),r.push(rt(g))}let i=new Map(Qe(t.workflows.map(a=>({id:a.id,name:a.title})),t.workflowRuns,e).map(a=>[a.id,a])),o=new Map;for(let a of t.workflowRuns){let c=o.get(a.workflowId);c?c.push(a):o.set(a.workflowId,[a])}for(let a of t.workflows){let c=a.nodes.find(_=>_.type.startsWith("trigger."));if(!c||c.type!=="trigger.cron"&&c.type!=="trigger.hook")continue;let l=c.config??{},u=a.state||"active",d=u==="active",g=(o.get(a.id)??[]).slice().sort((_,ne)=>ne.at-_.at),f=g.map(_=>({at:_.at,status:Cn(_.status)})),m=f[0],y=c.type==="trigger.cron",b=typeof l.spec=="string"?l.spec:"",te=typeof l.timezone=="string"?l.timezone:"UTC",U={id:`workflow:${a.id}`,source:"workflow",kind:y?"schedule":"event",name:$(a.title||a.id,k.text),trigger:y?{schedule:$(b,k.text),timezone:te}:{event:$(typeof l.event=="string"?l.event:"",k.text),filters:En(l.filter,a)},agent:Tn(a),enabled:d,state:u,nextRunAt:y&&d&&b?se(s(b,new Date(e),te)):null,lastRun:m?{at:new Date(m.at).toISOString(),status:m.status}:null,lastSuccessAt:(()=>{let _=f.find(ne=>ne.status==="success");return _?new Date(_.at).toISOString():null})(),consecutiveFailures:tt(f),sampledRuns:g.length,flags:[],attention:null},F=Date.parse(a.updated||a.created||"");U.flags=y?nt(U,f,b,te,Number.isFinite(F)?F:null,e,n,s):An(U,i.get(a.id)?.state==="dormant",Number.isFinite(F)?F:null,e,n),r.push(rt(U))}return r.sort(Rn).slice(0,k.routines)}function tt(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 nt(t,e,n,s,r,i,o,a){let c=[],l=e.length?e[0].at:null;if(!t.enabled){let g=it(l,r,i,o);return g&&c.push(g),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 g=0;g<o.missedFires&&(d=a(n,u,s),!!d);g++)u=d;return d&&i>d.getTime()+o.graceMs&&c.push({reason:"overdue",detail:`No attempt since ${new Date(l).toISOString()}; ${o.missedFires} scheduled fires missed`}),c}function An(t,e,n,s,r){let i=[],o=t.lastRun?Date.parse(t.lastRun.at):null;if(!t.enabled){let a=it(o,n,s,r);return a&&i.push(a),i}return t.consecutiveFailures>=r.failStreak&&i.push({reason:"failing",detail:`${t.consecutiveFailures} failed runs in a row`}),o===null?i.push({reason:"never-ran",detail:"No run recorded for this trigger"}):e&&i.push({reason:"dormant",detail:"Fired in the prior week, silent in the last one"}),i}function it(t,e,n,s){let r=Math.max(t??0,e??0);return r&&n-r<s.disabledDays*et?null:{reason:"disabled-long",detail:r?`Disabled; no activity for ${Math.floor((n-r)/et)} days`:"Disabled and never ran"}}function rt(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 st={critical:0,warning:1,info:2};function Rn(t,e){let n=t.attention?st[t.attention]:3,s=e.attention?st[e.attention]:3;return n-s||Number(e.enabled)-Number(t.enabled)||t.name.localeCompare(e.name)}function Cn(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 Tn(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 En(t,e){let n=[],s=e?.project;if(s&&n.push($(`project=${s}`,k.filterValue)),t&&typeof t=="object"&&!Array.isArray(t))for(let[r,i]of Object.entries(t)){let o=Array.isArray(i)?i.map(String):i==null?[]:[String(i)];o.length&&n.push($(`${r}=${o.join(",")}`,k.filterValue))}return n.slice(0,k.filters)}function se(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 Dn(t,e){return t===void 0?void 0:$(t,e)}import{createHash as Ln,randomBytes as ot}from"crypto";import{existsSync as Pn,mkdirSync as jn,readFileSync as On,writeFileSync as Nn}from"fs";import{resolve as Mn,dirname as Vn}from"path";var ie="agx_live_",Un=".agentx/tokens.json",at=class{file;constructor(e=process.cwd(),n=Un){this.file=Mn(e,n)}load(){if(!Pn(this.file))return[];try{return JSON.parse(On(this.file,"utf-8"))}catch{return[]}}save(e){jn(Vn(this.file),{recursive:!0}),Nn(this.file,JSON.stringify(e,null,2)+`
|
|
3
|
-
`,"utf-8")}create(e){if(!e.name?.trim())throw new Error("Token name is required.");if(!Array.isArray(e.scopes)||e.scopes.length===0)throw new Error("At least one scope is required.");for(let o of e.scopes)if(!Fn(o))throw new Error(`Invalid scope: ${o}`);let n=ot(32).toString("hex"),s=ie+n,r={id:"tok_"+ot(4).toString("hex"),name:e.name.trim(),prefix:ie+n.slice(0,4),hash:lt(s),scopes:[...e.scopes],createdAt:new Date().toISOString(),expiresAt:e.expiresInDays?new Date(Date.now()+e.expiresInDays*86400*1e3).toISOString():void 0},i=this.load();return i.push(r),this.save(i),{token:s,record:r}}list(){return this.load()}revoke(e){let n=this.load(),s=n.find(r=>r.id===e);return s?(s.revokedAt=new Date().toISOString(),this.save(n),s):null}isActive(e){let n=this.load().find(s=>s.id===e);return!!n&&!n.revokedAt&&!(n.expiresAt&&Date.parse(n.expiresAt)<Date.now())}verify(e){if(!e||!e.startsWith(ie))return null;let n=lt(e),s=this.load(),r=s.find(a=>a.hash===n);if(!r||r.revokedAt||r.expiresAt&&Date.parse(r.expiresAt)<Date.now())return null;let i=Date.now(),o=r.lastUsedAt?Date.parse(r.lastUsedAt):0;if(i-o>6e4){r.lastUsedAt=new Date(i).toISOString();try{this.save(s)}catch{}}return r}};function gi(t,e){return!!(t.scopes.includes(e)||e.startsWith("agent:")&&t.scopes.includes("agent:*")||e==="dashboard:read"&&t.scopes.includes("dashboard:write"))}function Fn(t){return t==="dashboard:read"||t==="dashboard:write"||t==="agent:*"||/^agent:[a-z0-9][a-z0-9_-]*$/.test(t)||t==="mesh:peer"||t==="app"}function lt(t){return"sha256:"+Ln("sha256").update(t).digest("hex")}function fi(t){let e=t.headers.authorization,n=Array.isArray(e)?e[0]:e;if(n&&n.toLowerCase().startsWith("bearer "))return n.slice(7).trim();if(t.url)try{let r=new URL(t.url,"http://localhost").searchParams.get("token");if(r)return r}catch{}return null}import{existsSync as oe,readdirSync as sr,readFileSync as ir}from"fs";import{resolve as E}from"path";import{existsSync as Bn,mkdirSync as Wn,readdirSync as zn,readFileSync as Hn,renameSync as Kn,writeFileSync as Gn}from"fs";import{resolve as ut}from"path";var ct=["discard","keep","pause","approve"],v={title:120,ask:300,recommend:300,source:500,note:500,pendingPerAgent:25},Xn={defaultExpiryDays:3,maxExpiryDays:30};function T(t){return ut(t,".agentx","approvals")}var qn=/^[a-z0-9][a-z0-9-]{0,80}$/;function dt(t){return qn.test(t)}function gt(t,e){if(!dt(e))throw new Error(`invalid card id: ${e}`);return ut(T(t),`${e}.json`)}function Jn(t,e){let n=new Date(t).toISOString().slice(0,10),s=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return`${n}-${s||"card"}-${Math.random().toString(36).slice(2,6)}`}function W(t,e){Wn(T(t),{recursive:!0});let n=gt(t,e.id),s=`${n}.${process.pid}.tmp`;Gn(s,JSON.stringify(e,null,2)+`
|
|
4
|
-
`),Kn(s,n)}function O(t,e){if(!dt(e))return null;try{return JSON.parse(Hn(gt(t,e),"utf-8"))}catch{return null}}function N(t,e){let n=T(t);if(!Bn(n))return[];let s=[];for(let r of zn(n).filter(i=>i.endsWith(".json")&&!i.startsWith("_")).sort()){let i=O(t,r.slice(0,-5));i&&(!e||i.status===e)&&s.push(i)}return s}function w(t){return typeof t=="string"?t.replace(/\s+/g," ").trim():""}function Yn(t,e,n){let s=e+n.maxExpiryDays*864e5,r,i=w(t);if(!i)r=e+n.defaultExpiryDays*864e5;else{let o=/^(\d+)\s*([hd])$/i.exec(i);if(o)r=e+Number(o[1])*(o[2].toLowerCase()==="d"?864e5:36e5);else if(r=Date.parse(i),Number.isNaN(r))return{ok:!1,error:`expires must be an ISO date or time, or like "12h" / "3d" (got "${i}")`}}return r<=e?{ok:!1,error:"expires must be in the future"}:{ok:!0,at:new Date(Math.min(r,s)).toISOString()}}function Zn(t,e={}){let n=e.now??Date.now(),s=e.settings??Xn,r=w(t.title),i=w(t.ask),o=w(t.recommend),a=w(t.raised_by);if(!r)return{ok:!1,error:"title is required"};if(!i)return{ok:!1,error:"ask is required: the yes/no question"};if(!o)return{ok:!1,error:"recommend is required: your advice and why, in one line"};if(!a)return{ok:!1,error:"raised_by is required: the agent id"};if(r.length>v.title)return{ok:!1,error:`title is longer than ${v.title} characters`};if(i.length>v.ask)return{ok:!1,error:`ask is longer than ${v.ask} characters`};if(o.length>v.recommend)return{ok:!1,error:`recommend is longer than ${v.recommend} characters`};let c=w(t.if_silent).toLowerCase();if(!ct.includes(c))return{ok:!1,error:`if_silent must be one of ${ct.join(", ")}`};let l=Yn(t.expires,n,s);if(!l.ok)return l;let u=w(t.source);if(u.length>v.source)return{ok:!1,error:`source is longer than ${v.source} characters`};if(u&&/^[a-z][a-z0-9+.-]*:/i.test(u)&&!/^https?:\/\//i.test(u))return{ok:!1,error:"source must be an http(s) link or a plain reference"};let d,g=t.reply;return g&&typeof g=="object"&&w(g.channel)&&w(g.chatId)&&(d={channel:w(g.channel),chatId:w(g.chatId),...w(g.accountId)?{accountId:w(g.accountId)}:{}}),{ok:!0,card:{id:Jn(n,r),title:r,ask:i,recommend:o,if_silent:c,expires:l.at,...u?{source:u}:{},raised_by:a,created_at:new Date(n).toISOString(),...d?{reply:d}:{},status:"pending"}}}function yi(t,e,n={}){let s=Zn(e,n);if(!s.ok)return s;let r=N(t,"pending").filter(i=>i.raised_by===s.card.raised_by).length;return r>=v.pendingPerAgent?{ok:!1,error:`${s.card.raised_by} already has ${r} cards waiting; wait for decisions before raising more`}:(W(t,s.card),s)}function ft(t,e,n,s={}){let r=O(t,e);if(!r)return{ok:!1,error:`no card "${e}"`};if(r.status!=="pending")return{ok:!1,error:`card "${e}" is already ${r.status}`};let i=w(s.note).slice(0,v.note),o={...r,status:"decided",verdict:n,decided_by:s.by??"operator",decided_at:new Date(s.now??Date.now()).toISOString(),...i?{note:i}:{}};return W(t,o),{ok:!0,card:o}}function bi(t,e=Date.now()){let n=[];for(let s of N(t,"pending")){if(Date.parse(s.expires)>e)continue;let r={...s,status:"expired",outcome:s.if_silent,decided_by:"expiry",decided_at:new Date(e).toISOString()};W(t,r),n.push(r)}return n}function wi(t){return N(t).filter(e=>e.status!=="pending"&&!e.agent_notified_at)}function ki(t,e,n=Date.now()){let s=O(t,e);!s||s.agent_notified_at||W(t,{...s,agent_notified_at:new Date(n).toISOString()})}function Si(t){let e=t.status==="decided"?t.verdict==="yes"?"The operator said YES.":"The operator said NO.":`Nobody answered before it expired, so the default applied: ${t.outcome??t.if_silent}.`,n=[`[Approval result] Your decision card "${t.title}" (${t.id}) is closed.`,`Question: ${t.ask}`,e];return t.note&&n.push(`Operator note: ${t.note}`),t.source&&n.push(`Source: ${t.source}`),t.reply&&n.push(`You raised it from ${t.reply.channel} chat ${t.reply.chatId}; reply there if the requester should know.`),n.push("Act on this result now. Do not raise the same card again."),n.join(`
|
|
5
|
-
`)}import{mkdirSync as Qn,readFileSync as er,renameSync as tr,writeFileSync as nr}from"fs";import{resolve as rr}from"path";function mt(t){return rr(T(t),"_state.json")}function z(t){try{let e=JSON.parse(er(mt(t),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{}}}catch{return{snoozed:{}}}}function pt(t,e){Qn(T(t),{recursive:!0});let n=mt(t),s=`${n}.${process.pid}.tmp`;nr(s,JSON.stringify(e,null,2)+`
|
|
6
|
-
`),tr(s,n)}function ht(t,e,n,s=Date.now()){let r=z(t),i={};for(let[o,a]of Object.entries(r.snoozed))Date.parse(a)>s&&(i[o]=a);i[e]=n.toISOString(),pt(t,{...r,snoozed:i})}function _i(t,e){pt(t,{...z(t),lastDigest:e})}var yt=["card","schedule","memory","wiki"],or=280;function ae(t,e=or){let n=t.replace(/\s+/g," ").trim();return n.length>e?`${n.slice(0,e-1)}\u2026`:n}function bt(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=>oe(n))??e[0]}function le(t){return t.wikiDir?E(t.wikiDir):E(t.root,".agentx","wiki")}function ar(t){return N(t.root,"pending").map(lr)}function lr(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}}function cr(t){let e=bt(t);if(!oe(e))return[];let n;try{n=JSON.parse(ir(e,"utf-8"))}catch{return[]}let s=new Date(t.now??Date.now()),r=[];for(let[i,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?ze(o.schedule):"",u=o.schedule?`${l.charAt(0).toLowerCase()}${l.slice(1)} (${o.schedule})`:"no schedule",d=String(o.prompt??o.command??""),g=a.action==="create";r.push({key:`schedule:${i}`,kind:"schedule",title:g?`New schedule "${i}" for ${o.agent??"an agent"}`:`Delete schedule "${i}"`,ask:g?`Let ${o.agent??"the agent"} run this ${u}?`:`Remove the schedule "${i}" (${u})?`,yes:g?"enable it":"remove it",no:g?"drop the request":"keep the schedule",raised_by:String(a.requestedBy??"unknown"),created_at:String(a.requestedAt??""),detail:ae(`${d}${g&&o.schedule?` \xB7 first run ${Ke(He(o.schedule,c,s),c)}`:""}`),more:"agentx schedule list"})}return r}function wt(t){let e=E(t,".agentx","memory");return oe(e)?sr(e).filter(n=>n.endsWith(".jsonl")).map(n=>n.slice(0,-6)).sort():[]}function ur(t){let e=wt(t.root);if(e.length===0)return[];let n=new re(t.root),s=[];for(let r of e)for(let i of n.held(r))s.push({key:`memory:${r}/${i.id}`,kind:"memory",title:`Fact ${r} learned from ${i.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:i.createdAt,detail:ae(i.content),more:`agentx memory facts held --agent ${r}`});return s}function dr(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 gr(t){return Je(le(t),"pending").map(e=>{let n=e.evidence;return{key:`wiki:${e.id}`,kind:"wiki",title:e.article.title,ask:e.replaces?`Update "${e.article.path}" in the shared wiki?`:`Add "${e.article.path}" to the shared wiki?`,yes:"write the article",no:"decline it",raised_by:n.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:ae(`${dr(n)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}var kt={card:ar,schedule:cr,memory:ur,wiki:gr};function fr(t,e){let n=t.expires?Date.parse(t.expires):1/0,s=e.expires?Date.parse(e.expires):1/0;return n!==s?n-s:(Date.parse(t.created_at)||0)-(Date.parse(e.created_at)||0)}function Oi(t,e={}){let n=t.now??Date.now(),{snoozed:s}=z(t.root),r=[],i=[],o=0;for(let a of e.kinds??yt){let c;try{c=kt[a](t)}catch(l){i.push({kind:a,error:String(l?.message??l).slice(0,200)});continue}for(let l of c){let u=s[l.key];if(u&&Date.parse(u)>n){if(!e.includeSnoozed){o++;continue}l.snoozed_until=u}r.push(l)}}return r.sort(fr),{items:r,snoozed:o,errors:i}}function mr(t){let e=t.indexOf(":");if(e<=0)return null;let n=t.slice(0,e),s=t.slice(e+1);return!yt.includes(n)||!s?null:{kind:n,ref:s}}function pr(t,e,n){switch(e){case"card":return O(t.root,n)?.status==="pending";case"wiki":return qe(le(t),n)?.status==="pending";default:return kt[e](t).some(s=>s.key===`${e}:${n}`)}}async function Ni(t,e,n,s={}){let r=mr(e);if(!r)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:i,ref:o}=r,a=t.now??Date.now(),c=s.by??"operator";if(n==="later"){if(!pr(t,i,o))return{ok:!1,error:`nothing waiting for "${e}"`};let u=s.laterHours&&s.laterHours>0?s.laterHours:24,d=new Date(a+u*36e5);return ht(t.root,e,d,a),{ok:!0,message:`${e} put off until ${d.toISOString()}`}}let l=n==="yes";switch(i){case"card":{let u=ft(t.root,o,l?"yes":"no",{by:c,note:s.note,now:a});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${l?"yes":"no"}`}:u}case"schedule":{let u=await(l?Ge:Xe)(o,{configPath:bt(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),g=o.slice(u+1);if(!wt(t.root).includes(d))return{ok:!1,error:`no memory for agent "${d}"`};let f=new re(t.root);return f.held(d).some(m=>m.id===g)?(f.review(d,g,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 "${g}" isn't waiting for review`}}case"wiki":{let u=le(t),d=l?Ye(u,o,{by:c,force:s.force,now:a}):Ze(u,o,{by:c,reason:s.note,now:a});return d.ok?{ok:!0,message:l?`${d.proposal.article.path} written to the shared wiki`:`${e} rejected`}:d}}}var St=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function Vi(t){return t==="/api/memory"||t.startsWith("/api/memory/")||t==="/approvals"||t.startsWith("/approvals/")||t==="/events/recent"||/^\/agents\/[^/]+\/events$/.test(t)||t==="/traces"||t.startsWith("/traces/")||t==="/voice/history"||t.startsWith("/voice/history/")||t==="/voice/transcribe"||t==="/voice/speak"}function Ui(t){return t==="/reload"||t==="/api/processes/kill"||t==="/send"||t==="/send/agent"||t==="/send/contact"||t==="/mesh/announce"||t==="/voice/settings"||t==="/voice/preview"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(t)||/^\/crons\/[^/]+\/enabled$/.test(t)}function Fi(t){return St.has(t)}function Bi(t){if(t.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(t.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(St.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 Wi(t,e=process.env){let n=new Set;e.MESH_TOKEN&&n.add(e.MESH_TOKEN);for(let s of t.mesh?.peers||[])s.token&&n.add(s.token);return n}function zi(t,e,n=process.env){let s=i=>i.replace(/\/+$/,"");return(e===s(t.daemonUrl)?t.token:t.daemons.find(i=>s(i.url)===e)?.token)||n.MESH_TOKEN||void 0}function H(t){return(Array.isArray(t)?t[0]:t)?.trim()??""}function hr(t){try{return new URL(t).host.toLowerCase()}catch{return null}}function yr(t=process.env){return new Set((t.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function Ki(t,e=yr()){let n=H(t.origin);if(n){if(e.has(n.replace(/\/+$/,"").toLowerCase()))return"same-origin";let r=hr(n),i=[H(t.host),H(t["x-forwarded-host"])].filter(Boolean).map(o=>o.toLowerCase());return r&&i.includes(r)?"same-origin":"foreign"}let s=H(t["sec-fetch-site"]).toLowerCase();return s==="cross-site"||s==="same-site"?"foreign":"none"}function Gi(t){let e=(t||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{readFileSync as ue,writeFileSync as At,existsSync as de,readdirSync as _r,statSync as Ar}from"fs";import{resolve as ge,join as Rr}from"path";import{existsSync as xt,mkdirSync as br,readFileSync as wr,writeFileSync as $t}from"fs";import{dirname as kr,resolve as vt}from"path";import{z as p}from"zod";var Sr=p.object({type:p.enum(["gitlab","github"]),host:p.string().optional(),project:p.string(),iid:p.number().int().positive(),url:p.string()}),xr=p.object({id:p.string(),title:p.string(),description:p.string().optional(),assignee:p.string().optional(),labels:p.array(p.string()).default([]),milestone:p.string().optional(),status:p.enum(["todo","doing","blocked","done"]).default("todo"),priority:p.number().int().optional(),estimatedSeconds:p.number().int().optional(),source:Sr.optional(),importedAt:p.string().optional(),createdAt:p.string(),updatedAt:p.string(),blocker:p.string().optional(),doneNote:p.string().optional()}),$r=p.object({version:p.literal(1),items:p.array(xr).default([])}),K=class{constructor(e){this.path=e}jsonPath(){return vt(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return vt(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return xt(this.jsonPath())}load(){let e=this.jsonPath();if(!xt(e))return{version:1,items:[]};let n=wr(e,"utf-8");try{return $r.parse(JSON.parse(n))}catch(s){throw new Error(`Backlog file invalid (${e}): ${s.message}`)}}save(e){let n=this.jsonPath();br(kr(n),{recursive:!0}),$t(n,JSON.stringify(e,null,2)+`
|
|
7
|
-
`),$t(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(i=>i.id===e.id))throw new Error(`backlog item ${e.id} already exists`);let s=new Date().toISOString(),r={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??s,updatedAt:s};return n.items.push(r),this.save(n),r}addMany(e){let n=this.load(),s=new Set(n.items.map(o=>o.id)),r=new Date().toISOString(),i=[];for(let o of e){if(s.has(o.id))continue;let a={...o,labels:o.labels??[],status:o.status??"todo",createdAt:o.createdAt??r,updatedAt:r};n.items.push(a),i.push(a),s.add(a.id)}return i.length&&this.save(n),i}update(e,n){let s=this.load(),r=s.items.findIndex(o=>o.id===e);if(r<0)throw new Error(`backlog item ${e} not found`);let i={...s.items[r],...n,id:s.items[r].id,createdAt:s.items[r].createdAt,updatedAt:new Date().toISOString()};return s.items[r]=i,this.save(s),i}remove(e){let n=this.load(),s=n.items.length;return n.items=n.items.filter(r=>r.id!==e),n.items.length===s?!1:(this.save(n),!0)}toMarkdown(e){let n=["# Backlog","","_Generated from `backlog.json`. Do not edit by hand \u2014 use `agentx backlog` commands._",""],s={doing:[],blocked:[],todo:[],done:[]};for(let i of e.items)s[i.status].push(i);let r=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[i,o]of r)if(s[i].length){n.push(`## ${o}`,"");for(let a of s[i]){let c=i==="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(`
|
|
8
|
-
`)}};function Zi(t){return`${t.type}:${t.project}:${t.iid}`}function It(t,e,n){let s=[];if(e.type==="gitlab"){let r=n.channels.gitlab?.agentMappings??[];for(let i of t){let o=r.find(a=>a.agentId===i);o?.gitlabUsernames?.length?s.push(o.gitlabUsernames[0]):s.push(i)}}else if(e.type==="github"){let r=n.channels.github?.agentMappings??[];for(let i of t){let o=r.find(a=>a.agentId===i);o?.githubUsernames?.length?s.push(o.githubUsernames[0]):s.push(i)}}return s}async function ce(t,e,n,s=()=>{}){return t.source?t.source.type==="gitlab"?vr(t.source,e,n,s):t.source.type==="github"?Ir(t.source,e,n,s):{ok:!1,error:`unknown source.type ${t.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function vr(t,e,n,s){let r=n.channels.gitlab,i=r?.token,o=r?.host||(t.host?`https://${t.host}`:void 0);if(!i||!o)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let a=[],c=async(f,m={})=>fetch(`${o}/api/v4${f}`,{...m,headers:{"PRIVATE-TOKEN":i,"Content-Type":"application/json",...m.headers||{}}}),l=encodeURIComponent(t.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async m=>{try{let y=await fetch(`${o}/api/v4/users?username=${encodeURIComponent(m)}`,{headers:{"PRIVATE-TOKEN":i}});if(!y.ok)return null;let b=await y.json();return Array.isArray(b)&&b[0]?.id?b[0].id:null}catch{return null}}))).filter(m=>typeof m=="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 m=await f.json();Array.isArray(m)&&m[0]?.id&&(d=m[0].id)}}catch(f){s(`[backlog-sync] milestone lookup failed: ${f.message}`)}let g={};if(e.title!==void 0&&(g.title=e.title),e.description!==void 0&&(g.description=e.description),e.labels!==void 0&&(g.labels=e.labels.join(",")),e.addLabels?.length&&(g.add_labels=e.addLabels.join(",")),e.removeLabels?.length&&(g.remove_labels=e.removeLabels.join(",")),u!==void 0&&(g.assignee_ids=u),d!==void 0&&(g.milestone_id=d),e.state&&(g.state_event=e.state==="closed"?"close":"reopen"),Object.keys(g).length)try{let f=await c(`/projects/${l}/issues/${t.iid}`,{method:"PUT",body:JSON.stringify(g)});if(a.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let m=await f.text().catch(()=>"");return{ok:!1,attempts:a,error:`PUT issue ${f.status}: ${m.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 Ir(t,e,n,s){let i=n.channels.github?.token;if(!i)return{ok:!1,error:"github token not configured",attempts:[]};let o=[],a=async(g,f={})=>fetch(`https://api.github.com${g}`,{...f,headers:{Authorization:`Bearer ${i}`,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 g=await a(`/repos/${c}/milestones?state=all&per_page=100`);if(g.ok){let f=await g.json(),m=Array.isArray(f)?f.find(y=>y.title===e.milestoneTitle):null;m?.number&&(l=m.number)}}catch(g){s(`[backlog-sync] github milestone lookup failed: ${g.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let g=await a(`/repos/${c}/issues/${t.iid}`);if(g.ok){let f=await g.json(),m=Array.isArray(f.labels)?f.labels.map(b=>typeof b=="string"?b:b.name):[],y=new Set([...m,...e.addLabels??[]]);for(let b of e.removeLabels??[])y.delete(b);u=[...y]}}catch(g){s(`[backlog-sync] github label fetch failed: ${g.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 g=await a(`/repos/${c}/issues/${t.iid}`,{method:"PATCH",body:JSON.stringify(d)});if(o.push({kind:"PATCH issue",ok:g.ok,status:g.status}),!g.ok){let f=await g.text().catch(()=>"");return{ok:!1,attempts:o,error:`PATCH issue ${g.status}: ${f.slice(0,200)}`,url:t.url}}}catch(g){return o.push({kind:"PATCH issue",ok:!1,error:g.message}),{ok:!1,attempts:o,error:g.message,url:t.url}}if(e.note)try{let g=await a(`/repos/${c}/issues/${t.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});o.push({kind:"POST comment",ok:g.ok,status:g.status})}catch(g){o.push({kind:"POST comment",ok:!1,error:g.message})}return{ok:o.every(g=>g.ok),attempts:o,url:t.url}}var fe=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,G=/@([a-z0-9_-]+)/i,_t=/\[time:\s*([0-9hm\s]+)\]/i;function Cr(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 me=class{constructor(e,n,s=()=>{}){this.path=e;this.daemon=n;this.log=s;this.store=new K(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=ge(process.cwd(),this.path);return de(e)?ue(e,"utf-8").split(`
|
|
9
|
-
`):[]}writeMd(e){let n=ge(process.cwd(),this.path);At(n,e.join(`
|
|
10
|
-
`))}async listOpen(e){if(this.store.exists())return this.store.list().filter(i=>i.status!=="done"&&(!i.assignee||i.assignee.toLowerCase()===e.toLowerCase())).map(i=>this.toWorkItem(i));let n=this.readMd(),s=[];for(let r=0;r<n.length;r++){let i=n[r].match(fe);if(!i||i[2].toLowerCase()==="x")continue;let a=i[3],c=a.match(G);if(c&&c[1].toLowerCase()!==e.toLowerCase())continue;let l=a.match(_t),u=a.replace(G,"").replace(_t,"").trim();s.push({id:`backlog:${r}`,title:u||`Task at line ${r+1}`,assignee:c?c[1]:void 0,estimatedSeconds:l?Cr(l[1]):void 0,priority:r})}return s}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 s=this.store.findById(n);if(!s)return;let r=this.store.update(n,{assignee:s.assignee||e,status:"doing"});if(r.source&&this.daemon){let i=It([r.assignee||e],r.source,this.daemon);ce(r,{assigneeUsernames:i,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&&ce(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 s=parseInt(e.slice(8),10),r=this.readMd(),i=r[s];if(!i)throw new Error(`backlog line ${s} missing`);if(!i.match(fe))throw new Error(`backlog line ${s} not a checkbox`);if(n.status==="done"){r[s]=i.replace(/- \[ \]/,"- [x]");let a=n.timeSeconds?` <!-- done by agent, ${Math.round(n.timeSeconds/60)}m -->`:" <!-- done by agent -->";r.splice(s+1,0,a)}else n.status==="blocked"?r.splice(s+1,0,` <!-- BLOCKED: ${n.blocker||n.note||"?"} -->`):n.note&&r.splice(s+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"}}},pe=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(de(e))for(let s of _r(e)){let r=Rr(e,s);Ar(r).isDirectory()?this.walk(r,n):s.endsWith(".md")&&n.push(r)}}async listOpen(e){let n=[];this.walk(ge(process.cwd(),this.root),n);let s=[];for(let r of n){let i=ue(r,"utf-8").split(`
|
|
11
|
-
`);for(let o=0;o<i.length;o++){let a=i[o].match(fe);if(!a||a[2].toLowerCase()==="x")continue;let c=a[3].match(G);!c||c[1].toLowerCase()!==e.toLowerCase()||s.push({id:`wiki:${r}:${o}`,title:a[3].replace(G,"").trim(),assignee:c[1],priority:o})}}return s}async claim(){}async report(e,n){let s=e.split(":"),r=parseInt(s[s.length-1],10),i=s.slice(1,-1).join(":");if(!de(i))return;let o=ue(i,"utf-8").split(`
|
|
12
|
-
`);n.status==="done"&&o[r]&&(o[r]=o[r].replace(/- \[ \]/,"- [x]"),At(i,o.join(`
|
|
13
|
-
`)))}},he=class{constructor(e,n,s,r,i){this.host=e;this.token=n;this.projects=s;this.agentUsernames=r;this.log=i}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[n,s]of Object.entries(this.agentUsernames))if(s.some(r=>r.toLowerCase()===e.toLowerCase()))return n}mapIssue(e,n){let s=e.references?.full?.split("#")[0]||n,r=[],i;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(i=e.labels.map(l=>({name:l.name,color:l.color,text_color:l.text_color})),r=i.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:${s}: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:i,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,n={}){let s=await fetch(`${this.host}/api/v4${e}`,{...n,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...n.headers||{}}});if(!s.ok)throw new Error(`GitLab ${s.status}: ${await s.text().catch(()=>"")}`);return s.json()}async listOpen(e){let n=this.agentUsernames[e]||[];if(!n.length)return[];let s=[],r=this.projects.length?this.projects:["__ALL__"];for(let i of n)for(let o of r)try{let a=`assignee_username=${encodeURIComponent(i)}&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,s.push(d)}}catch(a){this.log(`[business] GitLab listOpen failed for ${i} on ${o}: ${a.message}`)}return s}async claim(e,n){let{project:s,iid:r,type:i}=this.parseId(n),o=`/projects/${encodeURIComponent(s)}/${i==="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:s,iid:r,type:i}=this.parseId(e),o=i==="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(s)}/${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(s)}/${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(s)}/${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(s)}/${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,s=new Date(Date.now()-n*24*36e5).toISOString(),r=new URLSearchParams,i=e.state??"opened";r.set("state",i),r.set("updated_after",s),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 g of d)a.push(this.mapIssue(g,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:s,iid:r,type:i}=this.parseId(e),o=i==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(s)}/${o}/${r}?state_event=${n}`,{method:"PUT"})}async getItem(e){let{project:n,iid:s}=this.parseId(e);try{let r=await this.api(`/projects/${encodeURIComponent(n)}/issues/${s}?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:s,iid:r}=this.parseId(e),i;n.assigneeUsernames&&(i=(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(s)}/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(",")),i!==void 0&&(a.assignee_ids=i),o!==void 0&&(a.milestone_id=o);let c=await this.api(`/projects/${encodeURIComponent(s)}/issues/${r}`,{method:"PUT",body:JSON.stringify(a)});return this.mapIssue(c,s)}async listMembers(){let e=new Map;for(let n of this.projects)try{let s=await this.api(`/projects/${encodeURIComponent(n)}/members/all?per_page=100`);for(let r of s)r.username&&!e.has(r.username)&&e.set(r.username,{username:r.username,name:r.name,avatarUrl:r.avatar_url})}catch(s){this.log(`[board] listMembers failed for ${n}: ${s.message}`)}return[...e.values()].sort((n,s)=>n.username.localeCompare(s.username))}async listMilestones(){let e=new Map;for(let s of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(s)}/milestones?per_page=100`);for(let i of r)i.title&&!e.has(i.title)&&e.set(i.title,{id:i.id,title:i.title,state:i.state,dueDate:i.due_date})}catch(r){this.log(`[board] listMilestones failed for ${s}: ${r.message}`)}let n=[...e.values()];return n.sort((s,r)=>s.state!==r.state?s.state==="active"?-1:1:s.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 s,r=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];r.length&&(s=(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 i;if(e.milestoneTitle)try{let c=await this.api(`/projects/${encodeURIComponent(n)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(i=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(",")};s?.length&&(o.assignee_ids=s),i!==void 0&&(o.milestone_id=i);let a=await this.api(`/projects/${encodeURIComponent(n)}/issues`,{method:"POST",body:JSON.stringify(o)});return this.mapIssue(a,n)}async transition(e,n,s){await this.transitionMany(e,n?[n]:[],s?[s]:[])}async transitionMany(e,n,s){let{project:r,iid:i,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests",c=new URLSearchParams;n.length&&c.set("add_labels",n.join(",")),s.length&&c.set("remove_labels",s.join(",")),c.toString()&&await this.api(`/projects/${encodeURIComponent(r)}/${a}/${i}?${c.toString()}`,{method:"PUT"})}parseId(e){let s=e.replace(/^gitlab:/,"").split(":"),r=s.pop(),i=s.pop()==="mr"?"mr":"issue";return{project:s.join(":"),type:i,iid:r}}};function io(t,e,n){let s=t.workSource;switch(s.type){case"backlog":return new me(s.path,e,n);case"wiki":return new pe(s.path,s.glob);case"gitlab":{let r=e.channels.gitlab;if(!r?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let i={};for(let a of r.agentMappings)a.gitlabUsernames.length&&(i[a.agentId]=a.gitlabUsernames);let o=s.projects.length?s.projects:r.routes.map(a=>a.project);return new he(r.host,r.token,o,i,n)}}}var ye="unmapped";function be(t,e=[]){if(!t)return ye;let n=e.find(r=>r.id===t);if(n?.client)return n.client;let s=t.indexOf("/");return s>0?t.slice(0,s):t}function Tr(t){let e=new Map,n=t.projects??[],s=t.orgChart??{};for(let i of n)i.pm&&(e.has(i.pm)||e.set(i.pm,be(i.id,n)));let r=(i,o=new Set)=>{if(e.has(i))return e.get(i);if(o.has(i))return;o.add(i);let a=s[i]?.reportsTo;if(!a)return;let c=r(a,o);return c&&e.set(i,c),c};for(let i of Object.keys(s))r(i);return e}function Er(t,e,n=[]){if(!n.length)return;let s=n.filter(r=>!r.channel||r.channel===t);return s.find(r=>r.chatId&&e.chatId&&r.chatId===e.chatId)??s.find(r=>r.username&&e.username&&r.username===e.username)??s.find(r=>r.senderId&&e.senderId&&r.senderId===e.senderId)??s.find(r=>r.channel&&!r.chatId&&!r.username&&!r.senderId)}function ao(t,e){let n=Er(t.channel,{chatId:t.chatId,username:t.username},e.contactMap);if(n)return n.client;if(t.project)return be(t.project,e.projects);if(t.agentId){let s=Tr(e).get(t.agentId);if(s)return s}return ye}function lo(t,e){let n=String(t||"").split(":");if(n.length<3)return{agentId:e};let[s,r,...i]=n,o=i.join(":"),a={agentId:e||s,channel:r};return r==="gitlab"||r==="github"?a.project=o.split(":")[0]:r==="cron"||r==="api"||(a.chatId=o.split("@")[0]),a}var Dr=t=>t===ye?"internal":"client";function Lr(t,e){let n=e.clients?.[t];return{id:t,name:n?.name||t,kind:n?.kind??Dr(t),respondWithinMinutes:Pr(n?.respondWithin),standing:n?.standing??[],declared:!!n}}function co(t){let e=new Set;for(let n of t.projects??[])e.add(be(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=>Lr(n,t))}function Pr(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 jr=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n/i,Or=/(^|\n)[ \t]*```[ \t]*agentx:ui[ \t]*\r?\n([\s\S]*?)\r?\n[ \t]*```[ \t]*(?=\n|$)/gi;function Rt(t){if(!t||!t.includes("agentx:ui"))return{cleanText:t};let e=[...t.matchAll(Or)];if(e.length===0)return{cleanText:t};let n=e[e.length-1],s=n[2],r=Nr(s);if(!r)return{cleanText:t};let i=n.index??0,o=n[1]??"";return{cleanText:(t.slice(0,i)+o+t.slice(i+n[0].length)).trim(),ui:r}}function go(t){if(!t||!t.includes("agentx:ui"))return t;let e=jr.exec(t);return e?t.slice(0,e.index).trimEnd():t}function Nr(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 s=[],r=[];for(let i of e.buttons)!i||typeof i.label!="string"||(typeof i.url=="string"&&/^https?:\/\//i.test(i.url)?s.push({label:i.label,url:i.url}):i.action!=null&&r.push(i.label));s.length&&(n.buttons=s),r.length&&(n.skippedActions=r)}if(e.poll&&typeof e.poll=="object"){let s=e.poll.question,r=e.poll.options;typeof s=="string"&&s.trim()&&Array.isArray(r)&&r.filter(i=>typeof i=="string").length>=2&&(n.poll={question:s,options:r.filter(i=>typeof i=="string"),multiple:e.poll.multiple===!0})}if(e.media&&typeof e.media=="object"){let{type:s,url:r,caption:i}=e.media;["image","document","audio","video"].includes(s)&&typeof r=="string"&&r&&(n.media={type:s,url:r,...typeof i=="string"?{caption:i}:{}})}return!n.buttons&&!n.poll&&!n.media&&!n.skippedActions?null:n}import{execFile as Jr,execFileSync as Yr}from"child_process";import{execFileSync as Mr}from"child_process";import{existsSync as Tt,mkdirSync as Vr,readdirSync as Ur,readFileSync as Et,renameSync as Fr,writeFileSync as Br}from"fs";import{homedir as Dt}from"os";import{join as ke}from"path";var Se="siri:",Lt="com.apple.ttsbundle.gryphon-neural_",Pt=t=>!!t&&t.startsWith(Lt),Wr=["/usr/bin/say","/usr/bin/defaults","/usr/bin/plutil"],zr=()=>{try{return Mr("/usr/bin/defaults",["read","com.apple.Accessibility"],{stdio:"ignore",timeout:5e3}),!0}catch{return!1}},we;function xe(t={}){let e=t.platform!==void 0||t.exists!==void 0||t.prefDomain!==void 0;if(!e&&we!==void 0)return we;let{platform:n=process.platform,exists:s=Tt,prefDomain:r=zr}=t,i=n==="darwin"&&Wr.every(o=>s(o))&&r();return e||(we=i),i}var Hr=["/System/Library/AssetsV2/com_apple_MobileAsset_Trial_Siri_SiriTextToSpeech/purpose_auto","/System/Library/AssetsV2/com_apple_MobileAsset_UAF_Siri_TextToSpeech/purpose_auto"],Kr={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"},Gr=/com\.apple\.siri\.tts\.voice\.([a-z]{2})_([A-Z]{2})\.([a-z]+)\.neural\.premium/g;function Xr(t){let e=new Map;for(let n of t)for(let[,s,r,i]of n.matchAll(Gr)){let o=`${s}-${r}`,a=`${Lt}${i}_${o}_premium`;e.has(a)||e.set(a,{id:a,name:i[0].toUpperCase()+i.slice(1),locale:o,quality:"premium",gender:Kr[i]??null,siri:!0})}return[...e.values()]}function X(t=Hr,e={}){if(!xe(e))return[];let n=[];for(let s of t){let r;try{r=Ur(s)}catch{continue}for(let i of r)try{n.push(Et(ke(s,i,"Info.plist"),"latin1"))}catch{}}return Xr(n)}var Ct=`#!/bin/sh
|
|
14
|
-
# Written by agentx; shared by the daemon and AgentX Voice. Do not edit.
|
|
15
|
-
# siri-say.sh [voice] < text speak one line. A Siri voice id switches
|
|
16
|
-
# the OS default for it; any other id is
|
|
17
|
-
# passed to say -v.
|
|
18
|
-
# siri-say.sh --stop silence the line speaking, drop the queue.
|
|
19
|
-
# AGENTX_SAY_RATE=<words a minute> sets the speed; unset, say's own.
|
|
20
|
-
D=com.apple.Accessibility K=SpokenContentDefaultVoiceSelectionsByLanguage
|
|
21
|
-
dir="$HOME/.agentx/voice" lock="$HOME/.agentx/voice/siri.lock" saved="$HOME/.agentx/voice/siri-saved.plist"
|
|
22
|
-
stops="$dir/stop"
|
|
23
|
-
read_s=\${AGENTX_SAY_READ_S:-5} stale_s=\${AGENTX_SAY_STALE_S:-30} max_s=\${AGENTX_SAY_MAX_S:-300}
|
|
24
|
-
if [ "$1" = --stop ]; then
|
|
25
|
-
mkdir -p "$dir" || exit 1
|
|
26
|
-
# Queued lines see this change and drop. The owner's trap stops say,
|
|
27
|
-
# restores the voice, and frees the lock.
|
|
28
|
-
echo "$$ $(date +%s)" > "$stops"
|
|
29
|
-
owner=$(cat "$lock/pid" 2>/dev/null)
|
|
30
|
-
[ -n "$owner" ] && kill "$owner" 2>/dev/null
|
|
31
|
-
exit 0
|
|
32
|
-
fi
|
|
33
|
-
case "$1" in com.apple.ttsbundle.gryphon-neural_*) siri=$1 voice= ;; *) siri= voice=$1 ;; esac
|
|
34
|
-
rate=\${AGENTX_SAY_RATE:-}
|
|
35
|
-
case "$rate" in *[!0-9]*) rate= ;; esac
|
|
36
|
-
case "$siri" in *[!A-Za-z0-9._-]*) echo "bad voice id" >&2; exit 2;; esac
|
|
37
|
-
# Not macOS, or no pref tools: speak as is and never touch a pref.
|
|
38
|
-
if [ "$(uname)" != Darwin ] || ! command -v defaults >/dev/null || ! command -v plutil >/dev/null; then
|
|
39
|
-
if [ -n "$voice" ]; then exec say \${rate:+-r "$rate"} -v "$voice"; else exec say \${rate:+-r "$rate"}; fi
|
|
40
|
-
fi
|
|
41
|
-
mkdir -p "$dir" || exit 1
|
|
42
|
-
mine=$(cat "$stops" 2>/dev/null)
|
|
43
|
-
stopped() { [ "$(cat "$stops" 2>/dev/null)" != "$mine" ]; }
|
|
44
|
-
txt=$(mktemp "\${TMPDIR:-/tmp}/agentx-say.XXXXXX") || exit 1
|
|
45
|
-
say_pid= dog=
|
|
46
|
-
restore() {
|
|
47
|
-
[ -f "$saved" ] || return 0
|
|
48
|
-
if [ -s "$saved" ]; then defaults write $D $K "$(cat "$saved")"; else defaults delete $D $K 2>/dev/null; fi
|
|
49
|
-
rm -f "$saved"
|
|
50
|
-
}
|
|
51
|
-
finish() {
|
|
52
|
-
[ -n "$say_pid" ] && kill "$say_pid" 2>/dev/null
|
|
53
|
-
[ -n "$dog" ] && { pkill -P "$dog" 2>/dev/null; kill "$dog" 2>/dev/null; }
|
|
54
|
-
restore; rm -rf "$lock"; rm -f "$txt"; exit "$1"
|
|
55
|
-
}
|
|
56
|
-
drop() { rm -f "$txt"; exit 75; }
|
|
57
|
-
# The whole text first, before the lock: a writer that never closes stdin
|
|
58
|
-
# must not hold up every other speaker.
|
|
59
|
-
exec 3<&0 0</dev/null
|
|
60
|
-
cat <&3 > "$txt" & cat_pid=$!
|
|
61
|
-
exec 3<&-
|
|
62
|
-
n=0
|
|
63
|
-
while kill -0 "$cat_pid" 2>/dev/null; do
|
|
64
|
-
if [ $n -ge $((read_s * 10)) ]; then
|
|
65
|
-
kill "$cat_pid" 2>/dev/null; echo "stdin never closed; nothing said" >&2; rm -f "$txt"; exit 3
|
|
66
|
-
fi
|
|
67
|
-
sleep 0.1; n=$((n + 1))
|
|
68
|
-
done
|
|
69
|
-
# One speaker at a time. A lock whose owner died is taken over. A line
|
|
70
|
-
# that waits past stale_s, or that a stop overtook, is dropped unsaid.
|
|
71
|
-
n=0
|
|
72
|
-
while ! mkdir "$lock" 2>/dev/null; do
|
|
73
|
-
stopped && drop
|
|
74
|
-
if [ $n -ge $((stale_s * 10)) ]; then echo "waited \${stale_s}s for the speaker; dropped" >&2; drop; fi
|
|
75
|
-
owner=$(cat "$lock/pid" 2>/dev/null)
|
|
76
|
-
if [ -n "$owner" ] && ! kill -0 "$owner" 2>/dev/null; then rm -rf "$lock"
|
|
77
|
-
elif [ -z "$owner" ] && [ -n "$(find "$lock" -maxdepth 0 -mmin +1 2>/dev/null)" ]; then rm -rf "$lock"
|
|
78
|
-
else sleep 0.1; n=$((n + 1)); fi
|
|
79
|
-
done
|
|
80
|
-
echo $$ > "$lock/pid"
|
|
81
|
-
trap 'finish 143' TERM INT HUP
|
|
82
|
-
stopped && finish 75
|
|
83
|
-
restore
|
|
84
|
-
if [ -n "$siri" ]; then
|
|
85
|
-
lang=$(defaults read -g AppleLanguages 2>/dev/null | sed -n '2s/^[^A-Za-z]*\\([A-Za-z]*\\).*/\\1/p')
|
|
86
|
-
defaults export $D - 2>/dev/null | plutil -extract $K xml1 -o "$saved.tmp" - 2>/dev/null || : > "$saved.tmp"
|
|
87
|
-
mv "$saved.tmp" "$saved"
|
|
88
|
-
defaults write $D $K -array "\${lang:-en}" "{ _type = \\"Speech.VoiceSelection\\"; _version = 0; voiceId = \\"$siri\\"; }"
|
|
89
|
-
fi
|
|
90
|
-
# A watchdog: no line runs past its length's worth of speech (a hung say
|
|
91
|
-
# held the lock for minutes), capped at max_s.
|
|
92
|
-
limit=$((5 + $(wc -w < "$txt") * 6 / 10))
|
|
93
|
-
[ $limit -gt $max_s ] && limit=$max_s
|
|
94
|
-
if [ -n "$voice" ]; then say \${rate:+-r "$rate"} -v "$voice" -f "$txt" & else say \${rate:+-r "$rate"} -f "$txt" & fi
|
|
95
|
-
say_pid=$!
|
|
96
|
-
( sleep "$limit"; echo "say ran past \${limit}s; stopped" >&2; kill "$say_pid" 2>/dev/null ) & dog=$!
|
|
97
|
-
wait "$say_pid"
|
|
98
|
-
status=$?
|
|
99
|
-
say_pid=
|
|
100
|
-
finish $status
|
|
101
|
-
`,qr=(t=Dt())=>ke(t,".agentx","voice","siri-say.sh");function jt(t=Dt()){let e=qr(t);return Tt(e)&&Et(e,"utf8")===Ct||(Vr(ke(t,".agentx","voice"),{recursive:!0}),Br(`${e}.tmp`,Ct,{mode:493}),Fr(`${e}.tmp`,e)),e}var Ot=`ObjC.import("AVFoundation")
|
|
102
|
-
const vs = $.AVSpeechSynthesisVoice.speechVoices, out = []
|
|
103
|
-
for (let i = 0; i < vs.count; i++) {
|
|
104
|
-
const v = vs.objectAtIndex(i)
|
|
105
|
-
out.push([v.identifier.js, v.name.js, v.language.js, Number(v.quality), Number(v.gender)].join("\\t"))
|
|
106
|
-
}
|
|
107
|
-
out.join("\\n")`,Zr=new Set(["Fred","Kathy","Ralph","Junior"]),Qr={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 Nt(t){let e=[];for(let n of t.split(`
|
|
108
|
-
`)){let[s,r,i,o,a]=n.split(" ");!s||!r||!i||s.includes(".siri_")||s.startsWith("com.apple.speech.synthesis.voice.")&&!Zr.has(r)||e.push({id:s,name:r,locale:i,quality:o==="3"?"premium":o==="2"?"enhanced":"standard",gender:a==="1"?"male":a==="2"?"female":Qr[r]??null})}return e}var es=10*60*1e3,D=null,$e=!1;function ve(t=Date.now()){if(process.platform!=="darwin")return[];if(D)t-D.at>es&&!$e&&($e=!0,Jr("osascript",["-l","JavaScript","-e",Ot],{timeout:1e4},(e,n)=>{$e=!1,e||(D={at:Date.now(),voices:[...Nt(String(n)),...X()]})}));else try{D={at:t,voices:[...Nt(Yr("osascript",["-l","JavaScript","-e",Ot],{encoding:"utf8",timeout:1e4})),...X()]}}catch(e){Ie(`[voice] could not list system voices: ${String(e?.message??e).split(`
|
|
109
|
-
`)[0]}`),D={at:t,voices:X()}}return D.voices}var Ie=t=>process.stderr.write(t+`
|
|
110
|
-
`),Mt=new Set;function So(t){Ie=t}function L(t,e){Mt.has(t)||(Mt.add(t),Ie(e))}var ts={premium:3,enhanced:2,standard:1},ns=new Set(["Grandma","Grandpa"]);function Vt(t){let e=t.id.startsWith("com.apple.voice.")?2:t.id.startsWith("com.apple.eloquence.")&&!ns.has(t.name)?1:0;return ts[t.quality]*10+e}var Ut=t=>t.toLowerCase().split(/[-_]/)[0];function q(t,e="en"){let n=e.toLowerCase().replace("_","-"),s=Ut(e),r=t.filter(i=>Ut(i.locale)===s);return(r.length?r:t).slice().sort((i,o)=>Vt(o)-Vt(i)||+(o.locale.toLowerCase()===n)-+(i.locale.toLowerCase()===n)||i.name.localeCompare(o.name)||i.locale.localeCompare(o.locale))}function _e(t,e,n="en"){let s=t.trim();if(!s)return null;let r=e.find(l=>l.id===s);if(r)return r;if(s.toLowerCase().startsWith(Se)){let l=s.slice(Se.length).trim().toLowerCase(),u=q(e.filter(g=>g.siri&&g.name.toLowerCase()===l),n)[0];if(u||!l)return u??null;let d=_e(l,e,n);return d&&L(`siri:${l}`,`[voice] Siri voice "${l}" is not installed; speaking with ${d.name} (${d.locale}) instead.`),d}e=e.filter(l=>!l.siri);let i=/^(.+?)\s*\((premium|enhanced)\)$/i.exec(s),o=(i?i[1]:s.replace(/\s*\(.*\)\s*$/,"")).trim().toLowerCase(),a=q(e.filter(l=>l.name.toLowerCase()===o),n);return(i?a.find(l=>l.quality===i[2].toLowerCase()):void 0)??a[0]??null}function Ft(t,e,n=new Set){let s=new Map;if(!e.length)return s;let r=new Set([...n].map(o=>o.toLowerCase())),i="female";for(let o of t){let a=o.gender==="female"||o.gender==="male",c=a?o.gender:i,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[s.size%e.length];s.set(o.id,u),r.add(u.name.toLowerCase()),a||(i=i==="female"?"male":"female")}return s}import{spawn as Y}from"child_process";import{readFileSync as os,writeFileSync as as}from"fs";import{tmpdir as ls}from"os";import{join as cs}from"path";var rs=new Set("the and is are was were i you he she we they it this that to of in for with not but yes what have has will would can your my".split(" ")),ss=new Set("le la les des du de un une et est sont je tu il elle nous vous ils elles ce cette c'est pas pour que qui avec dans sur au aux mais tr\xE8s oui non merci bonjour votre mon".split(" ")),is=/[éèêëàâçùûîïôœ]/;function J(t){let e=(t.match(/[-ۿ]/g)??[]).length,n=(t.match(/[a-zA-ZÀ-ÿ]/g)??[]).length;if(e&&e>=n)return"ar";let s=0,r=0;for(let i of t.toLowerCase().replace(/[’]/g,"'").match(/[a-zà-ÿœ']+/g)??[])rs.has(i)&&s++,ss.has(i)||i.startsWith("l'")||i.startsWith("d'")||i.startsWith("qu'")?r++:is.test(i)&&(r+=.5);return s===r?null:s>r?"en":"fr"}var Bt=t=>t&&t!==1?Math.round(175*t):null,Z=t=>t&&t!==1?Math.min(1.2,Math.max(.7,t)):null;function us(){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=os(t,"utf8").trim();if(e)return e}catch{}return null}function Eo(t=us()){let e=0;return async(n,s)=>{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",...Z(n.voice.rate)?{voice_settings:{speed:Z(n.voice.rate)}}:{}}),signal:s});if(!r.ok)throw new Error(`ElevenLabs ${r.status}: ${(await r.text()).slice(0,160)}`);let i=cs(ls(),`agentx-say-${process.pid}-${++e}.mp3`);return as(i,Buffer.from(await r.arrayBuffer())),i}catch(r){if(s.aborted||!n.voice.fallback)throw r;return L(`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 Wt(t,e){let n=t.languages&&J(e);return n&&t.languages&&n in t.languages?t.languages[n]:t.system}var ds=(t,e="")=>{let n=Wt(t,e),s=Bt(t.rate);return[...n&&!Pt(n)?["-v",n]:[],...s?["-r",String(s)]:[]]};function gs(t,e,n){if(!n)return["say",ds(t,e)];let s=Wt(t,e);return["/bin/sh",[n,...s?[s]:[]]]}function Do(t){let e=t.split(/\s+/).filter(Boolean).length;return Math.min(300,5+Math.floor(e*6/10))*1e3}function Lo(t=zt()){if(t)try{Y("/bin/sh",[t,"--stop"],{stdio:"ignore"}).on("error",()=>{})}catch{}}function zt(t={},e){if(!xe(t))return null;try{return jt(e)}catch(n){return L("siri-say",`[voice] could not write the Siri voice script (${String(n?.message??n).split(`
|
|
111
|
-
`)[0]}); Siri voices will not switch`),null}}var Po=(t,e)=>{if(!t){let[n,s]=gs(e.voice,e.text,zt()),r=Bt(e.voice.rate),i=r?{...process.env,AGENTX_SAY_RATE:String(r)}:process.env,o=Y(n,s,{stdio:["pipe","ignore","ignore"],env:i});return o.stdin?.on("error",()=>{}),o.stdin?.end(e.text),o}return process.platform==="darwin"?Y("afplay",[t],{stdio:"ignore"}):Y("mpg123",["-q",t],{stdio:"ignore"})};import{spawn as Ht}from"child_process";import{accessSync as fs,constants as ms,readFileSync as Kt}from"fs";import{homedir as ps}from"os";import{basename as P,delimiter as Gt,dirname as hs,extname as ys,join as Ae}from"path";var R={ms:2*60*1e3,bitsPerSecond:64e3,bytes:2*1024*1024};function Xt(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)>R.ms+2e3?{status:413,error:Ce()}:null}var Ce=()=>`The recording is longer than ${R.ms/6e4} minutes.`,bs={"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 qt(t){let e=String(t||"").split(";")[0].trim().toLowerCase();return bs[e]??null}function Jt(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 Te(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 Re(t,e,n=process.env.PATH??""){let s=ps(),r=[Ae(s,".local","bin"),"/opt/homebrew/bin","/usr/local/bin",...n.split(Gt).filter(Boolean)];for(let i of[e,...r.map(o=>Ae(o,t))])if(i)try{return fs(i,ms.X_OK),i}catch{}return null}function Uo(t){return{key:t,mlx:Re("mlx_whisper",process.env.AGENTX_MLX_WHISPER),whisper:Re("whisper",process.env.AGENTX_WHISPER),ffmpeg:ws()}}var ws=()=>Re("ffmpeg",process.env.AGENTX_FFMPEG);async function Yt(t,e){return e?ks(t,e):null}async function ks(t,e){let n=String(R.ms/1e3+5);try{let r=[...(await Ss(e,["-nostdin","-hide_banner","-t",n,"-i",t,"-f","null","-"],3e4)).matchAll(/time=(\d+):(\d+):(\d+(?:\.\d+)?)/g)],i=r[r.length-1];return i?Number(i[1])*3600+Number(i[2])*60+Number(i[3]):null}catch{return null}}async function Zt(t,e,n,s){let r=new FormData;r.set("model_id",process.env.AGENTX_STT_MODEL||"scribe_v1"),r.set("file",new Blob([Kt(t)],{type:e}),P(t));let i=await fetch("https://api.elevenlabs.io/v1/speech-to-text",{method:"POST",headers:{"xi-api-key":n},body:r,signal:s??AbortSignal.timeout(6e4)});if(!i.ok)throw new Error(`ElevenLabs ${i.status}: ${(await i.text().catch(()=>"")).slice(0,160)}`);let o=await i.json();if(typeof o.text!="string")throw new Error("ElevenLabs returned no text");return o.text.trim()}async function Qt(t,e,n,s,r){let i=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:`${hs(s)}${Gt}${process.env.PATH??""}`};await xs(e,i,12e4,o);try{return Kt(Ae(r,P(n,ys(n))+".txt"),"utf8").trim()}catch{throw new Error(`${t} wrote no transcript`)}}function Ss(t,e,n){return new Promise((s,r)=>{let i=Ht(t,e,{stdio:["ignore","ignore","pipe"]}),o="",a=setTimeout(()=>{i.kill("SIGKILL"),r(new Error(`${P(t)} took too long`))},n);i.stderr.on("data",c=>{o=(o+c).slice(-8192)}),i.on("error",c=>{clearTimeout(a),r(c)}),i.on("exit",c=>{clearTimeout(a),c===0?s(o):r(new Error(`${P(t)} exited ${c}`))})})}function xs(t,e,n,s=process.env){return new Promise((r,i)=>{let o=Ht(t,e,{stdio:["ignore","pipe","pipe"],env:s}),a="",c="",l=setTimeout(()=>{o.kill("SIGKILL"),i(new Error(`${P(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),i(u)}),o.on("exit",u=>{clearTimeout(l),u===0?r(a):i(new Error(`${P(t)} exited ${u}: ${c.trim().split(`
|
|
112
|
-
`).pop()?.slice(0,160)??""}`))})})}function en(t,e=800){let n=t;return n=n.replace(/```[\s\S]*?```/g,". "),n=n.replace(/`[^`]*`/g,""),n=n.replace(/\*\*(.*?)\*\*/g,"$1"),n=n.replace(/__(.*?)__/g,"$1"),n=n.replace(/\*([^*]+)\*/g,"$1"),n=n.replace(/_([^_]+)_/g,"$1"),n=n.replace(/~~(.*?)~~/g,"$1"),n=n.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1"),n=n.replace(/!\[([^\]]*)\]\([^)]+\)/g,"image$1 "),n=n.replace(/^#{1,6}\s+/gm,""),n=n.replace(/^[\s]*[-*+]\s+/gm,". "),n=n.replace(/^[\s]*\d+\.\s+/gm,". "),n=n.replace(/^[-=_]{3,}$/gm,""),n=n.replace(/^>\s*/gm,""),n=n.replace(/https?:\/\/\S+/g,"link"),n=n.replace(/\/\w+(\/\w+)+/g,s=>s.split("/").filter(Boolean).join(" slash ")),n=n.replace(/&/g," and "),n=n.replace(/@/g," at "),n=n.replace(/=>/g," returns "),n=n.replace(/->/g," to "),n=n.replace(/\|/g," or "),n=n.replace(/\be\.g\./gi,"for example"),n=n.replace(/\bi\.e\./gi,"that is"),n=n.replace(/\betc\./gi,"etcetera"),n=n.replace(/\bvs\.?\b/gi,"versus"),n=n.replace(/\n{2,}/g,". "),n=n.replace(/\n/g," "),n=n.replace(/\s+/g," "),n=n.replace(/\.\s*\./g,"."),n=n.replace(/\s+([.,!?])/g,"$1"),n=n.trim().replace(/^[.,:;]+\s*/,""),n.length>e&&(n=n.slice(0,e).replace(/\s+\S*$/,"")+"..."),n}var $s="system",vs=t=>t.trim().toLowerCase()===$s,Is="21m00Tcm4TlvDq8ikWAM";function De(t,e,n={},s=ve()){let r=e[t],i=r?.name||t,o=r?.voice,a=Cs(e,n,s).get(t)??null,c=Rs(t,o?.system,o?.gender,n,s);return{agentId:t,name:i,provider:o?.provider??n.provider??"system",elevenlabsVoiceId:o?.elevenlabsVoiceId||null,systemVoice:a?.id??null,systemVoiceName:a?sn(a):null,systemByLanguage:c,fallback:(n.fallback??"system")==="system",gender:o?.gender??null,style:o?.style||null,intro:o?.intro||Es(i,r?.systemPrompt),...o?.rate?{rate:o.rate}:{},...o?.priority?{priority:o.priority}:{}}}var sn=t=>`${t.name}${t.siri?" (Siri)":t.quality==="standard"?"":` (${t.quality[0].toUpperCase()}${t.quality.slice(1)})`} ${t.locale}`;function _s(t,e,n,s){if(!e||!n.length)return null;let r=_e(e,n,s);return r||L(`${t}:${e}`,`[voice] ${t}: system voice "${e}" is not installed; using the next choice. Run \`agentx voice list\` to see installed voices.`),r}var on=t=>t.toLowerCase().split(/[-_]/)[0],tn=(t,e)=>typeof t=="string"?t:t?.[on(e)];function Ee(t,e,n,s){if(e!==void 0)return vs(e)?null:_s(t,e,n,s)??void 0}var an=(t,e)=>!t||!t.gender||t.gender==="neutral"||!e||e==="neutral"||t.gender===e;function As(t,e,n,s=new Set){let r=e.locale??"en",i=new Map,o=[],a=Ee("voice.system",tn(e.system,r),n,r);for(let l of t){let u=Ee(l.id,tn(l.system,r),n,r),d=u!==void 0?u:a!==void 0&&an(a,l.gender)?a:void 0;d!==void 0?i.set(l.id,d):o.push({id:l.id,gender:l.gender??null})}let c=new Set([...s,...[...i.values()].flatMap(l=>l?[l.name]:[])]);for(let[l,u]of Ft(o,q(n.filter(d=>!d.siri),r),c))i.set(l,u);return i}function Rs(t,e,n,s,r){if(typeof e=="string")return{};let i={},o=(a,c,l)=>{if(!(!c||typeof c=="string"))for(let[u,d]of Object.entries(c)){let g=Ee(`${a}.${u}`,d,r,u);g!==void 0&&l(g)&&(i[on(u)]=g)}};return o("voice.system",s.system,a=>an(a,n)),o(t,e,()=>!0),i}function Ho(t,e){let n=e?J(e):null;if(!n||!(n in t.systemByLanguage))return t;let s=t.systemByLanguage[n];return{...t,systemVoice:s?.id??null,systemVoiceName:s?sn(s):null}}function Cs(t,e={},n=ve()){let s=Object.entries(t).map(([r,i])=>({id:r,system:i.voice?.system,gender:i.voice?.gender}));return As(s,e,n)}function Le(t,e){let n={provider:t.provider,elevenlabs:Ts(e,t.elevenlabsVoiceId),system:t.systemVoice,fallback:t.fallback},s=Object.entries(t.systemByLanguage??{});return s.length&&(n.languages=Object.fromEntries(s.map(([r,i])=>[r,i?.id??null]))),t.rate&&t.rate!==1&&(n.rate=t.rate),t.priority&&t.priority!=="normal"&&(n.priority=t.priority),n}function Ts(t,e){return t||e||process.env.AGENTX_VOICE_ID||Is}function Es(t,e){let n=(e??"").split(/(?<=\.)\s/)[0]??"",s=/^You are (.+?)\.?$/i.exec(n.trim());if(!s)return`Hello, this is ${t}.`;let r=s[1].replace(/\s*\([^)]*\)/g,"").trim(),[i,...o]=r.split(/,\s*/),a=o.join(", ");return a&&i.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 Ds=8*60*60*1e3,Ls=500,nn=class{constructor(e=Ds){this.gapMs=e}lastSpoke=new Map;needsIntro(e,n,s=Date.now()){let r=this.lastSpoke.get(rn(e,n));return r===void 0||s-r>this.gapMs}spoke(e,n,s=Date.now()){let r=rn(e,n);this.lastSpoke.delete(r),this.lastSpoke.set(r,s),this.lastSpoke.size>Ls&&this.lastSpoke.delete(this.lastSpoke.keys().next().value)}},rn=(t,e)=>`${t}\0${e}`;function ln(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 Ko(t,e,n,s={}){let r=e[t],i=De(t,e,s),o=(r?.systemPrompt??"").split(/\n\s*\n/)[0].slice(0,600).trim();return{agentId:t,name:i.name,voice:Le(i),persona:o||`You are ${i.name}.`,introLine:ln(i,n)}}var Ps="[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 Go(t){let e=t;if(e?.channel!=="voice"||!e.voice||typeof e.voice!="object")return;let n=i=>typeof i=="string"?i.replace(/\s+/g," ").slice(0,200):"",s=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:s||"Hello."};return`${Ps}
|
|
113
|
-
${ln(r,e.voice.introduce===!0&&!!s)}`}import{mkdtemp as js,rm as Os,writeFile as Ns}from"fs/promises";import{tmpdir as Ms}from"os";import{join as cn}from"path";var Vs=1500,Us=64*1024,Fs=2,Pe=0;function ra(t){return t==="/voice/transcribe"||t==="/voice/speak"}async function sa(t,e,n,s){return t.method!=="POST"?h(e,405,{error:"POST"}):n==="/voice/transcribe"?Bs(t,e,s):Hs(t,e,s)}async function Bs(t,e,n){let s=String(t.headers["content-type"]||""),r=qt(s);if(!r)return h(e,415,{error:"Send the recording as audio (webm, mp4, ogg, mp3 or wav)."});let i=Xt(t.headers["x-audio-duration-ms"]);if(i)return t.resume(),h(e,i.status,{error:i.error});let o=await un(t,R.bytes);if(!o)return h(e,413,{error:Xs()});if(!o.length)return h(e,400,{error:"The recording is empty."});if(Pe>=Fs)return h(e,429,{error:"This computer is already writing down other recordings. Try again in a moment."});let a=n.stt(),c=n.host(),l=Jt(a,c);if(!c.ffmpeg&&!n.allowUnmeasured?.()){let d=n.nodeName?`on ${n.nodeName}`:"on this computer",g=l.length?"":" "+Te(a,c);return h(e,503,{error:"Voice input isn't set up on this computer.",hint:`Install ffmpeg ${d} for voice input from the phone.${g}`,setup:!1})}if(!l.length)return h(e,503,{error:"Voice input isn't set up on this computer.",hint:Te(a,c),setup:!1});Pe++;let u;try{let d=await js(cn(Ms(),"agentx-phone-voice-"));try{u=await Ws(d,`speech.${r}`,o,s,c,l,n)}finally{await Os(d,{recursive:!0,force:!0}).catch(()=>{})}}finally{Pe--}h(e,u[0],u[1])}async function Ws(t,e,n,s,r,i,o){let a=cn(t,e);if(await Ns(a,n,{mode:384}),r.ffmpeg){let l=await(o.measure??Yt)(a,r.ffmpeg);if(l==null)return[422,{error:"This computer couldn't read the recording. Try again."}];if(l*1e3>R.ms+2e3)return[413,{error:Ce()}]}let c=[];for(let l of i)try{let u=await zs(l,a,s,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(`
|
|
114
|
-
`)[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 zs(t,e,n,s,r,i){let o=i.engines?.[t];if(o)return o(e,n,s,r);if(t==="elevenlabs")return Zt(e,n,s.key);let a=t==="mlx-whisper"?s.mlx:s.whisper;return Qt(t,a,e,s.ffmpeg,r)}async function Hs(t,e,n){let s=await un(t,Us);if(!s)return h(e,413,{error:"request too large"});let r;try{r=JSON.parse(s.toString("utf8")||"{}")}catch{return h(e,400,{error:"expected JSON"})}let i=typeof r?.agent=="string"?r.agent:"",o=typeof r?.peer=="string"&&r.peer?r.peer:void 0;if(!i)return h(e,400,{error:"agent is required"});let a=Ks(typeof r?.text=="string"?r.text:"");if(!a)return h(e,422,{error:"Nothing in this answer can be said aloud."});let c=n.voiceOf(i,o);if(!c)return h(e,404,{error:`Unknown agent: ${i}`});let l=(d,g=200)=>h(e,g,{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??Gs)(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(`
|
|
115
|
-
`)[0].slice(0,160)}`),l("ElevenLabs could not speak this answer.",502)}}function Ks(t){return en(Rt(t).cleanText,Vs)}async function Gs(t,e,n){let s=Z(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",...s?{voice_settings:{speed:s}}:{}}),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 Xs=()=>`The recording is larger than ${R.bytes/1024/1024} MB, more than ${R.ms/6e4} minutes of speech.`;function ia(t,e,n,s){if(e)return s.speakerOn(e,t,!1)?.voice??null;let r=n.agents??{};return r[t]?Le(De(t,r,n.voice)):null}function un(t,e){return Number(t.headers["content-length"])>e?(t.resume(),Promise.resolve(null)):new Promise((n,s)=>{let r=[],i=0;t.on("data",o=>{if(!(i>e)){if(i+=o.length,i>e){r.length=0,n(null);return}r.push(o)}}),t.on("end",()=>{i<=e&&n(Buffer.concat(r))}),t.on("error",s)})}function h(t,e,n){t.writeHead(e,{"Content-Type":"application/json","Cache-Control":"no-store"}),t.end(JSON.stringify(n))}import{existsSync as x,readFileSync as Me,writeFileSync as Ve,mkdirSync as Q,readdirSync as Ne,rmSync as qs,statSync as I}from"fs";import{resolve as dn,relative as Js,dirname as Ue,join as C,extname as M,basename as Fe}from"path";var S=200*1024,gn=new Set([".md",".markdown",".txt"]),j=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"]),Ys=6,Zs=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function A(t,e){if(!t)throw new Error("Agent workspace is not configured.");let n=dn(t);if(x(n)||Q(n,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let s=dn(n,e);if(Js(n,s).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return s}function fn(t){let e=M(t).toLowerCase();if(!gn.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function je(t,e){let n=t.split(/\r?\n/).find(s=>s.trim().startsWith("#"));return n&&n.replace(/^#+\s*/,"").trim().slice(0,120)||e}function ca(t){let e=A(t,"."),n=[],s=new Set,r=[];try{r=Ne(e)}catch{}for(let a of Zs){let c=C(e,a);if(x(c)&&I(c).isFile()){let l=I(c).size,u=l>0&&l<S?Oe(c):"";n.push({path:a,title:je(u,a),size:l,exists:!0}),s.add(a)}else n.push({path:a,title:a,size:0,exists:!1}),s.add(a)}for(let a of r){if(s.has(a))continue;let c=C(e,a);try{let l=I(c);if(!l.isFile()||!gn.has(M(a).toLowerCase()))continue;let u=l.size>0&&l.size<S?Oe(c):"";n.push({path:a,title:je(u,a),size:l.size,exists:!0})}catch{}}let i=[],o=C(e,".claude","skills");if(x(o))try{for(let a of Ne(o)){let c=C(o,a),l;try{l=I(c)}catch{continue}if(!l.isDirectory())continue;let u=C(c,"SKILL.md");if(!x(u))continue;let d=I(u),g=d.size<S?Oe(u):"";i.push({slug:a,title:je(g,a),size:d.size,path:`.claude/skills/${a}/SKILL.md`})}}catch{}return i.sort((a,c)=>a.slug.localeCompare(c.slug)),{identity:n,skills:i,workspace:e}}function Oe(t){try{return Me(t,"utf-8")}catch{return""}}function ua(t,e){let n=A(t,e);if(fn(n),!x(n))return{path:e,content:""};if(I(n).size>S)throw new Error(`File is too large to edit in the admin panel (> ${S/1024} KB).`);return{path:e,content:Me(n,"utf-8")}}function da(t,e,n){let s=A(t,e);fn(s);let r=Buffer.from(n,"utf-8");if(r.length>S)throw new Error(`File too large (${r.length} > ${S} bytes).`);return Q(Ue(s),{recursive:!0}),Ve(s,r),{path:e,bytes:r.length}}function ga(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 s=`.claude/skills/${e}/SKILL.md`,r=A(t,s);if(x(r))throw new Error(`Skill "${e}" already exists.`);Q(Ue(r),{recursive:!0});let i=n.content?.trim()?n.content:Qs(e,n.title);return Ve(r,i),{slug:e,path:s}}function fa(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=A(t,`.claude/skills/${e}`);if(!x(n))throw new Error(`Skill "${e}" not found.`);if(!I(n).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return qs(n,{recursive:!0,force:!0}),{slug:e}}function ma(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=A(t,`.claude/skills/${e}`);if(!x(n))throw new Error(`Skill "${e}" not found.`);let s=[];return r(n,"",0,s),s.sort((i,o)=>i.kind!==o.kind?i.kind==="dir"?-1:1:i.path.localeCompare(o.path)),s;function r(i,o,a,c){if(a>Ys)return;let l=[];try{l=Ne(i)}catch{return}for(let u of l){if(u==="node_modules"||u===".git")continue;let d=C(i,u),g=o?`${o}/${u}`:u,f;try{f=I(d)}catch{continue}if(f.isDirectory())c.push({path:`${g}/`,kind:"dir",size:0,editable:!1}),r(d,g,a+1,c);else if(f.isFile()){let m=M(u).toLowerCase(),y=j.has(m)||j.has(u.toLowerCase());c.push({path:g,kind:"file",size:f.size,editable:y&&f.size<S})}}}}function pa(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 s=A(t,`.claude/skills/${e}/${n}`);if(!x(s)||!I(s).isFile())throw new Error(`File not found: ${n}`);let r=M(s).toLowerCase(),i=Fe(s).toLowerCase();if(!j.has(r)&&!j.has(i))throw new Error(`File type not editable: ${n}`);if(I(s).size>S)throw new Error(`File too large to edit (> ${S/1024} KB): ${n}`);return{path:n,content:Me(s,"utf-8")}}function ha(t,e,n,s){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=A(t,`.claude/skills/${e}/${n}`),i=M(r).toLowerCase(),o=Fe(r).toLowerCase();if(!j.has(i)&&!j.has(o))throw new Error(`File type not editable: ${n}`);let a=Buffer.from(s,"utf-8");if(a.length>S)throw new Error(`File too large (${a.length} > ${S} bytes).`);return Q(Ue(r),{recursive:!0}),Ve(r,a),{path:n,bytes:a.length}}function ya(t,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let n=A(t,`.claude/skills/${e}`);if(!x(n))throw new Error(`Skill "${e}" not found.`);let s=r=>x(C(n,r));return s("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:s("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:s("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:s("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:s("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function Qs(t,e){return`# ${e?.trim()||t}
|
|
116
|
-
|
|
117
|
-
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.
|
|
118
|
-
|
|
119
|
-
## When to use
|
|
120
|
-
- Trigger condition 1
|
|
121
|
-
- Trigger condition 2
|
|
122
|
-
|
|
123
|
-
## How to use
|
|
124
|
-
Document the arguments, commands, or files the skill expects. Example:
|
|
125
|
-
|
|
126
|
-
\`\`\`bash
|
|
127
|
-
# Example invocation
|
|
128
|
-
claude-code ${Fe(t)} --arg value
|
|
129
|
-
\`\`\`
|
|
130
|
-
`}bn();var mn={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function pn(t){return{...mn,...t??{},regions:{...t?.regions??{}},buffer:{...mn.buffer,...t?.buffer??{}}}}function ka(t){try{return pn(Be(t).screen)}catch{return pn(void 0)}}var ei=/^[a-z][\w-]*$/,hn=["window","screen","menubar","notifications"];function V(t,e,n,s){let r=Number(t);if(t===""||t===null||!Number.isFinite(r)||!n(r))throw new Error(`${e} must be ${s}`);return r}var ee=(t,e)=>V(t,e,n=>Number.isInteger(n)&&n>0,"a whole number above 0");function yn(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 Sa(t,e){let n={...t??{}};if("maxPixels"in e&&(n.maxPixels=ee(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(n.timeoutMs=ee(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(n.intervalMs=ee(e.intervalMs,"intervalMs")),"stableMs"in e&&(n.stableMs=V(e.stableMs,"stableMs",r=>Number.isInteger(r)&&r>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(n.changeThreshold=V(e.changeThreshold,"changeThreshold",r=>r>=0&&r<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let r={...n.regions??{}};for(let[i,o]of Object.entries(e.regions)){if(!ei.test(i))throw new Error(`region name "${i}" must be lowercase letters, digits, - or _`);o===null?delete r[i]:r[i]=yn(o)}n.regions=r}if(e.buffer&&typeof e.buffer=="object"){let r=e.buffer,i={...n.buffer??{}};"enabled"in r&&(i.enabled=!!r.enabled),"seconds"in r&&(i.seconds=V(r.seconds,"buffer.seconds",o=>o>0&&o<=120,"above 0 and at most 120")),"fps"in r&&(i.fps=V(r.fps,"buffer.fps",o=>o>0&&o<=10,"above 0 and at most 10")),"maxPixels"in r&&(i.maxPixels=ee(r.maxPixels,"buffer.maxPixels")),"region"in r&&(i.region=String(r.region).trim()),n.buffer=i}let s=n.buffer?.region;if(s!==void 0&&!hn.includes(s)&&!n.regions?.[s])try{yn(s)}catch{throw new Error(`buffer.region "${s}" is not a region \u2014 use ${[...hn,...Object.keys(n.regions??{})].join(", ")}, or x,y,w,h`)}return n}export{Qe as a,ri as b,be as c,Tr as d,Er as e,ao as f,lo as g,co as h,Rt as i,go as j,k,ai as l,at as m,gi as n,lt as o,fi as p,ct as q,dt as r,O as s,yi as t,bi as u,wi as v,ki as w,Si as x,z as y,_i as z,Oi as A,Ni as B,Vi as C,Ui as D,Fi as E,Bi as F,Wi as G,zi as H,Ki as I,Gi as J,ve as K,So as L,q as M,_e as N,us as O,Eo as P,Do as Q,Lo as R,zt as S,Po as T,R as U,Xt as V,qt as W,Uo as X,ws as Y,en as Z,$s as _,De as $,sn as aa,As as ba,Rs as ca,Ho as da,Cs as ea,Le as fa,Ts as ga,Es as ha,nn as ia,ln as ja,Ko as ka,Ps as la,Go as ma,ra as na,sa as oa,Xs as pa,ia as qa,un as ra,K as sa,Zi as ta,It as ua,ce as va,he as wa,io as xa,ca as ya,ua as za,da as Aa,ga as Ba,fa as Ca,ma as Da,pa as Ea,ha as Fa,ya as Ga,mn as Ha,pn as Ia,ka as Ja,hn as Ka,Sa as La};
|
|
131
|
-
//# sourceMappingURL=chunk-5UYXEO3I.js.map
|