agentix-cli 0.52.1 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (138) hide show
  1. package/dist/{App-X6FGYBLX.js → App-VRTLAPRF.js} +2 -2
  2. package/dist/{ChatApp-XMUOXQ2M.js → ChatApp-YENWPZT4.js} +2 -2
  3. package/dist/{agent-KKVMU3VB.js → agent-HVUGHYBF.js} +2 -2
  4. package/dist/{board-dashboard-KETIFTBD.js → board-dashboard-3XJVYDB3.js} +729 -191
  5. package/dist/board-dashboard-3XJVYDB3.js.map +1 -0
  6. package/dist/chunk-2D3RYIDU.js +3 -0
  7. package/dist/chunk-2D3RYIDU.js.map +1 -0
  8. package/dist/{chunk-H7R3F2CO.js → chunk-2TJYZF4E.js} +2 -2
  9. package/dist/chunk-33QV5O6P.js +7 -0
  10. package/dist/chunk-33QV5O6P.js.map +1 -0
  11. package/dist/{chunk-MHBUAU2B.js → chunk-37EABIOJ.js} +2 -2
  12. package/dist/chunk-3RCFUIYR.js +29 -0
  13. package/dist/chunk-3RCFUIYR.js.map +1 -0
  14. package/dist/{chunk-B5UA3X6E.js → chunk-3W2KMI5O.js} +2 -2
  15. package/dist/{chunk-3IUU4YFI.js → chunk-4FFWNPFX.js} +5 -5
  16. package/dist/chunk-4FFWNPFX.js.map +1 -0
  17. package/dist/{chunk-7BQQWI4T.js → chunk-4HNHHKJF.js} +2 -2
  18. package/dist/chunk-6JHA3ZE6.js +1111 -0
  19. package/dist/chunk-6JHA3ZE6.js.map +1 -0
  20. package/dist/{chunk-76NNONUJ.js → chunk-BKDUCPZ3.js} +2 -2
  21. package/dist/{chunk-64UYAWAK.js → chunk-BMSPRUEJ.js} +33 -33
  22. package/dist/chunk-BMSPRUEJ.js.map +1 -0
  23. package/dist/{chunk-NKSCUCVZ.js → chunk-ENRJ2QEH.js} +2 -2
  24. package/dist/{chunk-AWRRBNWQ.js → chunk-HQMISQ7L.js} +2 -2
  25. package/dist/{chunk-E57WKMRR.js → chunk-KLDGJSR5.js} +2 -2
  26. package/dist/{ntfy-ZY2NPGBA.js → chunk-KZKDVIOE.js} +3 -3
  27. package/dist/chunk-KZKDVIOE.js.map +1 -0
  28. package/dist/{chunk-7NF45XCM.js → chunk-M67AN4J7.js} +2 -2
  29. package/dist/{chunk-WKTFP3SK.js → chunk-NO2HOK4B.js} +2 -2
  30. package/dist/chunk-QD6IICK7.js +2 -0
  31. package/dist/chunk-QD6IICK7.js.map +1 -0
  32. package/dist/{chunk-QDPLR3SB.js → chunk-QX4R5WY7.js} +2 -2
  33. package/dist/{chunk-QZ4M2KAC.js → chunk-QYHABRLM.js} +2 -2
  34. package/dist/{chunk-AKAM4BNC.js → chunk-TLFJVLVQ.js} +166 -160
  35. package/dist/chunk-TLFJVLVQ.js.map +1 -0
  36. package/dist/{chunk-YS3Z2Z64.js → chunk-UYMK3XNB.js} +44 -45
  37. package/dist/chunk-UYMK3XNB.js.map +1 -0
  38. package/dist/{chunk-7M7VJMGP.js → chunk-WLRHL2P7.js} +2 -2
  39. package/dist/chunk-WWMFNLKD.js +10 -0
  40. package/dist/chunk-WWMFNLKD.js.map +1 -0
  41. package/dist/{chunk-YPPTPBBV.js → chunk-XWU7O3S5.js} +2 -2
  42. package/dist/{chunk-XOUIZBAQ.js → chunk-ZOJUHPD5.js} +2 -2
  43. package/dist/cli.js +1 -1
  44. package/dist/cli.js.map +1 -1
  45. package/dist/client-N4XQEAVL.js +2 -0
  46. package/dist/{compaction-NWPBPWY2.js → compaction-H5U32UU6.js} +2 -2
  47. package/dist/{config-FGCJVXYX.js → config-KHKIY6LI.js} +2 -2
  48. package/dist/config-mutator-ZZKFQ7HJ.js +2 -0
  49. package/dist/doctor-QICAXIQB.js +2 -0
  50. package/dist/index.d.ts +130 -0
  51. package/dist/index.js +1 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/memory-extract-F76BE6KA.js +2 -0
  54. package/dist/ntfy-52EXHVMD.js +2 -0
  55. package/dist/program-ZWNGK3RB.js +2 -0
  56. package/dist/{promote-NBFF7ZIW.js → promote-H6ZHJXTY.js} +2 -2
  57. package/dist/push-HEDA6P3B.js +2 -0
  58. package/dist/push-HEDA6P3B.js.map +1 -0
  59. package/dist/push-keys-2DTD7YNQ.js +2 -0
  60. package/dist/push-store-LXTYULUF.js +2 -0
  61. package/dist/query-FTE4FLYK.js +2 -0
  62. package/dist/registry-HDOFVNRK.js +2 -0
  63. package/dist/{request-planner-ZEXFARZE.js → request-planner-ABD4WIGM.js} +2 -2
  64. package/dist/{review-candidates-F2HNH2TZ.js → review-candidates-B6574GOJ.js} +2 -2
  65. package/dist/{routing-XSRZ7V23.js → routing-BGKZOHOA.js} +2 -2
  66. package/dist/schedule-tool-UDHXTKWV.js +2 -0
  67. package/dist/scheduler-NQM3HVUY.js +2 -0
  68. package/dist/scheduler-NQM3HVUY.js.map +1 -0
  69. package/dist/{seat-IPDLEUI5.js → seat-VGST5AQB.js} +2 -2
  70. package/dist/seat-VGST5AQB.js.map +1 -0
  71. package/dist/{select-BYOX63CR.js → select-Y7SBUCGJ.js} +2 -2
  72. package/dist/set-enabled-ARKMDLXN.js +2 -0
  73. package/dist/set-enabled-ARKMDLXN.js.map +1 -0
  74. package/dist/{tool-WW4YCMSP.js → tool-5EVYUN2G.js} +2 -2
  75. package/dist/wiki-GREI2TSP.js +2 -0
  76. package/dist/wiki-GREI2TSP.js.map +1 -0
  77. package/package.json +3 -1
  78. package/dist/board-dashboard-KETIFTBD.js.map +0 -1
  79. package/dist/chunk-3IUU4YFI.js.map +0 -1
  80. package/dist/chunk-64UYAWAK.js.map +0 -1
  81. package/dist/chunk-6BXKZY76.js +0 -7
  82. package/dist/chunk-6BXKZY76.js.map +0 -1
  83. package/dist/chunk-7PK32QT5.js +0 -1107
  84. package/dist/chunk-7PK32QT5.js.map +0 -1
  85. package/dist/chunk-AKAM4BNC.js.map +0 -1
  86. package/dist/chunk-HRBKSZ34.js +0 -2
  87. package/dist/chunk-HRBKSZ34.js.map +0 -1
  88. package/dist/chunk-WCNKTV6G.js +0 -28
  89. package/dist/chunk-WCNKTV6G.js.map +0 -1
  90. package/dist/chunk-YS3Z2Z64.js.map +0 -1
  91. package/dist/client-AVQSLPIZ.js +0 -2
  92. package/dist/config-mutator-5JSG3CHW.js +0 -2
  93. package/dist/doctor-VITHTLEC.js +0 -2
  94. package/dist/memory-extract-MGGXIZTE.js +0 -2
  95. package/dist/ntfy-ZY2NPGBA.js.map +0 -1
  96. package/dist/program-MNFDOQGQ.js +0 -2
  97. package/dist/query-XCXR57IV.js +0 -2
  98. package/dist/registry-5ZP3ZNSH.js +0 -2
  99. package/dist/schedule-tool-AKCVLCWK.js +0 -2
  100. package/dist/scheduler-BEGZJWJU.js +0 -2
  101. package/dist/wiki-IVJJQUKB.js +0 -2
  102. /package/dist/{App-X6FGYBLX.js.map → App-VRTLAPRF.js.map} +0 -0
  103. /package/dist/{ChatApp-XMUOXQ2M.js.map → ChatApp-YENWPZT4.js.map} +0 -0
  104. /package/dist/{agent-KKVMU3VB.js.map → agent-HVUGHYBF.js.map} +0 -0
  105. /package/dist/{chunk-H7R3F2CO.js.map → chunk-2TJYZF4E.js.map} +0 -0
  106. /package/dist/{chunk-MHBUAU2B.js.map → chunk-37EABIOJ.js.map} +0 -0
  107. /package/dist/{chunk-B5UA3X6E.js.map → chunk-3W2KMI5O.js.map} +0 -0
  108. /package/dist/{chunk-7BQQWI4T.js.map → chunk-4HNHHKJF.js.map} +0 -0
  109. /package/dist/{chunk-76NNONUJ.js.map → chunk-BKDUCPZ3.js.map} +0 -0
  110. /package/dist/{chunk-NKSCUCVZ.js.map → chunk-ENRJ2QEH.js.map} +0 -0
  111. /package/dist/{chunk-AWRRBNWQ.js.map → chunk-HQMISQ7L.js.map} +0 -0
  112. /package/dist/{chunk-E57WKMRR.js.map → chunk-KLDGJSR5.js.map} +0 -0
  113. /package/dist/{chunk-7NF45XCM.js.map → chunk-M67AN4J7.js.map} +0 -0
  114. /package/dist/{chunk-WKTFP3SK.js.map → chunk-NO2HOK4B.js.map} +0 -0
  115. /package/dist/{chunk-QDPLR3SB.js.map → chunk-QX4R5WY7.js.map} +0 -0
  116. /package/dist/{chunk-QZ4M2KAC.js.map → chunk-QYHABRLM.js.map} +0 -0
  117. /package/dist/{chunk-7M7VJMGP.js.map → chunk-WLRHL2P7.js.map} +0 -0
  118. /package/dist/{chunk-YPPTPBBV.js.map → chunk-XWU7O3S5.js.map} +0 -0
  119. /package/dist/{chunk-XOUIZBAQ.js.map → chunk-ZOJUHPD5.js.map} +0 -0
  120. /package/dist/{client-AVQSLPIZ.js.map → client-N4XQEAVL.js.map} +0 -0
  121. /package/dist/{compaction-NWPBPWY2.js.map → compaction-H5U32UU6.js.map} +0 -0
  122. /package/dist/{config-FGCJVXYX.js.map → config-KHKIY6LI.js.map} +0 -0
  123. /package/dist/{config-mutator-5JSG3CHW.js.map → config-mutator-ZZKFQ7HJ.js.map} +0 -0
  124. /package/dist/{doctor-VITHTLEC.js.map → doctor-QICAXIQB.js.map} +0 -0
  125. /package/dist/{memory-extract-MGGXIZTE.js.map → memory-extract-F76BE6KA.js.map} +0 -0
  126. /package/dist/{program-MNFDOQGQ.js.map → ntfy-52EXHVMD.js.map} +0 -0
  127. /package/dist/{promote-NBFF7ZIW.js.map → program-ZWNGK3RB.js.map} +0 -0
  128. /package/dist/{query-XCXR57IV.js.map → promote-H6ZHJXTY.js.map} +0 -0
  129. /package/dist/{registry-5ZP3ZNSH.js.map → push-keys-2DTD7YNQ.js.map} +0 -0
  130. /package/dist/{routing-XSRZ7V23.js.map → push-store-LXTYULUF.js.map} +0 -0
  131. /package/dist/{schedule-tool-AKCVLCWK.js.map → query-FTE4FLYK.js.map} +0 -0
  132. /package/dist/{scheduler-BEGZJWJU.js.map → registry-HDOFVNRK.js.map} +0 -0
  133. /package/dist/{request-planner-ZEXFARZE.js.map → request-planner-ABD4WIGM.js.map} +0 -0
  134. /package/dist/{review-candidates-F2HNH2TZ.js.map → review-candidates-B6574GOJ.js.map} +0 -0
  135. /package/dist/{seat-IPDLEUI5.js.map → routing-BGKZOHOA.js.map} +0 -0
  136. /package/dist/{wiki-IVJJQUKB.js.map → schedule-tool-UDHXTKWV.js.map} +0 -0
  137. /package/dist/{select-BYOX63CR.js.map → select-Y7SBUCGJ.js.map} +0 -0
  138. /package/dist/{tool-WW4YCMSP.js.map → tool-5EVYUN2G.js.map} +0 -0
@@ -1,2 +0,0 @@
1
- var r=new Set(["cli","chat-cli","exec","tui","dashboard","admin","test-drive","workflow-editor","voice","opencode","mcp","ntfy","raycast"]),a=new Set(["telegram","whatsapp","slack","discord","gitlab","github","api","a2a","mesh","subagent","compaction","cron","workflow","business","heartbeat","selftest"]);function n(e){let t=(e??"").toLowerCase().split("@")[0];return r.has(t)?"operator":a.has(t)?"internal":"external"}var s=[/\bglpat-[A-Za-z0-9_-]{16,}/,/\bgh[pousr]_[A-Za-z0-9]{30,}/,/\bgithub_pat_[A-Za-z0-9_]{20,}/,/\bsk-ant-[A-Za-z0-9_-]{16,}/,/\bsk-(proj-)?[A-Za-z0-9_-]{20,}/,/\bxox[abprs]-[A-Za-z0-9-]{10,}/,/\bAKIA[0-9A-Z]{16}\b/,/\bAIza[0-9A-Za-z_-]{35}\b/,/\b\d{8,10}:[A-Za-z0-9_-]{35}\b/,/-----BEGIN [A-Z ]*PRIVATE KEY-----/,/\beyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/,/\b(password|passwd|pwd|secret|api[_-]?key|access[_-]?key|token)\s*[:=]\s*["']?[^\s"',;]{8,}/i,/\b[a-z][a-z0-9+.-]*:\/\/[^\s:/@]+:[^\s:/@]{6,}@/i];function o(e){return s.some(t=>t.test(e))}function i(e){return e.source.trust??n(e.source.channel)}function c(e){return e==="external"?"held":void 0}function u(e){return e.category==="secret"||o(e.content)||e.review==="rejected"||e.review==="held"?!1:i(e)==="external"?e.review==="approved":!0}export{n as a,o as b,i as c,c as d,u as e};
2
- //# sourceMappingURL=chunk-HRBKSZ34.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/agents/memory-trust.ts"],"sourcesContent":["// --- What extracted memory may keep, and what it may inject ---\n//\n// Facts are extracted from conversations after every reply and injected\n// into later tasks of the same agent, in any chat. Three rules keep that\n// from becoming a leak or a persistent prompt injection:\n//\n// 1. Secrets are never stored or injected. A credential pasted into one\n// chat must not follow the agent into every other chat.\n// 2. Every fact records how far its source can be trusted, from the\n// channel it came through.\n// 3. Facts from external sources (webhooks, public widgets, anything\n// unknown) are held out of injection until someone approves them:\n// anybody can write to those channels.\n//\n// Pure functions, unit tested.\n\nexport type SourceTrust =\n /** Only the operator can reach it: CLI, dashboard, local voice, TUI and Raycast. */\n | \"operator\"\n /** Authenticated people or peers: allow-listed chat senders, forge\n * project members, mesh callers. */\n | \"internal\"\n /** Anyone can write to it. */\n | \"external\"\n\nexport type FactReview = \"held\" | \"approved\" | \"rejected\"\n\nconst OPERATOR_CHANNELS = new Set([\n \"cli\", \"chat-cli\", \"exec\", \"tui\", \"dashboard\", \"admin\", \"test-drive\",\n \"workflow-editor\", \"voice\", \"opencode\", \"mcp\", \"ntfy\", \"raycast\",\n])\n\n/** People behind an allow-list or project membership, mesh peers, and\n * this node's own automation. New extraction skips the machine channels\n * (cron, workflow, a2a) anyway; older facts from them keep working. */\nconst INTERNAL_CHANNELS = new Set([\n \"telegram\", \"whatsapp\", \"slack\", \"discord\", \"gitlab\", \"github\",\n \"api\", \"a2a\", \"mesh\", \"subagent\", \"compaction\",\n \"cron\", \"workflow\", \"business\", \"heartbeat\", \"selftest\",\n])\n\n/** Trust for a fact's source channel. Channels carry a node suffix\n * (\"telegram@peer-server\"). Anything else, including web-chat,\n * public-api, webhooks and channels added later, is external. */\nexport function trustForChannel(channel: string | undefined): SourceTrust {\n const base = (channel ?? \"\").toLowerCase().split(\"@\")[0]\n if (OPERATOR_CHANNELS.has(base)) return \"operator\"\n if (INTERNAL_CHANNELS.has(base)) return \"internal\"\n return \"external\"\n}\n\n// Shapes of credentials. Deliberately specific: each pattern is a known\n// token format or an explicit assignment, so ordinary prose about \"the\n// token\" or \"a password reset\" is not caught.\nconst SECRET_PATTERNS: RegExp[] = [\n /\\bglpat-[A-Za-z0-9_-]{16,}/, // GitLab PAT\n /\\bgh[pousr]_[A-Za-z0-9]{30,}/, // GitHub tokens\n /\\bgithub_pat_[A-Za-z0-9_]{20,}/,\n /\\bsk-ant-[A-Za-z0-9_-]{16,}/, // Anthropic\n /\\bsk-(proj-)?[A-Za-z0-9_-]{20,}/, // OpenAI-style\n /\\bxox[abprs]-[A-Za-z0-9-]{10,}/, // Slack\n /\\bAKIA[0-9A-Z]{16}\\b/, // AWS access key\n /\\bAIza[0-9A-Za-z_-]{35}\\b/, // Google API key\n /\\b\\d{8,10}:[A-Za-z0-9_-]{35}\\b/, // Telegram bot token\n /-----BEGIN [A-Z ]*PRIVATE KEY-----/,\n /\\beyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}/, // JWT\n /\\b(password|passwd|pwd|secret|api[_-]?key|access[_-]?key|token)\\s*[:=]\\s*[\"']?[^\\s\"',;]{8,}/i,\n /\\b[a-z][a-z0-9+.-]*:\\/\\/[^\\s:/@]+:[^\\s:/@]{6,}@/i, // URL with user:password@\n]\n\nexport function containsSecret(text: string): boolean {\n return SECRET_PATTERNS.some((p) => p.test(text))\n}\n\n/** The fields of a stored fact this module reads. Older facts have no\n * trust or review; trust then comes from their source channel. */\nexport interface FactTrustFields {\n category: string\n content: string\n source: { channel: string; trust?: SourceTrust }\n review?: FactReview\n}\n\nexport function factTrust(f: FactTrustFields): SourceTrust {\n return f.source.trust ?? trustForChannel(f.source.channel)\n}\n\n/** Whether a new fact from this source waits for review before use. */\nexport function initialReview(trust: SourceTrust): FactReview | undefined {\n return trust === \"external\" ? \"held\" : undefined\n}\n\n/** Whether a stored fact may be injected into a prompt. */\nexport function isInjectable(f: FactTrustFields): boolean {\n if (f.category === \"secret\" || containsSecret(f.content)) return false\n if (f.review === \"rejected\" || f.review === \"held\") return false\n if (factTrust(f) === \"external\") return f.review === \"approved\"\n return true\n}\n"],"mappings":"AA2BA,IAAMA,EAAoB,IAAI,IAAI,CAChC,MAAO,WAAY,OAAQ,MAAO,YAAa,QAAS,aACxD,kBAAmB,QAAS,WAAY,MAAO,OAAQ,SACzD,CAAC,EAKKC,EAAoB,IAAI,IAAI,CAChC,WAAY,WAAY,QAAS,UAAW,SAAU,SACtD,MAAO,MAAO,OAAQ,WAAY,aAClC,OAAQ,WAAY,WAAY,YAAa,UAC/C,CAAC,EAKM,SAASC,EAAgBC,EAA0C,CACxE,IAAMC,GAAQD,GAAW,IAAI,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC,EACvD,OAAIH,EAAkB,IAAII,CAAI,EAAU,WACpCH,EAAkB,IAAIG,CAAI,EAAU,WACjC,UACT,CAKA,IAAMC,EAA4B,CAChC,6BACA,+BACA,iCACA,8BACA,kCACA,iCACA,uBACA,4BACA,iCACA,qCACA,qEACA,+FACA,kDACF,EAEO,SAASC,EAAeC,EAAuB,CACpD,OAAOF,EAAgB,KAAMG,GAAMA,EAAE,KAAKD,CAAI,CAAC,CACjD,CAWO,SAASE,EAAUC,EAAiC,CACzD,OAAOA,EAAE,OAAO,OAASR,EAAgBQ,EAAE,OAAO,OAAO,CAC3D,CAGO,SAASC,EAAcC,EAA4C,CACxE,OAAOA,IAAU,WAAa,OAAS,MACzC,CAGO,SAASC,EAAaH,EAA6B,CAExD,OADIA,EAAE,WAAa,UAAYJ,EAAeI,EAAE,OAAO,GACnDA,EAAE,SAAW,YAAcA,EAAE,SAAW,OAAe,GACvDD,EAAUC,CAAC,IAAM,WAAmBA,EAAE,SAAW,WAC9C,EACT","names":["OPERATOR_CHANNELS","INTERNAL_CHANNELS","trustForChannel","channel","base","SECRET_PATTERNS","containsSecret","text","p","factTrust","f","initialReview","trust","isInjectable"]}
@@ -1,28 +0,0 @@
1
- import{t as Ie,u as ve}from"./chunk-B5UA3X6E.js";import{d as Se,e as $e}from"./chunk-AQASR6KR.js";import{b as G}from"./chunk-AWRRBNWQ.js";import{g as be,h as ye,i as ke,k as we,l as xe}from"./chunk-QZ4M2KAC.js";import{q as he}from"./chunk-XOUIZBAQ.js";import{m as pe,p as it}from"./chunk-3IUU4YFI.js";import{existsSync as ot,readdirSync as at,readFileSync as lt,statSync as ct}from"fs";import{resolve as ut}from"path";function Re(n,e,t=Date.now(),r=7){let s=r*864e5,i=new Map;for(let a of e){let o=i.get(a.workflowId);o?o.push(a):i.set(a.workflowId,[a])}return n.map(a=>{let o=i.get(a.id)??[],l=o.filter(m=>t-m.at<=s),c=o.filter(m=>t-m.at>s&&t-m.at<=s*2),u=l.filter(m=>m.status==="failed").length,g=o.filter(m=>m.status==="paused").length,d=o.length?Math.max(...o.map(m=>m.at)):null,f=o.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,o)=>{let l={dormant:0,failing:1,active:2,quiet:3,never:4};return l[a.state]-l[o.state]||(o.lastRunAt??0)-(a.lastRunAt??0)})}var B=new Map;function Sn(n,e=1e3){if(!ot(n))return[];let t=at(n).filter(i=>i.endsWith(".jsonl")).map(i=>{let a=ut(n,i);return{path:a,mtime:ct(a).mtimeMs}}).sort((i,a)=>a.mtime-i.mtime).slice(0,e),r=new Set(t.map(i=>i.path));for(let i of B.keys())r.has(i)||B.delete(i);let s=[];for(let{path:i,mtime:a}of t){let o=B.get(i);if(o&&o.mtime===a){o.summary&&s.push(o.summary);continue}let l=dt(i,a);B.set(i,{mtime:a,summary:l}),l&&s.push(l)}return s}function dt(n,e){try{let t=lt(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 i=r.run?.status??"unknown";for(let a=t.length-1;a>=0;a--){let o=JSON.parse(t[a]),l=o.status??o.run?.status;if(l){i=l;break}}return{workflowId:s,status:i,at:e}}catch{return null}}var gt={failStreak:3,disabledDays:30,missedFires:2,graceMs:15*6e4},k={routines:200,summary:160,filters:6,filterValue:60,text:120},ft=(n,e,t)=>{try{return he(n,e,t)}catch{return null}},_e=864e5;function Rn(n){let e=n.now??Date.now(),t={...gt,...n.thresholds},r=n.nextFire??ft,s=[];for(let o of n.crons){let l=n.cronRuns.get(o.id)??[],c=o.timezone||"UTC",u=l.map(f=>({at:Date.parse(f.startedAt),status:f.status})),g=l[0],d={id:`cron:${o.id}`,source:"cron",kind:"schedule",name:S(o.id,k.text),trigger:{schedule:S(o.schedule,k.text),timezone:c},agent:o.agent||null,enabled:o.enabled,state:o.enabled?"enabled":"disabled",nextRunAt:o.enabled?J(o.nextRun)??J(r(o.schedule,new Date(e),c)):null,lastRun:g?{at:g.startedAt,status:g.status,summary:kt(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,o.schedule,c,null,e,t,r),s.push(De(d))}let i=new Map(Re(n.workflows.map(o=>({id:o.id,name:o.title})),n.workflowRuns,e).map(o=>[o.id,o])),a=new Map;for(let o of n.workflowRuns){let l=a.get(o.workflowId);l?l.push(o):a.set(o.workflowId,[o])}for(let o of n.workflows){let l=o.nodes.find(v=>v.type.startsWith("trigger."));if(!l||l.type!=="trigger.cron"&&l.type!=="trigger.hook")continue;let c=l.config??{},u=o.state||"active",g=u==="active",d=(a.get(o.id)??[]).slice().sort((v,q)=>q.at-v.at),f=d.map(v=>({at:v.at,status:ht(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:${o.id}`,source:"workflow",kind:h?"schedule":"event",name:S(o.title||o.id,k.text),trigger:h?{schedule:S(b,k.text),timezone:K}:{event:S(typeof c.event=="string"?c.event:"",k.text),filters:yt(c.filter,o)},agent:bt(o),enabled:g,state:u,nextRunAt:h&&g&&b?J(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(o.updated||o.created||"");O.flags=h?Ce(O,f,b,K,Number.isFinite(P)?P:null,e,t,r):mt(O,i.get(o.id)?.state==="dormant",Number.isFinite(P)?P:null,e,t),s.push(De(O))}return s.sort(pt).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,i,a,o){let l=[],c=e.length?e[0].at:null;if(!n.enabled){let d=Te(c,s,i,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=o(t,u,r),!!g);d++)u=g;return g&&i>g.getTime()+a.graceMs&&l.push({reason:"overdue",detail:`No attempt since ${new Date(c).toISOString()}; ${a.missedFires} scheduled fires missed`}),l}function mt(n,e,t,r,s){let i=[],a=n.lastRun?Date.parse(n.lastRun.at):null;if(!n.enabled){let o=Te(a,t,r,s);return o&&i.push(o),i}return n.consecutiveFailures>=s.failStreak&&i.push({reason:"failing",detail:`${n.consecutiveFailures} failed runs in a row`}),a===null?i.push({reason:"never-ran",detail:"No run recorded for this trigger"}):e&&i.push({reason:"dormant",detail:"Fired in the prior week, silent in the last one"}),i}function 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 pt(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 ht(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 bt(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 yt(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,i]of Object.entries(n)){let a=Array.isArray(i)?i.map(String):i==null?[]:[String(i)];a.length&&t.push(S(`${s}=${a.join(",")}`,k.filterValue))}return t.slice(0,k.filters)}function J(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 kt(n,e){return n===void 0?void 0:S(n,e)}var Ee=new Set(["127.0.0.1","::1","::ffff:127.0.0.1"]);function An(n){return n==="/api/memory"||n.startsWith("/api/memory/")||n==="/approvals"||n.startsWith("/approvals/")||n==="/events/recent"}function Cn(n){return n==="/reload"||n==="/api/processes/kill"||n==="/send"||n==="/send/agent"||n==="/send/contact"||/^\/api\/tasks\/[^/]+\/(cancel|followup)$/.test(n)}function Dn(n){return Ee.has(n)}function jn(n){if(n.foreignBrowser)return{allowed:!1,reason:"foreign-browser-origin"};if(n.enforcementDisabled)return{allowed:!0,reason:"disabled"};if(Ee.has(n.remoteAddress))return{allowed:!0,reason:"loopback"};if(n.acceptedTokens.size===0)return{allowed:!0,reason:"no-tokens-configured"};let e=n.authorizationHeader||"",t=e.startsWith("Bearer ")?e.slice(7).trim():"";return t&&n.acceptedTokens.has(t)?{allowed:!0,reason:"token"}:{allowed:!1,reason:"missing-or-invalid-token"}}function Tn(n,e=process.env){let t=new Set;e.MESH_TOKEN&&t.add(e.MESH_TOKEN);for(let r of n.mesh?.peers||[])r.token&&t.add(r.token);return t}function En(n,e,t=process.env){let r=i=>i.replace(/\/+$/,"");return(e===r(n.daemonUrl)?n.token:n.daemons.find(i=>r(i.url)===e)?.token)||t.MESH_TOKEN||void 0}function F(n){return(Array.isArray(n)?n[0]:n)?.trim()??""}function wt(n){try{return new URL(n).host.toLowerCase()}catch{return null}}function xt(n=process.env){return new Set((n.AGENTX_ALLOWED_ORIGINS||"").split(",").map(e=>e.trim().replace(/\/+$/,"").toLowerCase()).filter(Boolean))}function On(n,e=xt()){let t=F(n.origin);if(t){if(e.has(t.replace(/\/+$/,"").toLowerCase()))return"same-origin";let s=wt(t),i=[F(n.host),F(n["x-forwarded-host"])].filter(Boolean).map(a=>a.toLowerCase());return s&&i.includes(s)?"same-origin":"foreign"}let r=F(n["sec-fetch-site"]).toLowerCase();return r==="cross-site"||r==="same-site"?"foreign":"none"}function Pn(n){let e=(n||"GET").toUpperCase();return e!=="GET"&&e!=="HEAD"}import{readFileSync as X,writeFileSync as Me,existsSync as Y,readdirSync as Dt,statSync as jt}from"fs";import{resolve as Q,join as Tt}from"path";import{existsSync as Le,mkdirSync as St,readFileSync as $t,writeFileSync as Oe}from"fs";import{dirname as It,resolve as Pe}from"path";import{z as p}from"zod";var vt=p.object({type:p.enum(["gitlab","github"]),host:p.string().optional(),project:p.string(),iid:p.number().int().positive(),url:p.string()}),Rt=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:vt.optional(),importedAt:p.string().optional(),createdAt:p.string(),updatedAt:p.string(),blocker:p.string().optional(),doneNote:p.string().optional()}),_t=p.object({version:p.literal(1),items:p.array(Rt).default([])}),M=class{constructor(e){this.path=e}jsonPath(){return Pe(process.cwd(),this.path).replace(/\.md$/i,".json")}mdPath(){return Pe(process.cwd(),this.path).replace(/\.json$/i,".md")}exists(){return Le(this.jsonPath())}load(){let e=this.jsonPath();if(!Le(e))return{version:1,items:[]};let t=$t(e,"utf-8");try{return _t.parse(JSON.parse(t))}catch(r){throw new Error(`Backlog file invalid (${e}): ${r.message}`)}}save(e){let t=this.jsonPath();St(It(t),{recursive:!0}),Oe(t,JSON.stringify(e,null,2)+`
3
- `),Oe(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(i=>i.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(),i=[];for(let a of e){if(r.has(a.id))continue;let o={...a,labels:a.labels??[],status:a.status??"todo",createdAt:a.createdAt??s,updatedAt:s};t.items.push(o),i.push(o),r.add(o.id)}return i.length&&this.save(t),i}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 i={...r.items[s],...t,id:r.items[s].id,createdAt:r.items[s].createdAt,updatedAt:new Date().toISOString()};return r.items[s]=i,this.save(r),i}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 i of e.items)r[i.status].push(i);let s=[["doing","Doing"],["blocked","Blocked"],["todo","To Do"],["done","Done"]];for(let[i,a]of s)if(r[i].length){t.push(`## ${a}`,"");for(let o of r[i]){let l=i==="done"?"x":" ",c=o.assignee?`@${o.assignee} `:"",u=o.estimatedSeconds?` [time: ${Math.round(o.estimatedSeconds/60)}m]`:"",g=o.source?` (${o.source.type}: ${o.source.project}#${o.source.iid})`:"";t.push(`- [${l}] ${c}${o.title}${u}${g}`),o.source?.url&&t.push(` - <${o.source.url}>`),o.labels.length&&t.push(` - labels: ${o.labels.join(", ")}`),o.milestone&&t.push(` - milestone: ${o.milestone}`),o.blocker&&t.push(` - BLOCKED: ${o.blocker}`)}t.push("")}return t.join(`
4
- `)}};function Nn(n){return`${n.type}:${n.project}:${n.iid}`}function Be(n,e,t){let r=[];if(e.type==="gitlab"){let s=t.channels.gitlab?.agentMappings??[];for(let i of n){let a=s.find(o=>o.agentId===i);a?.gitlabUsernames?.length?r.push(a.gitlabUsernames[0]):r.push(i)}}else if(e.type==="github"){let s=t.channels.github?.agentMappings??[];for(let i of n){let a=s.find(o=>o.agentId===i);a?.githubUsernames?.length?r.push(a.githubUsernames[0]):r.push(i)}}return r}async function V(n,e,t,r=()=>{}){return n.source?n.source.type==="gitlab"?At(n.source,e,t,r):n.source.type==="github"?Ct(n.source,e,t,r):{ok:!1,error:`unknown source.type ${n.source.type}`,attempts:[]}:{ok:!0,attempts:[]}}async function At(n,e,t,r){let s=t.channels.gitlab,i=s?.token,a=s?.host||(n.host?`https://${n.host}`:void 0);if(!i||!a)return{ok:!1,error:"gitlab token/host not configured",attempts:[]};let o=[],l=async(f,m={})=>fetch(`${a}/api/v4${f}`,{...m,headers:{"PRIVATE-TOKEN":i,"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":i}});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(o.push({kind:"PUT issue",ok:f.ok,status:f.status}),!f.ok){let m=await f.text().catch(()=>"");return{ok:!1,attempts:o,error:`PUT issue ${f.status}: ${m.slice(0,200)}`,url:n.url}}}catch(f){return o.push({kind:"PUT issue",ok:!1,error:f.message}),{ok:!1,attempts:o,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})});o.push({kind:"POST note",ok:f.ok,status:f.status})}catch(f){o.push({kind:"POST note",ok:!1,error:f.message})}return{ok:o.every(f=>f.ok),attempts:o,url:n.url}}async function Ct(n,e,t,r){let i=t.channels.github?.token;if(!i)return{ok:!1,error:"github token not configured",attempts:[]};let a=[],o=async(d,f={})=>fetch(`https://api.github.com${d}`,{...f,headers:{Authorization:`Bearer ${i}`,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 o(`/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 o(`/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 o(`/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 o(`/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*(.*)$/,U=/@([a-z0-9_-]+)/i,Fe=/\[time:\s*([0-9hm\s]+)\]/i;function Et(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 M(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);Me(t,e.join(`
6
- `))}async listOpen(e){if(this.store.exists())return this.store.list().filter(i=>i.status!=="done"&&(!i.assignee||i.assignee.toLowerCase()===e.toLowerCase())).map(i=>this.toWorkItem(i));let t=this.readMd(),r=[];for(let s=0;s<t.length;s++){let i=t[s].match(Z);if(!i||i[2].toLowerCase()==="x")continue;let o=i[3],l=o.match(U);if(l&&l[1].toLowerCase()!==e.toLowerCase())continue;let c=o.match(Fe),u=o.replace(U,"").replace(Fe,"").trim();r.push({id:`backlog:${s}`,title:u||`Task at line ${s+1}`,assignee:l?l[1]:void 0,estimatedSeconds:c?Et(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 i=Be([s.assignee||e],s.source,this.daemon);V(s,{assigneeUsernames:i,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 o={};t.status==="done"?o.status="done":t.status==="blocked"?(o.status="blocked",o.blocker=t.blocker||t.note||void 0):t.status==="in-progress"&&(o.status="doing"),t.timeSeconds&&(o.estimatedSeconds=t.timeSeconds);let l=this.store.update(e,o);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(),i=s[r];if(!i)throw new Error(`backlog line ${r} missing`);if(!i.match(Z))throw new Error(`backlog line ${r} not a checkbox`);if(t.status==="done"){s[r]=i.replace(/- \[ \]/,"- [x]");let o=t.timeSeconds?` <!-- done by agent, ${Math.round(t.timeSeconds/60)}m -->`:" <!-- done by agent -->";s.splice(r+1,0,o)}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 Dt(e)){let s=Tt(e,r);jt(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 i=X(s,"utf-8").split(`
7
- `);for(let a=0;a<i.length;a++){let o=i[a].match(Z);if(!o||o[2].toLowerCase()==="x")continue;let l=o[3].match(U);!l||l[1].toLowerCase()!==e.toLowerCase()||r.push({id:`wiki:${s}:${a}`,title:o[3].replace(U,"").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),i=r.slice(1,-1).join(":");if(!Y(i))return;let a=X(i,"utf-8").split(`
8
- `);t.status==="done"&&a[s]&&(a[s]=a[s].replace(/- \[ \]/,"- [x]"),Me(i,a.join(`
9
- `)))}},ne=class{constructor(e,t,r,s,i){this.host=e;this.token=t;this.projects=r;this.agentUsernames=s;this.log=i}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=[],i;Array.isArray(e.labels)&&(e.labels.length&&typeof e.labels[0]=="object"?(i=e.labels.map(c=>({name:c.name,color:c.color,text_color:c.text_color})),s=i.map(c=>c.name)):s=e.labels);let o=(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=o[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:o,url:e.web_url,priority:e.weight??99,estimatedSeconds:e.time_stats?.time_estimate||void 0,labels:s,labelDetails:i,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 i of t)for(let a of s)try{let o=`assignee_username=${encodeURIComponent(i)}&state=opened&scope=all&per_page=20`,l=a==="__ALL__"?`/issues?${o}`:`/projects/${encodeURIComponent(a)}/issues?${o}`,c=await this.api(l);for(let u of c){let g=this.mapIssue(u,a);g.assignee=e,r.push(g)}}catch(o){this.log(`[business] GitLab listOpen failed for ${i} on ${a}: ${o.message}`)}return r}async claim(e,t){let{project:r,iid:s,type:i}=this.parseId(t),a=`/projects/${encodeURIComponent(r)}/${i==="issue"?"issues":"merge_requests"}/${s}?add_labels=Doing&remove_labels=To Do`;try{await this.api(a,{method:"PUT"})}catch(o){this.log(`[business] claim label update failed: ${o.message}`)}}async report(e,t){let{project:r,iid:s,type:i}=this.parseId(e),a=i==="issue"?"issues":"merge_requests";if(t.timeSeconds&&t.timeSeconds>0){let o=Math.max(1,Math.round(t.timeSeconds/60)),l=o>=60?`${Math.floor(o/60)}h${o%60?` ${o%60}m`:""}`:`${o}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(o){this.log(`[business] done label update failed: ${o.message}`)}else if(t.status==="blocked")try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}?add_labels=Blocked`,{method:"PUT"})}catch(o){this.log(`[business] blocked label update failed: ${o.message}`)}if(t.note)try{await this.api(`/projects/${encodeURIComponent(r)}/${a}/${s}/notes`,{method:"POST",body:JSON.stringify({body:t.note})})}catch(o){this.log(`[business] report note failed: ${o.message}`)}}async listAll(e={}){let t=e.sinceDays??30,r=new Date(Date.now()-t*24*36e5).toISOString(),s=new URLSearchParams,i=e.state??"opened";s.set("state",i),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__"],o=[];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)o.push(this.mapIssue(d,c))}catch(u){this.log(`[business] GitLab listAll failed on ${c}: ${u.message}`)}let l=o;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:i}=this.parseId(e),a=i==="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),i;t.assigneeUsernames&&(i=(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 o={};t.title!==void 0&&(o.title=t.title),t.description!==void 0&&(o.description=t.description),t.labels!==void 0&&(o.labels=t.labels.join(",")),t.addLabels?.length&&(o.add_labels=t.addLabels.join(",")),t.removeLabels?.length&&(o.remove_labels=t.removeLabels.join(",")),i!==void 0&&(o.assignee_ids=i),a!==void 0&&(o.milestone_id=a);let l=await this.api(`/projects/${encodeURIComponent(r)}/issues/${s}`,{method:"PUT",body:JSON.stringify(o)});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 i of s)i.title&&!e.has(i.title)&&e.set(i.title,{id:i.id,title:i.title,state:i.state,dueDate:i.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 i;if(e.milestoneTitle)try{let l=await this.api(`/projects/${encodeURIComponent(t)}/milestones?title=${encodeURIComponent(e.milestoneTitle)}`);Array.isArray(l)&&l[0]?.id&&(i=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),i!==void 0&&(a.milestone_id=i);let o=await this.api(`/projects/${encodeURIComponent(t)}/issues`,{method:"POST",body:JSON.stringify(a)});return this.mapIssue(o,t)}async transition(e,t,r){await this.transitionMany(e,t?[t]:[],r?[r]:[])}async transitionMany(e,t,r){let{project:s,iid:i,type:a}=this.parseId(e),o=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)}/${o}/${i}?${l.toString()}`,{method:"PUT"})}parseId(e){let r=e.replace(/^gitlab:/,"").split(":"),s=r.pop(),i=r.pop()==="mr"?"mr":"issue";return{project:r.join(":"),type:i,iid:s}}};function Jn(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 i={};for(let o of s.agentMappings)o.gitlabUsernames.length&&(i[o.agentId]=o.gitlabUsernames);let a=r.projects.length?r.projects:s.routes.map(o=>o.project);return new ne(s.host,s.token,a,i,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 Lt(n){let e=new Map,t=n.projects??[],r=n.orgChart??{};for(let i of t)i.pm&&(e.has(i.pm)||e.set(i.pm,re(i.id,t)));let s=(i,a=new Set)=>{if(e.has(i))return e.get(i);if(a.has(i))return;a.add(i);let o=r[i]?.reportsTo;if(!o)return;let l=s(o,a);return l&&e.set(i,l),l};for(let i of Object.keys(r))s(i);return e}function Ot(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 Xn(n,e){let t=Ot(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=Lt(e).get(n.agentId);if(r)return r}return se}function Yn(n,e){let t=String(n||"").split(":");if(t.length<3)return{agentId:e};let[r,s,...i]=t,a=i.join(":"),o={agentId:e||r,channel:s};return s==="gitlab"||s==="github"?o.project=a.split(":")[0]:s==="cron"||s==="api"||(o.chatId=a.split("@")[0]),o}var Pt=n=>n===se?"internal":"client";function Bt(n,e){let t=e.clients?.[n];return{id:n,name:t?.name||n,kind:t?.kind??Pt(n),respondWithinMinutes:Ft(t?.respondWithin),standing:t?.standing??[],declared:!!t}}function Qn(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=>Bt(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 Mt,mkdirSync as Ut,readdirSync as Nt,readFileSync as Wt,renameSync as zt,writeFileSync as Ht}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},Kt={defaultExpiryDays:3,maxExpiryDays:30};function A(n){return Ne(n,".agentx","approvals")}var qt=/^[a-z0-9][a-z0-9-]{0,80}$/;function We(n){return qt.test(n)}function ze(n,e){if(!We(e))throw new Error(`invalid card id: ${e}`);return Ne(A(n),`${e}.json`)}function Gt(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 N(n,e){Ut(A(n),{recursive:!0});let t=ze(n,e.id),r=`${t}.${process.pid}.tmp`;Ht(r,JSON.stringify(e,null,2)+`
10
- `),zt(r,t)}function j(n,e){if(!We(e))return null;try{return JSON.parse(Wt(ze(n,e),"utf-8"))}catch{return null}}function T(n,e){let t=A(n);if(!Mt(t))return[];let r=[];for(let s of Nt(t).filter(i=>i.endsWith(".json")&&!i.startsWith("_")).sort()){let i=j(n,s.slice(0,-5));i&&(!e||i.status===e)&&r.push(i)}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,i=y(n);if(!i)s=e+t.defaultExpiryDays*864e5;else{let a=/^(\d+)\s*([hd])$/i.exec(i);if(a)s=e+Number(a[1])*(a[2].toLowerCase()==="d"?864e5:36e5);else if(s=Date.parse(i),Number.isNaN(s))return{ok:!1,error:`expires must be an ISO date or time, or like "12h" / "3d" (got "${i}")`}}return s<=e?{ok:!1,error:"expires must be in the future"}:{ok:!0,at:new Date(Math.min(s,r)).toISOString()}}function Vt(n,e={}){let t=e.now??Date.now(),r=e.settings??Kt,s=y(n.title),i=y(n.ask),a=y(n.recommend),o=y(n.raised_by);if(!s)return{ok:!1,error:"title is required"};if(!i)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(!o)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(i.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:Gt(t,s),title:s,ask:i,recommend:a,if_silent:l,expires:c.at,...u?{source:u}:{},raised_by:o,created_at:new Date(t).toISOString(),...g?{reply:g}:{},status:"pending"}}}function ns(n,e,t={}){let r=Vt(e,t);if(!r.ok)return r;let s=T(n,"pending").filter(i=>i.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`}:(N(n,r.card),r)}function He(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 i=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(),...i?{note:i}:{}};return N(n,a),{ok:!0,card:a}}function ss(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()};N(n,s),t.push(s)}return t}function rs(n){return T(n).filter(e=>e.status!=="pending"&&!e.agent_notified_at)}function is(n,e,t=Date.now()){let r=j(n,e);!r||r.agent_notified_at||N(n,{...r,agent_notified_at:new Date(t).toISOString()})}function os(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
- `)}import{existsSync as ie,readdirSync as tn,readFileSync as nn}from"fs";import{resolve as C}from"path";import{mkdirSync as Xt,readFileSync as Yt,renameSync as Qt,writeFileSync as Zt}from"fs";import{resolve as en}from"path";function Ke(n){return en(A(n),"_state.json")}function W(n){try{let e=JSON.parse(Yt(Ke(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 qe(n,e){Xt(A(n),{recursive:!0});let t=Ke(n),r=`${t}.${process.pid}.tmp`;Zt(r,JSON.stringify(e,null,2)+`
12
- `),Qt(r,t)}function Ge(n,e,t,r=Date.now()){let s=W(n),i={};for(let[a,o]of Object.entries(s.snoozed))Date.parse(o)>r&&(i[a]=o);i[e]=t.toISOString(),qe(n,{...s,snoozed:i})}function ds(n,e){qe(n,{...W(n),lastDigest:e})}var Je=["card","schedule","memory","wiki"],sn=280;function oe(n,e=sn){let t=n.replace(/\s+/g," ").trim();return t.length>e?`${t.slice(0,e-1)}\u2026`:t}function Ve(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 rn(n){return T(n.root,"pending").map(on)}function on(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 an(n){let e=Ve(n);if(!ie(e))return[];let t;try{t=JSON.parse(nn(e,"utf-8"))}catch{return[]}let r=new Date(n.now??Date.now()),s=[];for(let[i,a]of Object.entries(t?.crons??{})){let o=a?.approval;if(!o||o.action!=="create"&&o.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=o.action==="create";s.push({key:`schedule:${i}`,kind:"schedule",title:d?`New schedule "${i}" for ${a.agent??"an agent"}`:`Delete schedule "${i}"`,ask:d?`Let ${a.agent??"the agent"} run this ${u}?`:`Remove the schedule "${i}" (${u})?`,yes:d?"enable it":"remove it",no:d?"drop the request":"keep the schedule",raised_by:String(o.requestedBy??"unknown"),created_at:String(o.requestedAt??""),detail:oe(`${g}${d&&a.schedule?` \xB7 first run ${ke(ye(a.schedule,l,r),l)}`:""}`),more:"agentx schedule list"})}return s}function Xe(n){let e=C(n,".agentx","memory");return ie(e)?tn(e).filter(t=>t.endsWith(".jsonl")).map(t=>t.slice(0,-6)).sort():[]}function ln(n){let e=Xe(n.root);if(e.length===0)return[];let t=new G(n.root),r=[];for(let s of e)for(let i of t.held(s))r.push({key:`memory:${s}/${i.id}`,kind:"memory",title:`Fact ${s} learned from ${i.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:i.createdAt,detail:oe(i.content),more:`agentx memory facts held --agent ${s}`});return r}function cn(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 un(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(`${cn(t)} ${e.article.content}`),more:`agentx wiki proposals show ${e.id}`}})}var Ye={card:rn,schedule:an,memory:ln,wiki:un};function dn(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 xs(n,e={}){let t=n.now??Date.now(),{snoozed:r}=W(n.root),s=[],i=[],a=0;for(let o of e.kinds??Je){let l;try{l=Ye[o](n)}catch(c){i.push({kind:o,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(dn),{items:s,snoozed:a,errors:i}}function gn(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 fn(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 Ye[e](n).some(r=>r.key===`${e}:${t}`)}}async function Ss(n,e,t,r={}){let s=gn(e);if(!s)return{ok:!1,error:`unknown item "${e}": use a key from \`agentx approvals list\``};let{kind:i,ref:a}=s,o=n.now??Date.now(),l=r.by??"operator";if(t==="later"){if(!fn(n,i,a))return{ok:!1,error:`nothing waiting for "${e}"`};let u=r.laterHours&&r.laterHours>0?r.laterHours:24,g=new Date(o+u*36e5);return Ge(n.root,e,g,o),{ok:!0,message:`${e} put off until ${g.toISOString()}`}}let c=t==="yes";switch(i){case"card":{let u=He(n.root,a,c?"yes":"no",{by:l,note:r.note,now:o});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:Ve(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(!Xe(n.root).includes(g))return{ok:!1,error:`no memory for agent "${g}"`};let f=new G(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:o}):ve(u,a,{by:l,reason:r.note,now:o});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 mn,statSync as I}from"fs";import{resolve as Qe,relative as pn,dirname as fe,join as _,extname as E,basename as me}from"path";var w=200*1024,Ze=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"]),hn=6,bn=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=Qe(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=Qe(t,e);if(pn(t,r).startsWith(".."))throw new Error(`Path escapes the workspace: ${e}`);return r}function et(n){let e=E(n).toLowerCase();if(!Ze.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 Rs(n){let e=R(n,"."),t=[],r=new Set,s=[];try{s=ue(e)}catch{}for(let o of bn){let l=_(e,o);if(x(l)&&I(l).isFile()){let c=I(l).size,u=c>0&&c<w?ce(l):"";t.push({path:o,title:le(u,o),size:c,exists:!0}),r.add(o)}else t.push({path:o,title:o,size:0,exists:!1}),r.add(o)}for(let o of s){if(r.has(o))continue;let l=_(e,o);try{let c=I(l);if(!c.isFile()||!Ze.has(E(o).toLowerCase()))continue;let u=c.size>0&&c.size<w?ce(l):"";t.push({path:o,title:le(u,o),size:c.size,exists:!0})}catch{}}let i=[],a=_(e,".claude","skills");if(x(a))try{for(let o of ue(a)){let l=_(a,o),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):"";i.push({slug:o,title:le(d,o),size:g.size,path:`.claude/skills/${o}/SKILL.md`})}}catch{}return i.sort((o,l)=>o.slug.localeCompare(l.slug)),{identity:t,skills:i,workspace:e}}function ce(n){try{return de(n,"utf-8")}catch{return""}}function _s(n,e){let t=R(n,e);if(et(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 As(n,e,t){let r=R(n,e);et(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 Cs(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 i=t.content?.trim()?t.content:yn(e,t.title);return ge(s,i),{slug:e,path:r}}function Ds(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 mn(t,{recursive:!0,force:!0}),{slug:e}}function js(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((i,a)=>i.kind!==a.kind?i.kind==="dir"?-1:1:i.path.localeCompare(a.path)),r;function s(i,a,o,l){if(o>hn)return;let c=[];try{c=ue(i)}catch{return}for(let u of c){if(u==="node_modules"||u===".git")continue;let g=_(i,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,o+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 Ts(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(),i=me(r).toLowerCase();if(!D.has(s)&&!D.has(i))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 Es(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}`),i=E(s).toLowerCase(),a=me(s).toLowerCase();if(!D.has(i)&&!D.has(a))throw new Error(`File type not editable: ${t}`);let o=Buffer.from(r,"utf-8");if(o.length>w)throw new Error(`File too large (${o.length} > ${w} bytes).`);return z(fe(s),{recursive:!0}),ge(s,o),{path:t,bytes:o.length}}function Ls(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 yn(n,e){return`# ${e?.trim()||n}
13
-
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
-
16
- ## When to use
17
- - Trigger condition 1
18
- - Trigger condition 2
19
-
20
- ## How to use
21
- Document the arguments, commands, or files the skill expects. Example:
22
-
23
- \`\`\`bash
24
- # Example invocation
25
- claude-code ${me(n)} --arg value
26
- \`\`\`
27
- `}it();var tt={maxPixels:12e5,timeoutMs:5e3,intervalMs:100,changeThreshold:.015,stableMs:400,regions:{},buffer:{enabled:!1,seconds:10,fps:2,region:"screen",maxPixels:3e5}};function nt(n){return{...tt,...n??{},regions:{...n?.regions??{}},buffer:{...tt.buffer,...n?.buffer??{}}}}function Bs(n){try{return nt(pe(n).screen)}catch{return nt(void 0)}}var kn=/^[a-z][\w-]*$/,st=["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 rt(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 Fs(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[i,a]of Object.entries(e.regions)){if(!kn.test(i))throw new Error(`region name "${i}" must be lowercase letters, digits, - or _`);a===null?delete s[i]:s[i]=rt(a)}t.regions=s}if(e.buffer&&typeof e.buffer=="object"){let s=e.buffer,i={...t.buffer??{}};"enabled"in s&&(i.enabled=!!s.enabled),"seconds"in s&&(i.seconds=L(s.seconds,"buffer.seconds",a=>a>0&&a<=120,"above 0 and at most 120")),"fps"in s&&(i.fps=L(s.fps,"buffer.fps",a=>a>0&&a<=10,"above 0 and at most 10")),"maxPixels"in s&&(i.maxPixels=H(s.maxPixels,"buffer.maxPixels")),"region"in s&&(i.region=String(s.region).trim()),t.buffer=i}let r=t.buffer?.region;if(r!==void 0&&!st.includes(r)&&!t.regions?.[r])try{rt(r)}catch{throw new Error(`buffer.region "${r}" is not a region \u2014 use ${[...st,...Object.keys(t.regions??{})].join(", ")}, or x,y,w,h`)}return t}export{Re as a,Sn as b,re as c,Lt as d,Ot as e,Xn as f,Yn as g,Qn as h,k as i,Rn as j,Ue as k,We as l,j as m,ns as n,ss as o,rs as p,is as q,os as r,W as s,ds as t,xs as u,Ss as v,An as w,Cn as x,Dn as y,jn as z,Tn as A,En as B,On as C,Pn as D,M as E,Nn as F,Be as G,V as H,ne as I,Jn as J,Rs as K,_s as L,As as M,Cs as N,Ds as O,js as P,Ts as Q,Es as R,Ls as S,tt as T,nt as U,Bs as V,st as W,Fs as X};
28
- //# sourceMappingURL=chunk-WCNKTV6G.js.map