agentix-cli 0.43.0 → 0.44.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/apps/mac-helper/Resources/AppIcon.png +0 -0
  2. package/apps/mac-helper/Sources/AgentXHelper/Notify.swift +51 -0
  3. package/apps/mac-helper/Sources/AgentXHelper/main.swift +15 -1
  4. package/apps/mac-helper/build.sh +25 -2
  5. package/dist/{App-HSRGG5VA.js → App-QTUGMHG7.js} +2 -2
  6. package/dist/{ChatApp-4FOU6Q3S.js → ChatApp-634FDG3W.js} +2 -2
  7. package/dist/{agent-54NUP2Z3.js → agent-3XDPLWMX.js} +2 -2
  8. package/dist/{board-dashboard-HLTVSSGW.js → board-dashboard-B5FMUMGA.js} +470 -182
  9. package/dist/board-dashboard-B5FMUMGA.js.map +1 -0
  10. package/dist/{chunk-XRPMP6A5.js → chunk-3TL5EIVN.js} +151 -148
  11. package/dist/chunk-3TL5EIVN.js.map +1 -0
  12. package/dist/{chunk-H4MIYENA.js → chunk-6HMZ5TTM.js} +2 -2
  13. package/dist/{chunk-SJPLXXCI.js → chunk-7A7RC3R4.js} +2 -2
  14. package/dist/chunk-BIFJSQB5.js +123 -0
  15. package/dist/chunk-BIFJSQB5.js.map +1 -0
  16. package/dist/{chunk-WBGROLOX.js → chunk-BTGPZ6B7.js} +2 -2
  17. package/dist/{chunk-X763UOES.js → chunk-ICZPZYYR.js} +2 -2
  18. package/dist/{chunk-RCVGIKC2.js → chunk-MTVRYTLL.js} +2 -2
  19. package/dist/chunk-MX5GCR7Y.js +36 -0
  20. package/dist/chunk-MX5GCR7Y.js.map +1 -0
  21. package/dist/{chunk-B32HVIDN.js → chunk-NSYY5NCR.js} +3 -3
  22. package/dist/chunk-NSYY5NCR.js.map +1 -0
  23. package/dist/chunk-QJANPP4C.js +15 -0
  24. package/dist/chunk-QJANPP4C.js.map +1 -0
  25. package/dist/{chunk-REPZID5M.js → chunk-SAFAI4AV.js} +43 -43
  26. package/dist/chunk-SAFAI4AV.js.map +1 -0
  27. package/dist/chunk-T76YTN34.js +178 -0
  28. package/dist/chunk-T76YTN34.js.map +1 -0
  29. package/dist/chunk-TCJ3SMOF.js +9 -0
  30. package/dist/chunk-TCJ3SMOF.js.map +1 -0
  31. package/dist/{chunk-RQKUQOFC.js → chunk-TNFOGJWZ.js} +2 -2
  32. package/dist/{chunk-FAJEBVZE.js → chunk-V5FZJUK4.js} +2 -2
  33. package/dist/chunk-WLVQDEOT.js +2 -0
  34. package/dist/chunk-WLVQDEOT.js.map +1 -0
  35. package/dist/{chunk-B5HKRYCU.js → chunk-YQVR2HQS.js} +2 -2
  36. package/dist/{chunk-2HNKBYQ6.js → chunk-ZQOGAUQS.js} +194 -210
  37. package/dist/chunk-ZQOGAUQS.js.map +1 -0
  38. package/dist/cli.js +1 -1
  39. package/dist/cli.js.map +1 -1
  40. package/dist/client-NTC667CA.js +2 -0
  41. package/dist/config-5V444ZFW.js +2 -0
  42. package/dist/config-mutator-E6NQLFWR.js +2 -0
  43. package/dist/doctor-5HDW5F66.js +2 -0
  44. package/dist/{editor-chat-OB7IQOB5.js → editor-chat-MOMQHMO4.js} +2 -2
  45. package/dist/editor-chat-MOMQHMO4.js.map +1 -0
  46. package/dist/index.d.ts +462 -46
  47. package/dist/index.js +1 -1
  48. package/dist/index.js.map +1 -1
  49. package/dist/program-JLCKBO2A.js +2 -0
  50. package/dist/query-6EMTLCHQ.js +2 -0
  51. package/dist/registry-5QOY65FS.js +2 -0
  52. package/dist/{request-planner-326NOKPZ.js → request-planner-KYQCJDAW.js} +2 -2
  53. package/dist/{review-candidates-LEOPEOEG.js → review-candidates-BFAWNDOR.js} +2 -2
  54. package/dist/routing-OC3QJI3W.js +2 -0
  55. package/dist/schedule-tool-VQCNMBJF.js +8 -0
  56. package/dist/schedule-tool-VQCNMBJF.js.map +1 -0
  57. package/dist/scheduler-NRXPVG7P.js +2 -0
  58. package/dist/seat-3WT3VJC2.js +2 -0
  59. package/dist/{select-L4VIYSFJ.js → select-KPQWIC22.js} +2 -2
  60. package/dist/web/activity-graph.global.js.map +1 -1
  61. package/dist/web/workflow-editor.global.js +1 -1
  62. package/dist/web/workflow-editor.global.js.map +1 -1
  63. package/dist/wiki-5JORBO4G.js +2 -0
  64. package/package.json +2 -1
  65. package/dist/board-dashboard-HLTVSSGW.js.map +0 -1
  66. package/dist/chunk-2HNKBYQ6.js.map +0 -1
  67. package/dist/chunk-B32HVIDN.js.map +0 -1
  68. package/dist/chunk-DIKZWTL5.js +0 -170
  69. package/dist/chunk-DIKZWTL5.js.map +0 -1
  70. package/dist/chunk-F6CNF7V3.js +0 -25
  71. package/dist/chunk-F6CNF7V3.js.map +0 -1
  72. package/dist/chunk-IAG6FI3Q.js +0 -13
  73. package/dist/chunk-IAG6FI3Q.js.map +0 -1
  74. package/dist/chunk-NZ6AQIKJ.js +0 -121
  75. package/dist/chunk-NZ6AQIKJ.js.map +0 -1
  76. package/dist/chunk-P7LNYB53.js +0 -9
  77. package/dist/chunk-P7LNYB53.js.map +0 -1
  78. package/dist/chunk-REPZID5M.js.map +0 -1
  79. package/dist/chunk-XRPMP6A5.js.map +0 -1
  80. package/dist/client-6BGTH2TT.js +0 -2
  81. package/dist/config-SRTXHGSK.js +0 -2
  82. package/dist/config-mutator-KJ5GEMVV.js +0 -2
  83. package/dist/doctor-J4FLV45L.js +0 -2
  84. package/dist/editor-chat-OB7IQOB5.js.map +0 -1
  85. package/dist/program-LYFTYF7E.js +0 -2
  86. package/dist/query-ZSUBNWOL.js +0 -2
  87. package/dist/registry-OMUDCBKM.js +0 -2
  88. package/dist/routing-AWIRBYGU.js +0 -2
  89. package/dist/scheduler-PGGYW5AB.js +0 -2
  90. package/dist/seat-XB4EGUKJ.js +0 -2
  91. package/dist/wiki-GBC6I7ZX.js +0 -2
  92. /package/dist/{App-HSRGG5VA.js.map → App-QTUGMHG7.js.map} +0 -0
  93. /package/dist/{ChatApp-4FOU6Q3S.js.map → ChatApp-634FDG3W.js.map} +0 -0
  94. /package/dist/{agent-54NUP2Z3.js.map → agent-3XDPLWMX.js.map} +0 -0
  95. /package/dist/{chunk-H4MIYENA.js.map → chunk-6HMZ5TTM.js.map} +0 -0
  96. /package/dist/{chunk-SJPLXXCI.js.map → chunk-7A7RC3R4.js.map} +0 -0
  97. /package/dist/{chunk-WBGROLOX.js.map → chunk-BTGPZ6B7.js.map} +0 -0
  98. /package/dist/{chunk-X763UOES.js.map → chunk-ICZPZYYR.js.map} +0 -0
  99. /package/dist/{chunk-RCVGIKC2.js.map → chunk-MTVRYTLL.js.map} +0 -0
  100. /package/dist/{chunk-RQKUQOFC.js.map → chunk-TNFOGJWZ.js.map} +0 -0
  101. /package/dist/{chunk-FAJEBVZE.js.map → chunk-V5FZJUK4.js.map} +0 -0
  102. /package/dist/{chunk-B5HKRYCU.js.map → chunk-YQVR2HQS.js.map} +0 -0
  103. /package/dist/{client-6BGTH2TT.js.map → client-NTC667CA.js.map} +0 -0
  104. /package/dist/{config-SRTXHGSK.js.map → config-5V444ZFW.js.map} +0 -0
  105. /package/dist/{config-mutator-KJ5GEMVV.js.map → config-mutator-E6NQLFWR.js.map} +0 -0
  106. /package/dist/{doctor-J4FLV45L.js.map → doctor-5HDW5F66.js.map} +0 -0
  107. /package/dist/{program-LYFTYF7E.js.map → program-JLCKBO2A.js.map} +0 -0
  108. /package/dist/{query-ZSUBNWOL.js.map → query-6EMTLCHQ.js.map} +0 -0
  109. /package/dist/{registry-OMUDCBKM.js.map → registry-5QOY65FS.js.map} +0 -0
  110. /package/dist/{request-planner-326NOKPZ.js.map → request-planner-KYQCJDAW.js.map} +0 -0
  111. /package/dist/{review-candidates-LEOPEOEG.js.map → review-candidates-BFAWNDOR.js.map} +0 -0
  112. /package/dist/{routing-AWIRBYGU.js.map → routing-OC3QJI3W.js.map} +0 -0
  113. /package/dist/{scheduler-PGGYW5AB.js.map → scheduler-NRXPVG7P.js.map} +0 -0
  114. /package/dist/{seat-XB4EGUKJ.js.map → seat-3WT3VJC2.js.map} +0 -0
  115. /package/dist/{select-L4VIYSFJ.js.map → select-KPQWIC22.js.map} +0 -0
  116. /package/dist/{wiki-GBC6I7ZX.js.map → wiki-5JORBO4G.js.map} +0 -0
@@ -1,4 +1,4 @@
1
- import{a as T,b as P,c as _,d as G}from"./chunk-PNWNVOEZ.js";import{b as ee}from"./chunk-64P4QHSZ.js";import{a as te,b as se,c as re,d as ie,e as ne}from"./chunk-AJ5RMU7X.js";import{v as Z,w as he}from"./chunk-H4MIYENA.js";import{a as Q,b as pe}from"./chunk-AJONZWLT.js";import{c as M,d as L}from"./chunk-QOYAX2FT.js";import{o as X,p as de}from"./chunk-LCIREYTD.js";var A={version:2,levels:[{id:"category",description:"Top-level kind of work. Closed set \u2014 pick the closest fit.",axes:[{name:"kind",type:"enum",values:["code","ops","support","admin","knowledge","social","system"],description:"Which category this work belongs in."}]},{id:"verb",description:"Specific intent \u2014 verb-level only, NOT client/project-bound.",axes:[{name:"name",type:"free",description:"Lower-kebab dot-namespaced verb. Examples: review.merge-request, fix.bug, investigate.error, deploy.staging, deploy.production, rollback.release, spec.feature, triage.issue, document.feature, chat.greeting, chat.support-request, schedule.add, config.change, ingest.contact, transcribe.audio, brief.daily, summarize.thread, plan.work."}]}],leafInput:{name:"input",type:"enum",values:["telegram","whatsapp","slack","discord","gitlab-mr","gitlab-issue","github-issue","github-pr","cron","webhook","mesh","http"],description:"Where the message entered the system."},leafOutput:{name:"output",type:"free",description:"One short sentence describing what the agent is expected to produce. Generic \u2014 refers to the verb's outcome, not the specific client/project (those are on the event metadata already)."}},F=[{category:"code",verb:"review.merge-request",description:"Review a GitLab MR or GitHub PR"},{category:"code",verb:"review.code-change",description:"General code review (snippet, diff)"},{category:"code",verb:"fix.bug",description:"Fix a reported bug"},{category:"code",verb:"implement.feature",description:"Build a new feature"},{category:"code",verb:"investigate.error",description:"Investigate a failing test, exception, pipeline"},{category:"code",verb:"refactor.code",description:"Restructure existing code without behaviour change"},{category:"code",verb:"spec.feature",description:"Write or update a feature spec / RFC"},{category:"code",verb:"triage.issue",description:"Classify, label, or assign an issue"},{category:"code",verb:"answer.code-question",description:"Answer a code-related question"},{category:"ops",verb:"deploy.staging",description:"Deploy to a staging/preview environment"},{category:"ops",verb:"deploy.production",description:"Deploy to production"},{category:"ops",verb:"rollback.release",description:"Roll back a release"},{category:"ops",verb:"investigate.incident",description:"Investigate a production incident"},{category:"ops",verb:"monitor.system",description:"Check system status / metrics"},{category:"ops",verb:"rotate.credential",description:"Rotate a token, key, certificate"},{category:"ops",verb:"audit.security",description:"Review for security issues"},{category:"support",verb:"chat.greeting",description:"A casual hello, no actionable request"},{category:"support",verb:"chat.support-request",description:"End-user / customer asking for help"},{category:"support",verb:"chat.casual",description:"Informal back-and-forth chat"},{category:"support",verb:"answer.question",description:"Answer an open-ended question"},{category:"support",verb:"route.request",description:"Forward a request to the right agent"},{category:"admin",verb:"config.change",description:"Change agentx.json / environment / config"},{category:"admin",verb:"schedule.add",description:"Add a new cron / scheduled task"},{category:"admin",verb:"schedule.remove",description:"Remove or disable a schedule"},{category:"admin",verb:"token.create",description:"Mint a scoped API token"},{category:"admin",verb:"agent.add",description:"Configure a new agent"},{category:"admin",verb:"channel.add",description:"Wire up a new channel"},{category:"knowledge",verb:"document.feature",description:"Write or update documentation"},{category:"knowledge",verb:"summarize.thread",description:"Summarize a long conversation/thread"},{category:"knowledge",verb:"research.topic",description:"Investigate / gather info on a topic"},{category:"knowledge",verb:"wiki.absorb",description:"Roll raw entries into typed wiki articles"},{category:"social",verb:"brief.daily",description:"Compose a daily brief / digest"},{category:"social",verb:"draft.post",description:"Draft a marketing post / announcement"},{category:"social",verb:"report.weekly",description:"Compose a weekly status report"},{category:"system",verb:"classify.intent",description:"Internal: graph-classifier sub-call"}];import{readFileSync as D,writeFileSync as J,appendFileSync as ge,existsSync as I,mkdirSync as U,renameSync as ue}from"fs";import{resolve as R,dirname as ae}from"path";import{createHash as fe}from"crypto";var H=class{baseDir;log;constructor(e={}){this.baseDir=e.baseDir??R(process.cwd(),".agentx/graph"),this.log=e.log??console.error.bind(console,"[graph]"),U(this.baseDir,{recursive:!0})}schemaPath(){return R(this.baseDir,"schema.json")}nodesPath(){return R(this.baseDir,"nodes.json")}indexPath(){return R(this.baseDir,"index.json")}classificationsPath(){return R(this.baseDir,"classifications.jsonl")}loadSchema(){let e=this.schemaPath();if(!I(e))return this.saveSchema(A),this.log("seeded starter schema at",e),A;let t=D(e,"utf-8"),s=T.safeParse(JSON.parse(t));if(!s.success)throw new Error(`Invalid ${e}: ${s.error.issues.map(r=>r.message).join("; ")}`);if((s.data.version??1)<(A.version??2)){let r=e.replace(/\.json$/,`.v${s.data.version??1}.bak.json`);try{J(r,t),this.log(`migrated graph schema v${s.data.version??1} -> v${A.version}; old saved at ${r}`)}catch(n){this.log(`could not back up old schema: ${n?.message??n}`)}this.saveSchema(A);let o=this.nodesPath();if(I(o)){let n=o.replace(/\.json$/,".v1.bak.json");try{J(n,D(o,"utf-8")),this.log(`archived v1 nodes.json -> ${n}`)}catch(i){this.log(`could not back up old nodes: ${i?.message??i}`)}try{let i=oe();this.saveNodes(i)}catch(i){this.log(`could not seed v2 nodes: ${i?.message??i}`)}}return A}return s.data}saveSchema(e){let t=T.safeParse(e);if(!t.success)throw new Error(`Refusing to save invalid schema: ${t.error.issues.map(s=>s.message).join("; ")}`);B(this.schemaPath(),t.data)}loadNodes(){let e=this.nodesPath();if(!I(e)){let r=oe();return this.saveNodes(r),r}let t=D(e,"utf-8"),s=_.safeParse(JSON.parse(t));if(!s.success)throw new Error(`Invalid ${e}: ${s.error.issues.map(r=>r.message).join("; ")}`);return s.data}saveNodes(e){let t=_.safeParse(e);if(!t.success)throw new Error(`Refusing to save invalid nodes file: ${t.error.issues.map(s=>s.message).join("; ")}`);B(this.nodesPath(),t.data)}validateNode(e,t,s){let r=t.levels.find(i=>i.id===e.level);if(!r)throw new Error(`Unknown level: "${e.level}"`);let o=r.axes.filter(i=>!i.optional).filter(i=>!(i.name in e.axes));if(o.length)throw new Error(`Node ${e.id} (${e.level}) missing required axes: ${o.map(i=>i.name).join(", ")}`);for(let i of r.axes){let a=e.axes[i.name];if(a!=null){if(i.type==="enum"&&i.values&&!i.values.includes(a))throw new Error(`Node ${e.id}: axis ${i.name}="${a}" not in enum ${JSON.stringify(i.values)}`);if(i.type==="ref"){if(!s.some(c=>c.id===a))throw new Error(`Node ${e.id}: axis ${i.name}="${a}" refers to unknown node`);if(i.refLevel){let c=s.find(l=>l.id===a);if(c.level!==i.refLevel)throw new Error(`Node ${e.id}: axis ${i.name} expected level "${i.refLevel}" but got "${c.level}"`)}}}}let n=t.levels.findIndex(i=>i.id===e.level);if(n===0){if(e.parentId!==null)throw new Error(`Root-level node ${e.id} must have parentId: null`)}else{if(!e.parentId)throw new Error(`Non-root node ${e.id} must have a parentId`);let i=s.find(c=>c.id===e.parentId);if(!i)throw new Error(`Node ${e.id}: parent "${e.parentId}" not found`);let a=t.levels.findIndex(c=>c.id===i.level);if(a<0||a>=n)throw new Error(`Node ${e.id} at level "${e.level}" has parent at level "${i.level}" \u2014 parent must be at a higher level`)}}commitNodesAlongPath(e,t,s,r){let o=[],n=[],i=new Date().toISOString();for(let a=0;a<e.length;a++){let c=e[a],l=this.loadNodes().nodes;if(l.find(m=>m.id===c)){n.push(c);continue}let p=0;for(let m=a-1;m>=0;m--){let w=e[m],N=l.find(k=>k.id===w)||o.find(k=>k.id===w);if(N){p=s.levels.findIndex(k=>k.id===N.level)+1;break}}let g=t[c]??{},d=null;for(let m=p;m<s.levels.length;m++){let w=s.levels[m];if(w.axes.filter(k=>!k.optional).filter(k=>!(k.name in g)).length===0){d=w.id,p=m+1;break}}if(!d&&p<s.levels.length&&(d=s.levels[p].id,p++),!d)throw new Error(`Can't place node ${c} \u2014 no schema level left (cursor=${p}, levels=${s.levels.length})`);let h=null,f=s.levels.findIndex(m=>m.id===d);for(let m=a-1;m>=0;m--){let w=e[m],N=l.find(C=>C.id===w)||o.find(C=>C.id===w);if(!N)continue;let k=s.levels.findIndex(C=>C.id===N.level);if(k>=0&&k<f){h=w;break}}let u={id:c,level:d,parentId:h,axes:g,createdAt:i,createdBy:r};this.addNode(u),o.push(u)}return{added:o,skipped:n}}addNode(e){let t=this.loadSchema(),s=this.loadNodes();if(s.nodes.some(r=>r.id===e.id))throw new Error(`Node id already exists: ${e.id}`);return this.validateNode(e,t,[...s.nodes,e]),s.nodes.push(e),this.saveNodes(s),e}appendClassification(e){let t=P.safeParse(e);if(!t.success){let o=t.error.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(" \xB7 ");return this.log(`skipped invalid classification \u2014 ${o} \xB7`,`path=${JSON.stringify(e.path)}`,`axes-keys=${JSON.stringify(Object.keys(e.proposedAxes||{}))}`),!1}let s=JSON.stringify(t.data)+`
1
+ import{a as T,b as P,c as _,d as G}from"./chunk-PNWNVOEZ.js";import{b as ee}from"./chunk-64P4QHSZ.js";import{a as te,b as se,c as re,d as ie,e as ne}from"./chunk-AJ5RMU7X.js";import{v as Z,w as he}from"./chunk-6HMZ5TTM.js";import{a as Q,b as pe}from"./chunk-AJONZWLT.js";import{c as M,d as L}from"./chunk-QOYAX2FT.js";import{o as X,p as de}from"./chunk-LCIREYTD.js";var A={version:2,levels:[{id:"category",description:"Top-level kind of work. Closed set \u2014 pick the closest fit.",axes:[{name:"kind",type:"enum",values:["code","ops","support","admin","knowledge","social","system"],description:"Which category this work belongs in."}]},{id:"verb",description:"Specific intent \u2014 verb-level only, NOT client/project-bound.",axes:[{name:"name",type:"free",description:"Lower-kebab dot-namespaced verb. Examples: review.merge-request, fix.bug, investigate.error, deploy.staging, deploy.production, rollback.release, spec.feature, triage.issue, document.feature, chat.greeting, chat.support-request, schedule.add, config.change, ingest.contact, transcribe.audio, brief.daily, summarize.thread, plan.work."}]}],leafInput:{name:"input",type:"enum",values:["telegram","whatsapp","slack","discord","gitlab-mr","gitlab-issue","github-issue","github-pr","cron","webhook","mesh","http"],description:"Where the message entered the system."},leafOutput:{name:"output",type:"free",description:"One short sentence describing what the agent is expected to produce. Generic \u2014 refers to the verb's outcome, not the specific client/project (those are on the event metadata already)."}},F=[{category:"code",verb:"review.merge-request",description:"Review a GitLab MR or GitHub PR"},{category:"code",verb:"review.code-change",description:"General code review (snippet, diff)"},{category:"code",verb:"fix.bug",description:"Fix a reported bug"},{category:"code",verb:"implement.feature",description:"Build a new feature"},{category:"code",verb:"investigate.error",description:"Investigate a failing test, exception, pipeline"},{category:"code",verb:"refactor.code",description:"Restructure existing code without behaviour change"},{category:"code",verb:"spec.feature",description:"Write or update a feature spec / RFC"},{category:"code",verb:"triage.issue",description:"Classify, label, or assign an issue"},{category:"code",verb:"answer.code-question",description:"Answer a code-related question"},{category:"ops",verb:"deploy.staging",description:"Deploy to a staging/preview environment"},{category:"ops",verb:"deploy.production",description:"Deploy to production"},{category:"ops",verb:"rollback.release",description:"Roll back a release"},{category:"ops",verb:"investigate.incident",description:"Investigate a production incident"},{category:"ops",verb:"monitor.system",description:"Check system status / metrics"},{category:"ops",verb:"rotate.credential",description:"Rotate a token, key, certificate"},{category:"ops",verb:"audit.security",description:"Review for security issues"},{category:"support",verb:"chat.greeting",description:"A casual hello, no actionable request"},{category:"support",verb:"chat.support-request",description:"End-user / customer asking for help"},{category:"support",verb:"chat.casual",description:"Informal back-and-forth chat"},{category:"support",verb:"answer.question",description:"Answer an open-ended question"},{category:"support",verb:"route.request",description:"Forward a request to the right agent"},{category:"admin",verb:"config.change",description:"Change agentx.json / environment / config"},{category:"admin",verb:"schedule.add",description:"Add a new cron / scheduled task"},{category:"admin",verb:"schedule.remove",description:"Remove or disable a schedule"},{category:"admin",verb:"token.create",description:"Mint a scoped API token"},{category:"admin",verb:"agent.add",description:"Configure a new agent"},{category:"admin",verb:"channel.add",description:"Wire up a new channel"},{category:"knowledge",verb:"document.feature",description:"Write or update documentation"},{category:"knowledge",verb:"summarize.thread",description:"Summarize a long conversation/thread"},{category:"knowledge",verb:"research.topic",description:"Investigate / gather info on a topic"},{category:"knowledge",verb:"wiki.absorb",description:"Roll raw entries into typed wiki articles"},{category:"social",verb:"brief.daily",description:"Compose a daily brief / digest"},{category:"social",verb:"draft.post",description:"Draft a marketing post / announcement"},{category:"social",verb:"report.weekly",description:"Compose a weekly status report"},{category:"system",verb:"classify.intent",description:"Internal: graph-classifier sub-call"}];import{readFileSync as D,writeFileSync as J,appendFileSync as ge,existsSync as I,mkdirSync as U,renameSync as ue}from"fs";import{resolve as R,dirname as ae}from"path";import{createHash as fe}from"crypto";var H=class{baseDir;log;constructor(e={}){this.baseDir=e.baseDir??R(process.cwd(),".agentx/graph"),this.log=e.log??console.error.bind(console,"[graph]"),U(this.baseDir,{recursive:!0})}schemaPath(){return R(this.baseDir,"schema.json")}nodesPath(){return R(this.baseDir,"nodes.json")}indexPath(){return R(this.baseDir,"index.json")}classificationsPath(){return R(this.baseDir,"classifications.jsonl")}loadSchema(){let e=this.schemaPath();if(!I(e))return this.saveSchema(A),this.log("seeded starter schema at",e),A;let t=D(e,"utf-8"),s=T.safeParse(JSON.parse(t));if(!s.success)throw new Error(`Invalid ${e}: ${s.error.issues.map(r=>r.message).join("; ")}`);if((s.data.version??1)<(A.version??2)){let r=e.replace(/\.json$/,`.v${s.data.version??1}.bak.json`);try{J(r,t),this.log(`migrated graph schema v${s.data.version??1} -> v${A.version}; old saved at ${r}`)}catch(n){this.log(`could not back up old schema: ${n?.message??n}`)}this.saveSchema(A);let o=this.nodesPath();if(I(o)){let n=o.replace(/\.json$/,".v1.bak.json");try{J(n,D(o,"utf-8")),this.log(`archived v1 nodes.json -> ${n}`)}catch(i){this.log(`could not back up old nodes: ${i?.message??i}`)}try{let i=oe();this.saveNodes(i)}catch(i){this.log(`could not seed v2 nodes: ${i?.message??i}`)}}return A}return s.data}saveSchema(e){let t=T.safeParse(e);if(!t.success)throw new Error(`Refusing to save invalid schema: ${t.error.issues.map(s=>s.message).join("; ")}`);B(this.schemaPath(),t.data)}loadNodes(){let e=this.nodesPath();if(!I(e)){let r=oe();return this.saveNodes(r),r}let t=D(e,"utf-8"),s=_.safeParse(JSON.parse(t));if(!s.success)throw new Error(`Invalid ${e}: ${s.error.issues.map(r=>r.message).join("; ")}`);return s.data}saveNodes(e){let t=_.safeParse(e);if(!t.success)throw new Error(`Refusing to save invalid nodes file: ${t.error.issues.map(s=>s.message).join("; ")}`);B(this.nodesPath(),t.data)}validateNode(e,t,s){let r=t.levels.find(i=>i.id===e.level);if(!r)throw new Error(`Unknown level: "${e.level}"`);let o=r.axes.filter(i=>!i.optional).filter(i=>!(i.name in e.axes));if(o.length)throw new Error(`Node ${e.id} (${e.level}) missing required axes: ${o.map(i=>i.name).join(", ")}`);for(let i of r.axes){let a=e.axes[i.name];if(a!=null){if(i.type==="enum"&&i.values&&!i.values.includes(a))throw new Error(`Node ${e.id}: axis ${i.name}="${a}" not in enum ${JSON.stringify(i.values)}`);if(i.type==="ref"){if(!s.some(c=>c.id===a))throw new Error(`Node ${e.id}: axis ${i.name}="${a}" refers to unknown node`);if(i.refLevel){let c=s.find(l=>l.id===a);if(c.level!==i.refLevel)throw new Error(`Node ${e.id}: axis ${i.name} expected level "${i.refLevel}" but got "${c.level}"`)}}}}let n=t.levels.findIndex(i=>i.id===e.level);if(n===0){if(e.parentId!==null)throw new Error(`Root-level node ${e.id} must have parentId: null`)}else{if(!e.parentId)throw new Error(`Non-root node ${e.id} must have a parentId`);let i=s.find(c=>c.id===e.parentId);if(!i)throw new Error(`Node ${e.id}: parent "${e.parentId}" not found`);let a=t.levels.findIndex(c=>c.id===i.level);if(a<0||a>=n)throw new Error(`Node ${e.id} at level "${e.level}" has parent at level "${i.level}" \u2014 parent must be at a higher level`)}}commitNodesAlongPath(e,t,s,r){let o=[],n=[],i=new Date().toISOString();for(let a=0;a<e.length;a++){let c=e[a],l=this.loadNodes().nodes;if(l.find(m=>m.id===c)){n.push(c);continue}let p=0;for(let m=a-1;m>=0;m--){let w=e[m],N=l.find(k=>k.id===w)||o.find(k=>k.id===w);if(N){p=s.levels.findIndex(k=>k.id===N.level)+1;break}}let g=t[c]??{},d=null;for(let m=p;m<s.levels.length;m++){let w=s.levels[m];if(w.axes.filter(k=>!k.optional).filter(k=>!(k.name in g)).length===0){d=w.id,p=m+1;break}}if(!d&&p<s.levels.length&&(d=s.levels[p].id,p++),!d)throw new Error(`Can't place node ${c} \u2014 no schema level left (cursor=${p}, levels=${s.levels.length})`);let h=null,f=s.levels.findIndex(m=>m.id===d);for(let m=a-1;m>=0;m--){let w=e[m],N=l.find(C=>C.id===w)||o.find(C=>C.id===w);if(!N)continue;let k=s.levels.findIndex(C=>C.id===N.level);if(k>=0&&k<f){h=w;break}}let u={id:c,level:d,parentId:h,axes:g,createdAt:i,createdBy:r};this.addNode(u),o.push(u)}return{added:o,skipped:n}}addNode(e){let t=this.loadSchema(),s=this.loadNodes();if(s.nodes.some(r=>r.id===e.id))throw new Error(`Node id already exists: ${e.id}`);return this.validateNode(e,t,[...s.nodes,e]),s.nodes.push(e),this.saveNodes(s),e}appendClassification(e){let t=P.safeParse(e);if(!t.success){let o=t.error.issues.map(n=>`${n.path.join(".")}: ${n.message}`).join(" \xB7 ");return this.log(`skipped invalid classification \u2014 ${o} \xB7`,`path=${JSON.stringify(e.path)}`,`axes-keys=${JSON.stringify(Object.keys(e.proposedAxes||{}))}`),!1}let s=JSON.stringify(t.data)+`
2
2
  `,r=this.classificationsPath();return I(r)||U(ae(r),{recursive:!0}),ge(r,s),!0}listPendingClassifications(e=200){return this.listByStatus("pending",e)}listAllClassifications(){return this.readAllCollapsed()}listByStatus(e,t=200){return this.readAllCollapsed().filter(r=>r.status===e).slice(0,t)}readAllCollapsed(){let e=this.classificationsPath();if(!I(e))return[];let s=D(e,"utf-8").split(`
3
3
  `).filter(Boolean),r=new Map;for(let o of s)try{let n=P.safeParse(JSON.parse(o));if(!n.success)continue;r.set(n.data.msgHash,n.data)}catch{}return Array.from(r.values()).sort((o,n)=>o.ts<n.ts?1:-1)}updateClassificationStatus(e,t){let r=this.readAllCollapsed().find(n=>n.msgHash===e);if(!r)return null;let o={...r,status:t.status,ts:new Date().toISOString()};if(t.reviewer||t.reviewReason){let n=` \xB7 ${t.reviewer?`reviewer=${t.reviewer}`:""}${t.reviewReason?` \xB7 ${t.reviewReason}`:""}`;o.preview=((r.preview||"")+n).slice(0,500)}return this.appendClassification(o),o}readRecentClassifications(e=50){let t=this.classificationsPath();if(!I(t))return[];let r=D(t,"utf-8").split(`
4
4
  `).filter(Boolean),o=[];for(let n=r.length-1;n>=0&&o.length<e;n--)try{let i=P.safeParse(JSON.parse(r[n]));i.success&&o.push(i.data)}catch{}return o}fingerprint(e){let s=[e.text.toLowerCase().replace(/\s+/g," ").trim(),e.channel??"",e.sender??""].join("");return fe("sha256").update(s).digest("hex").slice(0,32)}loadIndex(){let e=this.indexPath();if(!I(e))return{version:1,entries:{}};let t=D(e,"utf-8"),s=G.safeParse(JSON.parse(t));if(!s.success)throw new Error(`Invalid ${e}: ${s.error.issues.map(r=>r.message).join("; ")}`);return s.data}saveIndex(e){let t=G.safeParse(e);if(!t.success)throw new Error(`Refusing to save invalid index: ${t.error.issues.map(s=>s.message).join("; ")}`);B(this.indexPath(),t.data)}getFingerprint(e){return this.loadIndex().entries[e]}setFingerprint(e,t){let s=this.loadIndex();s.entries[e]={...t,fingerprint:e,updatedAt:new Date().toISOString()},this.saveIndex(s)}updateNodeAxes(e,t){let s=this.loadSchema(),r=this.loadNodes(),o=r.nodes.find(i=>i.id===e);if(!o)throw new Error(`Node not found: ${e}`);let n={...o,axes:t};return this.validateNode(n,s,r.nodes.map(i=>i.id===e?n:i)),r.nodes=r.nodes.map(i=>i.id===e?n:i),this.saveNodes(r),n}deleteNode(e){let t=this.loadNodes(),s=t.nodes.find(o=>o.parentId===e);if(s)throw new Error(`Cannot delete "${e}" \u2014 child node "${s.id}" still points to it`);let r=t.nodes.find(o=>Object.values(o.axes).some(n=>n===e));if(r)throw new Error(`Cannot delete "${e}" \u2014 node "${r.id}" references it via an axis`);t.nodes=t.nodes.filter(o=>o.id!==e),this.saveNodes(t)}approveClassification(e){if(this.getFingerprint(e.msgHash))return;let t=this.loadSchema(),s=new Set(this.loadNodes().nodes.map(r=>r.id));for(let r=0;r<e.path.length;r++){let o=e.path[r];if(s.has(o))continue;let n=t.levels[r]?.id;if(!n)break;let i=e.proposedAxes?.[o]??{},a=r===0?null:e.path[r-1];this.addNode({id:o,level:n,parentId:a,axes:i,createdAt:new Date().toISOString(),createdBy:e.agentId}),s.add(o)}this.setFingerprint(e.msgHash,{path:e.path,leaf:e.leaf}),this.appendClassification({...e,status:"approved",ts:new Date().toISOString()})}rejectClassification(e){this.appendClassification({...e,status:"rejected",ts:new Date().toISOString()})}};function B(b,e){U(ae(b),{recursive:!0});let t=`${b}.tmp-${process.pid}`;J(t,JSON.stringify(e,null,2)),ue(t,b)}function oe(){let b=new Date().toISOString(),e=[],t=new Set;for(let s of F)t.has(s.category)||(e.push({id:s.category,level:"category",parentId:null,axes:{kind:s.category},createdAt:b,createdBy:"starter"}),t.add(s.category));for(let s of F)e.push({id:s.verb,level:"verb",parentId:s.category,axes:{name:s.verb,...s.description?{description:s.description}:{}},createdAt:b,createdBy:"starter"});return{version:1,nodes:e}}pe();de();import{createHash as me}from"crypto";var q=class{store;daemonUrl;token;draftAgent;autoApprove;autoApproveStructure;classifierModel;classifierProviderName;providerInstance;log;constructor(e){this.store=e.store,this.daemonUrl=e.daemonUrl.replace(/\/+$/,""),this.token=e.token,this.draftAgent=e.draftAgent,this.autoApprove=e.autoApproveConfidence??1,this.autoApproveStructure=e.autoApproveStructure??"extend-leaves",this.classifierModel=e.classifierModel??"claude-haiku-4-5-20251001",this.classifierProviderName=e.classifierProvider??"claude-code",this.log=e.log??console.error.bind(console,"[classifier]")}getProvider(){return this.providerInstance||(this.providerInstance=X(this.classifierProviderName)),this.providerInstance}async classify(e){let t=this.store.fingerprint({text:e.text,channel:e.channel,sender:e.sender}),s=this.store.getFingerprint(t);if(s)return this.store.appendClassification({ts:new Date().toISOString(),msgHash:t,agentId:e.agentId,channel:e.channel,sender:e.sender,path:s.path,proposedAxes:{},leaf:s.leaf,source:"cache",status:"approved",preview:e.text.slice(0,200)}),{path:s.path,pathId:z(s.path),pathLabel:K(s.path,this.store.loadNodes().nodes),axes:{},leaf:s.leaf,source:"cache",status:"approved"};let r=this.store.loadSchema(),o=this.store.loadNodes().nodes,n=await this.proposePath(e,r,o).catch(u=>(this.log("LLM proposal failed:",u?.message||u),null));if(!n)return null;let{path:i,proposedAxes:a,confidence:c,leaf:l}=n;if(i.length===0)return null;let v={ts:new Date().toISOString(),msgHash:t,agentId:e.agentId,channel:e.channel,sender:e.sender,path:i,proposedAxes:a,leaf:l,source:"llm",status:"pending",confidence:c,preview:e.text.slice(0,200)},p=new Set(o.map(u=>u.id)),g=i.map((u,m)=>p.has(u)?-1:m).filter(u=>u>=0),d=!1;if(this.autoApproveStructure==="any")d=!0;else if(this.autoApproveStructure==="extend-leaves"){let u=g.length===0,m=g.length===1&&g[0]===i.length-1;d=u||m}let h=c!==void 0&&c>=this.autoApprove,f="pending";if(d||h)try{this.commitNewNodes(i,a,r,o,e.sender),this.store.setFingerprint(t,{path:i,leaf:l}),f="approved"}catch(u){this.log("auto-approve failed \u2014 staying pending \xB7",`path=${JSON.stringify(i)}`,`reason=${(u?.message||u).toString().slice(0,200)}`)}return v.status=f,this.store.appendClassification(v),{path:i,pathId:z(i),pathLabel:K(i,this.store.loadNodes().nodes),axes:a,leaf:l,source:"llm",status:f,confidence:c}}async proposePath(e,t,s){let r=s.map(d=>({id:d.id,level:d.level,parentId:d.parentId,axes:d.axes})),o=["You are the intent classifier for AgentX. You answer ONE question:",'"what kind of work does this message describe?" \u2014 verb-level only.',"","IMPORTANT \u2014 what NOT to encode in the path:","- Client / company / project / team names. Those are already on the event"," metadata (project, channel, agentId). Embedding them in the path causes"," duplicate nodes (one per client) for the same verb.","- The specific subject (issue number, file name, person name). Same reason.","- The agent's name or role. Pick the verb the *requester* intended.","","SCHEMA (fixed levels \u2014 pick one node per level):","```json",JSON.stringify(t,null,2),"```","","EXISTING NODES (prefer reusing these; only invent a new node when no","existing one fits):","```json",JSON.stringify(r,null,2),"```","","MESSAGE:","```",e.text.slice(0,2e3),"```",`channel: ${e.channel??"?"}`,`sender: ${e.sender??"?"}`,"","TASK:","1. Classify into 'category' (closed enum): code, ops, support, admin,"," knowledge, social, system. Pick the closest fit.","2. Pick or propose a 'verb' node. Verb ids are dot-namespaced lower-kebab,",' e.g. "review.merge-request", "deploy.staging", "investigate.error",',' "chat.greeting", "fix.bug". Reuse an existing verb when the message is'," the same kind of work as something already classified, even when the"," client / project / subject differs.","","Examples (right vs wrong):",'- "Please review MR #957 on globex/system" \u2192 ["code", "review.merge-request"]',' NOT ["business", "acme", "globex-v2", "review-mr-957-system"]','- "Deploy initech-v2 to staging please" \u2192 ["ops", "deploy.staging"]',' NOT ["business", "acme", "initech-v2", "deploy-initech-v2-to-staging"]','- "Hello Atlas" \u2192 ["support", "chat.greeting"]',"","NODE ID RULES (strict \u2014 invalid ids get dropped):","- lowercase-kebab + dots only: [a-z0-9][a-z0-9._-]*","- no spaces, no uppercase, no Arabic/other non-Latin",'- verb ids should use a "category.specific" or "verb.modifier" shape',"","Return ONE JSON object on one line, no prose, no fences:",' { "path": string[], "proposedAxes": { [nodeId]: { [axisName]: string } }, "leaf": { "input"?: string, "output"?: string }, "confidence": number }',"confidence in [0,1]. Prefer low confidence over guessing."].join(`
@@ -106,4 +106,4 @@ We use GitLab for version control.
106
106
  There are ${t.length} unprocessed entries. Read each, understand what it means, and create or update wiki articles.
107
107
 
108
108
  ${s}`}walkDir(e,t){if(x(e))for(let s of O(e)){let r=be(e,s);ye(r).isDirectory()?this.walkDir(r,t):t(r)}}};import{resolve as Y}from"path";import{existsSync as ke,readdirSync as Se,mkdirSync as xe}from"fs";var le=class{baseDir;agentsDir;mode;sharedStore;agentStores=new Map;log;constructor(e=Y(process.cwd(),".agentx/wiki"),t=console.error.bind(console,"[wiki-hub]"),s="graph"){this.baseDir=e,this.agentsDir=Y(e,"agents"),this.mode=s,this.log=t,xe(this.agentsDir,{recursive:!0}),this.sharedStore=new E(e,t)}getMode(){return this.mode}getAgentWiki(e){let t=`${e}:${this.mode}`;if(this.agentStores.has(t))return this.agentStores.get(t);let s=Y(this.agentsDir,e,this.mode),r=new E(s,this.log);return this.agentStores.set(t,r),r}getSharedStore(){return this.sharedStore}listAgents(){let e=new Set,t=this.sharedStore.listEntries();for(let s of t)e.add(s.agentId);if(ke(this.agentsDir))for(let s of Se(this.agentsDir))!s.startsWith("_")&&!s.startsWith(".")&&e.add(s);return[...e].sort()}getAgentEntries(e){return this.sharedStore.listEntries({agentId:e})}getUnabsorbedEntries(e){let t=this.getAgentWiki(e),s=this.getAgentEntries(e),r=new Set,o=t.rebuildIndex();for(let n of o.articles)if(n.sources)for(let i of n.sources)r.add(i);return s.filter(n=>!r.has(n.id))}summary(){return this.listAgents().map(t=>{let s=this.getAgentEntries(t),o=this.getAgentWiki(t).rebuildIndex(),n=this.getUnabsorbedEntries(t);return{agentId:t,totalEntries:s.length,totalArticles:o.articles.length,unabsorbed:n.length,articles:o.articles}})}};export{A as a,H as b,q as c,K as d,E as e,le as f};
109
- //# sourceMappingURL=chunk-RCVGIKC2.js.map
109
+ //# sourceMappingURL=chunk-MTVRYTLL.js.map
@@ -0,0 +1,36 @@
1
+ import{i as se}from"./chunk-BIFJSQB5.js";import{existsSync as Re,readdirSync as Ie,readFileSync as ve,statSync as Ae}from"fs";import{resolve as je}from"path";function re(s,e,t=Date.now(),r=7){let n=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 s.map(a=>{let i=o.get(a.id)??[],l=i.filter(f=>t-f.at<=n),c=i.filter(f=>t-f.at>n&&t-f.at<=n*2),u=l.filter(f=>f.status==="failed").length,m=i.filter(f=>f.status==="paused").length,d=i.length?Math.max(...i.map(f=>f.at)):null,g=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:g,lastRunAt:d,recent:l.length,prior:c.length,failed:u,paused:m}}).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 _=new Map;function wt(s,e=1e3){if(!Re(s))return[];let t=Ie(s).filter(o=>o.endsWith(".jsonl")).map(o=>{let a=je(s,o);return{path:a,mtime:Ae(a).mtimeMs}}).sort((o,a)=>a.mtime-o.mtime).slice(0,e),r=new Set(t.map(o=>o.path));for(let o of _.keys())r.has(o)||_.delete(o);let n=[];for(let{path:o,mtime:a}of t){let i=_.get(o);if(i&&i.mtime===a){i.summary&&n.push(i.summary);continue}let l=Te(o,a);_.set(o,{mtime:a,summary:l}),l&&n.push(l)}return n}function Te(s,e){try{let t=ve(s,"utf-8").split(`
2
+ `).filter(Boolean);if(!t.length)return null;let r=JSON.parse(t[0]),n=r.run?.workflowId;if(!n)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:n,status:o,at:e}}catch{return null}}var _e={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},y={routines:200,summary:160,filters:6,filterValue:60,text:120},Le=(s,e,t)=>{try{return se(s,e,t)}catch{return null}},ie=864e5;function Rt(s){let e=s.now??Date.now(),t={..._e,...s.thresholds},r=s.nextFire??Le,n=[];for(let i of s.crons){let l=s.cronRuns.get(i.id)??[],c=i.timezone||"UTC",u=l.map(g=>({at:Date.parse(g.startedAt),status:g.status})),m=l[0],d={id:`cron:${i.id}`,source:"cron",kind:"schedule",name:S(i.id,y.text),trigger:{schedule:S(i.schedule,y.text),timezone:c},agent:i.agent||null,enabled:i.enabled,state:i.enabled?"enabled":"disabled",nextRunAt:i.enabled?B(i.nextRun)??B(r(i.schedule,new Date(e),c)):null,lastRun:m?{at:m.startedAt,status:m.status,summary:Be(m.status==="success"?void 0:m.errorSummary,y.summary)}:null,lastSuccessAt:l.find(g=>g.status==="success")?.startedAt??null,consecutiveFailures:oe(u),sampledRuns:l.length,flags:[],attention:null};d.flags=ae(d,u,i.schedule,c,null,e,t,r),n.push(le(d))}let o=new Map(re(s.workflows.map(i=>({id:i.id,name:i.title})),s.workflowRuns,e).map(i=>[i.id,i])),a=new Map;for(let i of s.workflowRuns){let l=a.get(i.workflowId);l?l.push(i):a.set(i.workflowId,[i])}for(let i of s.workflows){let l=i.nodes.find(x=>x.type.startsWith("trigger."));if(!l||l.type!=="trigger.cron"&&l.type!=="trigger.hook")continue;let c=l.config??{},u=i.state||"active",m=u==="active",d=(a.get(i.id)??[]).slice().sort((x,D)=>D.at-x.at),g=d.map(x=>({at:x.at,status:Pe(x.status)})),f=g[0],h=l.type==="trigger.cron",b=typeof c.spec=="string"?c.spec:"",O=typeof c.timezone=="string"?c.timezone:"UTC",j={id:`workflow:${i.id}`,source:"workflow",kind:h?"schedule":"event",name:S(i.title||i.id,y.text),trigger:h?{schedule:S(b,y.text),timezone:O}:{event:S(typeof c.event=="string"?c.event:"",y.text),filters:De(c.filter,i)},agent:Oe(i),enabled:m,state:u,nextRunAt:h&&m&&b?B(r(b,new Date(e),O)):null,lastRun:f?{at:new Date(f.at).toISOString(),status:f.status}:null,lastSuccessAt:(()=>{let x=g.find(D=>D.status==="success");return x?new Date(x.at).toISOString():null})(),consecutiveFailures:oe(g),sampledRuns:d.length,flags:[],attention:null},T=Date.parse(i.updated||i.created||"");j.flags=h?ae(j,g,b,O,Number.isFinite(T)?T:null,e,t,r):Ee(j,o.get(i.id)?.state==="dormant",Number.isFinite(T)?T:null,e,t),n.push(le(j))}return n.sort(Ce).slice(0,y.routines)}function oe(s){let e=0;for(let t of s)if(!(t.status==="running"||t.status==="paused"||t.status==="unknown"))if(t.status==="failed"||t.status==="timeout")e++;else break;return e}function ae(s,e,t,r,n,o,a,i){let l=[],c=e.length?e[0].at:null;if(!s.enabled){let d=ue(c,n,o,a);return d&&l.push(d),l}if(s.consecutiveFailures>=a.failStreak&&l.push({reason:"failing",detail:`${s.consecutiveFailures} failed attempts in a row`}),c===null)return l.push({reason:"never-ran",detail:"No persisted attempt"}),l;let u=new Date(c),m=null;for(let d=0;d<a.missedFires&&(m=i(t,u,r),!!m);d++)u=m;return m&&o>m.getTime()+a.graceMs&&l.push({reason:"overdue",detail:`No attempt since ${new Date(c).toISOString()}; ${a.missedFires} scheduled fires missed`}),l}function Ee(s,e,t,r,n){let o=[],a=s.lastRun?Date.parse(s.lastRun.at):null;if(!s.enabled){let i=ue(a,t,r,n);return i&&o.push(i),o}return s.consecutiveFailures>=n.failStreak&&o.push({reason:"failing",detail:`${s.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 ue(s,e,t,r){let n=Math.max(s??0,e??0);return n&&t-n<r.disabledDays*ie?null:{reason:"disabled-long",detail:n?`Disabled; no activity for ${Math.floor((t-n)/ie)} days`:"Disabled and never ran"}}function le(s){let e=new Set(s.flags.map(t=>t.reason));return s.attention=e.has("failing")?"critical":e.has("overdue")||e.has("dormant")||e.has("never-ran")?"warning":e.has("disabled-long")?"info":null,s}var ce={critical:0,warning:1,info:2};function Ce(s,e){let t=s.attention?ce[s.attention]:3,r=e.attention?ce[e.attention]:3;return t-r||Number(e.enabled)-Number(s.enabled)||s.name.localeCompare(e.name)}function Pe(s){switch(s){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 Oe(s){if(s.ownerAgent)return S(s.ownerAgent,y.text);let e=s.nodes.find(t=>t.type==="agent"&&typeof t.config?.agentId=="string"&&t.config.agentId);return e?S(String(e.config.agentId),y.text):null}function De(s,e){let t=[],r=e?.project;if(r&&t.push(S(`project=${r}`,y.filterValue)),s&&typeof s=="object"&&!Array.isArray(s))for(let[n,o]of Object.entries(s)){let a=Array.isArray(o)?o.map(String):o==null?[]:[String(o)];a.length&&t.push(S(`${n}=${a.join(",")}`,y.filterValue))}return t.slice(0,y.filters)}function B(s){if(!s)return null;let e=s instanceof Date?s:new Date(s);return Number.isFinite(e.getTime())?e.toISOString():null}function S(s,e){return s.length<=e?s:s.slice(0,e-3)+"..."}function Be(s,e){return s===void 0?void 0:S(s,e)}function L(s){return(Array.isArray(s)?s[0]:s)?.trim()??""}function Ue(s){try{return new URL(s).host.toLowerCase()}catch{return null}}function Fe(s=process.env){return new Set((s.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function vt(s,e=Fe()){let t=L(s.origin);if(t){if(e.has(t.replace(/\/+$/,"").toLowerCase()))return"same-origin";let n=Ue(t),o=[L(s.host),L(s["x-forwarded-host"])].filter(Boolean).map(a=>a.toLowerCase());return n&&o.includes(n)?"same-origin":"foreign"}let r=L(s["sec-fetch-site"]).toLowerCase();return r==="cross-site"||r==="same-site"?"foreign":"none"}function At(s){let e=(s||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{readFileSync as F,writeFileSync as he,existsSync as W,readdirSync as Je,statSync as Xe}from"fs";import{resolve as N,join as Ve}from"path";import{existsSync as de,mkdirSync as We,readFileSync as Ne,writeFileSync as ge}from"fs";import{dirname as Me,resolve as me}from"path";import{z as p}from"zod";var ze=p.object({type:p.enum(["gitlab","github"]),host:p.string().optional(),project:p.string(),iid:p.number().int().positive(),url:p.string()}),He=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:ze.optional(),importedAt:p.string().optional(),createdAt:p.string(),updatedAt:p.string(),blocker:p.string().optional(),doneNote:p.string().optional()}),Ge=p.object({version:p.literal(1),items:p.array(He).default([])}),E=class{constructor(e){this.path=e}jsonPath(){return me(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return me(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return de(this.jsonPath())}load(){let e=this.jsonPath();if(!de(e))return{version:1,items:[]};let t=Ne(e,"utf-8");try{return Ge.parse(JSON.parse(t))}catch(r){throw new Error(`Backlog file invalid (${e}): ${r.message}`)}}save(e){let t=this.jsonPath();We(Me(t),{recursive:!0}),ge(t,JSON.stringify(e,null,2)+`
3
+ `),ge(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(),n={...e,labels:e.labels??[],status:e.status??"todo",createdAt:e.createdAt??r,updatedAt:r};return t.items.push(n),this.save(t),n}addMany(e){let t=this.load(),r=new Set(t.items.map(a=>a.id)),n=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??n,updatedAt:n};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(),n=r.items.findIndex(a=>a.id===e);if(n<0)throw new Error(`backlog item ${e} not found`);let o={...r.items[n],...t,id:r.items[n].id,createdAt:r.items[n].createdAt,updatedAt:new Date().toISOString()};return r.items[n]=o,this.save(r),o}remove(e){let t=this.load(),r=t.items.length;return t.items=t.items.filter(n=>n.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 n=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[o,a]of n)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]`:"",m=i.source?` (${i.source.type}: ${i.source.project}#${i.source.iid})`:"";t.push(`- [${l}] ${c}${i.title}${u}${m}`),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 Et(s){return`${s.type}:${s.project}:${s.iid}`}function fe(s,e,t){let r=[];if(e.type==="gitlab"){let n=t.channels.gitlab?.agentMappings??[];for(let o of s){let a=n.find(i=>i.agentId===o);a?.gitlabUsernames?.length?r.push(a.gitlabUsernames[0]):r.push(o)}}else if(e.type==="github"){let n=t.channels.github?.agentMappings??[];for(let o of s){let a=n.find(i=>i.agentId===o);a?.githubUsernames?.length?r.push(a.githubUsernames[0]):r.push(o)}}return r}async function U(s,e,t,r=()=>{}){return s.source?s.source.type==="gitlab"?Ke(s.source,e,t,r):s.source.type==="github"?qe(s.source,e,t,r):{ok:!1,error:`unknown source.type ${s.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function Ke(s,e,t,r){let n=t.channels.gitlab,o=n?.token,a=n?.host||(s.host?`https://${s.host}`:void 0);if(!o||!a)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let i=[],l=async(g,f={})=>fetch(`${a}/api/v4${g}`,{...f,headers:{"PRIVATE-TOKEN":o,"Content-Type":"application/json",...f.headers||{}}}),c=encodeURIComponent(s.project),u;e.assigneeUsernames!==void 0&&(u=(await Promise.all(e.assigneeUsernames.map(async f=>{try{let h=await fetch(`${a}/api/v4/users?username=${encodeURIComponent(f)}`,{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(f=>typeof f=="number"));let m;if(e.milestoneTitle!==void 0)if(e.milestoneTitle===null||e.milestoneTitle==="")m=0;else try{let g=await l(`/projects/${c}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);if(g.ok){let f=await g.json();Array.isArray(f)&&f[0]?.id&&(m=f[0].id)}}catch(g){r(`[backlog-sync] milestone lookup failed: ${g.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),m!==void 0&&(d.milestone_id=m),e.state&&(d.state_event=e.state==="closed"?"close":"reopen"),Object.keys(d).length)try{let g=await l(`/projects/${c}/issues/${s.iid}`,{method:"PUT",body:JSON.stringify(d)});if(i.push({kind:"PUT issue",ok:g.ok,status:g.status}),!g.ok){let f=await g.text().catch(()=>"");return{ok:!1,attempts:i,error:`PUT issue ${g.status}: ${f.slice(0,200)}`,url:s.url}}}catch(g){return i.push({kind:"PUT issue",ok:!1,error:g.message}),{ok:!1,attempts:i,error:g.message,url:s.url}}if(e.note)try{let g=await l(`/projects/${c}/issues/${s.iid}/notes`,{method:"POST",body:JSON.stringify({body:e.note})});i.push({kind:"POST note",ok:g.ok,status:g.status})}catch(g){i.push({kind:"POST note",ok:!1,error:g.message})}return{ok:i.every(g=>g.ok),attempts:i,url:s.url}}async function qe(s,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,g={})=>fetch(`https://api.github.com${d}`,{...g,headers:{Authorization:`Bearer ${o}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28",...g.headers||{}}}),l=s.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 g=await d.json(),f=Array.isArray(g)?g.find(h=>h.title===e.milestoneTitle):null;f?.number&&(c=f.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/${s.iid}`);if(d.ok){let g=await d.json(),f=Array.isArray(g.labels)?g.labels.map(b=>typeof b=="string"?b:b.name):[],h=new Set([...f,...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 m={};if(e.title!==void 0&&(m.title=e.title),e.description!==void 0&&(m.body=e.description),u!==void 0&&(m.labels=u),e.assigneeUsernames!==void 0&&(m.assignees=e.assigneeUsernames),c!==void 0&&(m.milestone=c),e.state&&(m.state=e.state),Object.keys(m).length)try{let d=await i(`/repos/${l}/issues/${s.iid}`,{method:"PATCH",body:JSON.stringify(m)});if(a.push({kind:"PATCH issue",ok:d.ok,status:d.status}),!d.ok){let g=await d.text().catch(()=>"");return{ok:!1,attempts:a,error:`PATCH issue ${d.status}: ${g.slice(0,200)}`,url:s.url}}}catch(d){return a.push({kind:"PATCH issue",ok:!1,error:d.message}),{ok:!1,attempts:a,error:d.message,url:s.url}}if(e.note)try{let d=await i(`/repos/${l}/issues/${s.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:s.url}}var M=/^(\s*)-\s*\[( |x|X)\]\s*(.*)$/,C=/@([a-z0-9_-]+)/i,pe=/\[time:\s*([0-9hm\s]+)\]/i;function Ye(s){let e=s.match(/(\d+)\s*h/i),t=s.match(/(\d+)\s*m/i);return(e?parseInt(e[1],10)*3600:0)+(t?parseInt(t[1],10)*60:0)}var z=class{constructor(e,t,r=()=>{}){this.path=e;this.daemon=t;this.log=r;this.store=new E(this.path)}type="backlog";capabilities={listAll:!0,create:!1,transition:!1,labels:!0,search:!1};store;getStore(){return this.store}readMd(){let e=N(process.cwd(),this.path);return W(e)?F(e,"utf-8").split(`
5
+ `):[]}writeMd(e){let t=N(process.cwd(),this.path);he(t,e.join(`
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 n=0;n<t.length;n++){let o=t[n].match(M);if(!o||o[2].toLowerCase()==="x")continue;let i=o[3],l=i.match(C);if(l&&l[1].toLowerCase()!==e.toLowerCase())continue;let c=i.match(pe),u=i.replace(C,"").replace(pe,"").trim();r.push({id:`backlog:${n}`,title:u||`Task at line ${n+1}`,assignee:l?l[1]:void 0,estimatedSeconds:c?Ye(c[1]):void 0,priority:n})}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 n=this.store.update(t,{assignee:r.assignee||e,status:"doing"});if(n.source&&this.daemon){let o=fe([n.assignee||e],n.source,this.daemon);U(n,{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&&U(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),n=this.readMd(),o=n[r];if(!o)throw new Error(`backlog line ${r} missing`);if(!o.match(M))throw new Error(`backlog line ${r} not a checkbox`);if(t.status==="done"){n[r]=o.replace(/- \[ \]/,"- [x]");let i=t.timeSeconds?` <!-- done by agent, ${Math.round(t.timeSeconds/60)}m -->`:" <!-- done by agent -->";n.splice(r+1,0,i)}else t.status==="blocked"?n.splice(r+1,0,` <!-- BLOCKED: ${t.blocker||t.note||"?"} -->`):t.note&&n.splice(r+1,0,` <!-- ${t.note.replace(/-->/g,"\u2014 >")} -->`);this.writeMd(n)}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"}}},H=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(W(e))for(let r of Je(e)){let n=Ve(e,r);Xe(n).isDirectory()?this.walk(n,t):r.endsWith(".md")&&t.push(n)}}async listOpen(e){let t=[];this.walk(N(process.cwd(),this.root),t);let r=[];for(let n of t){let o=F(n,"utf-8").split(`
7
+ `);for(let a=0;a<o.length;a++){let i=o[a].match(M);if(!i||i[2].toLowerCase()==="x")continue;let l=i[3].match(C);!l||l[1].toLowerCase()!==e.toLowerCase()||r.push({id:`wiki:${n}:${a}`,title:i[3].replace(C,"").trim(),assignee:l[1],priority:a})}}return r}async claim(){}async report(e,t){let r=e.split(":"),n=parseInt(r[r.length-1],10),o=r.slice(1,-1).join(":");if(!W(o))return;let a=F(o,"utf-8").split(`
8
+ `);t.status==="done"&&a[n]&&(a[n]=a[n].replace(/- \[ \]/,"- [x]"),he(o,a.join(`
9
+ `)))}},G=class{constructor(e,t,r,n,o){this.host=e;this.token=t;this.projects=r;this.agentUsernames=n;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(n=>n.toLowerCase()===e.toLowerCase()))return t}mapIssue(e,t){let r=e.references?.full?.split("#")[0]||t,n=[],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})),n=o.map(c=>c.name)):n=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:n,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=[],n=this.projects.length?this.projects:["__ALL__"];for(let o of t)for(let a of n)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 m=this.mapIssue(u,a);m.assignee=e,r.push(m)}}catch(i){this.log(`[business] GitLab listOpen failed for ${o} on ${a}: ${i.message}`)}return r}async claim(e,t){let{project:r,iid:n,type:o}=this.parseId(t),a=`/projects/${encodeURIComponent(r)}/${o==="issue"?"issues":"merge_requests"}/${n}?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:n,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}/${n}/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}/${n}?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}/${n}?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}/${n}/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(),n=new URLSearchParams,o=e.state??"opened";n.set("state",o),n.set("updated_after",r),n.set("scope","all"),n.set("per_page","100"),n.set("with_labels_details","true"),n.set("order_by","updated_at"),n.set("sort","desc"),e.labels?.length&&n.set("labels",e.labels.join(",")),e.milestone&&n.set("milestone",e.milestone),e.search&&n.set("search",e.search);let a=this.projects.length?this.projects:["__ALL__"],i=[];for(let c of a)try{let u=c==="__ALL__"?`/issues?${n.toString()}`:`/projects/${encodeURIComponent(c)}/issues?${n.toString()}`,m=await this.api(u);for(let d of m)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(m=>c.has(m)))}if(e.withoutScopedPrefix){let c=e.withoutScopedPrefix+"::";l=l.filter(u=>!(u.labels||[]).some(m=>m.startsWith(c)))}return l}async setState(e,t){let{project:r,iid:n,type:o}=this.parseId(e),a=o==="issue"?"issues":"merge_requests";await this.api(`/projects/${encodeURIComponent(r)}/${a}/${n}?state_event=${t}`,{method:"PUT"})}async getItem(e){let{project:t,iid:r}=this.parseId(e);try{let n=await this.api(`/projects/${encodeURIComponent(t)}/issues/${r}?with_labels_details=true`);return{...this.mapIssue(n,t),descriptionHtml:n.description_html||void 0,createdAt:n.created_at,author:n.author?{username:n.author.username,name:n.author.name,avatarUrl:n.author.avatar_url}:void 0,allLabels:Array.isArray(n.labels)?typeof n.labels[0]=="object"?n.labels.map(a=>a.name):n.labels:[]}}catch(n){return this.log(`[board] GitLab getItem failed for ${e}: ${n.message}`),null}}async updateItem(e,t){let{project:r,iid:n}=this.parseId(e),o;t.assigneeUsernames&&(o=(await Promise.all(t.assigneeUsernames.map(async u=>{try{let m=await this.api(`/users?username=${encodeURIComponent(u)}`);return Array.isArray(m)&&m[0]?.id?m[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/${n}`,{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 n of r)n.username&&!e.has(n.username)&&e.set(n.username,{username:n.username,name:n.name,avatarUrl:n.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 n=await this.api(`/projects/${encodeURIComponent(r)}/milestones?per_page=100`);for(let o of n)o.title&&!e.has(o.title)&&e.set(o.title,{id:o.id,title:o.title,state:o.state,dueDate:o.due_date})}catch(n){this.log(`[board] listMilestones failed for ${r}: ${n.message}`)}let t=[...e.values()];return t.sort((r,n)=>r.state!==n.state?r.state==="active"?-1:1:r.title.localeCompare(n.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,n=e.assigneeUsernames?.length?e.assigneeUsernames:e.assignee?(this.agentUsernames[e.assignee]||[]).slice(0,1):[];n.length&&(r=(await Promise.all(n.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:n,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(n)}/${i}/${o}?${l.toString()}`,{method:"PUT"})}parseId(e){let r=e.replace(/^gitlab:/,"").split(":"),n=r.pop(),o=r.pop()==="mr"?"mr":"issue";return{project:r.join(":"),type:o,iid:n}}};function Ft(s,e,t){let r=s.workSource;switch(r.type){case"backlog":return new z(r.path,e,t);case"wiki":return new H(r.path,r.glob);case"gitlab":{let n=e.channels.gitlab;if(!n?.token)throw new Error("business.workSource.type=gitlab requires channels.gitlab.token");let o={};for(let i of n.agentMappings)i.gitlabUsernames.length&&(o[i.agentId]=i.gitlabUsernames);let a=r.projects.length?r.projects:n.routes.map(i=>i.project);return new G(n.host,n.token,a,o,t)}}}var K="unmapped";function q(s,e=[]){if(!s)return K;let t=e.find(n=>n.id===s);if(t?.client)return t.client;let r=s.indexOf("/");return r>0?s.slice(0,r):s}function Qe(s){let e=new Map,t=s.projects??[],r=s.orgChart??{};for(let o of t)o.pm&&(e.has(o.pm)||e.set(o.pm,q(o.id,t)));let n=(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=n(i,a);return l&&e.set(o,l),l};for(let o of Object.keys(r))n(o);return e}function Ze(s,e,t=[]){if(!t.length)return;let r=t.filter(n=>!n.channel||n.channel===s);return r.find(n=>n.chatId&&e.chatId&&n.chatId===e.chatId)??r.find(n=>n.username&&e.username&&n.username===e.username)??r.find(n=>n.senderId&&e.senderId&&n.senderId===e.senderId)??r.find(n=>n.channel&&!n.chatId&&!n.username&&!n.senderId)}function Nt(s,e){let t=Ze(s.channel,{chatId:s.chatId,username:s.username},e.contactMap);if(t)return t.client;if(s.project)return q(s.project,e.projects);if(s.agentId){let r=Qe(e).get(s.agentId);if(r)return r}return K}function Mt(s,e){let t=String(s||"").split(":");if(t.length<3)return{agentId:e};let[r,n,...o]=t,a=o.join(":"),i={agentId:e||r,channel:n};return n==="gitlab"||n==="github"?i.project=a.split(":")[0]:n==="cron"||n==="api"||(i.chatId=a.split("@")[0]),i}var et=s=>s===K?"internal":"client";function tt(s,e){let t=e.clients?.[s];return{id:s,name:t?.name||s,kind:t?.kind??et(s),respondWithinMinutes:nt(t?.respondWithin),standing:t?.standing??[],declared:!!t}}function zt(s){let e=new Set;for(let t of s.projects??[])e.add(q(t.id,s.projects));for(let t of s.contactMap??[])e.add(t.client);for(let t of Object.keys(s.clients??{}))e.add(t);return[...e].sort().map(t=>tt(t,s))}function nt(s){let e=/^(\d+)\s*([mhd])$/.exec(String(s??"").trim());if(!e)return;let t=Number(e[1]);return e[2]==="m"?t:e[2]==="h"?t*60:t*1440}import{existsSync as st}from"node:fs";import{join as be}from"node:path";var rt="tn.acme.agentx.voice",qt="AgentX Desktop.app",it="AgentX Helper.app";function Jt(s,e,t){return s!=="darwin"||e!=="arm64"||Number(t.split(".")[0])<23?"AgentX Desktop currently requires Apple Silicon and macOS 14 or newer.":null}function Xt(s,e){if(e&&!Object.hasOwn(s,e))throw new Error(`Unknown agent: ${e}. Run agentx agent list.`);let t=e||Object.keys(s)[0];if(!t)throw new Error("No agents configured. Run agentx setup first.");return t}function J(s){return`'${s.replace(/'/g,"'\\''")}'`}function Vt(s){let e=r=>r.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;"),t={AGENTX_VOICE_AGENT:s.agent,AGENTX_DAEMON_URL:s.url,AGENTX_MAC_HELPER:s.helper,AGENTX_PASTE_COMMAND:`cd ${J(s.cwd)} && ${J(s.node)} ${J(s.cli)} paste`};return`<?xml version="1.0" encoding="UTF-8"?>
10
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
11
+ <plist version="1.0"><dict>
12
+ <key>Label</key><string>${rt}</string>
13
+ <key>ProgramArguments</key><array><string>${e(s.executable)}</string></array>
14
+ <key>WorkingDirectory</key><string>${e(s.cwd)}</string>
15
+ <key>EnvironmentVariables</key><dict>${Object.entries(t).map(([r,n])=>`<key>${r}</key><string>${e(n)}</string>`).join("")}</dict>
16
+ <key>RunAtLoad</key><true/><key>KeepAlive</key><true/>
17
+ <key>ProcessType</key><string>Interactive</string>
18
+ <key>StandardErrorPath</key><string>${e(s.log)}</string>
19
+ </dict></plist>
20
+ `}function Yt(s){return s?["--icon",s]:[]}function ot(s){return be(s,"Applications",it,"Contents/MacOS/agentx-mac-helper")}function ye(s,e,t){if(t)return t;let r=ot(e);return st(r)?r:be(s,"apps/mac-helper/build/AgentX Helper.app/Contents/MacOS/agentx-mac-helper")}import{execFile as at}from"child_process";import{existsSync as X}from"fs";import{homedir as ke}from"os";import{isAbsolute as lt}from"path";var ct={banner:!0,sound:!0,soundName:"Glass",volume:.4},ut=5e3,dt=(s,e)=>new Promise(t=>{try{at(s,e,{timeout:ut},r=>t(!r))}catch{t(!1)}});function rn(s){return{...ct,...s??{}}}function we(s){if(!/^[\w -]+$/.test(s))return null;let e=`/System/Library/Sounds/${s}.aiff`;return X(e)?e:null}function gt(){let s=ye(process.cwd(),ke());return X(s)?s:null}function on(s,e={}){let t=e.run??dt,r=e.platform??process.platform,n=async(o,a)=>{let i=e.helper===void 0?gt():e.helper;i&&await t(i,["notify","--title",o,"--message",a])||await t("/usr/bin/osascript",["-e","on run argv","-e","display notification (item 2 of argv) with title (item 1 of argv)","-e","end run",o,a])};return async(o,a)=>{if(r!=="darwin")return;let i=[];s.banner&&i.push(n(o,a));let l=s.sound?we(s.soundName):null;if(l){let c=Math.min(1,Math.max(0,s.volume));i.push(t("/usr/bin/afplay",["-v",String(c),l]))}await Promise.all(i)}}function an(s,e,t=process.platform){let r={...s??{}};if("banner"in e&&(r.banner=!!e.banner),"sound"in e&&(r.sound=!!e.sound),"soundName"in e){let n=String(e.soundName).trim();if(!(t==="darwin"?we(n)!==null:/^[\w -]+$/.test(n)))throw new Error(`no system sound named "${n}" in /System/Library/Sounds`);r.soundName=n}if("icon"in e){let n=String(e.icon??"").trim().replace(/^~(?=\/)/,ke());if(!n)delete r.icon;else{if(!lt(n)||!/\.(png|jpe?g|icns)$/i.test(n))throw new Error("icon must be the full path to a .png, .jpg or .icns file");if(t==="darwin"&&!X(n))throw new Error(`no icon file at ${n}`);r.icon=n}}if("volume"in e){let n=Number(e.volume);if(!Number.isFinite(n)||n<0||n>1)throw new Error("volume must be between 0 and 1");r.volume=n}return r}import{existsSync as w,readFileSync as Z,writeFileSync as ee,mkdirSync as P,readdirSync as Q,rmSync as mt,statSync as $}from"fs";import{resolve as Se,relative as ft,dirname as te,join as I,extname as A,basename as ne}from"path";var k=200*1024,$e=new Set([".md",".markdown",".txt"]),v=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"]),pt=6,ht=new Set(["CLAUDE.md","SOUL.md","IDENTITY.md","PERSONA.md","AGENT.md","BOOTSTRAP.md"]);function R(s,e){if(!s)throw new Error("Agent workspace is not configured.");let t=Se(s);if(w(t)||P(t,{recursive:!0}),!e||e.startsWith("/")||e.match(/^[a-zA-Z]:/))throw new Error(`Path must be relative to the workspace: ${e}`);let r=Se(t,e);if(ft(t,r).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return r}function xe(s){let e=A(s).toLowerCase();if(!$e.has(e))throw new Error(`Only text files (.md, .markdown, .txt) can be edited from the admin panel (got ${e}).`)}function V(s,e){let t=s.split(/\r?\n/).find(r=>r.trim().startsWith("#"));return t&&t.replace(/^#+\s*/,"").trim().slice(0,120)||e}function dn(s){let e=R(s,"."),t=[],r=new Set,n=[];try{n=Q(e)}catch{}for(let i of ht){let l=I(e,i);if(w(l)&&$(l).isFile()){let c=$(l).size,u=c>0&&c<k?Y(l):"";t.push({path:i,title:V(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 n){if(r.has(i))continue;let l=I(e,i);try{let c=$(l);if(!c.isFile()||!$e.has(A(i).toLowerCase()))continue;let u=c.size>0&&c.size<k?Y(l):"";t.push({path:i,title:V(u,i),size:c.size,exists:!0})}catch{}}let o=[],a=I(e,".claude","skills");if(w(a))try{for(let i of Q(a)){let l=I(a,i),c;try{c=$(l)}catch{continue}if(!c.isDirectory())continue;let u=I(l,"SKILL.md");if(!w(u))continue;let m=$(u),d=m.size<k?Y(u):"";o.push({slug:i,title:V(d,i),size:m.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 Y(s){try{return Z(s,"utf-8")}catch{return""}}function gn(s,e){let t=R(s,e);if(xe(t),!w(t))return{path:e,content:""};if($(t).size>k)throw new Error(`File is too large to edit in the admin panel (> ${k/1024} KB).`);return{path:e,content:Z(t,"utf-8")}}function mn(s,e,t){let r=R(s,e);xe(r);let n=Buffer.from(t,"utf-8");if(n.length>k)throw new Error(`File too large (${n.length} > ${k} bytes).`);return P(te(r),{recursive:!0}),ee(r,n),{path:e,bytes:n.length}}function fn(s,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`,n=R(s,r);if(w(n))throw new Error(`Skill "${e}" already exists.`);P(te(n),{recursive:!0});let o=t.content?.trim()?t.content:bt(e,t.title);return ee(n,o),{slug:e,path:r}}function pn(s,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(s,`.claude/skills/${e}`);if(!w(t))throw new Error(`Skill "${e}" not found.`);if(!$(t).isDirectory())throw new Error(`Skill path is not a directory: ${e}`);return mt(t,{recursive:!0,force:!0}),{slug:e}}function hn(s,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(s,`.claude/skills/${e}`);if(!w(t))throw new Error(`Skill "${e}" not found.`);let r=[];return n(t,"",0,r),r.sort((o,a)=>o.kind!==a.kind?o.kind==="dir"?-1:1:o.path.localeCompare(a.path)),r;function n(o,a,i,l){if(i>pt)return;let c=[];try{c=Q(o)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let m=I(o,u),d=a?`${a}/${u}`:u,g;try{g=$(m)}catch{continue}if(g.isDirectory())l.push({path:`${d}/`,kind:"dir",size:0,editable:!1}),n(m,d,i+1,l);else if(g.isFile()){let f=A(u).toLowerCase(),h=v.has(f)||v.has(u.toLowerCase());l.push({path:d,kind:"file",size:g.size,editable:h&&g.size<k})}}}}function bn(s,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(s,`.claude/skills/${e}/${t}`);if(!w(r)||!$(r).isFile())throw new Error(`File not found: ${t}`);let n=A(r).toLowerCase(),o=ne(r).toLowerCase();if(!v.has(n)&&!v.has(o))throw new Error(`File type not editable: ${t}`);if($(r).size>k)throw new Error(`File too large to edit (> ${k/1024} KB): ${t}`);return{path:t,content:Z(r,"utf-8")}}function yn(s,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 n=R(s,`.claude/skills/${e}/${t}`),o=A(n).toLowerCase(),a=ne(n).toLowerCase();if(!v.has(o)&&!v.has(a))throw new Error(`File type not editable: ${t}`);let i=Buffer.from(r,"utf-8");if(i.length>k)throw new Error(`File too large (${i.length} > ${k} bytes).`);return P(te(n),{recursive:!0}),ee(n,i),{path:t,bytes:i.length}}function kn(s,e){if(!/^[a-z0-9][a-z0-9_-]*$/.test(e))throw new Error(`Invalid skill slug: ${e}`);let t=R(s,`.claude/skills/${e}`);if(!w(t))throw new Error(`Skill "${e}" not found.`);let r=n=>w(I(t,n));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 bt(s,e){return`# ${e?.trim()||s}
21
+
22
+ 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.
23
+
24
+ ## When to use
25
+ - Trigger condition 1
26
+ - Trigger condition 2
27
+
28
+ ## How to use
29
+ Document the arguments, commands, or files the skill expects. Example:
30
+
31
+ \`\`\`bash
32
+ # Example invocation
33
+ claude-code ${ne(s)} --arg value
34
+ \`\`\`
35
+ `}export{re as a,wt as b,q as c,Qe as d,Ze as e,Nt as f,Mt as g,zt as h,y as i,Rt as j,rt as k,qt as l,it as m,Jt as n,Xt as o,Vt as p,Yt as q,ot as r,ye as s,ct as t,rn as u,on as v,an as w,vt as x,At as y,E as z,Et as A,fe as B,U as C,G as D,Ft as E,dn as F,gn as G,mn as H,fn as I,pn as J,hn as K,bn as L,yn as M,kn as N};
36
+ //# sourceMappingURL=chunk-MX5GCR7Y.js.map