agentix-cli 0.48.0 → 0.50.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/README.md +17 -0
- package/apps/mac-voice/Sources/AgentXVoice/AgentClient.swift +17 -5
- package/apps/mac-voice/Sources/AgentXVoice/Config.swift +6 -1
- package/apps/mac-voice/Sources/AgentXVoice/main.swift +5 -2
- package/dist/{App-EXB4HP3B.js → App-KE4SURSS.js} +2 -2
- package/dist/{ChatApp-XMNE3SPH.js → ChatApp-NNHIKXO2.js} +2 -2
- package/dist/{agent-ORYXXL5K.js → agent-RY7Z3IYY.js} +2 -2
- package/dist/{board-dashboard-2B3HYIXD.js → board-dashboard-RUOASCSQ.js} +6 -6
- package/dist/board-dashboard-RUOASCSQ.js.map +1 -0
- package/dist/{chunk-DLKRPK5M.js → chunk-4BNQSUWV.js} +7 -2
- package/dist/{chunk-DLKRPK5M.js.map → chunk-4BNQSUWV.js.map} +1 -1
- package/dist/{chunk-26OP3X5B.js → chunk-4NBWF4TL.js} +2 -2
- package/dist/{chunk-P7MR53U7.js → chunk-4TITGMPX.js} +2 -2
- package/dist/{chunk-XM7ZQW4F.js → chunk-5ALS7SVV.js} +2 -2
- package/dist/{chunk-3ZHMIWSV.js → chunk-5XQCGPQJ.js} +2 -2
- package/dist/{chunk-DVNIFP7S.js → chunk-6VKCUMCN.js} +2 -2
- package/dist/{chunk-GCHUE3TN.js → chunk-7WDJW37G.js} +2 -2
- package/dist/{chunk-FRHSQVFN.js → chunk-AQASR6KR.js} +3 -3
- package/dist/chunk-AQASR6KR.js.map +1 -0
- package/dist/{chunk-M5R3PWW5.js → chunk-B5XHX44Y.js} +2 -2
- package/dist/{chunk-4ZX4E7P3.js → chunk-BYD55JXH.js} +8 -8
- package/dist/chunk-BYD55JXH.js.map +1 -0
- package/dist/{chunk-DIV66W3N.js → chunk-EMI3VJLH.js} +10 -10
- package/dist/chunk-EMI3VJLH.js.map +1 -0
- package/dist/chunk-HRBKSZ34.js +2 -0
- package/dist/chunk-HRBKSZ34.js.map +1 -0
- package/dist/{chunk-MLLEOFX2.js → chunk-IXUEJBHD.js} +2 -2
- package/dist/{chunk-LDILAHMN.js → chunk-JVNFRS26.js} +2 -2
- package/dist/{chunk-GIK7S3OY.js → chunk-N2XXKFJ6.js} +7 -7
- package/dist/chunk-N2XXKFJ6.js.map +1 -0
- package/dist/{chunk-DJQA2CWD.js → chunk-N6EWZGIX.js} +6 -6
- package/dist/{chunk-DJQA2CWD.js.map → chunk-N6EWZGIX.js.map} +1 -1
- package/dist/{chunk-HEQPHUTR.js → chunk-NLZD2QKF.js} +2 -2
- package/dist/chunk-OHA3J5ZV.js +243 -0
- package/dist/chunk-OHA3J5ZV.js.map +1 -0
- package/dist/{chunk-P5JXQRBH.js → chunk-OTW5MPFT.js} +2 -2
- package/dist/{chunk-WMI5B36E.js → chunk-OUZ7YVQZ.js} +2 -2
- package/dist/{chunk-GAGVFSZM.js → chunk-P2ZYT5D6.js} +2 -2
- package/dist/chunk-P2ZYT5D6.js.map +1 -0
- package/dist/{chunk-2WPTP5HO.js → chunk-PZCTCCC5.js} +2 -2
- package/dist/chunk-Q7C3X3R6.js +61 -0
- package/dist/chunk-Q7C3X3R6.js.map +1 -0
- package/dist/{chunk-3WLO2UKI.js → chunk-QDE75R4U.js} +2 -2
- package/dist/{chunk-ZUZESPCH.js → chunk-TTL37CS5.js} +64 -64
- package/dist/chunk-TTL37CS5.js.map +1 -0
- package/dist/{chunk-2GSEEKQK.js → chunk-TUNQFPVA.js} +2 -2
- package/dist/{chunk-SL657MIM.js → chunk-WQLBJ2O5.js} +2 -2
- package/dist/{chunk-OZX7HVHC.js → chunk-Y6I3BYWV.js} +172 -165
- package/dist/chunk-Y6I3BYWV.js.map +1 -0
- package/dist/{chunk-SFLF64Q3.js → chunk-Z3IP66SL.js} +2 -2
- package/dist/cli.js +1 -1
- package/dist/client-JZTH46N2.js +2 -0
- package/dist/{compaction-U5SAYTX6.js → compaction-PIZINFHR.js} +2 -2
- package/dist/{config-ROQ4VEU3.js → config-R47ITLIY.js} +2 -2
- package/dist/config-mutator-T6JGXJ26.js +2 -0
- package/dist/context-planner-FJMU5WAT.js +17 -0
- package/dist/context-planner-FJMU5WAT.js.map +1 -0
- package/dist/doctor-2DMGAWMW.js +2 -0
- package/dist/failure-candidates-ARRMFXRY.js +8 -0
- package/dist/failure-candidates-ARRMFXRY.js.map +1 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.js +1 -1
- package/dist/memory-extract-OWTI6MN5.js +2 -0
- package/dist/processes-KUJJ7XE7.js +2 -0
- package/dist/program-KY5ZYPFN.js +2 -0
- package/dist/promote-57YNOVXV.js +2 -0
- package/dist/proposals-TX2HBBYV.js +2 -0
- package/dist/query-ZT7WXY2F.js +2 -0
- package/dist/registry-LLAFJJN4.js +2 -0
- package/dist/{request-planner-FAFNFVFX.js → request-planner-PEAYYXAP.js} +2 -2
- package/dist/{review-candidates-2XKJ2R6U.js → review-candidates-W7NIHNAI.js} +2 -2
- package/dist/{routing-PUPVGJ77.js → routing-7LCO7UJ7.js} +2 -2
- package/dist/schedule-tool-ZD3VBUBW.js +2 -0
- package/dist/scheduler-GC3FQKXY.js +2 -0
- package/dist/{seat-2MW3DEXX.js → seat-HR6QMAR2.js} +2 -2
- package/dist/{select-Q3AGLQQX.js → select-4XYRIZ5L.js} +2 -2
- package/dist/{surface-usage-FM2ZHGYE.js → surface-usage-V2BX4SBD.js} +2 -2
- package/dist/{tool-IVUNSAXY.js → tool-PAQ47HV2.js} +2 -2
- package/dist/wiki-EREMPSAE.js +2 -0
- package/package.json +1 -1
- package/dist/board-dashboard-2B3HYIXD.js.map +0 -1
- package/dist/chunk-4ZX4E7P3.js.map +0 -1
- package/dist/chunk-7DXE264B.js +0 -2
- package/dist/chunk-7DXE264B.js.map +0 -1
- package/dist/chunk-DIV66W3N.js.map +0 -1
- package/dist/chunk-FRHSQVFN.js.map +0 -1
- package/dist/chunk-GAGVFSZM.js.map +0 -1
- package/dist/chunk-GIK7S3OY.js.map +0 -1
- package/dist/chunk-OZX7HVHC.js.map +0 -1
- package/dist/chunk-RYLTCOYE.js +0 -241
- package/dist/chunk-RYLTCOYE.js.map +0 -1
- package/dist/chunk-WZGABQ72.js +0 -59
- package/dist/chunk-WZGABQ72.js.map +0 -1
- package/dist/chunk-ZUZESPCH.js.map +0 -1
- package/dist/client-6HCY7UMW.js +0 -2
- package/dist/config-mutator-ML4BAOFT.js +0 -2
- package/dist/context-planner-AQHJMVY2.js +0 -17
- package/dist/context-planner-AQHJMVY2.js.map +0 -1
- package/dist/doctor-3HWGAPET.js +0 -2
- package/dist/memory-extract-YZI2QZVR.js +0 -2
- package/dist/processes-XWRGOLMT.js +0 -2
- package/dist/program-JLZOHWIU.js +0 -2
- package/dist/promote-YGNTKEXI.js +0 -2
- package/dist/proposals-MWMEXRDW.js +0 -2
- package/dist/query-V76JDSOC.js +0 -2
- package/dist/registry-DKN4HEI3.js +0 -2
- package/dist/schedule-tool-6J7AHAHH.js +0 -2
- package/dist/scheduler-ZHQBSSRH.js +0 -2
- package/dist/wiki-FPX2YBKS.js +0 -2
- /package/dist/{App-EXB4HP3B.js.map → App-KE4SURSS.js.map} +0 -0
- /package/dist/{ChatApp-XMNE3SPH.js.map → ChatApp-NNHIKXO2.js.map} +0 -0
- /package/dist/{agent-ORYXXL5K.js.map → agent-RY7Z3IYY.js.map} +0 -0
- /package/dist/{chunk-26OP3X5B.js.map → chunk-4NBWF4TL.js.map} +0 -0
- /package/dist/{chunk-P7MR53U7.js.map → chunk-4TITGMPX.js.map} +0 -0
- /package/dist/{chunk-XM7ZQW4F.js.map → chunk-5ALS7SVV.js.map} +0 -0
- /package/dist/{chunk-3ZHMIWSV.js.map → chunk-5XQCGPQJ.js.map} +0 -0
- /package/dist/{chunk-DVNIFP7S.js.map → chunk-6VKCUMCN.js.map} +0 -0
- /package/dist/{chunk-GCHUE3TN.js.map → chunk-7WDJW37G.js.map} +0 -0
- /package/dist/{chunk-M5R3PWW5.js.map → chunk-B5XHX44Y.js.map} +0 -0
- /package/dist/{chunk-MLLEOFX2.js.map → chunk-IXUEJBHD.js.map} +0 -0
- /package/dist/{chunk-LDILAHMN.js.map → chunk-JVNFRS26.js.map} +0 -0
- /package/dist/{chunk-HEQPHUTR.js.map → chunk-NLZD2QKF.js.map} +0 -0
- /package/dist/{chunk-P5JXQRBH.js.map → chunk-OTW5MPFT.js.map} +0 -0
- /package/dist/{chunk-WMI5B36E.js.map → chunk-OUZ7YVQZ.js.map} +0 -0
- /package/dist/{chunk-2WPTP5HO.js.map → chunk-PZCTCCC5.js.map} +0 -0
- /package/dist/{chunk-3WLO2UKI.js.map → chunk-QDE75R4U.js.map} +0 -0
- /package/dist/{chunk-2GSEEKQK.js.map → chunk-TUNQFPVA.js.map} +0 -0
- /package/dist/{chunk-SL657MIM.js.map → chunk-WQLBJ2O5.js.map} +0 -0
- /package/dist/{chunk-SFLF64Q3.js.map → chunk-Z3IP66SL.js.map} +0 -0
- /package/dist/{client-6HCY7UMW.js.map → client-JZTH46N2.js.map} +0 -0
- /package/dist/{compaction-U5SAYTX6.js.map → compaction-PIZINFHR.js.map} +0 -0
- /package/dist/{config-ROQ4VEU3.js.map → config-R47ITLIY.js.map} +0 -0
- /package/dist/{config-mutator-ML4BAOFT.js.map → config-mutator-T6JGXJ26.js.map} +0 -0
- /package/dist/{doctor-3HWGAPET.js.map → doctor-2DMGAWMW.js.map} +0 -0
- /package/dist/{memory-extract-YZI2QZVR.js.map → memory-extract-OWTI6MN5.js.map} +0 -0
- /package/dist/{processes-XWRGOLMT.js.map → processes-KUJJ7XE7.js.map} +0 -0
- /package/dist/{program-JLZOHWIU.js.map → program-KY5ZYPFN.js.map} +0 -0
- /package/dist/{promote-YGNTKEXI.js.map → promote-57YNOVXV.js.map} +0 -0
- /package/dist/{proposals-MWMEXRDW.js.map → proposals-TX2HBBYV.js.map} +0 -0
- /package/dist/{query-V76JDSOC.js.map → query-ZT7WXY2F.js.map} +0 -0
- /package/dist/{registry-DKN4HEI3.js.map → registry-LLAFJJN4.js.map} +0 -0
- /package/dist/{request-planner-FAFNFVFX.js.map → request-planner-PEAYYXAP.js.map} +0 -0
- /package/dist/{review-candidates-2XKJ2R6U.js.map → review-candidates-W7NIHNAI.js.map} +0 -0
- /package/dist/{routing-PUPVGJ77.js.map → routing-7LCO7UJ7.js.map} +0 -0
- /package/dist/{schedule-tool-6J7AHAHH.js.map → schedule-tool-ZD3VBUBW.js.map} +0 -0
- /package/dist/{scheduler-ZHQBSSRH.js.map → scheduler-GC3FQKXY.js.map} +0 -0
- /package/dist/{seat-2MW3DEXX.js.map → seat-HR6QMAR2.js.map} +0 -0
- /package/dist/{select-Q3AGLQQX.js.map → select-4XYRIZ5L.js.map} +0 -0
- /package/dist/{surface-usage-FM2ZHGYE.js.map → surface-usage-V2BX4SBD.js.map} +0 -0
- /package/dist/{tool-IVUNSAXY.js.map → tool-PAQ47HV2.js.map} +0 -0
- /package/dist/{wiki-FPX2YBKS.js.map → wiki-EREMPSAE.js.map} +0 -0
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import{
|
|
2
|
-
`).filter(Boolean);if(!t.length)return null;let r=JSON.parse(t[0]),s=r.run?.workflowId;if(!s)return null;let o=r.run?.status??"unknown";for(let a=t.length-1;a>=0;a--){let i=JSON.parse(t[a]),l=i.status??i.run?.status;if(l){o=l;break}}return{workflowId:s,status:o,at:e}}catch{return null}}var dt={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},gt=(n,e,t)=>{try{return he(n,e,t)}catch{return null}},_e=864e5;function
|
|
1
|
+
import{t as Ie,u as ve}from"./chunk-OHA3J5ZV.js";import{d as Se,e as $e}from"./chunk-AQASR6KR.js";import{b as J}from"./chunk-N2XXKFJ6.js";import{g as be,h as ye,i as ke,k as we,l as xe}from"./chunk-5XQCGPQJ.js";import{k as he}from"./chunk-B5XHX44Y.js";import{m as pe,p as rt}from"./chunk-P2ZYT5D6.js";import{existsSync as it,readdirSync as ot,readFileSync as at,statSync as lt}from"fs";import{resolve as ct}from"path";function Re(n,e,t=Date.now(),r=7){let s=r*864e5,o=new Map;for(let a of e){let i=o.get(a.workflowId);i?i.push(a):o.set(a.workflowId,[a])}return n.map(a=>{let i=o.get(a.id)??[],l=i.filter(m=>t-m.at<=s),c=i.filter(m=>t-m.at>s&&t-m.at<=s*2),u=l.filter(m=>m.status==="failed").length,g=i.filter(m=>m.status==="paused").length,d=i.length?Math.max(...i.map(m=>m.at)):null,f=i.length?c.length>0&&l.length===0?"dormant":l.length>0&&u*2>=l.length?"failing":l.length>0?"active":"quiet":"never";return{id:a.id,name:a.name||a.id,state:f,lastRunAt:d,recent:l.length,prior:c.length,failed:u,paused:g}}).sort((a,i)=>{let l={dormant:0,failing:1,active:2,quiet:3,never:4};return l[a.state]-l[i.state]||(i.lastRunAt??0)-(a.lastRunAt??0)})}var F=new Map;function xn(n,e=1e3){if(!it(n))return[];let t=ot(n).filter(o=>o.endsWith(".jsonl")).map(o=>{let a=ct(n,o);return{path:a,mtime:lt(a).mtimeMs}}).sort((o,a)=>a.mtime-o.mtime).slice(0,e),r=new Set(t.map(o=>o.path));for(let o of F.keys())r.has(o)||F.delete(o);let s=[];for(let{path:o,mtime:a}of t){let i=F.get(o);if(i&&i.mtime===a){i.summary&&s.push(i.summary);continue}let l=ut(o,a);F.set(o,{mtime:a,summary:l}),l&&s.push(l)}return s}function ut(n,e){try{let t=at(n,"utf-8").split(`
|
|
2
|
+
`).filter(Boolean);if(!t.length)return null;let r=JSON.parse(t[0]),s=r.run?.workflowId;if(!s)return null;let o=r.run?.status??"unknown";for(let a=t.length-1;a>=0;a--){let i=JSON.parse(t[a]),l=i.status??i.run?.status;if(l){o=l;break}}return{workflowId:s,status:o,at:e}}catch{return null}}var dt={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},gt=(n,e,t)=>{try{return he(n,e,t)}catch{return null}},_e=864e5;function vn(n){let e=n.now??Date.now(),t={...dt,...n.thresholds},r=n.nextFire??gt,s=[];for(let i of n.crons){let l=n.cronRuns.get(i.id)??[],c=i.timezone||"UTC",u=l.map(f=>({at:Date.parse(f.startedAt),status:f.status})),g=l[0],d={id:`cron:${i.id}`,source:"cron",kind:"schedule",name:S(i.id,k.text),trigger:{schedule:S(i.schedule,k.text),timezone:c},agent:i.agent||null,enabled:i.enabled,state:i.enabled?"enabled":"disabled",nextRunAt:i.enabled?G(i.nextRun)??G(r(i.schedule,new Date(e),c)):null,lastRun:g?{at:g.startedAt,status:g.status,summary:yt(g.status==="success"?void 0:g.errorSummary,k.summary)}:null,lastSuccessAt:l.find(f=>f.status==="success")?.startedAt??null,consecutiveFailures:Ae(u),sampledRuns:l.length,flags:[],attention:null};d.flags=Ce(d,u,i.schedule,c,null,e,t,r),s.push(De(d))}let o=new Map(Re(n.workflows.map(i=>({id:i.id,name:i.title})),n.workflowRuns,e).map(i=>[i.id,i])),a=new Map;for(let i of n.workflowRuns){let l=a.get(i.workflowId);l?l.push(i):a.set(i.workflowId,[i])}for(let i of n.workflows){let l=i.nodes.find(v=>v.type.startsWith("trigger."));if(!l||l.type!=="trigger.cron"&&l.type!=="trigger.hook")continue;let c=l.config??{},u=i.state||"active",g=u==="active",d=(a.get(i.id)??[]).slice().sort((v,q)=>q.at-v.at),f=d.map(v=>({at:v.at,status:pt(v.status)})),m=f[0],h=l.type==="trigger.cron",b=typeof c.spec=="string"?c.spec:"",K=typeof c.timezone=="string"?c.timezone:"UTC",O={id:`workflow:${i.id}`,source:"workflow",kind:h?"schedule":"event",name:S(i.title||i.id,k.text),trigger:h?{schedule:S(b,k.text),timezone:K}:{event:S(typeof c.event=="string"?c.event:"",k.text),filters:bt(c.filter,i)},agent:ht(i),enabled:g,state:u,nextRunAt:h&&g&&b?G(r(b,new Date(e),K)):null,lastRun:m?{at:new Date(m.at).toISOString(),status:m.status}:null,lastSuccessAt:(()=>{let v=f.find(q=>q.status==="success");return v?new Date(v.at).toISOString():null})(),consecutiveFailures:Ae(f),sampledRuns:d.length,flags:[],attention:null},P=Date.parse(i.updated||i.created||"");O.flags=h?Ce(O,f,b,K,Number.isFinite(P)?P:null,e,t,r):ft(O,o.get(i.id)?.state==="dormant",Number.isFinite(P)?P:null,e,t),s.push(De(O))}return s.sort(mt).slice(0,k.routines)}function Ae(n){let e=0;for(let t of n)if(!(t.status==="running"||t.status==="paused"||t.status==="unknown"))if(t.status==="failed"||t.status==="timeout")e++;else break;return e}function Ce(n,e,t,r,s,o,a,i){let l=[],c=e.length?e[0].at:null;if(!n.enabled){let d=Te(c,s,o,a);return d&&l.push(d),l}if(n.consecutiveFailures>=a.failStreak&&l.push({reason:"failing",detail:`${n.consecutiveFailures} failed attempts in a row`}),c===null)return l.push({reason:"never-ran",detail:"No persisted attempt"}),l;let u=new Date(c),g=null;for(let d=0;d<a.missedFires&&(g=i(t,u,r),!!g);d++)u=g;return g&&o>g.getTime()+a.graceMs&&l.push({reason:"overdue",detail:`No attempt since ${new Date(c).toISOString()}; ${a.missedFires} scheduled fires missed`}),l}function ft(n,e,t,r,s){let o=[],a=n.lastRun?Date.parse(n.lastRun.at):null;if(!n.enabled){let i=Te(a,t,r,s);return i&&o.push(i),o}return n.consecutiveFailures>=s.failStreak&&o.push({reason:"failing",detail:`${n.consecutiveFailures} failed runs in a row`}),a===null?o.push({reason:"never-ran",detail:"No run recorded for this trigger"}):e&&o.push({reason:"dormant",detail:"Fired in the prior week, silent in the last one"}),o}function Te(n,e,t,r){let s=Math.max(n??0,e??0);return s&&t-s<r.disabledDays*_e?null:{reason:"disabled-long",detail:s?`Disabled; no activity for ${Math.floor((t-s)/_e)} days`:"Disabled and never ran"}}function De(n){let e=new Set(n.flags.map(t=>t.reason));return n.attention=e.has("failing")?"critical":e.has("overdue")||e.has("dormant")||e.has("never-ran")?"warning":e.has("disabled-long")?"info":null,n}var je={critical:0,warning:1,info:2};function mt(n,e){let t=n.attention?je[n.attention]:3,r=e.attention?je[e.attention]:3;return t-r||Number(e.enabled)-Number(n.enabled)||n.name.localeCompare(e.name)}function pt(n){switch(n){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 ht(n){if(n.ownerAgent)return S(n.ownerAgent,k.text);let e=n.nodes.find(t=>t.type==="agent"&&typeof t.config?.agentId=="string"&&t.config.agentId);return e?S(String(e.config.agentId),k.text):null}function bt(n,e){let t=[],r=e?.project;if(r&&t.push(S(`project=${r}`,k.filterValue)),n&&typeof n=="object"&&!Array.isArray(n))for(let[s,o]of Object.entries(n)){let a=Array.isArray(o)?o.map(String):o==null?[]:[String(o)];a.length&&t.push(S(`${s}=${a.join(",")}`,k.filterValue))}return t.slice(0,k.filters)}function G(n){if(!n)return null;let e=n instanceof Date?n:new Date(n);return Number.isFinite(e.getTime())?e.toISOString():null}function S(n,e){return n.length<=e?n:n.slice(0,e-3)+"..."}function yt(n,e){return n===void 0?void 0:S(n,e)}function B(n){return(Array.isArray(n)?n[0]:n)?.trim()??""}function kt(n){try{return new URL(n).host.toLowerCase()}catch{return null}}function wt(n=process.env){return new Set((n.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function _n(n,e=wt()){let t=B(n.origin);if(t){if(e.has(t.replace(/\/+$/,"").toLowerCase()))return"same-origin";let s=kt(t),o=[B(n.host),B(n["x-forwarded-host"])].filter(Boolean).map(a=>a.toLowerCase());return s&&o.includes(s)?"same-origin":"foreign"}let r=B(n["sec-fetch-site"]).toLowerCase();return r==="cross-site"||r==="same-site"?"foreign":"none"}function An(n){let e=(n||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{readFileSync as X,writeFileSync as Be,existsSync as Y,readdirSync as Ct,statSync as Dt}from"fs";import{resolve as Q,join as jt}from"path";import{existsSync as Ee,mkdirSync as xt,readFileSync as St,writeFileSync as Le}from"fs";import{dirname as $t,resolve as Oe}from"path";import{z as p}from"zod";var It=p.object({type:p.enum(["gitlab","github"]),host:p.string().optional(),project:p.string(),iid:p.number().int().positive(),url:p.string()}),vt=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:It.optional(),importedAt:p.string().optional(),createdAt:p.string(),updatedAt:p.string(),blocker:p.string().optional(),doneNote:p.string().optional()}),Rt=p.object({version:p.literal(1),items:p.array(vt).default([])}),U=class{constructor(e){this.path=e}jsonPath(){return Oe(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return Oe(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return Ee(this.jsonPath())}load(){let e=this.jsonPath();if(!Ee(e))return{version:1,items:[]};let t=St(e,"utf-8");try{return Rt.parse(JSON.parse(t))}catch(r){throw new Error(`Backlog file invalid (${e}): ${r.message}`)}}save(e){let t=this.jsonPath();xt($t(t),{recursive:!0}),Le(t,JSON.stringify(e,null,2)+`
|
|
3
3
|
`),Le(this.mdPath(),this.toMarkdown(e))}list(){return this.load().items}findById(e){return this.list().find(t=>t.id===e)}add(e){let t=this.load();if(t.items.some(o=>o.id===e.id))throw new Error(`backlog item ${e.id} already exists`);let r=new Date().toISOString(),s={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??r,updatedAt:r};return t.items.push(s),this.save(t),s}addMany(e){let t=this.load(),r=new Set(t.items.map(a=>a.id)),s=new Date().toISOString(),o=[];for(let a of e){if(r.has(a.id))continue;let i={...a,labels:a.labels??[],status:a.status??"todo",createdAt:a.createdAt??s,updatedAt:s};t.items.push(i),o.push(i),r.add(i.id)}return o.length&&this.save(t),o}update(e,t){let r=this.load(),s=r.items.findIndex(a=>a.id===e);if(s<0)throw new Error(`backlog item ${e} not found`);let o={...r.items[s],...t,id:r.items[s].id,createdAt:r.items[s].createdAt,updatedAt:new Date().toISOString()};return r.items[s]=o,this.save(r),o}remove(e){let t=this.load(),r=t.items.length;return t.items=t.items.filter(s=>s.id!==e),t.items.length===r?!1:(this.save(t),!0)}toMarkdown(e){let t=["# Backlog","","_Generated from `backlog.json`. Do not edit by hand \u2014 use `agentx backlog` commands._",""],r={doing:[],blocked:[],todo:[],done:[]};for(let o of e.items)r[o.status].push(o);let s=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[o,a]of s)if(r[o].length){t.push(`## ${a}`,"");for(let i of r[o]){let l=o==="done"?"x":" ",c=i.assignee?`@${i.assignee} `:"",u=i.estimatedSeconds?` [time: ${Math.round(i.estimatedSeconds/60)}m]`:"",g=i.source?` (${i.source.type}: ${i.source.project}#${i.source.iid})`:"";t.push(`- [${l}] ${c}${i.title}${u}${g}`),i.source?.url&&t.push(` - <${i.source.url}>`),i.labels.length&&t.push(` - labels: ${i.labels.join(", ")}`),i.milestone&&t.push(` - milestone: ${i.milestone}`),i.blocker&&t.push(` - BLOCKED: ${i.blocker}`)}t.push("")}return t.join(`
|
|
4
|
-
`)}};function
|
|
5
|
-
`):[]}writeMd(e){let t=Q(process.cwd(),this.path);
|
|
4
|
+
`)}};function En(n){return`${n.type}:${n.project}:${n.iid}`}function Pe(n,e,t){let r=[];if(e.type==="gitlab"){let s=t.channels.gitlab?.agentMappings??[];for(let o of n){let a=s.find(i=>i.agentId===o);a?.gitlabUsernames?.length?r.push(a.gitlabUsernames[0]):r.push(o)}}else if(e.type==="github"){let s=t.channels.github?.agentMappings??[];for(let o of n){let a=s.find(i=>i.agentId===o);a?.githubUsernames?.length?r.push(a.githubUsernames[0]):r.push(o)}}return r}async function V(n,e,t,r=()=>{}){return n.source?n.source.type==="gitlab"?_t(n.source,e,t,r):n.source.type==="github"?At(n.source,e,t,r):{ok:!1,error:`unknown source.type ${n.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function _t(n,e,t,r){let s=t.channels.gitlab,o=s?.token,a=s?.host||(n.host?`https://${n.host}`:void 0);if(!o||!a)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let i=[],l=async(f,m={})=>fetch(`${a}/api/v4${f}`,{...m,headers:{"PRIVATE-TOKEN":o,"Content-Type":"application/json",...m.headers||{}}}),c=encodeURIComponent(n.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async m=>{try{let h=await fetch(`${a}/api/v4/users?username=${encodeURIComponent(m)}`,{headers:{"PRIVATE-TOKEN":o}});if(!h.ok)return null;let b=await h.json();return Array.isArray(b)&&b[0]?.id?b[0].id:null}catch{return null}}))).filter(m=>typeof m=="number"));let g;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")g=0;else try{let f=await l(`/projects/${c}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(f.ok){let m=await f.json();Array.isArray(m)&&m[0]?.id&&(g=m[0].id)}}catch(f){r(`[backlog-sync] milestone lookup failed: ${f.message}`)}let d={};if(e.title!==void 0&&(d.title=e.title),e.description!==void 0&&(d.description=e.description),e.labels!==void 0&&(d.labels=e.labels.join(",")),e.addLabels?.length&&(d.add_labels=e.addLabels.join(",")),e.removeLabels?.length&&(d.remove_labels=e.removeLabels.join(",")),u!==void 0&&(d.assignee_ids=u),g!==void 0&&(d.milestone_id=g),e.state&&(d.state_event=e.state==="closed"?"close":"reopen"),Object.keys(d).length)try{let f=await l(`/projects/${c}/issues/${n.iid}`,{method:"PUT",body:JSON.stringify(d)});if(i.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let m=await f.text().catch(()=>"");return{ok:!1,attempts:i,error:`PUT issue ${f.status}: ${m.slice(0,200)}`,url:n.url}}}catch(f){return i.push({kind:"PUT issue",ok:!1,error:f.message}),{ok:!1,attempts:i,error:f.message,url:n.url}}if(e.note)try{let f=await l(`/projects/${c}/issues/${n.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});i.push({kind:"POST note",ok:f.ok,status:f.status})}catch(f){i.push({kind:"POST note",ok:!1,error:f.message})}return{ok:i.every(f=>f.ok),attempts:i,url:n.url}}async function At(n,e,t,r){let o=t.channels.github?.token;if(!o)return{ok:!1,error:"github token not configured",attempts:[]};let a=[],i=async(d,f={})=>fetch(`https://api.github.com${d}`,{...f,headers:{Authorization:`Bearer ${o}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...f.headers||{}}}),l=n.project,c;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")c=null;else try{let d=await i(`/repos/${l}/milestones?state=all&per_page=100`);if(d.ok){let f=await d.json(),m=Array.isArray(f)?f.find(h=>h.title===e.milestoneTitle):null;m?.number&&(c=m.number)}}catch(d){r(`[backlog-sync] github milestone lookup failed: ${d.message}`)}let u;if(e.labels!==void 0)u=e.labels;else if(e.addLabels?.length||e.removeLabels?.length)try{let d=await i(`/repos/${l}/issues/${n.iid}`);if(d.ok){let f=await d.json(),m=Array.isArray(f.labels)?f.labels.map(b=>typeof b=="string"?b:b.name):[],h=new Set([...m,...e.addLabels??[]]);for(let b of e.removeLabels??[])h.delete(b);u=[...h]}}catch(d){r(`[backlog-sync] github label fetch failed: ${d.message}`)}let g={};if(e.title!==void 0&&(g.title=e.title),e.description!==void 0&&(g.body=e.description),u!==void 0&&(g.labels=u),e.assigneeUsernames!==void 0&&(g.assignees=e.assigneeUsernames),c!==void 0&&(g.milestone=c),e.state&&(g.state=e.state),Object.keys(g).length)try{let d=await i(`/repos/${l}/issues/${n.iid}`,{method:"PATCH",body:JSON.stringify(g)});if(a.push({kind:"PATCH issue",ok:d.ok,status:d.status}),!d.ok){let f=await d.text().catch(()=>"");return{ok:!1,attempts:a,error:`PATCH issue ${d.status}: ${f.slice(0,200)}`,url:n.url}}}catch(d){return a.push({kind:"PATCH issue",ok:!1,error:d.message}),{ok:!1,attempts:a,error:d.message,url:n.url}}if(e.note)try{let d=await i(`/repos/${l}/issues/${n.iid}/comments`,{method:"POST",body:JSON.stringify({body:e.note})});a.push({kind:"POST comment",ok:d.ok,status:d.status})}catch(d){a.push({kind:"POST comment",ok:!1,error:d.message})}return{ok:a.every(d=>d.ok),attempts:a,url:n.url}}var Z=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,N=/@([a-z0-9_-]+)/i,Fe=/\[time:\s*([0-9hm\s]+)\]/i;function Tt(n){let e=n.match(/(\d+)\s*h/i),t=n.match(/(\d+)\s*m/i);return(e?parseInt(e[1],10)*3600:0)+(t?parseInt(t[1],10)*60:0)}var ee=class{constructor(e,t,r=()=>{}){this.path=e;this.daemon=t;this.log=r;this.store=new U(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=Q(process.cwd(),this.path);return Y(e)?X(e,"utf-8").split(`
|
|
5
|
+
`):[]}writeMd(e){let t=Q(process.cwd(),this.path);Be(t,e.join(`
|
|
6
6
|
`))}async listOpen(e){if(this.store.exists())return this.store.list().filter(o=>o.status!=="done"&&(!o.assignee||o.assignee.toLowerCase()===e.toLowerCase())).map(o=>this.toWorkItem(o));let t=this.readMd(),r=[];for(let s=0;s<t.length;s++){let o=t[s].match(Z);if(!o||o[2].toLowerCase()==="x")continue;let i=o[3],l=i.match(N);if(l&&l[1].toLowerCase()!==e.toLowerCase())continue;let c=i.match(Fe),u=i.replace(N,"").replace(Fe,"").trim();r.push({id:`backlog:${s}`,title:u||`Task at line ${s+1}`,assignee:l?l[1]:void 0,estimatedSeconds:c?Tt(c[1]):void 0,priority:s})}return r}async listAll(e={}){return this.store.exists()?this.store.list().map(t=>this.toWorkItem(t)):[]}async claim(e,t){if(!this.store.exists())return;let r=this.store.findById(t);if(!r)return;let s=this.store.update(t,{assignee:r.assignee||e,status:"doing"});if(s.source&&this.daemon){let o=Pe([s.assignee||e],s.source,this.daemon);V(s,{assigneeUsernames:o,addLabels:["Doing"],removeLabels:["To Do"]},this.daemon,this.log).catch(a=>this.log(`[backlog-sync] claim failed for ${t}: ${a?.message??a}`))}}async report(e,t){if(this.store.exists()&&this.store.findById(e)){let i={};t.status==="done"?i.status="done":t.status==="blocked"?(i.status="blocked",i.blocker=t.blocker||t.note||void 0):t.status==="in-progress"&&(i.status="doing"),t.timeSeconds&&(i.estimatedSeconds=t.timeSeconds);let l=this.store.update(e,i);if(l.source&&this.daemon){let c={};t.status==="done"?(c.addLabels=["Done"],c.removeLabels=["Doing"]):t.status==="blocked"&&(c.addLabels=["Blocked"]),t.note&&(c.note=t.note),Object.keys(c).length&&V(l,c,this.daemon,this.log).catch(u=>this.log(`[backlog-sync] report failed for ${e}: ${u?.message??u}`))}return}if(!e.startsWith("backlog:"))throw new Error(`not a backlog id: ${e}`);let r=parseInt(e.slice(8),10),s=this.readMd(),o=s[r];if(!o)throw new Error(`backlog line ${r} missing`);if(!o.match(Z))throw new Error(`backlog line ${r} not a checkbox`);if(t.status==="done"){s[r]=o.replace(/- \[ \]/,"- [x]");let i=t.timeSeconds?` <!-- done by agent, ${Math.round(t.timeSeconds/60)}m -->`:" <!-- done by agent -->";s.splice(r+1,0,i)}else t.status==="blocked"?s.splice(r+1,0,` <!-- BLOCKED: ${t.blocker||t.note||"?"} -->`):t.note&&s.splice(r+1,0,` <!-- ${t.note.replace(/-->/g,"\u2014 >")} -->`);this.writeMd(s)}toWorkItem(e){let t={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:t,milestone:e.milestone,url:e.source?.url,updatedAt:e.updatedAt,state:e.status==="done"?"closed":"opened"}}},te=class{constructor(e,t){this.root=e;this.glob=t}type="wiki";capabilities={listAll:!1,create:!1,transition:!1,labels:!1,search:!1};walk(e,t){if(Y(e))for(let r of Ct(e)){let s=jt(e,r);Dt(s).isDirectory()?this.walk(s,t):r.endsWith(".md")&&t.push(s)}}async listOpen(e){let t=[];this.walk(Q(process.cwd(),this.root),t);let r=[];for(let s of t){let o=X(s,"utf-8").split(`
|
|
7
7
|
`);for(let a=0;a<o.length;a++){let i=o[a].match(Z);if(!i||i[2].toLowerCase()==="x")continue;let l=i[3].match(N);!l||l[1].toLowerCase()!==e.toLowerCase()||r.push({id:`wiki:${s}:${a}`,title:i[3].replace(N,"").trim(),assignee:l[1],priority:a})}}return r}async claim(){}async report(e,t){let r=e.split(":"),s=parseInt(r[r.length-1],10),o=r.slice(1,-1).join(":");if(!Y(o))return;let a=X(o,"utf-8").split(`
|
|
8
|
-
`);t.status==="done"&&a[s]&&(a[s]=a[s].replace(/- \[ \]/,"- [x]"),
|
|
9
|
-
`)))}},ne=class{constructor(e,t,r,s,o){this.host=e;this.token=t;this.projects=r;this.agentUsernames=s;this.log=o}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[t,r]of Object.entries(this.agentUsernames))if(r.some(s=>s.toLowerCase()===e.toLowerCase()))return t}mapIssue(e,t){let r=e.references?.full?.split("#")[0]||t,s=[],o;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(o=e.labels.map(c=>({name:c.name,color:c.color,text_color:c.text_color})),s=o.map(c=>c.name)):s=e.labels);let i=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(c=>({username:c.username,name:c.name,avatarUrl:c.avatar_url})),l=i[0]?.username;return{id:`gitlab:${r}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:l?this.usernameToAgent(l)||l:void 0,assignees:i,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:s,labelDetails:o,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,t={}){let r=await fetch(`${this.host}/api/v4${e}`,{...t,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...t.headers||{}}});if(!r.ok)throw new Error(`GitLab ${r.status}: ${await r.text().catch(()=>"")}`);return r.json()}async listOpen(e){let t=this.agentUsernames[e]||[];if(!t.length)return[];let r=[],s=this.projects.length?this.projects:["__ALL__"];for(let o of t)for(let a of s)try{let i=`assignee_username=${encodeURIComponent(o)}&state=opened&scope=all&per_page=20`,l=a==="__ALL__"?`/issues?${i}`:`/projects/${encodeURIComponent(a)}/issues?${i}`,c=await this.api(l);for(let u of c){let g=this.mapIssue(u,a);g.assignee=e,r.push(g)}}catch(i){this.log(`[business] GitLab listOpen failed for ${o} on ${a}: ${i.message}`)}return r}async claim(e,t){let{project:r,iid:s,type:o}=this.parseId(t),a=`/projects/${encodeURIComponent(r)}/${o==="issue"?"issues":"merge_requests"}/${s}?add_labels=Doing&remove_labels=To Do`;try{await this.api(a,{method:"PUT"})}catch(i){this.log(`[business] claim label update failed: ${i.message}`)}}async report(e,t){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests";if(t.timeSeconds&&t.timeSeconds>0){let i=Math.max(1,Math.round(t.timeSeconds/60)),l=i>=60?`${Math.floor(i/60)}h${i%60?` ${i%60}m`:""}`:`${i}m`;try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}/add_spent_time?duration=${encodeURIComponent(l)}`,{method:"POST"})}catch(c){this.log(`[business] add_spent_time failed: ${c.message}`)}}if(t.status==="done")try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(i){this.log(`[business] done label update failed: ${i.message}`)}else if(t.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?add_labels=Blocked`,{method:"PUT"})}catch(i){this.log(`[business] blocked label update failed: ${i.message}`)}if(t.note)try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}/notes`,{method:"POST",body:JSON.stringify({body:t.note})})}catch(i){this.log(`[business] report note failed: ${i.message}`)}}async listAll(e={}){let t=e.sinceDays??30,r=new Date(Date.now()-t*24*36e5).toISOString(),s=new URLSearchParams,o=e.state??"opened";s.set("state",o),s.set("updated_after",r),s.set("scope","all"),s.set("per_page","100"),s.set("with_labels_details","true"),s.set("order_by","updated_at"),s.set("sort","desc"),e.labels?.length&&s.set("labels",e.labels.join(",")),e.milestone&&s.set("milestone",e.milestone),e.search&&s.set("search",e.search);let a=this.projects.length?this.projects:["__ALL__"],i=[];for(let c of a)try{let u=c==="__ALL__"?`/issues?${s.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${s.toString()}`,g=await this.api(u);for(let d of g)i.push(this.mapIssue(d,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=i;if(e.notLabels?.length){let c=new Set(e.notLabels);l=l.filter(u=>!(u.labels||[]).some(g=>c.has(g)))}if(e.withoutScopedPrefix){let c=e.withoutScopedPrefix+"::";l=l.filter(u=>!(u.labels||[]).some(g=>g.startsWith(c)))}return l}async setState(e,t){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?state_event=${t}`,{method:"PUT"})}async getItem(e){let{project:t,iid:r}=this.parseId(e);try{let s=await this.api(`/projects/${encodeURIComponent(t)}/issues/${r}?with_labels_details=true`);return{...this.mapIssue(s,t),descriptionHtml:s.description_html||void 0,createdAt:s.created_at,author:s.author?{username:s.author.username,name:s.author.name,avatarUrl:s.author.avatar_url}:void 0,allLabels:Array.isArray(s.labels)?typeof s.labels[0]=="object"?s.labels.map(a=>a.name):s.labels:[]}}catch(s){return this.log(`[board] GitLab getItem failed for ${e}: ${s.message}`),null}}async updateItem(e,t){let{project:r,iid:s}=this.parseId(e),o;t.assigneeUsernames&&(o=(await Promise.all(t.assigneeUsernames.map(async u=>{try{let g=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(g)&&g[0]?.id?g[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let a;if(t.milestoneTitle!==void 0)if(t.milestoneTitle===null||t.milestoneTitle==="")a=0;else try{let c=await this.api(`/projects/${encodeURIComponent(r)}/milestones?title=${encodeURIComponent(t.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(a=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${t.milestoneTitle}": ${c.message}`)}let i={};t.title!==void 0&&(i.title=t.title),t.description!==void 0&&(i.description=t.description),t.labels!==void 0&&(i.labels=t.labels.join(",")),t.addLabels?.length&&(i.add_labels=t.addLabels.join(",")),t.removeLabels?.length&&(i.remove_labels=t.removeLabels.join(",")),o!==void 0&&(i.assignee_ids=o),a!==void 0&&(i.milestone_id=a);let l=await this.api(`/projects/${encodeURIComponent(r)}/issues/${s}`,{method:"PUT",body:JSON.stringify(i)});return this.mapIssue(l,r)}async listMembers(){let e=new Map;for(let t of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(t)}/members/all?per_page=100`);for(let s of r)s.username&&!e.has(s.username)&&e.set(s.username,{username:s.username,name:s.name,avatarUrl:s.avatar_url})}catch(r){this.log(`[board] listMembers failed for ${t}: ${r.message}`)}return[...e.values()].sort((t,r)=>t.username.localeCompare(r.username))}async listMilestones(){let e=new Map;for(let r of this.projects)try{let s=await this.api(`/projects/${encodeURIComponent(r)}/milestones?per_page=100`);for(let o of s)o.title&&!e.has(o.title)&&e.set(o.title,{id:o.id,title:o.title,state:o.state,dueDate:o.due_date})}catch(s){this.log(`[board] listMilestones failed for ${r}: ${s.message}`)}let t=[...e.values()];return t.sort((r,s)=>r.state!==s.state?r.state==="active"?-1:1:r.title.localeCompare(s.title)),t}async create(e){let t=e.projectHint||this.projects[0];if(!t)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let r,s=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];s.length&&(r=(await Promise.all(s.map(async c=>{try{let u=await this.api(`/users?username=${encodeURIComponent(c)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${c}: ${u.message}`),null}}))).filter(c=>typeof c=="number"));let o;if(e.milestoneTitle)try{let l=await this.api(`/projects/${encodeURIComponent(t)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${l.message}`)}let a={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};r?.length&&(a.assignee_ids=r),o!==void 0&&(a.milestone_id=o);let i=await this.api(`/projects/${encodeURIComponent(t)}/issues`,{method:"POST",body:JSON.stringify(a)});return this.mapIssue(i,t)}async transition(e,t,r){await this.transitionMany(e,t?[t]:[],r?[r]:[])}async transitionMany(e,t,r){let{project:s,iid:o,type:a}=this.parseId(e),i=a==="issue"?"issues":"merge_requests",l=new URLSearchParams;t.length&&l.set("add_labels",t.join(",")),r.length&&l.set("remove_labels",r.join(",")),l.toString()&&await this.api(`/projects/${encodeURIComponent(s)}/${i}/${o}?${l.toString()}`,{method:"PUT"})}parseId(e){let r=e.replace(/^gitlab:/,"").split(":"),s=r.pop(),o=r.pop()==="mr"?"mr":"issue";return{project:r.join(":"),type:o,iid:s}}};function Bn(n,e,t){let r=n.workSource;switch(r.type){case"backlog":return new ee(r.path,e,t);case"wiki":return new te(r.path,r.glob);case"gitlab":{let s=e.channels.gitlab;if(!s?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let o={};for(let i of s.agentMappings)i.gitlabUsernames.length&&(o[i.agentId]=i.gitlabUsernames);let a=r.projects.length?r.projects:s.routes.map(i=>i.project);return new ne(s.host,s.token,a,o,t)}}}var se="unmapped";function re(n,e=[]){if(!n)return se;let t=e.find(s=>s.id===n);if(t?.client)return t.client;let r=n.indexOf("/");return r>0?n.slice(0,r):n}function Et(n){let e=new Map,t=n.projects??[],r=n.orgChart??{};for(let o of t)o.pm&&(e.has(o.pm)||e.set(o.pm,re(o.id,t)));let s=(o,a=new Set)=>{if(e.has(o))return e.get(o);if(a.has(o))return;a.add(o);let i=r[o]?.reportsTo;if(!i)return;let l=s(i,a);return l&&e.set(o,l),l};for(let o of Object.keys(r))s(o);return e}function Lt(n,e,t=[]){if(!t.length)return;let r=t.filter(s=>!s.channel||s.channel===n);return r.find(s=>s.chatId&&e.chatId&&s.chatId===e.chatId)??r.find(s=>s.username&&e.username&&s.username===e.username)??r.find(s=>s.senderId&&e.senderId&&s.senderId===e.senderId)??r.find(s=>s.channel&&!s.chatId&&!s.username&&!s.senderId)}function Mn(n,e){let t=Lt(n.channel,{chatId:n.chatId,username:n.username},e.contactMap);if(t)return t.client;if(n.project)return re(n.project,e.projects);if(n.agentId){let r=Et(e).get(n.agentId);if(r)return r}return se}function Wn(n,e){let t=String(n||"").split(":");if(t.length<3)return{agentId:e};let[r,s,...o]=t,a=o.join(":"),i={agentId:e||r,channel:s};return s==="gitlab"||s==="github"?i.project=a.split(":")[0]:s==="cron"||s==="api"||(i.chatId=a.split("@")[0]),i}var Ot=n=>n===se?"internal":"client";function Pt(n,e){let t=e.clients?.[n];return{id:n,name:t?.name||n,kind:t?.kind??Ot(n),respondWithinMinutes:Ft(t?.respondWithin),standing:t?.standing??[],declared:!!t}}function zn(n){let e=new Set;for(let t of n.projects??[])e.add(re(t.id,n.projects));for(let t of n.contactMap??[])e.add(t.client);for(let t of Object.keys(n.clients??{}))e.add(t);return[...e].sort().map(t=>Pt(t,n))}function Ft(n){let e=/^(\d+)\s*([mhd])$/.exec(String(n??"").trim());if(!e)return;let t=Number(e[1]);return e[2]==="m"?t:e[2]==="h"?t*60:t*1440}import{existsSync as Ut,mkdirSync as Bt,readdirSync as Nt,readFileSync as Mt,renameSync as Wt,writeFileSync as zt}from"fs";import{resolve as Ne}from"path";var Be=["discard","keep","pause","approve"],I={title:120,ask:300,recommend:300,source:500,note:500,pendingPerAgent:25},Ht={defaultExpiryDays:3,maxExpiryDays:30};function A(n){return Ne(n,".agentx","approvals")}var Kt=/^[a-z0-9][a-z0-9-]{0,80}$/;function Me(n){return Kt.test(n)}function We(n,e){if(!Me(e))throw new Error(`invalid card id: ${e}`);return Ne(A(n),`${e}.json`)}function qt(n,e){let t=new Date(n).toISOString().slice(0,10),r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return`${t}-${r||"card"}-${Math.random().toString(36).slice(2,6)}`}function M(n,e){Bt(A(n),{recursive:!0});let t=We(n,e.id),r=`${t}.${process.pid}.tmp`;zt(r,JSON.stringify(e,null,2)+`
|
|
10
|
-
`),Wt(r,t)}function j(n,e){if(!Me(e))return null;try{return JSON.parse(Mt(We(n,e),"utf-8"))}catch{return null}}function T(n,e){let t=A(n);if(!
|
|
8
|
+
`);t.status==="done"&&a[s]&&(a[s]=a[s].replace(/- \[ \]/,"- [x]"),Be(o,a.join(`
|
|
9
|
+
`)))}},ne=class{constructor(e,t,r,s,o){this.host=e;this.token=t;this.projects=r;this.agentUsernames=s;this.log=o}type="gitlab";capabilities={listAll:!0,create:!0,transition:!0,labels:!0,search:!0};usernameToAgent(e){for(let[t,r]of Object.entries(this.agentUsernames))if(r.some(s=>s.toLowerCase()===e.toLowerCase()))return t}mapIssue(e,t){let r=e.references?.full?.split("#")[0]||t,s=[],o;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(o=e.labels.map(c=>({name:c.name,color:c.color,text_color:c.text_color})),s=o.map(c=>c.name)):s=e.labels);let i=(Array.isArray(e.assignees)&&e.assignees.length?e.assignees:e.assignee?[e.assignee]:[]).map(c=>({username:c.username,name:c.name,avatarUrl:c.avatar_url})),l=i[0]?.username;return{id:`gitlab:${r}:issue:${e.iid}`,title:e.title,description:e.description||void 0,assignee:l?this.usernameToAgent(l)||l:void 0,assignees:i,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:s,labelDetails:o,updatedAt:e.updated_at,state:e.state==="closed"?"closed":"opened",milestone:e.milestone?.title||void 0}}async api(e,t={}){let r=await fetch(`${this.host}/api/v4${e}`,{...t,headers:{"PRIVATE-TOKEN":this.token,"Content-Type":"application/json",...t.headers||{}}});if(!r.ok)throw new Error(`GitLab ${r.status}: ${await r.text().catch(()=>"")}`);return r.json()}async listOpen(e){let t=this.agentUsernames[e]||[];if(!t.length)return[];let r=[],s=this.projects.length?this.projects:["__ALL__"];for(let o of t)for(let a of s)try{let i=`assignee_username=${encodeURIComponent(o)}&state=opened&scope=all&per_page=20`,l=a==="__ALL__"?`/issues?${i}`:`/projects/${encodeURIComponent(a)}/issues?${i}`,c=await this.api(l);for(let u of c){let g=this.mapIssue(u,a);g.assignee=e,r.push(g)}}catch(i){this.log(`[business] GitLab listOpen failed for ${o} on ${a}: ${i.message}`)}return r}async claim(e,t){let{project:r,iid:s,type:o}=this.parseId(t),a=`/projects/${encodeURIComponent(r)}/${o==="issue"?"issues":"merge_requests"}/${s}?add_labels=Doing&remove_labels=To Do`;try{await this.api(a,{method:"PUT"})}catch(i){this.log(`[business] claim label update failed: ${i.message}`)}}async report(e,t){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests";if(t.timeSeconds&&t.timeSeconds>0){let i=Math.max(1,Math.round(t.timeSeconds/60)),l=i>=60?`${Math.floor(i/60)}h${i%60?` ${i%60}m`:""}`:`${i}m`;try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}/add_spent_time?duration=${encodeURIComponent(l)}`,{method:"POST"})}catch(c){this.log(`[business] add_spent_time failed: ${c.message}`)}}if(t.status==="done")try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?add_labels=Done&remove_labels=Doing`,{method:"PUT"})}catch(i){this.log(`[business] done label update failed: ${i.message}`)}else if(t.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?add_labels=Blocked`,{method:"PUT"})}catch(i){this.log(`[business] blocked label update failed: ${i.message}`)}if(t.note)try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}/notes`,{method:"POST",body:JSON.stringify({body:t.note})})}catch(i){this.log(`[business] report note failed: ${i.message}`)}}async listAll(e={}){let t=e.sinceDays??30,r=new Date(Date.now()-t*24*36e5).toISOString(),s=new URLSearchParams,o=e.state??"opened";s.set("state",o),s.set("updated_after",r),s.set("scope","all"),s.set("per_page","100"),s.set("with_labels_details","true"),s.set("order_by","updated_at"),s.set("sort","desc"),e.labels?.length&&s.set("labels",e.labels.join(",")),e.milestone&&s.set("milestone",e.milestone),e.search&&s.set("search",e.search);let a=this.projects.length?this.projects:["__ALL__"],i=[];for(let c of a)try{let u=c==="__ALL__"?`/issues?${s.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${s.toString()}`,g=await this.api(u);for(let d of g)i.push(this.mapIssue(d,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=i;if(e.notLabels?.length){let c=new Set(e.notLabels);l=l.filter(u=>!(u.labels||[]).some(g=>c.has(g)))}if(e.withoutScopedPrefix){let c=e.withoutScopedPrefix+"::";l=l.filter(u=>!(u.labels||[]).some(g=>g.startsWith(c)))}return l}async setState(e,t){let{project:r,iid:s,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?state_event=${t}`,{method:"PUT"})}async getItem(e){let{project:t,iid:r}=this.parseId(e);try{let s=await this.api(`/projects/${encodeURIComponent(t)}/issues/${r}?with_labels_details=true`);return{...this.mapIssue(s,t),descriptionHtml:s.description_html||void 0,createdAt:s.created_at,author:s.author?{username:s.author.username,name:s.author.name,avatarUrl:s.author.avatar_url}:void 0,allLabels:Array.isArray(s.labels)?typeof s.labels[0]=="object"?s.labels.map(a=>a.name):s.labels:[]}}catch(s){return this.log(`[board] GitLab getItem failed for ${e}: ${s.message}`),null}}async updateItem(e,t){let{project:r,iid:s}=this.parseId(e),o;t.assigneeUsernames&&(o=(await Promise.all(t.assigneeUsernames.map(async u=>{try{let g=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(g)&&g[0]?.id?g[0].id:null}catch{return null}}))).filter(u=>typeof u=="number"));let a;if(t.milestoneTitle!==void 0)if(t.milestoneTitle===null||t.milestoneTitle==="")a=0;else try{let c=await this.api(`/projects/${encodeURIComponent(r)}/milestones?title=${encodeURIComponent(t.milestoneTitle)}`);Array.isArray(c)&&c[0]?.id&&(a=c[0].id)}catch(c){this.log(`[board] milestone lookup failed for "${t.milestoneTitle}": ${c.message}`)}let i={};t.title!==void 0&&(i.title=t.title),t.description!==void 0&&(i.description=t.description),t.labels!==void 0&&(i.labels=t.labels.join(",")),t.addLabels?.length&&(i.add_labels=t.addLabels.join(",")),t.removeLabels?.length&&(i.remove_labels=t.removeLabels.join(",")),o!==void 0&&(i.assignee_ids=o),a!==void 0&&(i.milestone_id=a);let l=await this.api(`/projects/${encodeURIComponent(r)}/issues/${s}`,{method:"PUT",body:JSON.stringify(i)});return this.mapIssue(l,r)}async listMembers(){let e=new Map;for(let t of this.projects)try{let r=await this.api(`/projects/${encodeURIComponent(t)}/members/all?per_page=100`);for(let s of r)s.username&&!e.has(s.username)&&e.set(s.username,{username:s.username,name:s.name,avatarUrl:s.avatar_url})}catch(r){this.log(`[board] listMembers failed for ${t}: ${r.message}`)}return[...e.values()].sort((t,r)=>t.username.localeCompare(r.username))}async listMilestones(){let e=new Map;for(let r of this.projects)try{let s=await this.api(`/projects/${encodeURIComponent(r)}/milestones?per_page=100`);for(let o of s)o.title&&!e.has(o.title)&&e.set(o.title,{id:o.id,title:o.title,state:o.state,dueDate:o.due_date})}catch(s){this.log(`[board] listMilestones failed for ${r}: ${s.message}`)}let t=[...e.values()];return t.sort((r,s)=>r.state!==s.state?r.state==="active"?-1:1:r.title.localeCompare(s.title)),t}async create(e){let t=e.projectHint||this.projects[0];if(!t)throw new Error("GitLabWorkSource.create requires projectHint or configured projects");let r,s=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];s.length&&(r=(await Promise.all(s.map(async c=>{try{let u=await this.api(`/users?username=${encodeURIComponent(c)}`);return Array.isArray(u)&&u[0]?.id?u[0].id:null}catch(u){return this.log(`[board] user lookup failed for ${c}: ${u.message}`),null}}))).filter(c=>typeof c=="number"));let o;if(e.milestoneTitle)try{let l=await this.api(`/projects/${encodeURIComponent(t)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(o=l[0].id)}catch(l){this.log(`[board] milestone lookup failed for "${e.milestoneTitle}": ${l.message}`)}let a={title:e.title,description:e.description,labels:(e.labels||[]).join(",")};r?.length&&(a.assignee_ids=r),o!==void 0&&(a.milestone_id=o);let i=await this.api(`/projects/${encodeURIComponent(t)}/issues`,{method:"POST",body:JSON.stringify(a)});return this.mapIssue(i,t)}async transition(e,t,r){await this.transitionMany(e,t?[t]:[],r?[r]:[])}async transitionMany(e,t,r){let{project:s,iid:o,type:a}=this.parseId(e),i=a==="issue"?"issues":"merge_requests",l=new URLSearchParams;t.length&&l.set("add_labels",t.join(",")),r.length&&l.set("remove_labels",r.join(",")),l.toString()&&await this.api(`/projects/${encodeURIComponent(s)}/${i}/${o}?${l.toString()}`,{method:"PUT"})}parseId(e){let r=e.replace(/^gitlab:/,"").split(":"),s=r.pop(),o=r.pop()==="mr"?"mr":"issue";return{project:r.join(":"),type:o,iid:s}}};function Nn(n,e,t){let r=n.workSource;switch(r.type){case"backlog":return new ee(r.path,e,t);case"wiki":return new te(r.path,r.glob);case"gitlab":{let s=e.channels.gitlab;if(!s?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let o={};for(let i of s.agentMappings)i.gitlabUsernames.length&&(o[i.agentId]=i.gitlabUsernames);let a=r.projects.length?r.projects:s.routes.map(i=>i.project);return new ne(s.host,s.token,a,o,t)}}}var se="unmapped";function re(n,e=[]){if(!n)return se;let t=e.find(s=>s.id===n);if(t?.client)return t.client;let r=n.indexOf("/");return r>0?n.slice(0,r):n}function Et(n){let e=new Map,t=n.projects??[],r=n.orgChart??{};for(let o of t)o.pm&&(e.has(o.pm)||e.set(o.pm,re(o.id,t)));let s=(o,a=new Set)=>{if(e.has(o))return e.get(o);if(a.has(o))return;a.add(o);let i=r[o]?.reportsTo;if(!i)return;let l=s(i,a);return l&&e.set(o,l),l};for(let o of Object.keys(r))s(o);return e}function Lt(n,e,t=[]){if(!t.length)return;let r=t.filter(s=>!s.channel||s.channel===n);return r.find(s=>s.chatId&&e.chatId&&s.chatId===e.chatId)??r.find(s=>s.username&&e.username&&s.username===e.username)??r.find(s=>s.senderId&&e.senderId&&s.senderId===e.senderId)??r.find(s=>s.channel&&!s.chatId&&!s.username&&!s.senderId)}function Wn(n,e){let t=Lt(n.channel,{chatId:n.chatId,username:n.username},e.contactMap);if(t)return t.client;if(n.project)return re(n.project,e.projects);if(n.agentId){let r=Et(e).get(n.agentId);if(r)return r}return se}function zn(n,e){let t=String(n||"").split(":");if(t.length<3)return{agentId:e};let[r,s,...o]=t,a=o.join(":"),i={agentId:e||r,channel:s};return s==="gitlab"||s==="github"?i.project=a.split(":")[0]:s==="cron"||s==="api"||(i.chatId=a.split("@")[0]),i}var Ot=n=>n===se?"internal":"client";function Pt(n,e){let t=e.clients?.[n];return{id:n,name:t?.name||n,kind:t?.kind??Ot(n),respondWithinMinutes:Ft(t?.respondWithin),standing:t?.standing??[],declared:!!t}}function Hn(n){let e=new Set;for(let t of n.projects??[])e.add(re(t.id,n.projects));for(let t of n.contactMap??[])e.add(t.client);for(let t of Object.keys(n.clients??{}))e.add(t);return[...e].sort().map(t=>Pt(t,n))}function Ft(n){let e=/^(\d+)\s*([mhd])$/.exec(String(n??"").trim());if(!e)return;let t=Number(e[1]);return e[2]==="m"?t:e[2]==="h"?t*60:t*1440}import{existsSync as Bt,mkdirSync as Ut,readdirSync as Nt,readFileSync as Mt,renameSync as Wt,writeFileSync as zt}from"fs";import{resolve as Ne}from"path";var Ue=["discard","keep","pause","approve"],$={title:120,ask:300,recommend:300,source:500,note:500,pendingPerAgent:25},Ht={defaultExpiryDays:3,maxExpiryDays:30};function A(n){return Ne(n,".agentx","approvals")}var Kt=/^[a-z0-9][a-z0-9-]{0,80}$/;function Me(n){return Kt.test(n)}function We(n,e){if(!Me(e))throw new Error(`invalid card id: ${e}`);return Ne(A(n),`${e}.json`)}function qt(n,e){let t=new Date(n).toISOString().slice(0,10),r=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"").slice(0,40);return`${t}-${r||"card"}-${Math.random().toString(36).slice(2,6)}`}function M(n,e){Ut(A(n),{recursive:!0});let t=We(n,e.id),r=`${t}.${process.pid}.tmp`;zt(r,JSON.stringify(e,null,2)+`
|
|
10
|
+
`),Wt(r,t)}function j(n,e){if(!Me(e))return null;try{return JSON.parse(Mt(We(n,e),"utf-8"))}catch{return null}}function T(n,e){let t=A(n);if(!Bt(t))return[];let r=[];for(let s of Nt(t).filter(o=>o.endsWith(".json")&&!o.startsWith("_")).sort()){let o=j(n,s.slice(0,-5));o&&(!e||o.status===e)&&r.push(o)}return r}function y(n){return typeof n=="string"?n.replace(/\s+/g," ").trim():""}function Jt(n,e,t){let r=e+t.maxExpiryDays*864e5,s,o=y(n);if(!o)s=e+t.defaultExpiryDays*864e5;else{let a=/^(\d+)\s*([hd])$/i.exec(o);if(a)s=e+Number(a[1])*(a[2].toLowerCase()==="d"?864e5:36e5);else if(s=Date.parse(o),Number.isNaN(s))return{ok:!1,error:`expires must be an ISO date or time, or like "12h" / "3d" (got "${o}")`}}return s<=e?{ok:!1,error:"expires must be in the future"}:{ok:!0,at:new Date(Math.min(s,r)).toISOString()}}function Gt(n,e={}){let t=e.now??Date.now(),r=e.settings??Ht,s=y(n.title),o=y(n.ask),a=y(n.recommend),i=y(n.raised_by);if(!s)return{ok:!1,error:"title is required"};if(!o)return{ok:!1,error:"ask is required: the yes/no question"};if(!a)return{ok:!1,error:"recommend is required: your advice and why, in one line"};if(!i)return{ok:!1,error:"raised_by is required: the agent id"};if(s.length>$.title)return{ok:!1,error:`title is longer than ${$.title} characters`};if(o.length>$.ask)return{ok:!1,error:`ask is longer than ${$.ask} characters`};if(a.length>$.recommend)return{ok:!1,error:`recommend is longer than ${$.recommend} characters`};let l=y(n.if_silent).toLowerCase();if(!Ue.includes(l))return{ok:!1,error:`if_silent must be one of ${Ue.join(", ")}`};let c=Jt(n.expires,t,r);if(!c.ok)return c;let u=y(n.source);if(u.length>$.source)return{ok:!1,error:`source is longer than ${$.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 g,d=n.reply;return d&&typeof d=="object"&&y(d.channel)&&y(d.chatId)&&(g={channel:y(d.channel),chatId:y(d.chatId),...y(d.accountId)?{accountId:y(d.accountId)}:{}}),{ok:!0,card:{id:qt(t,s),title:s,ask:o,recommend:a,if_silent:l,expires:c.at,...u?{source:u}:{},raised_by:i,created_at:new Date(t).toISOString(),...g?{reply:g}:{},status:"pending"}}}function Gn(n,e,t={}){let r=Gt(e,t);if(!r.ok)return r;let s=T(n,"pending").filter(o=>o.raised_by===r.card.raised_by).length;return s>=$.pendingPerAgent?{ok:!1,error:`${r.card.raised_by} already has ${s} cards waiting; wait for decisions before raising more`}:(M(n,r.card),r)}function ze(n,e,t,r={}){let s=j(n,e);if(!s)return{ok:!1,error:`no card "${e}"`};if(s.status!=="pending")return{ok:!1,error:`card "${e}" is already ${s.status}`};let o=y(r.note).slice(0,$.note),a={...s,status:"decided",verdict:t,decided_by:r.by??"operator",decided_at:new Date(r.now??Date.now()).toISOString(),...o?{note:o}:{}};return M(n,a),{ok:!0,card:a}}function Vn(n,e=Date.now()){let t=[];for(let r of T(n,"pending")){if(Date.parse(r.expires)>e)continue;let s={...r,status:"expired",outcome:r.if_silent,decided_by:"expiry",decided_at:new Date(e).toISOString()};M(n,s),t.push(s)}return t}function Xn(n){return T(n).filter(e=>e.status!=="pending"&&!e.agent_notified_at)}function Yn(n,e,t=Date.now()){let r=j(n,e);!r||r.agent_notified_at||M(n,{...r,agent_notified_at:new Date(t).toISOString()})}function Qn(n){let e=n.status==="decided"?n.verdict==="yes"?"The operator said YES.":"The operator said NO.":`Nobody answered before it expired, so the default applied: ${n.outcome??n.if_silent}.`,t=[`[Approval result] Your decision card "${n.title}" (${n.id}) is closed.`,`Question: ${n.ask}`,e];return n.note&&t.push(`Operator note: ${n.note}`),n.source&&t.push(`Source: ${n.source}`),n.reply&&t.push(`You raised it from ${n.reply.channel} chat ${n.reply.chatId}; reply there if the requester should know.`),t.push("Act on this result now. Do not raise the same card again."),t.join(`
|
|
11
11
|
`)}import{existsSync as ie,readdirSync as en,readFileSync as tn}from"fs";import{resolve as C}from"path";import{mkdirSync as Vt,readFileSync as Xt,renameSync as Yt,writeFileSync as Qt}from"fs";import{resolve as Zt}from"path";function He(n){return Zt(A(n),"_state.json")}function W(n){try{let e=JSON.parse(Xt(He(n),"utf-8"));return{snoozed:e&&typeof e.snoozed=="object"&&e.snoozed?e.snoozed:{},...typeof e?.lastDigest=="string"?{lastDigest:e.lastDigest}:{}}}catch{return{snoozed:{}}}}function Ke(n,e){Vt(A(n),{recursive:!0});let t=He(n),r=`${t}.${process.pid}.tmp`;Qt(r,JSON.stringify(e,null,2)+`
|
|
12
|
-
`),Yt(r,t)}function qe(n,e,t,r=Date.now()){let s=W(n),o={};for(let[a,i]of Object.entries(s.snoozed))Date.parse(i)>r&&(o[a]=i);o[e]=t.toISOString(),Ke(n,{...s,snoozed:o})}function ns(n,e){Ke(n,{...W(n),lastDigest:e})}var Je=["card","schedule","memory","wiki"],nn=280;function oe(n,e=nn){let t=n.replace(/\s+/g," ").trim();return t.length>e?`${t.slice(0,e-1)}\u2026`:t}function Ge(n){if(n.configPath)return C(n.configPath);let e=[C(n.root,"agentx.json"),C(n.root,".agentx","config.json")];return e.find(t=>ie(t))??e[0]}function ae(n){return n.wikiDir?C(n.wikiDir):C(n.root,".agentx","wiki")}function sn(n){return T(n.root,"pending").map(rn)}function rn(n){return{key:`card:${n.id}`,kind:"card",title:n.title,ask:n.ask,yes:`tell ${n.raised_by} yes`,no:`tell ${n.raised_by} no`,recommend:n.recommend,if_silent:n.if_silent,expires:n.expires,...n.source?{source:n.source}:{},raised_by:n.raised_by,created_at:n.created_at}}function on(n){let e=Ge(n);if(!ie(e))return[];let t;try{t=JSON.parse(tn(e,"utf-8"))}catch{return[]}let r=new Date(n.now??Date.now()),s=[];for(let[o,a]of Object.entries(t?.crons??{})){let i=a?.approval;if(!i||i.action!=="create"&&i.action!=="delete")continue;let l=a.timezone||"UTC",c=a.schedule?be(a.schedule):"",u=a.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${a.schedule})`:"no schedule",g=String(a.prompt??a.command??""),d=i.action==="create";s.push({key:`schedule:${o}`,kind:"schedule",title:d?`New schedule "${o}" for ${a.agent??"an agent"}`:`Delete schedule "${o}"`,ask:d?`Let ${a.agent??"the agent"} run this ${u}?`:`Remove the schedule "${o}" (${u})?`,yes:d?"enable it":"remove it",no:d?"drop the request":"keep the schedule",raised_by:String(i.requestedBy??"unknown"),created_at:String(i.requestedAt??""),detail:oe(`${g}${d&&a.schedule?` \xB7 first run ${ke(ye(a.schedule,l,r),l)}`:""}`),more:"agentx schedule list"})}return s}function Ve(n){let e=C(n,".agentx","memory");return ie(e)?en(e).filter(t=>t.endsWith(".jsonl")).map(t=>t.slice(0,-6)).sort():[]}function an(n){let e=Ve(n.root);if(e.length===0)return[];let t=new J(n.root),r=[];for(let s of e)for(let o of t.held(s))r.push({key:`memory:${s}/${o.id}`,kind:"memory",title:`Fact ${s} learned from ${o.source.channel}`,ask:`Let ${s} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:s,created_at:o.createdAt,detail:oe(o.content),more:`agentx memory facts held --agent ${s}`});return r}function ln(n){return Ie(ae(n),"pending").map(e=>{let t=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:t.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:oe(`${t.sources.length} source(s)${t.occurrences>1?`, seen in ${t.occurrences} sessions`:""}. ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}var Xe={card:sn,schedule:on,memory:an,wiki:ln};function cn(n,e){let t=n.expires?Date.parse(n.expires):1/0,r=e.expires?Date.parse(e.expires):1/0;return t!==r?t-r:(Date.parse(n.created_at)||0)-(Date.parse(e.created_at)||0)}function gs(n,e={}){let t=n.now??Date.now(),{snoozed:r}=W(n.root),s=[],o=[],a=0;for(let i of e.kinds??Je){let l;try{l=Xe[i](n)}catch(c){o.push({kind:i,error:String(c?.message??c).slice(0,200)});continue}for(let c of l){let u=r[c.key];if(u&&Date.parse(u)>t){if(!e.includeSnoozed){a++;continue}c.snoozed_until=u}s.push(c)}}return s.sort(cn),{items:s,snoozed:a,errors:o}}function un(n){let e=n.indexOf(":");if(e<=0)return null;let t=n.slice(0,e),r=n.slice(e+1);return!Je.includes(t)||!r?null:{kind:t,ref:r}}function dn(n,e,t){switch(e){case"card":return j(n.root,t)?.status==="pending";case"wiki":return Se(ae(n),t)?.status==="pending";default:return Xe[e](n).some(r=>r.key===`${e}:${t}`)}}async function fs(n,e,t,r={}){let s=un(e);if(!s)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:o,ref:a}=s,i=n.now??Date.now(),l=r.by??"operator";if(t==="later"){if(!dn(n,o,a))return{ok:!1,error:`nothing waiting for "${e}"`};let u=r.laterHours&&r.laterHours>0?r.laterHours:24,g=new Date(i+u*36e5);return qe(n.root,e,g,i),{ok:!0,message:`${e} put off until ${g.toISOString()}`}}let c=t==="yes";switch(o){case"card":{let u=ze(n.root,a,c?"yes":"no",{by:l,note:r.note,now:i});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${c?"yes":"no"}`}:u}case"schedule":{let u=await(c?we:xe)(a,{configPath:Ge(n),reload:n.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=a.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let g=a.slice(0,u),d=a.slice(u+1);if(!Ve(n.root).includes(g))return{ok:!1,error:`no memory for agent "${g}"`};let f=new J(n.root);return f.held(g).some(m=>m.id===d)?(f.review(g,d,c?"approved":"rejected",l),{ok:!0,message:`${e} ${c?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${d}" isn't waiting for review`}}case"wiki":{let u=ae(n),g=c?$e(u,a,{by:l,force:r.force,now:i}):ve(u,a,{by:l,reason:r.note,now:i});return g.ok?{ok:!0,message:c?`${g.proposal.article.path} written to the shared wiki`:`${e} rejected`}:g}}}import{existsSync as x,readFileSync as de,writeFileSync as ge,mkdirSync as z,readdirSync as ue,rmSync as gn,statSync as $}from"fs";import{resolve as Ye,relative as fn,dirname as fe,join as _,extname as E,basename as me}from"path";var w=200*1024,Qe=new Set([".md",".markdown",".txt"]),D=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"]),mn=6,pn=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function R(n,e){if(!n)throw new Error("Agent workspace is not configured.");let t=Ye(n);if(x(t)||z(t,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let r=Ye(t,e);if(fn(t,r).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return r}function Ze(n){let e=E(n).toLowerCase();if(!Qe.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function le(n,e){let t=n.split(/\r?\n/).find(r=>r.trim().startsWith("#"));return t&&t.replace(/^#+\s*/,"").trim().slice(0,120)||e}function bs(n){let e=R(n,"."),t=[],r=new Set,s=[];try{s=ue(e)}catch{}for(let i of pn){let l=_(e,i);if(x(l)&&$(l).isFile()){let c=$(l).size,u=c>0&&c<w?ce(l):"";t.push({path:i,title:le(u,i),size:c,exists:!0}),r.add(i)}else t.push({path:i,title:i,size:0,exists:!1}),r.add(i)}for(let i of s){if(r.has(i))continue;let l=_(e,i);try{let c=$(l);if(!c.isFile()||!Qe.has(E(i).toLowerCase()))continue;let u=c.size>0&&c.size<w?ce(l):"";t.push({path:i,title:le(u,i),size:c.size,exists:!0})}catch{}}let o=[],a=_(e,".claude","skills");if(x(a))try{for(let i of ue(a)){let l=_(a,i),c;try{c=$(l)}catch{continue}if(!c.isDirectory())continue;let u=_(l,"SKILL.md");if(!x(u))continue;let g=$(u),d=g.size<w?ce(u):"";o.push({slug:i,title:le(d,i),size:g.size,path:`.claude/skills/${i}/SKILL.md`})}}catch{}return o.sort((i,l)=>i.slug.localeCompare(l.slug)),{identity:t,skills:o,workspace:e}}function ce(n){try{return de(n,"utf-8")}catch{return""}}function ys(n,e){let t=R(n,e);if(Ze(t),!x(t))return{path:e,content:""};if($(t).size>w)throw new Error(`File is too large to edit in the admin panel (> ${w/1024} KB).`);return{path:e,content:de(t,"utf-8")}}function ks(n,e,t){let r=R(n,e);Ze(r);let s=Buffer.from(t,"utf-8");if(s.length>w)throw new Error(`File too large (${s.length} > ${w} bytes).`);return z(fe(r),{recursive:!0}),ge(r,s),{path:e,bytes:s.length}}function ws(n,e,t={}){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 r=`.claude/skills/${e}/SKILL.md`,s=R(n,r);if(x(s))throw new Error(`Skill "${e}" already exists.`);z(fe(s),{recursive:!0});let o=t.content?.trim()?t.content:hn(e,t.title);return ge(s,o),{slug:e,path:r}}function xs(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);if(!$(t).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return gn(t,{recursive:!0,force:!0}),{slug:e}}function Ss(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);let r=[];return s(t,"",0,r),r.sort((o,a)=>o.kind!==a.kind?o.kind==="dir"?-1:1:o.path.localeCompare(a.path)),r;function s(o,a,i,l){if(i>mn)return;let c=[];try{c=ue(o)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let g=_(o,u),d=a?`${a}/${u}`:u,f;try{f=$(g)}catch{continue}if(f.isDirectory())l.push({path:`${d}/`,kind:"dir",size:0,editable:!1}),s(g,d,i+1,l);else if(f.isFile()){let m=E(u).toLowerCase(),h=D.has(m)||D.has(u.toLowerCase());l.push({path:d,kind:"file",size:f.size,editable:h&&f.size<w})}}}}function Is(n,e,t){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!t||t.includes(".."))throw new Error(`Invalid file path: ${t}`);let r=R(n,`.claude/skills/${e}/${t}`);if(!x(r)||!$(r).isFile())throw new Error(`File not found: ${t}`);let s=E(r).toLowerCase(),o=me(r).toLowerCase();if(!D.has(s)&&!D.has(o))throw new Error(`File type not editable: ${t}`);if($(r).size>w)throw new Error(`File too large to edit (> ${w/1024} KB): ${t}`);return{path:t,content:de(r,"utf-8")}}function $s(n,e,t,r){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!t||t.includes(".."))throw new Error(`Invalid file path: ${t}`);let s=R(n,`.claude/skills/${e}/${t}`),o=E(s).toLowerCase(),a=me(s).toLowerCase();if(!D.has(o)&&!D.has(a))throw new Error(`File type not editable: ${t}`);let i=Buffer.from(r,"utf-8");if(i.length>w)throw new Error(`File too large (${i.length} > ${w} bytes).`);return z(fe(s),{recursive:!0}),ge(s,i),{path:t,bytes:i.length}}function vs(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);let r=s=>x(_(t,s));return r("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:r("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:r("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:r("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:r("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function hn(n,e){return`# ${e?.trim()||n}
|
|
12
|
+
`),Yt(r,t)}function qe(n,e,t,r=Date.now()){let s=W(n),o={};for(let[a,i]of Object.entries(s.snoozed))Date.parse(i)>r&&(o[a]=i);o[e]=t.toISOString(),Ke(n,{...s,snoozed:o})}function ss(n,e){Ke(n,{...W(n),lastDigest:e})}var Je=["card","schedule","memory","wiki"],nn=280;function oe(n,e=nn){let t=n.replace(/\s+/g," ").trim();return t.length>e?`${t.slice(0,e-1)}\u2026`:t}function Ge(n){if(n.configPath)return C(n.configPath);let e=[C(n.root,"agentx.json"),C(n.root,".agentx","config.json")];return e.find(t=>ie(t))??e[0]}function ae(n){return n.wikiDir?C(n.wikiDir):C(n.root,".agentx","wiki")}function sn(n){return T(n.root,"pending").map(rn)}function rn(n){return{key:`card:${n.id}`,kind:"card",title:n.title,ask:n.ask,yes:`tell ${n.raised_by} yes`,no:`tell ${n.raised_by} no`,recommend:n.recommend,if_silent:n.if_silent,expires:n.expires,...n.source?{source:n.source}:{},raised_by:n.raised_by,created_at:n.created_at}}function on(n){let e=Ge(n);if(!ie(e))return[];let t;try{t=JSON.parse(tn(e,"utf-8"))}catch{return[]}let r=new Date(n.now??Date.now()),s=[];for(let[o,a]of Object.entries(t?.crons??{})){let i=a?.approval;if(!i||i.action!=="create"&&i.action!=="delete")continue;let l=a.timezone||"UTC",c=a.schedule?be(a.schedule):"",u=a.schedule?`${c.charAt(0).toLowerCase()}${c.slice(1)} (${a.schedule})`:"no schedule",g=String(a.prompt??a.command??""),d=i.action==="create";s.push({key:`schedule:${o}`,kind:"schedule",title:d?`New schedule "${o}" for ${a.agent??"an agent"}`:`Delete schedule "${o}"`,ask:d?`Let ${a.agent??"the agent"} run this ${u}?`:`Remove the schedule "${o}" (${u})?`,yes:d?"enable it":"remove it",no:d?"drop the request":"keep the schedule",raised_by:String(i.requestedBy??"unknown"),created_at:String(i.requestedAt??""),detail:oe(`${g}${d&&a.schedule?` \xB7 first run ${ke(ye(a.schedule,l,r),l)}`:""}`),more:"agentx schedule list"})}return s}function Ve(n){let e=C(n,".agentx","memory");return ie(e)?en(e).filter(t=>t.endsWith(".jsonl")).map(t=>t.slice(0,-6)).sort():[]}function an(n){let e=Ve(n.root);if(e.length===0)return[];let t=new J(n.root),r=[];for(let s of e)for(let o of t.held(s))r.push({key:`memory:${s}/${o.id}`,kind:"memory",title:`Fact ${s} learned from ${o.source.channel}`,ask:`Let ${s} use this fact in its prompts?`,yes:"use it",no:"keep it out for good",raised_by:s,created_at:o.createdAt,detail:oe(o.content),more:`agentx memory facts held --agent ${s}`});return r}function ln(n){let e=n.sources.filter(t=>t.failure);return e.length?e.map(t=>`Recurring failure: ${t.agentId}'s ${t.failure.tool} fails with "${t.failure.errorClass}" in ${t.occurrences??1} sessions (${t.failure.runs} runs).`).join(" "):`${n.sources.length} source(s)${n.occurrences>1?`, seen in ${n.occurrences} sessions`:""}.`}function cn(n){return $e(ae(n),"pending").map(e=>{let t=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:t.agents.join(", ")||"wiki promote",created_at:e.createdAt,detail:oe(`${ln(t)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}var Xe={card:sn,schedule:on,memory:an,wiki:cn};function un(n,e){let t=n.expires?Date.parse(n.expires):1/0,r=e.expires?Date.parse(e.expires):1/0;return t!==r?t-r:(Date.parse(n.created_at)||0)-(Date.parse(e.created_at)||0)}function fs(n,e={}){let t=n.now??Date.now(),{snoozed:r}=W(n.root),s=[],o=[],a=0;for(let i of e.kinds??Je){let l;try{l=Xe[i](n)}catch(c){o.push({kind:i,error:String(c?.message??c).slice(0,200)});continue}for(let c of l){let u=r[c.key];if(u&&Date.parse(u)>t){if(!e.includeSnoozed){a++;continue}c.snoozed_until=u}s.push(c)}}return s.sort(un),{items:s,snoozed:a,errors:o}}function dn(n){let e=n.indexOf(":");if(e<=0)return null;let t=n.slice(0,e),r=n.slice(e+1);return!Je.includes(t)||!r?null:{kind:t,ref:r}}function gn(n,e,t){switch(e){case"card":return j(n.root,t)?.status==="pending";case"wiki":return Se(ae(n),t)?.status==="pending";default:return Xe[e](n).some(r=>r.key===`${e}:${t}`)}}async function ms(n,e,t,r={}){let s=dn(e);if(!s)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:o,ref:a}=s,i=n.now??Date.now(),l=r.by??"operator";if(t==="later"){if(!gn(n,o,a))return{ok:!1,error:`nothing waiting for "${e}"`};let u=r.laterHours&&r.laterHours>0?r.laterHours:24,g=new Date(i+u*36e5);return qe(n.root,e,g,i),{ok:!0,message:`${e} put off until ${g.toISOString()}`}}let c=t==="yes";switch(o){case"card":{let u=ze(n.root,a,c?"yes":"no",{by:l,note:r.note,now:i});return u.ok?{ok:!0,message:`${e}: ${u.card.raised_by} will be told ${c?"yes":"no"}`}:u}case"schedule":{let u=await(c?we:xe)(a,{configPath:Ge(n),reload:n.reload});return u.success?{ok:!0,message:u.message}:{ok:!1,error:u.message}}case"memory":{let u=a.indexOf("/");if(u<=0)return{ok:!1,error:"memory keys look like memory:<agent>/<fact-id>"};let g=a.slice(0,u),d=a.slice(u+1);if(!Ve(n.root).includes(g))return{ok:!1,error:`no memory for agent "${g}"`};let f=new J(n.root);return f.held(g).some(m=>m.id===d)?(f.review(g,d,c?"approved":"rejected",l),{ok:!0,message:`${e} ${c?"approved: the agent may use it":"rejected: it stays out of prompts"}`}):{ok:!1,error:`fact "${d}" isn't waiting for review`}}case"wiki":{let u=ae(n),g=c?Ie(u,a,{by:l,force:r.force,now:i}):ve(u,a,{by:l,reason:r.note,now:i});return g.ok?{ok:!0,message:c?`${g.proposal.article.path} written to the shared wiki`:`${e} rejected`}:g}}}import{existsSync as x,readFileSync as de,writeFileSync as ge,mkdirSync as z,readdirSync as ue,rmSync as fn,statSync as I}from"fs";import{resolve as Ye,relative as mn,dirname as fe,join as _,extname as E,basename as me}from"path";var w=200*1024,Qe=new Set([".md",".markdown",".txt"]),D=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"]),pn=6,hn=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function R(n,e){if(!n)throw new Error("Agent workspace is not configured.");let t=Ye(n);if(x(t)||z(t,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let r=Ye(t,e);if(mn(t,r).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return r}function Ze(n){let e=E(n).toLowerCase();if(!Qe.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function le(n,e){let t=n.split(/\r?\n/).find(r=>r.trim().startsWith("#"));return t&&t.replace(/^#+\s*/,"").trim().slice(0,120)||e}function ys(n){let e=R(n,"."),t=[],r=new Set,s=[];try{s=ue(e)}catch{}for(let i of hn){let l=_(e,i);if(x(l)&&I(l).isFile()){let c=I(l).size,u=c>0&&c<w?ce(l):"";t.push({path:i,title:le(u,i),size:c,exists:!0}),r.add(i)}else t.push({path:i,title:i,size:0,exists:!1}),r.add(i)}for(let i of s){if(r.has(i))continue;let l=_(e,i);try{let c=I(l);if(!c.isFile()||!Qe.has(E(i).toLowerCase()))continue;let u=c.size>0&&c.size<w?ce(l):"";t.push({path:i,title:le(u,i),size:c.size,exists:!0})}catch{}}let o=[],a=_(e,".claude","skills");if(x(a))try{for(let i of ue(a)){let l=_(a,i),c;try{c=I(l)}catch{continue}if(!c.isDirectory())continue;let u=_(l,"SKILL.md");if(!x(u))continue;let g=I(u),d=g.size<w?ce(u):"";o.push({slug:i,title:le(d,i),size:g.size,path:`.claude/skills/${i}/SKILL.md`})}}catch{}return o.sort((i,l)=>i.slug.localeCompare(l.slug)),{identity:t,skills:o,workspace:e}}function ce(n){try{return de(n,"utf-8")}catch{return""}}function ks(n,e){let t=R(n,e);if(Ze(t),!x(t))return{path:e,content:""};if(I(t).size>w)throw new Error(`File is too large to edit in the admin panel (> ${w/1024} KB).`);return{path:e,content:de(t,"utf-8")}}function ws(n,e,t){let r=R(n,e);Ze(r);let s=Buffer.from(t,"utf-8");if(s.length>w)throw new Error(`File too large (${s.length} > ${w} bytes).`);return z(fe(r),{recursive:!0}),ge(r,s),{path:e,bytes:s.length}}function xs(n,e,t={}){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 r=`.claude/skills/${e}/SKILL.md`,s=R(n,r);if(x(s))throw new Error(`Skill "${e}" already exists.`);z(fe(s),{recursive:!0});let o=t.content?.trim()?t.content:bn(e,t.title);return ge(s,o),{slug:e,path:r}}function Ss(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);if(!I(t).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return fn(t,{recursive:!0,force:!0}),{slug:e}}function $s(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);let r=[];return s(t,"",0,r),r.sort((o,a)=>o.kind!==a.kind?o.kind==="dir"?-1:1:o.path.localeCompare(a.path)),r;function s(o,a,i,l){if(i>pn)return;let c=[];try{c=ue(o)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let g=_(o,u),d=a?`${a}/${u}`:u,f;try{f=I(g)}catch{continue}if(f.isDirectory())l.push({path:`${d}/`,kind:"dir",size:0,editable:!1}),s(g,d,i+1,l);else if(f.isFile()){let m=E(u).toLowerCase(),h=D.has(m)||D.has(u.toLowerCase());l.push({path:d,kind:"file",size:f.size,editable:h&&f.size<w})}}}}function Is(n,e,t){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!t||t.includes(".."))throw new Error(`Invalid file path: ${t}`);let r=R(n,`.claude/skills/${e}/${t}`);if(!x(r)||!I(r).isFile())throw new Error(`File not found: ${t}`);let s=E(r).toLowerCase(),o=me(r).toLowerCase();if(!D.has(s)&&!D.has(o))throw new Error(`File type not editable: ${t}`);if(I(r).size>w)throw new Error(`File too large to edit (> ${w/1024} KB): ${t}`);return{path:t,content:de(r,"utf-8")}}function vs(n,e,t,r){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);if(!t||t.includes(".."))throw new Error(`Invalid file path: ${t}`);let s=R(n,`.claude/skills/${e}/${t}`),o=E(s).toLowerCase(),a=me(s).toLowerCase();if(!D.has(o)&&!D.has(a))throw new Error(`File type not editable: ${t}`);let i=Buffer.from(r,"utf-8");if(i.length>w)throw new Error(`File too large (${i.length} > ${w} bytes).`);return z(fe(s),{recursive:!0}),ge(s,i),{path:t,bytes:i.length}}function Rs(n,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(n,`.claude/skills/${e}`);if(!x(t))throw new Error(`Skill "${e}" not found.`);let r=s=>x(_(t,s));return r("pnpm-lock.yaml")?{manager:"pnpm",file:"pnpm-lock.yaml",command:"pnpm install"}:r("yarn.lock")?{manager:"yarn",file:"yarn.lock",command:"yarn install"}:r("package.json")?{manager:"npm",file:"package.json",command:"npm install"}:r("requirements.txt")?{manager:"pip",file:"requirements.txt",command:"pip install -r requirements.txt"}:r("Gemfile")?{manager:"bundle",file:"Gemfile",command:"bundle install"}:{manager:null,file:null,command:null}}function bn(n,e){return`# ${e?.trim()||n}
|
|
13
13
|
|
|
14
14
|
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.
|
|
15
15
|
|
|
@@ -24,5 +24,5 @@ Document the arguments, commands, or files the skill expects. Example:
|
|
|
24
24
|
# Example invocation
|
|
25
25
|
claude-code ${me(n)} --arg value
|
|
26
26
|
\`\`\`
|
|
27
|
-
`}rt();var et={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function tt(n){return{...et,...n??{},regions:{...n?.regions??{}},buffer:{...et.buffer,...n?.buffer??{}}}}function
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
27
|
+
`}rt();var et={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function tt(n){return{...et,...n??{},regions:{...n?.regions??{}},buffer:{...et.buffer,...n?.buffer??{}}}}function Cs(n){try{return tt(pe(n).screen)}catch{return tt(void 0)}}var yn=/^[a-z][\w-]*$/,nt=["window","screen","menubar","notifications"];function L(n,e,t,r){let s=Number(n);if(n===""||n===null||!Number.isFinite(s)||!t(s))throw new Error(`${e} must be ${r}`);return s}var H=(n,e)=>L(n,e,t=>Number.isInteger(t)&&t>0,"a whole number above 0");function st(n){let e=typeof n=="string"?n.split(",").map(Number):[n?.x,n?.y,n?.width,n?.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 Ds(n,e){let t={...n??{}};if("maxPixels"in e&&(t.maxPixels=H(e.maxPixels,"maxPixels")),"timeoutMs"in e&&(t.timeoutMs=H(e.timeoutMs,"timeoutMs")),"intervalMs"in e&&(t.intervalMs=H(e.intervalMs,"intervalMs")),"stableMs"in e&&(t.stableMs=L(e.stableMs,"stableMs",s=>Number.isInteger(s)&&s>=0,"a whole number, 0 or more")),"changeThreshold"in e&&(t.changeThreshold=L(e.changeThreshold,"changeThreshold",s=>s>=0&&s<=1,"between 0 and 1")),e.regions&&typeof e.regions=="object"){let s={...t.regions??{}};for(let[o,a]of Object.entries(e.regions)){if(!yn.test(o))throw new Error(`region name "${o}" must be lowercase letters, digits, - or _`);a===null?delete s[o]:s[o]=st(a)}t.regions=s}if(e.buffer&&typeof e.buffer=="object"){let s=e.buffer,o={...t.buffer??{}};"enabled"in s&&(o.enabled=!!s.enabled),"seconds"in s&&(o.seconds=L(s.seconds,"buffer.seconds",a=>a>0&&a<=120,"above 0 and at most 120")),"fps"in s&&(o.fps=L(s.fps,"buffer.fps",a=>a>0&&a<=10,"above 0 and at most 10")),"maxPixels"in s&&(o.maxPixels=H(s.maxPixels,"buffer.maxPixels")),"region"in s&&(o.region=String(s.region).trim()),t.buffer=o}let r=t.buffer?.region;if(r!==void 0&&!nt.includes(r)&&!t.regions?.[r])try{st(r)}catch{throw new Error(`buffer.region "${r}" is not a region \u2014 use ${[...nt,...Object.keys(t.regions??{})].join(", ")}, or x,y,w,h`)}return t}export{Re as a,xn as b,re as c,Et as d,Lt as e,Wn as f,zn as g,Hn as h,k as i,vn as j,Ue as k,Me as l,j as m,Gn as n,Vn as o,Xn as p,Yn as q,Qn as r,W as s,ss as t,fs as u,ms as v,_n as w,An as x,U as y,En as z,Pe as A,V as B,ne as C,Nn as D,ys as E,ks as F,ws as G,xs as H,Ss as I,$s as J,Is as K,vs as L,Rs as M,et as N,tt as O,Cs as P,nt as Q,Ds as R};
|
|
28
|
+
//# sourceMappingURL=chunk-EMI3VJLH.js.map
|