agentix-cli 0.80.0 → 0.80.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 (111) hide show
  1. package/dist/{App-2UCGXCX3.js → App-KVH5POXZ.js} +2 -2
  2. package/dist/{ChatApp-IRPSBYC7.js → ChatApp-LD4TXJWP.js} +2 -2
  3. package/dist/{agent-UPTK3HFR.js → agent-FUMJM6OW.js} +2 -2
  4. package/dist/{board-dashboard-GAUAYKWV.js → board-dashboard-OS5J3F73.js} +7 -4
  5. package/dist/board-dashboard-OS5J3F73.js.map +1 -0
  6. package/dist/{chunk-PT5Z5WW4.js → chunk-3UN6CXRL.js} +2 -2
  7. package/dist/{chunk-445P5QPS.js → chunk-42Y3BXXS.js} +1 -1
  8. package/dist/{chunk-445P5QPS.js.map → chunk-42Y3BXXS.js.map} +1 -1
  9. package/dist/{chunk-6TLQ4I32.js → chunk-6JJ3GODZ.js} +23 -23
  10. package/dist/{chunk-6TLQ4I32.js.map → chunk-6JJ3GODZ.js.map} +1 -1
  11. package/dist/{chunk-KAFUQILA.js → chunk-7IGSJGXI.js} +2 -2
  12. package/dist/{chunk-ECEDX6C6.js → chunk-AF46YOLU.js} +121 -121
  13. package/dist/chunk-AF46YOLU.js.map +1 -0
  14. package/dist/{chunk-NMFXY3QU.js → chunk-API4IZZG.js} +2 -2
  15. package/dist/{chunk-36TJTWG3.js → chunk-BEHC3X42.js} +59 -59
  16. package/dist/chunk-BEHC3X42.js.map +1 -0
  17. package/dist/{chunk-3GYCFRBK.js → chunk-BJPIRNP6.js} +2 -2
  18. package/dist/{chunk-Z522XZBL.js → chunk-BVZFYBBP.js} +2 -2
  19. package/dist/{chunk-AIHWGU4P.js → chunk-H7253EHW.js} +2 -2
  20. package/dist/{chunk-I2Z6D3MI.js → chunk-MOQNLS5Z.js} +2 -2
  21. package/dist/{chunk-7EIUNFDF.js → chunk-MYRSNJJ4.js} +2 -2
  22. package/dist/{chunk-KBSBMOOL.js → chunk-NOAAK2XI.js} +48 -48
  23. package/dist/chunk-NOAAK2XI.js.map +1 -0
  24. package/dist/{chunk-2YJ2ZIYC.js → chunk-PE55MMLK.js} +2 -2
  25. package/dist/{chunk-PXIGWFIQ.js → chunk-R42S57G6.js} +2 -2
  26. package/dist/{chunk-BIJB7CNG.js → chunk-TEFMZY6B.js} +2 -2
  27. package/dist/{chunk-PHFOYJUB.js → chunk-UB63NQQL.js} +2 -2
  28. package/dist/{chunk-AFSM3IY3.js → chunk-UR3ZIDMA.js} +2 -2
  29. package/dist/{chunk-4NUF3SXN.js → chunk-UXSYVMPK.js} +2 -2
  30. package/dist/{chunk-Z6G26FWC.js → chunk-XESESMKN.js} +52 -52
  31. package/dist/chunk-XESESMKN.js.map +1 -0
  32. package/dist/{chunk-O67KV3DX.js → chunk-YCI3KUYF.js} +2 -2
  33. package/dist/{chunk-D3FDPA74.js → chunk-Z3XUGXPD.js} +2 -2
  34. package/dist/{chunk-BBI3HG77.js → chunk-ZR3NZLJL.js} +2 -2
  35. package/dist/cli.js +1 -1
  36. package/dist/client-TJ5YZOEE.js +2 -0
  37. package/dist/{config-XPFCUOQT.js → config-4WZ7Y34V.js} +2 -2
  38. package/dist/config-mutator-5Z7EEB5N.js +2 -0
  39. package/dist/{doctor-XLLNQRRT.js → doctor-7K3NRBNN.js} +2 -2
  40. package/dist/{facts-YY2364CP.js → facts-U7BUYRXN.js} +2 -2
  41. package/dist/index.d.ts +11 -3
  42. package/dist/index.js +1 -1
  43. package/dist/program-KMQNX6YK.js +2 -0
  44. package/dist/{promote-YUZL3ZU2.js → promote-NDC3X54P.js} +2 -2
  45. package/dist/{query-3XH7I6WX.js → query-F7BD3JPE.js} +2 -2
  46. package/dist/{registry-5OD2IN5G.js → registry-5NBHBVY3.js} +2 -2
  47. package/dist/{request-planner-RNXA2QAH.js → request-planner-H74KHFGJ.js} +2 -2
  48. package/dist/{review-candidates-THKWXS7S.js → review-candidates-IPJWEXR2.js} +2 -2
  49. package/dist/{routing-X45VX723.js → routing-3RSG7SKW.js} +2 -2
  50. package/dist/schedule-tool-7NYAK43U.js +2 -0
  51. package/dist/scheduler-24O7PADJ.js +2 -0
  52. package/dist/{seat-LQ47SSNN.js → seat-TOM2WHQR.js} +2 -2
  53. package/dist/{select-PRQP2B6G.js → select-BUWOD47K.js} +2 -2
  54. package/dist/{set-enabled-E2ML2E33.js → set-enabled-XWSFTICB.js} +2 -2
  55. package/dist/tool-GUINJ2BQ.js +4 -0
  56. package/dist/tool-GUINJ2BQ.js.map +1 -0
  57. package/dist/{tool-4WPUUUE4.js → tool-VOA4HSVP.js} +2 -2
  58. package/dist/wiki-VFME4T2H.js +2 -0
  59. package/package.json +1 -1
  60. package/dist/board-dashboard-GAUAYKWV.js.map +0 -1
  61. package/dist/chunk-36TJTWG3.js.map +0 -1
  62. package/dist/chunk-ECEDX6C6.js.map +0 -1
  63. package/dist/chunk-KBSBMOOL.js.map +0 -1
  64. package/dist/chunk-Z6G26FWC.js.map +0 -1
  65. package/dist/client-ABDGDO7S.js +0 -2
  66. package/dist/config-mutator-WYHQV2XF.js +0 -2
  67. package/dist/program-KZOBDSXQ.js +0 -2
  68. package/dist/schedule-tool-ZTL6UZCC.js +0 -2
  69. package/dist/scheduler-VH7IJ4VA.js +0 -2
  70. package/dist/tool-67JK7SK6.js +0 -4
  71. package/dist/tool-67JK7SK6.js.map +0 -1
  72. package/dist/wiki-AS5YHSR7.js +0 -2
  73. /package/dist/{App-2UCGXCX3.js.map → App-KVH5POXZ.js.map} +0 -0
  74. /package/dist/{ChatApp-IRPSBYC7.js.map → ChatApp-LD4TXJWP.js.map} +0 -0
  75. /package/dist/{agent-UPTK3HFR.js.map → agent-FUMJM6OW.js.map} +0 -0
  76. /package/dist/{chunk-PT5Z5WW4.js.map → chunk-3UN6CXRL.js.map} +0 -0
  77. /package/dist/{chunk-KAFUQILA.js.map → chunk-7IGSJGXI.js.map} +0 -0
  78. /package/dist/{chunk-NMFXY3QU.js.map → chunk-API4IZZG.js.map} +0 -0
  79. /package/dist/{chunk-3GYCFRBK.js.map → chunk-BJPIRNP6.js.map} +0 -0
  80. /package/dist/{chunk-Z522XZBL.js.map → chunk-BVZFYBBP.js.map} +0 -0
  81. /package/dist/{chunk-AIHWGU4P.js.map → chunk-H7253EHW.js.map} +0 -0
  82. /package/dist/{chunk-I2Z6D3MI.js.map → chunk-MOQNLS5Z.js.map} +0 -0
  83. /package/dist/{chunk-7EIUNFDF.js.map → chunk-MYRSNJJ4.js.map} +0 -0
  84. /package/dist/{chunk-2YJ2ZIYC.js.map → chunk-PE55MMLK.js.map} +0 -0
  85. /package/dist/{chunk-PXIGWFIQ.js.map → chunk-R42S57G6.js.map} +0 -0
  86. /package/dist/{chunk-BIJB7CNG.js.map → chunk-TEFMZY6B.js.map} +0 -0
  87. /package/dist/{chunk-PHFOYJUB.js.map → chunk-UB63NQQL.js.map} +0 -0
  88. /package/dist/{chunk-AFSM3IY3.js.map → chunk-UR3ZIDMA.js.map} +0 -0
  89. /package/dist/{chunk-4NUF3SXN.js.map → chunk-UXSYVMPK.js.map} +0 -0
  90. /package/dist/{chunk-O67KV3DX.js.map → chunk-YCI3KUYF.js.map} +0 -0
  91. /package/dist/{chunk-D3FDPA74.js.map → chunk-Z3XUGXPD.js.map} +0 -0
  92. /package/dist/{chunk-BBI3HG77.js.map → chunk-ZR3NZLJL.js.map} +0 -0
  93. /package/dist/{client-ABDGDO7S.js.map → client-TJ5YZOEE.js.map} +0 -0
  94. /package/dist/{config-XPFCUOQT.js.map → config-4WZ7Y34V.js.map} +0 -0
  95. /package/dist/{config-mutator-WYHQV2XF.js.map → config-mutator-5Z7EEB5N.js.map} +0 -0
  96. /package/dist/{doctor-XLLNQRRT.js.map → doctor-7K3NRBNN.js.map} +0 -0
  97. /package/dist/{facts-YY2364CP.js.map → facts-U7BUYRXN.js.map} +0 -0
  98. /package/dist/{program-KZOBDSXQ.js.map → program-KMQNX6YK.js.map} +0 -0
  99. /package/dist/{promote-YUZL3ZU2.js.map → promote-NDC3X54P.js.map} +0 -0
  100. /package/dist/{query-3XH7I6WX.js.map → query-F7BD3JPE.js.map} +0 -0
  101. /package/dist/{registry-5OD2IN5G.js.map → registry-5NBHBVY3.js.map} +0 -0
  102. /package/dist/{request-planner-RNXA2QAH.js.map → request-planner-H74KHFGJ.js.map} +0 -0
  103. /package/dist/{review-candidates-THKWXS7S.js.map → review-candidates-IPJWEXR2.js.map} +0 -0
  104. /package/dist/{routing-X45VX723.js.map → routing-3RSG7SKW.js.map} +0 -0
  105. /package/dist/{schedule-tool-ZTL6UZCC.js.map → schedule-tool-7NYAK43U.js.map} +0 -0
  106. /package/dist/{scheduler-VH7IJ4VA.js.map → scheduler-24O7PADJ.js.map} +0 -0
  107. /package/dist/{seat-LQ47SSNN.js.map → seat-TOM2WHQR.js.map} +0 -0
  108. /package/dist/{select-PRQP2B6G.js.map → select-BUWOD47K.js.map} +0 -0
  109. /package/dist/{set-enabled-E2ML2E33.js.map → set-enabled-XWSFTICB.js.map} +0 -0
  110. /package/dist/{tool-4WPUUUE4.js.map → tool-VOA4HSVP.js.map} +0 -0
  111. /package/dist/{wiki-AS5YHSR7.js.map → wiki-VFME4T2H.js.map} +0 -0
@@ -1,24 +1,24 @@
1
- import{b as nt,c as rt}from"./chunk-WP6KLXTP.js";import{a as ae}from"./chunk-N6EWZGIX.js";import{c as Ze}from"./chunk-SZDACK6O.js";import{b as pe}from"./chunk-AFRHKA7B.js";import{b as Je,e as Ge,f as Xe,i as Qe,k as et,l as tt,q as it}from"./chunk-PXIGWFIQ.js";import{c as Ke,e as ze,f as Ye}from"./chunk-KA2UIZXG.js";import{e as Ue,g as qe,h as Be,i as ue}from"./chunk-GQ76J72O.js";import{a as Ve}from"./chunk-GV7S5BAX.js";import{a as je,b as de,c as ce,d as He,e as le}from"./chunk-QD6IICK7.js";import{v as Me,w as un}from"./chunk-2YJ2ZIYC.js";import{b as Le,f as ln}from"./chunk-72SZI2UW.js";import{c as Fe,d as Ce}from"./chunk-QOYAX2FT.js";import{existsSync as pn,mkdirSync as ot,readFileSync as gn,writeFileSync as fn,renameSync as mn}from"fs";import{resolve as st,dirname as hn}from"path";var at=class{filePath;log;constructor(e={}){let t=e.baseDir??st(process.cwd(),".agentx");this.filePath=st(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),ot(t,{recursive:!0})}key(e,t,n){return`${e}::${t}::${n||"-"}`}load(){if(!pn(this.filePath))return{version:1,overrides:{}};try{let e=gn(this.filePath,"utf-8"),t=JSON.parse(e);return!t||typeof t!="object"?{version:1,overrides:{}}:(t.overrides||(t.overrides={}),t)}catch(e){return this.log(`load failed, starting empty: ${e?.message||e}`),{version:1,overrides:{}}}}save(e){ot(hn(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;fn(t,JSON.stringify(e,null,2)),mn(t,this.filePath)}get(e,t,n){let o=this.load().overrides[this.key(e,t,n)];if(o&&!(o.expiresAt&&Date.parse(o.expiresAt)<Date.now()))return o}set(e){if(!e.channel||!e.chatId||!e.toAgent)throw new Error("channel, chatId and toAgent are required");let t=this.load(),n={...e,createdAt:e.createdAt??new Date().toISOString()};return t.overrides[this.key(n.channel,n.chatId,n.accountId)]=n,this.save(t),n}remove(e,t,n){let i=this.load(),o=this.key(e,t,n);return o in i.overrides?(delete i.overrides[o],this.save(i),!0):!1}consumeSummary(e,t,n){let i=this.load(),o=i.overrides[this.key(e,t,n)];if(!o||!o.summary||o.summaryConsumedAt)return;let s=o.summary;return o.summaryConsumedAt=new Date().toISOString(),this.save(i),s}listActive(){let e=this.load(),t=Date.now();return Object.values(e.overrides).filter(n=>!n.expiresAt||Date.parse(n.expiresAt)>=t)}listByAgent(e){let t=this.listActive();return{incoming:t.filter(n=>n.toAgent===e),outgoing:t.filter(n=>n.fromAgent===e)}}};import{readFileSync as pt,writeFileSync as ge,appendFileSync as bn,mkdirSync as vn,existsSync as gt,statSync as Sn}from"fs";import{resolve as K}from"path";var dt="[Agent Memory \u2014 persistent facts from past conversations]",yn=2400;function ct(r,e){return r?`UNVERIFIED (${e===null?"age unknown":`${e}d old`}) `:""}function wn(r,e=Date.now()){let t=ze(r,e),n=r.undated?"UNVERIFIED (never checked) ":ct(t,Ue(r.verifiedAt,e));return{line:`- [wiki ${r.id}] ${n}${r.subject} \xB7 ${r.attribute}: ${r.value} (${r.source}, checked ${r.verifiedAt.slice(0,10)} by ${r.verifiedBy})`,unverified:t}}function kn(r,e){let n=!r.source.chatId.startsWith("-")&&/^\d+$/.test(r.source.chatId)?"DM":r.source.chatId,i=Be(r,e);return{line:`- [${r.category}] ${ct(i,qe(r,e))}${r.content} (${n}, ${r.source.date})`,unverified:i}}function lt(r,e=[],t=Date.now()){let n=[],i=new Set,o=dt.length,s=!1;for(let a of r){let d=e.length>0?Ye(a.content,e):null,c,u,p=d&&Date.parse(a.createdAt)>Date.parse(d.verifiedAt)&&!a.content.toLowerCase().includes(d.value.toLowerCase());if(d&&!p){if(i.has(d.id))continue;i.add(d.id),c=wn(d,t),u=d.id}else c=kn(a,t),d&&(c.line+=` [differs from wiki ${d.id}]`);let g=c.unverified&&!s?ue.length:0;if(o+g+c.line.length>yn)break;n.push({fact:a,...c,...u?{wikiRef:u}:{}}),o+=g+c.line.length,g&&(s=!0)}return n}function ut(r){if(r.length===0)return"";let e=r.some(t=>t.unverified)?[ue]:[];return[dt,...e,...r.map(t=>t.line),"[End Memory]"].join(`
2
- `)}var ft=200,In=7,mt=class{memoryDir;ledger;constructor(e=process.cwd()){this.memoryDir=K(e,".agentx/memory"),this.ledger=new Ke(K(e,".agentx/wiki")),gt(this.memoryDir)||vn(this.memoryDir,{recursive:!0})}filePath(e){return K(this.memoryDir,`${e}.jsonl`)}addMemory(e,t){if(t.category==="secret"||de(t.content))return!1;let n=t.source.trust??je(t.source.channel),i=t.review??He(n),o={...t,source:{...t.source,trust:n},...i?{review:i}:{},id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,createdAt:new Date().toISOString()};return bn(this.filePath(e),JSON.stringify(o)+`
3
- `),!0}parsedCache=new Map;getAll(e){let t=this.filePath(e);if(!gt(t))return[];try{let{mtimeMs:n,size:i}=Sn(t),o=this.parsedCache.get(t);if(o&&o.mtimeMs===n&&o.size===i)return o.facts.slice();let a=pt(t,"utf-8").split(`
4
- `).filter(d=>d.trim()).map(d=>{try{return JSON.parse(d)}catch{return null}}).filter(d=>d!==null);return this.parsedCache.set(t,{mtimeMs:n,size:i,facts:a}),a.slice()}catch{return[]}}findRelevant(e,t,n=8){let i=this.getAll(t).filter(le);if(i.length===0)return[];let o=i.map(f=>`${f.keywords.join(" ")} ${f.content}`),s=K(this.memoryDir,`${t}_bm25_cache.json`),a=Ce(o,s),d=Fe(e,a),c=new Map(d.map(f=>[f.docIndex,f.score])),p=i.map((f,h)=>{let m=c.get(h)??0;return f.category==="commitment"&&(m+=1),{memory:f,score:m}}).filter(f=>f.score>0);if(p.length===0)return i.slice(-n);let g=p.sort((f,h)=>h.score-f.score).slice(0,n).map(f=>f.memory);if(g.length>0)try{this.recordAccess(t,g.map(f=>f.id))}catch{}return g}buildContext(e){return ut(this.contextLines(e))}contextFacts(e){return this.contextLines(e).map(t=>t.fact)}contextLines(e){let t=[];try{t=this.ledger.list()}catch{}return lt(e,t)}recordAccess(e,t){if(t.length===0)return;let n=this.getAll(e),i=new Set(t),o=!1;for(let s of n)if(i.has(s.id)){s.accessCount=(s.accessCount||0)+1,s.lastAccessed=new Date().toISOString();let a=s.intervalDays||1;s.intervalDays=Math.min(a*2,30),s.nextReview=new Date(Date.now()+s.intervalDays*864e5).toISOString(),o=!0}o&&ge(this.filePath(e),n.map(s=>JSON.stringify(s)).join(`
1
+ import{b as nt,c as rt}from"./chunk-WP6KLXTP.js";import{a as ae}from"./chunk-N6EWZGIX.js";import{c as Ze}from"./chunk-SZDACK6O.js";import{b as pe}from"./chunk-AFRHKA7B.js";import{b as Je,e as Ge,f as Xe,i as Qe,k as et,l as tt,q as it}from"./chunk-R42S57G6.js";import{c as Ke,e as ze,f as Ye}from"./chunk-KA2UIZXG.js";import{e as Ue,g as qe,h as Be,i as ue}from"./chunk-GQ76J72O.js";import{a as Ve}from"./chunk-GV7S5BAX.js";import{a as je,b as de,c as ce,d as He,e as le}from"./chunk-QD6IICK7.js";import{v as Le,w as un}from"./chunk-PE55MMLK.js";import{b as Me,f as ln}from"./chunk-72SZI2UW.js";import{c as Fe,d as Ce}from"./chunk-QOYAX2FT.js";import{existsSync as pn,mkdirSync as ot,readFileSync as gn,writeFileSync as fn,renameSync as mn}from"fs";import{resolve as st,dirname as hn}from"path";var at=class{filePath;log;constructor(e={}){let t=e.baseDir??st(process.cwd(),".agentx");this.filePath=st(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),ot(t,{recursive:!0})}key(e,t,r){return`${e}::${t}::${r||"-"}`}load(){if(!pn(this.filePath))return{version:1,overrides:{}};try{let e=gn(this.filePath,"utf-8"),t=JSON.parse(e);return!t||typeof t!="object"?{version:1,overrides:{}}:(t.overrides||(t.overrides={}),t)}catch(e){return this.log(`load failed, starting empty: ${e?.message||e}`),{version:1,overrides:{}}}}save(e){ot(hn(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;fn(t,JSON.stringify(e,null,2)),mn(t,this.filePath)}get(e,t,r){let o=this.load().overrides[this.key(e,t,r)];if(o&&!(o.expiresAt&&Date.parse(o.expiresAt)<Date.now()))return o}set(e){if(!e.channel||!e.chatId||!e.toAgent)throw new Error("channel, chatId and toAgent are required");let t=this.load(),r={...e,createdAt:e.createdAt??new Date().toISOString()};return t.overrides[this.key(r.channel,r.chatId,r.accountId)]=r,this.save(t),r}remove(e,t,r){let i=this.load(),o=this.key(e,t,r);return o in i.overrides?(delete i.overrides[o],this.save(i),!0):!1}consumeSummary(e,t,r){let i=this.load(),o=i.overrides[this.key(e,t,r)];if(!o||!o.summary||o.summaryConsumedAt)return;let s=o.summary;return o.summaryConsumedAt=new Date().toISOString(),this.save(i),s}listActive(){let e=this.load(),t=Date.now();return Object.values(e.overrides).filter(r=>!r.expiresAt||Date.parse(r.expiresAt)>=t)}listByAgent(e){let t=this.listActive();return{incoming:t.filter(r=>r.toAgent===e),outgoing:t.filter(r=>r.fromAgent===e)}}};import{readFileSync as pt,writeFileSync as ge,appendFileSync as bn,mkdirSync as vn,existsSync as gt,statSync as Sn}from"fs";import{resolve as K}from"path";var dt="[Agent Memory \u2014 persistent facts from past conversations]",yn=2400;function ct(n,e){return n?`UNVERIFIED (${e===null?"age unknown":`${e}d old`}) `:""}function wn(n,e=Date.now()){let t=ze(n,e),r=n.undated?"UNVERIFIED (never checked) ":ct(t,Ue(n.verifiedAt,e));return{line:`- [wiki ${n.id}] ${r}${n.subject} \xB7 ${n.attribute}: ${n.value} (${n.source}, checked ${n.verifiedAt.slice(0,10)} by ${n.verifiedBy})`,unverified:t}}function kn(n,e){let r=!n.source.chatId.startsWith("-")&&/^\d+$/.test(n.source.chatId)?"DM":n.source.chatId,i=Be(n,e);return{line:`- [${n.category}] ${ct(i,qe(n,e))}${n.content} (${r}, ${n.source.date})`,unverified:i}}function lt(n,e=[],t=Date.now()){let r=[],i=new Set,o=dt.length,s=!1;for(let a of n){let d=e.length>0?Ye(a.content,e):null,c,u,p=d&&Date.parse(a.createdAt)>Date.parse(d.verifiedAt)&&!a.content.toLowerCase().includes(d.value.toLowerCase());if(d&&!p){if(i.has(d.id))continue;i.add(d.id),c=wn(d,t),u=d.id}else c=kn(a,t),d&&(c.line+=` [differs from wiki ${d.id}]`);let g=c.unverified&&!s?ue.length:0;if(o+g+c.line.length>yn)break;r.push({fact:a,...c,...u?{wikiRef:u}:{}}),o+=g+c.line.length,g&&(s=!0)}return r}function ut(n){if(n.length===0)return"";let e=n.some(t=>t.unverified)?[ue]:[];return[dt,...e,...n.map(t=>t.line),"[End Memory]"].join(`
2
+ `)}var ft=200,Rn=7,mt=class{memoryDir;ledger;constructor(e=process.cwd()){this.memoryDir=K(e,".agentx/memory"),this.ledger=new Ke(K(e,".agentx/wiki")),gt(this.memoryDir)||vn(this.memoryDir,{recursive:!0})}filePath(e){return K(this.memoryDir,`${e}.jsonl`)}addMemory(e,t){if(t.category==="secret"||de(t.content))return!1;let r=t.source.trust??je(t.source.channel),i=t.review??He(r),o={...t,source:{...t.source,trust:r},...i?{review:i}:{},id:`${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,createdAt:new Date().toISOString()};return bn(this.filePath(e),JSON.stringify(o)+`
3
+ `),!0}parsedCache=new Map;getAll(e){let t=this.filePath(e);if(!gt(t))return[];try{let{mtimeMs:r,size:i}=Sn(t),o=this.parsedCache.get(t);if(o&&o.mtimeMs===r&&o.size===i)return o.facts.slice();let a=pt(t,"utf-8").split(`
4
+ `).filter(d=>d.trim()).map(d=>{try{return JSON.parse(d)}catch{return null}}).filter(d=>d!==null);return this.parsedCache.set(t,{mtimeMs:r,size:i,facts:a}),a.slice()}catch{return[]}}findRelevant(e,t,r=8){let i=this.getAll(t).filter(le);if(i.length===0)return[];let o=i.map(f=>`${f.keywords.join(" ")} ${f.content}`),s=K(this.memoryDir,`${t}_bm25_cache.json`),a=Ce(o,s),d=Fe(e,a),c=new Map(d.map(f=>[f.docIndex,f.score])),p=i.map((f,h)=>{let m=c.get(h)??0;return f.category==="commitment"&&(m+=1),{memory:f,score:m}}).filter(f=>f.score>0);if(p.length===0)return i.slice(-r);let g=p.sort((f,h)=>h.score-f.score).slice(0,r).map(f=>f.memory);if(g.length>0)try{this.recordAccess(t,g.map(f=>f.id))}catch{}return g}buildContext(e){return ut(this.contextLines(e))}contextFacts(e){return this.contextLines(e).map(t=>t.fact)}contextLines(e){let t=[];try{t=this.ledger.list()}catch{}return lt(e,t)}recordAccess(e,t){if(t.length===0)return;let r=this.getAll(e),i=new Set(t),o=!1;for(let s of r)if(i.has(s.id)){s.accessCount=(s.accessCount||0)+1,s.lastAccessed=new Date().toISOString();let a=s.intervalDays||1;s.intervalDays=Math.min(a*2,30),s.nextReview=new Date(Date.now()+s.intervalDays*864e5).toISOString(),o=!0}o&&ge(this.filePath(e),r.map(s=>JSON.stringify(s)).join(`
5
5
  `)+`
6
- `)}getDueForReview(e,t=5){let n=this.getAll(e).filter(le),i=Date.now();return n.filter(o=>o.category==="task-state"?!1:o.nextReview?new Date(o.nextReview).getTime()<=i:!0).sort((o,s)=>!o.nextReview&&s.nextReview?-1:o.nextReview&&!s.nextReview?1:o.nextReview&&s.nextReview?new Date(o.nextReview).getTime()-new Date(s.nextReview).getTime():(o.accessCount||0)-(s.accessCount||0)).slice(0,t)}buildRecallContext(e){let t=this.getDueForReview(e,5);if(t.length===0)return"";let n=["[Memory Recall \u2014 facts due for review, verify they are still accurate]"];for(let i of t){let o=Math.round((Date.now()-new Date(i.createdAt).getTime())/864e5);n.push(`- [${i.category}] ${i.content} (${o}d old, accessed ${i.accessCount||0}x)`)}return n.push("[If any fact is outdated, note the correction. Otherwise, acknowledge recall.]"),n.join(`
7
- `)}held(e){return this.getAll(e).filter(t=>t.review==="held"||t.review===void 0&&ce(t)==="external")}review(e,t,n,i="operator"){let o=this.getAll(e),s=o.find(a=>a.id===t);return s?(s.review=n,s.reviewedBy=i,s.reviewedAt=new Date().toISOString(),this.rewrite(e,o),!0):!1}scrubSecrets(e,t=!1){let n=this.getAll(e),i=n.filter(s=>s.category!=="secret"&&!de(s.content)),o=n.length-i.length;return t&&o>0&&this.rewrite(e,i),o}trustSummary(e){let t={};for(let n of this.getAll(e)){let i=`${ce(n)}${n.review?`/${n.review}`:""}`;t[i]=(t[i]??0)+1}return t}fileFor(e){return this.filePath(e)}rewrite(e,t){let n=[];try{n=pt(this.filePath(e),"utf-8").split(`
8
- `).filter(o=>{if(!o.trim())return!1;try{return JSON.parse(o),!1}catch{return!0}})}catch{}let i=[...t.map(o=>JSON.stringify(o)),...n];ge(this.filePath(e),i.join(`
6
+ `)}getDueForReview(e,t=5){let r=this.getAll(e).filter(le),i=Date.now();return r.filter(o=>o.category==="task-state"?!1:o.nextReview?new Date(o.nextReview).getTime()<=i:!0).sort((o,s)=>!o.nextReview&&s.nextReview?-1:o.nextReview&&!s.nextReview?1:o.nextReview&&s.nextReview?new Date(o.nextReview).getTime()-new Date(s.nextReview).getTime():(o.accessCount||0)-(s.accessCount||0)).slice(0,t)}buildRecallContext(e){let t=this.getDueForReview(e,5);if(t.length===0)return"";let r=["[Memory Recall \u2014 facts due for review, verify they are still accurate]"];for(let i of t){let o=Math.round((Date.now()-new Date(i.createdAt).getTime())/864e5);r.push(`- [${i.category}] ${i.content} (${o}d old, accessed ${i.accessCount||0}x)`)}return r.push("[If any fact is outdated, note the correction. Otherwise, acknowledge recall.]"),r.join(`
7
+ `)}held(e){return this.getAll(e).filter(t=>t.review==="held"||t.review===void 0&&ce(t)==="external")}review(e,t,r,i="operator"){let o=this.getAll(e),s=o.find(a=>a.id===t);return s?(s.review=r,s.reviewedBy=i,s.reviewedAt=new Date().toISOString(),this.rewrite(e,o),!0):!1}scrubSecrets(e,t=!1){let r=this.getAll(e),i=r.filter(s=>s.category!=="secret"&&!de(s.content)),o=r.length-i.length;return t&&o>0&&this.rewrite(e,i),o}trustSummary(e){let t={};for(let r of this.getAll(e)){let i=`${ce(r)}${r.review?`/${r.review}`:""}`;t[i]=(t[i]??0)+1}return t}fileFor(e){return this.filePath(e)}rewrite(e,t){let r=[];try{r=pt(this.filePath(e),"utf-8").split(`
8
+ `).filter(o=>{if(!o.trim())return!1;try{return JSON.parse(o),!1}catch{return!0}})}catch{}let i=[...t.map(o=>JSON.stringify(o)),...r];ge(this.filePath(e),i.join(`
9
9
  `)+(i.length?`
10
- `:""))}hasSimilar(e,t){let n=this.getAll(e),o=t.toLowerCase().split(/\s+/).filter(s=>s.length>3);return n.some(s=>{let a=s.content.toLowerCase();return o.filter(c=>a.includes(c)).length>=o.length*.7})}prune(e){let t=this.getAll(e);if(t.length===0)return;let n=Date.now(),i=In*24*60*60*1e3;t=t.filter(s=>s.category==="task-state"&&s.expiresAt?new Date(s.expiresAt).getTime()>n:s.category==="task-state"&&!s.expiresAt?n-new Date(s.createdAt).getTime()<i:!0),t.length>ft&&(t=t.slice(-ft));let o=this.filePath(e);ge(o,t.map(s=>JSON.stringify(s)).join(`
10
+ `:""))}hasSimilar(e,t){let r=this.getAll(e),o=t.toLowerCase().split(/\s+/).filter(s=>s.length>3);return r.some(s=>{let a=s.content.toLowerCase();return o.filter(c=>a.includes(c)).length>=o.length*.7})}prune(e){let t=this.getAll(e);if(t.length===0)return;let r=Date.now(),i=Rn*24*60*60*1e3;t=t.filter(s=>s.category==="task-state"&&s.expiresAt?new Date(s.expiresAt).getTime()>r:s.category==="task-state"&&!s.expiresAt?r-new Date(s.createdAt).getTime()<i:!0),t.length>ft&&(t=t.slice(-ft));let o=this.filePath(e);ge(o,t.map(s=>JSON.stringify(s)).join(`
11
11
  `)+`
12
- `)}};function ht(r){let e=(r||"").trim();for(let t=0;t<5;t++){let n=e;if(e=e.replace(/^Peer\s+"[^"]*"\s+\/task error:\s*\d{3}:\s*/i,"").replace(/^Peer\s+"[^"]*"\s+agent error:\s*/i,"").replace(/^mesh fallback failed:\s*/i,"").trim(),e===n)break}return e}var Rn="__queued__";function Ti(r,e){return`${Rn}:${r}:${e}`}var An=/^__queued__(?::([A-Za-z-]+):(\d+))?$/;function $n(r){if(!r)return null;let e=An.exec(ht(r));return e?{mode:e[1]||"collect",pending:e[2]?Number(e[2]):1}:null}function Ei(r){return $n(r)!==null}import{existsSync as S,mkdirSync as Kn,readdirSync as J,readFileSync as G,statSync as zn,unlinkSync as X,writeFileSync as ye}from"fs";import{resolve as I,relative as we}from"path";import{z as l}from"zod";var Tn=l.enum(["trigger.channel","trigger.manual","trigger.cron","trigger.hook","trigger.form","trigger.poll","agent","transform","classify","branch","gateway.parallel","rule","action.send","action.createIssue","action.setLabel","action.readLabel","action.react","action.editMessage","action.logTime","action.callHTTP","action.run","action.builtin","subProcess","signal.emit","signal.wait","timer.boundary","checkpoint","end"]),En=l.enum(["equals","contains","matches","exists"]),fe=l.object({kind:En,params:l.record(l.unknown()).default({})}),wt=l.object({maxAttempts:l.number().int().min(1).max(10).default(1),backoffMs:l.number().int().min(0).max(6e4).default(1e3)}).default({maxAttempts:1,backoffMs:1e3}),kt=l.object({id:l.string().min(1).regex(/^[a-zA-Z_][a-zA-Z0-9_-]*$/,"node id must be identifier-safe"),type:Tn,config:l.record(l.unknown()).default({}),retry:wt,position:l.object({x:l.number(),y:l.number()}).optional()}),bt=l.object({from:l.string(),fromPort:l.string().optional(),to:l.string(),toPort:l.string().optional(),label:l.string().optional()}),yt=l.union([l.string(),l.date().transform(r=>r.toISOString())]),T=l.object({id:l.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"workflow id must be lower-kebab"),version:l.literal(2).default(2),title:l.string().min(1),description:l.string().optional(),status:l.enum(["draft","review","active","deprecated"]).default("active"),tags:l.array(l.string()).default([]),project:l.string().optional(),entity:l.string().optional(),intentPath:l.array(l.string()).default([]),generatedFrom:l.string().optional(),sourceTaskIds:l.array(l.string()).default([]),confidence:l.number().min(0).max(1).optional(),workflowVersion:l.string().optional(),ownerAgent:l.string().optional(),lastMatchedAt:l.string().optional(),matchCount:l.number().int().min(0).default(0),state:l.enum(["active","disabled","quarantined"]).default("active"),priority:l.number().int().default(0),fanOut:l.boolean().default(!1),nodes:l.array(kt).refine(r=>r.length>0,{message:"workflow must have at least one node"}),edges:l.array(bt).default([]),envAllow:l.array(l.string()).default([]),retention:l.object({maxRuns:l.number().int().positive().default(500),maxDays:l.number().int().positive().default(90)}).default({maxRuns:500,maxDays:90}),maxChildDepth:l.number().int().positive().default(5),mesh:l.object({allowRemote:l.boolean().default(!1),peers:l.array(l.string()).optional()}).default({allowRemote:!1}),created:yt.optional(),updated:yt.optional()});function me(r){let e=[],t=new Map(r.nodes.map(s=>[s.id,s])),n=r.nodes.filter(s=>s.type.startsWith("trigger."));n.length===0&&e.push("workflow must have exactly one trigger.* node (found 0)"),n.length>1&&e.push(`workflow has ${n.length} trigger.* nodes; v1 supports exactly one`);for(let s of r.edges)t.has(s.from)||e.push(`edge references missing node: from="${s.from}"`),t.has(s.to)||e.push(`edge references missing node: to="${s.to}"`);let i=n[0];if(i){let s=new Map;for(let c of r.edges)s.has(c.from)||s.set(c.from,[]),s.get(c.from).push(c.to);let a=new Set,d=[i.id];for(;d.length;){let c=d.pop();if(!a.has(c)){a.add(c);for(let u of s.get(c)??[])d.push(u)}}for(let c of r.nodes)a.has(c.id)||e.push(`node "${c.id}" is unreachable from trigger "${i.id}"`);r.nodes.some(c=>a.has(c.id)&&xn(c.type))||e.push("no reachable `end`, `checkpoint`, `subProcess`, `signal.wait`, or `timer.boundary` node \u2014 the run cannot terminate or pause")}for(let s of r.nodes){if(s.type!=="branch"&&s.type!=="rule")continue;let a=s.type==="branch"?s.config.cases??[]:(s.config.rules??[]).filter(p=>typeof p.to=="string"),d=s.type==="branch"?s.config.default:s.config.default?.to,c=new Set(a.map(p=>p.to));d&&c.add(d);let u=r.edges.filter(p=>p.from===s.id);for(let p of u){let g=p.fromPort??"";c.has(g)||e.push(`${s.type} "${s.id}" has outgoing edge with port "${g}" not declared in cases or default`)}}let o=Pn(r);for(let s of o)e.push(`cycle without agent/checkpoint: ${s.join(" -> ")}`);return e}function xn(r){return r==="end"||r==="checkpoint"||r==="subProcess"||r==="signal.wait"||r==="timer.boundary"}function Nn(r){return r==="agent"||r==="checkpoint"||r==="subProcess"||r==="signal.wait"||r==="timer.boundary"}function Pn(r){let e=new Map;for(let a of r.edges)e.has(a.from)||e.set(a.from,[]),e.get(a.from).push(a.to);let t=new Map(r.nodes.map(a=>[a.id,a])),n=[],i=new Map,o=[],s=a=>{if(i.get(a)===1){let d=o.indexOf(a);if(d>=0){let c=o.slice(d).concat(a);c.some(p=>{let g=t.get(p)?.type;return g?Nn(g):!1})||n.push(c)}return}if(i.get(a)!==2){i.set(a,1),o.push(a);for(let d of e.get(a)??[])s(d);o.pop(),i.set(a,2)}};for(let a of r.nodes)i.get(a.id)!==2&&s(a.id);return n}var vt=l.enum(["running","paused","completed","failed","canceled"]),On=l.enum(["ok","failed","timeout","skipped","paused","resumed"]),_n=l.object({at:l.string(),nodeId:l.string(),inputKeys:l.array(l.string()).default([]),status:On,output:l.record(l.unknown()).optional(),idempotencyKey:l.string(),note:l.string().optional()}),Dn=l.object({backend:l.string(),id:l.string()}),Wn=l.discriminatedUnion("kind",[l.object({kind:l.literal("checkpoint"),nodeId:l.string(),checkpointName:l.string(),resumeMatch:l.record(l.unknown()).default({})}),l.object({kind:l.literal("subProcess"),nodeId:l.string(),childRunId:l.string(),childWorkflowId:l.string()}),l.object({kind:l.literal("signalWait"),nodeId:l.string(),signalName:l.string(),match:l.record(l.unknown()).default({}),scope:l.enum(["workflow","global"]).default("workflow")}),l.object({kind:l.literal("timerWait"),nodeId:l.string(),fireAt:l.string()})]),Fn=l.object({id:l.string(),workflowId:l.string(),workflowVersion:l.literal(2),homeNode:l.string(),status:vt,pausedAt:Wn.optional(),context:l.record(l.record(l.unknown())).default({}),pending:l.array(l.string()).default([]),joinCounters:l.record(l.array(l.string())).default({}),entityRef:Dn,history:l.array(_n).default([]),parentRunId:l.string().nullable().default(null),parentNodeId:l.string().nullable().default(null),rootRunId:l.string().nullable().default(null),depth:l.number().int().min(0).default(0),eventRootId:l.string().optional(),createdAt:l.string(),updatedAt:l.string()});import It from"js-yaml";var Cn=new Set(["branch","gateway.parallel","rule","signal.wait","subProcess","timer.boundary","checkpoint"]),v=class extends Error{constructor(t,n){super(t);this.mark=n;this.name="WorkflowYamlError"}};function z(r,e={}){if(!r||r.trim()==="")throw new v(`${E(e)}empty file \u2014 workflow YAML must contain at least an id, version, title, and one node.`);let t;try{t=It.loadAll(r)}catch(i){let o=i?.mark;throw new v(`${E(e)}YAML parse error: ${i?.reason??i?.message??i}`+(o?` (line ${o.line+1}, column ${o.column+1})`:""),o)}if(t.length===0||t.length===1&&t[0]==null)throw new v(`${E(e)}YAML produced no document.`);if(t.length>1)throw new v(`${E(e)}multi-document YAML is not supported in v1; one workflow per file.`);let n=t[0];if(typeof n!="object"||n===null||Array.isArray(n)){let i=Array.isArray(n)?"array":typeof n;throw new v(`${E(e)}top-level YAML must be a mapping (got ${i}).`)}return Rt(n,e)}function Rt(r,e={}){if(!("flow"in r))return r;let t=r.flow;if(t==null){let p={...r};return delete p.flow,p}if(!Array.isArray(t))throw new v(`${E(e)}flow must be an array of node ids (got ${typeof t}).`);for(let p of t)if(typeof p!="string")throw new v(`${E(e)}flow entries must be strings (got ${typeof p}).`);let n=t,i=Array.isArray(r.nodes)?r.nodes:[],o=new Map;for(let p of i)p&&typeof p=="object"&&typeof p.id=="string"&&typeof p.type=="string"&&o.set(p.id,p.type);for(let p of n){if(!o.has(p))throw new v(`${E(e)}flow references unknown node "${p}".`);let g=o.get(p);if(Cn.has(g))throw new v(`${E(e)}flow cannot include ${g} node "${p}"; use explicit edges for ${g} nodes.`)}let s=[];for(let p=0;p<n.length-1;p++)s.push({from:n[p],to:n[p+1]});let a=Array.isArray(r.edges)?r.edges:[],d=new Set,c=[];for(let p of a){if(!p||typeof p!="object")continue;let g=St(p.from,p.fromPort,p.to);g&&!d.has(g)?(d.add(g),c.push(p)):g||c.push(p)}for(let p of s){let g=St(p.from,void 0,p.to);g&&!d.has(g)&&(d.add(g),c.push(p))}let u={...r,edges:c};return delete u.flow,u}function St(r,e,t){return typeof r!="string"||typeof t!="string"?null:`${r}::${typeof e=="string"?e:""}::${t}`}function E(r){return r.filePath?`${r.filePath}: `:""}function Ln(r){return It.dump(r,{noRefs:!0,lineWidth:100,sortKeys:!1})}import{Document as Mn,isMap as Y,isSeq as jn,isScalar as At,parseDocument as Hn}from"yaml";function $t(r,e){let t=Hn(r);if(!t.contents||!Y(t.contents)){let n=new Mn(e);return t.commentBefore&&(n.commentBefore=t.commentBefore),String(n)}return he(t,t.contents,e),String(t)}function he(r,e,t){let n=Object.keys(t),i=new Set(n),o=new Map;for(let a of e.items){let d=Bn(a);d!==null&&o.set(d,a)}let s=[];for(let a of n){let d=t[a],c=o.get(a);c?(Un(r,c,d),s.push(c)):s.push(r.createPair(a,d))}e.items=s}function Un(r,e,t){let n=e.value;if(t==null){e.value=r.createNode(null);return}if(typeof t!="object"){e.value=r.createNode(t);return}if(Array.isArray(t)){jn(n)?qn(r,n,t):e.value=r.createNode(t);return}Y(n)?he(r,n,t):e.value=r.createNode(t)}function qn(r,e,t){if(!(t.length>0&&t.every(s=>s&&typeof s=="object"&&typeof s.id=="string"))){let s=r.createNode(t);e.items=s.items;return}let i=new Map;for(let s of e.items)if(Y(s)){let a=s.get("id",!0);At(a)&&typeof a.value=="string"&&i.set(a.value,s)}let o=[];for(let s of t){let a=s.id,d=i.get(a);d&&Y(d)?(he(r,d,s),o.push(d)):o.push(r.createNode(s))}e.items=o}function Bn(r){let e=r.key;return At(e)&&typeof e.value=="string"?e.value:typeof e=="string"?e:null}var Tt=new Map,ke=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??I(process.cwd(),".agentx/workflows"),Kn(this.baseDir,{recursive:!0})}pathFor(e){return this.pathForJson(e)}pathForJson(e){return I(this.baseDir,`${e}.json`)}pathForYaml(e){return I(this.baseDir,`${e}.yaml`)}isWorkflowFile(e){return e.startsWith("_")?!1:e.endsWith(".json")||e.endsWith(".yaml")||e.endsWith(".yml")}idFromFilename(e){return e.replace(/\.(json|ya?ml)$/,"")}readAndParse(e){let t=I(this.baseDir,e),n=G(t,"utf-8");return e.endsWith(".json")?JSON.parse(n):z(n,{filePath:e})}list(){if(!S(this.baseDir))return[];let e=new Map,t=[];for(let a of J(this.baseDir,{withFileTypes:!0})){if(!a.isFile()||!this.isWorkflowFile(a.name))continue;let d=this.idFromFilename(a.name),c=e.get(d)??[];c.push(a.name),e.set(d,c);try{let u=zn(I(this.baseDir,a.name));t.push(`${a.name}:${u.mtimeMs}:${u.size}`)}catch{t.push(`${a.name}:?`)}}let n=t.sort().join("|"),i=Tt.get(this.baseDir);if(i&&i.signature===n)return i.workflows.slice();let o=[];for(let[,a]of e)if(!(a.length>1))try{let d=this.readAndParse(a[0]),c=T.safeParse(d);c.success&&o.push(c.data)}catch{}let s=o.sort((a,d)=>a.id.localeCompare(d.id));return Tt.set(this.baseDir,{signature:n,workflows:s}),s.slice()}validateAll(){let e=[];if(!S(this.baseDir))return e;let t=new Map;for(let n of J(this.baseDir,{withFileTypes:!0})){if(!n.isFile()||!this.isWorkflowFile(n.name))continue;let i=this.idFromFilename(n.name),o=t.get(i)??[];o.push(n.name),t.set(i,o)}for(let[n,i]of t){if(i.length>1){let p=[...i].sort();for(let g of p)e.push({id:n,path:we(this.baseDir,I(this.baseDir,g)),issues:[`duplicate workflow id "${n}" \u2014 found ${p.join(" and ")}; delete one to disambiguate`],isValid:!1});continue}let o=i[0],s=I(this.baseDir,o),a=we(this.baseDir,s),d;try{d=this.readAndParse(o)}catch(p){let g=p instanceof v?p.message:`parse error: ${p?.message??p}`;e.push({id:n,path:a,issues:[g],isValid:!1});continue}let c=T.safeParse(d);if(!c.success){let p=c.error.issues.map(g=>`${g.path.join(".")||"<root>"}: ${g.message}`);e.push({id:String(d?.id??n),path:a,issues:p,isValid:!1});continue}let u=me(c.data);e.push({workflow:c.data,issues:u,isValid:u.length===0})}return e}get(e){let t=this.pathForJson(e),n=this.pathForYaml(e),i=I(this.baseDir,`${e}.yml`),o=S(t),s=S(n)||S(i);if(o&&s)return null;if(o)try{let d=JSON.parse(G(t,"utf-8")),c=T.safeParse(d);return c.success?c.data:null}catch{return null}let a=S(n)?n:S(i)?i:null;if(a)try{let d=G(a,"utf-8"),c=z(d,{filePath:we(this.baseDir,a)}),u=T.safeParse(c);return u.success?u.data:null}catch{return null}if(!S(this.baseDir))return null;for(let d of J(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name)||this.idFromFilename(d.name)===e))try{let u=this.readAndParse(d.name),p=T.safeParse(u);if(p.success&&p.data.id===e)return p.data}catch{}return null}save(e,t={}){let n=new Date().toISOString().slice(0,10),i=T.parse({...e,created:e.created||n,updated:n}),o=this.pathForYaml(i.id),s=I(this.baseDir,`${i.id}.yml`),a=S(o)?o:S(s)?s:null;if(!a&&S(this.baseDir)){for(let d of J(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name))&&!d.name.endsWith(".json"))try{let c=this.readAndParse(d.name),u=T.safeParse(c);if(u.success&&u.data.id===i.id){a=I(this.baseDir,d.name);break}}catch{}}if(a&&t.convertFromYaml)return X(a),ye(this.pathForJson(i.id),JSON.stringify(i,null,2)+`
12
+ `)}};function ht(n){let e=(n||"").trim();for(let t=0;t<5;t++){let r=e;if(e=e.replace(/^Peer\s+"[^"]*"\s+\/task error:\s*\d{3}:\s*/i,"").replace(/^Peer\s+"[^"]*"\s+agent error:\s*/i,"").replace(/^mesh fallback failed:\s*/i,"").trim(),e===r)break}return e}var In="__queued__";function Ti(n,e){return`${In}:${n}:${e}`}var An=/^__queued__(?::([A-Za-z-]+):(\d+))?$/;function $n(n){if(!n)return null;let e=An.exec(ht(n));return e?{mode:e[1]||"collect",pending:e[2]?Number(e[2]):1}:null}function Ei(n){return $n(n)!==null}import{existsSync as S,mkdirSync as Kn,readdirSync as J,readFileSync as G,statSync as zn,unlinkSync as X,writeFileSync as ye}from"fs";import{resolve as R,relative as we}from"path";import{z as l}from"zod";var Tn=l.enum(["trigger.channel","trigger.manual","trigger.cron","trigger.hook","trigger.form","trigger.poll","agent","transform","classify","branch","gateway.parallel","rule","action.send","action.createIssue","action.setLabel","action.readLabel","action.react","action.editMessage","action.logTime","action.callHTTP","action.run","action.builtin","subProcess","signal.emit","signal.wait","timer.boundary","checkpoint","end"]),En=l.enum(["equals","contains","matches","exists"]),fe=l.object({kind:En,params:l.record(l.unknown()).default({})}),wt=l.object({maxAttempts:l.number().int().min(1).max(10).default(1),backoffMs:l.number().int().min(0).max(6e4).default(1e3)}).default({maxAttempts:1,backoffMs:1e3}),kt=l.object({id:l.string().min(1).regex(/^[a-zA-Z_][a-zA-Z0-9_-]*$/,"node id must be identifier-safe"),type:Tn,config:l.record(l.unknown()).default({}),retry:wt,position:l.object({x:l.number(),y:l.number()}).optional()}),bt=l.object({from:l.string(),fromPort:l.string().optional(),to:l.string(),toPort:l.string().optional(),label:l.string().optional()}),yt=l.union([l.string(),l.date().transform(n=>n.toISOString())]),T=l.object({id:l.string().regex(/^[a-z0-9][a-z0-9_-]*$/,"workflow id must be lower-kebab"),version:l.literal(2).default(2),title:l.string().min(1),description:l.string().optional(),status:l.enum(["draft","review","active","deprecated"]).default("active"),tags:l.array(l.string()).default([]),project:l.string().optional(),entity:l.string().optional(),intentPath:l.array(l.string()).default([]),generatedFrom:l.string().optional(),sourceTaskIds:l.array(l.string()).default([]),confidence:l.number().min(0).max(1).optional(),workflowVersion:l.string().optional(),ownerAgent:l.string().optional(),lastMatchedAt:l.string().optional(),matchCount:l.number().int().min(0).default(0),state:l.enum(["active","disabled","quarantined"]).default("active"),priority:l.number().int().default(0),fanOut:l.boolean().default(!1),nodes:l.array(kt).refine(n=>n.length>0,{message:"workflow must have at least one node"}),edges:l.array(bt).default([]),envAllow:l.array(l.string()).default([]),retention:l.object({maxRuns:l.number().int().positive().default(500),maxDays:l.number().int().positive().default(90)}).default({maxRuns:500,maxDays:90}),maxChildDepth:l.number().int().positive().default(5),mesh:l.object({allowRemote:l.boolean().default(!1),peers:l.array(l.string()).optional()}).default({allowRemote:!1}),created:yt.optional(),updated:yt.optional()});function me(n){let e=[],t=new Map(n.nodes.map(s=>[s.id,s])),r=n.nodes.filter(s=>s.type.startsWith("trigger."));r.length===0&&e.push("workflow must have exactly one trigger.* node (found 0)"),r.length>1&&e.push(`workflow has ${r.length} trigger.* nodes; v1 supports exactly one`);for(let s of n.edges)t.has(s.from)||e.push(`edge references missing node: from="${s.from}"`),t.has(s.to)||e.push(`edge references missing node: to="${s.to}"`);let i=r[0];if(i){let s=new Map;for(let c of n.edges)s.has(c.from)||s.set(c.from,[]),s.get(c.from).push(c.to);let a=new Set,d=[i.id];for(;d.length;){let c=d.pop();if(!a.has(c)){a.add(c);for(let u of s.get(c)??[])d.push(u)}}for(let c of n.nodes)a.has(c.id)||e.push(`node "${c.id}" is unreachable from trigger "${i.id}"`);n.nodes.some(c=>a.has(c.id)&&xn(c.type))||e.push("no reachable `end`, `checkpoint`, `subProcess`, `signal.wait`, or `timer.boundary` node \u2014 the run cannot terminate or pause")}for(let s of n.nodes){if(s.type!=="branch"&&s.type!=="rule")continue;let a=s.type==="branch"?s.config.cases??[]:(s.config.rules??[]).filter(p=>typeof p.to=="string"),d=s.type==="branch"?s.config.default:s.config.default?.to,c=new Set(a.map(p=>p.to));d&&c.add(d);let u=n.edges.filter(p=>p.from===s.id);for(let p of u){let g=p.fromPort??"";c.has(g)||e.push(`${s.type} "${s.id}" has outgoing edge with port "${g}" not declared in cases or default`)}}let o=Pn(n);for(let s of o)e.push(`cycle without agent/checkpoint: ${s.join(" -> ")}`);return e}function xn(n){return n==="end"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function Nn(n){return n==="agent"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function Pn(n){let e=new Map;for(let a of n.edges)e.has(a.from)||e.set(a.from,[]),e.get(a.from).push(a.to);let t=new Map(n.nodes.map(a=>[a.id,a])),r=[],i=new Map,o=[],s=a=>{if(i.get(a)===1){let d=o.indexOf(a);if(d>=0){let c=o.slice(d).concat(a);c.some(p=>{let g=t.get(p)?.type;return g?Nn(g):!1})||r.push(c)}return}if(i.get(a)!==2){i.set(a,1),o.push(a);for(let d of e.get(a)??[])s(d);o.pop(),i.set(a,2)}};for(let a of n.nodes)i.get(a.id)!==2&&s(a.id);return r}var vt=l.enum(["running","paused","completed","failed","canceled"]),On=l.enum(["ok","failed","timeout","skipped","paused","resumed"]),_n=l.object({at:l.string(),nodeId:l.string(),inputKeys:l.array(l.string()).default([]),status:On,output:l.record(l.unknown()).optional(),idempotencyKey:l.string(),note:l.string().optional()}),Dn=l.object({backend:l.string(),id:l.string()}),Wn=l.discriminatedUnion("kind",[l.object({kind:l.literal("checkpoint"),nodeId:l.string(),checkpointName:l.string(),resumeMatch:l.record(l.unknown()).default({})}),l.object({kind:l.literal("subProcess"),nodeId:l.string(),childRunId:l.string(),childWorkflowId:l.string()}),l.object({kind:l.literal("signalWait"),nodeId:l.string(),signalName:l.string(),match:l.record(l.unknown()).default({}),scope:l.enum(["workflow","global"]).default("workflow")}),l.object({kind:l.literal("timerWait"),nodeId:l.string(),fireAt:l.string()})]),Fn=l.object({id:l.string(),workflowId:l.string(),workflowVersion:l.literal(2),homeNode:l.string(),status:vt,pausedAt:Wn.optional(),context:l.record(l.record(l.unknown())).default({}),pending:l.array(l.string()).default([]),joinCounters:l.record(l.array(l.string())).default({}),entityRef:Dn,history:l.array(_n).default([]),parentRunId:l.string().nullable().default(null),parentNodeId:l.string().nullable().default(null),rootRunId:l.string().nullable().default(null),depth:l.number().int().min(0).default(0),eventRootId:l.string().optional(),createdAt:l.string(),updatedAt:l.string()});import Rt from"js-yaml";var Cn=new Set(["branch","gateway.parallel","rule","signal.wait","subProcess","timer.boundary","checkpoint"]),v=class extends Error{constructor(t,r){super(t);this.mark=r;this.name="WorkflowYamlError"}};function z(n,e={}){if(!n||n.trim()==="")throw new v(`${E(e)}empty file \u2014 workflow YAML must contain at least an id, version, title, and one node.`);let t;try{t=Rt.loadAll(n)}catch(i){let o=i?.mark;throw new v(`${E(e)}YAML parse error: ${i?.reason??i?.message??i}`+(o?` (line ${o.line+1}, column ${o.column+1})`:""),o)}if(t.length===0||t.length===1&&t[0]==null)throw new v(`${E(e)}YAML produced no document.`);if(t.length>1)throw new v(`${E(e)}multi-document YAML is not supported in v1; one workflow per file.`);let r=t[0];if(typeof r!="object"||r===null||Array.isArray(r)){let i=Array.isArray(r)?"array":typeof r;throw new v(`${E(e)}top-level YAML must be a mapping (got ${i}).`)}return It(r,e)}function It(n,e={}){if(!("flow"in n))return n;let t=n.flow;if(t==null){let p={...n};return delete p.flow,p}if(!Array.isArray(t))throw new v(`${E(e)}flow must be an array of node ids (got ${typeof t}).`);for(let p of t)if(typeof p!="string")throw new v(`${E(e)}flow entries must be strings (got ${typeof p}).`);let r=t,i=Array.isArray(n.nodes)?n.nodes:[],o=new Map;for(let p of i)p&&typeof p=="object"&&typeof p.id=="string"&&typeof p.type=="string"&&o.set(p.id,p.type);for(let p of r){if(!o.has(p))throw new v(`${E(e)}flow references unknown node "${p}".`);let g=o.get(p);if(Cn.has(g))throw new v(`${E(e)}flow cannot include ${g} node "${p}"; use explicit edges for ${g} nodes.`)}let s=[];for(let p=0;p<r.length-1;p++)s.push({from:r[p],to:r[p+1]});let a=Array.isArray(n.edges)?n.edges:[],d=new Set,c=[];for(let p of a){if(!p||typeof p!="object")continue;let g=St(p.from,p.fromPort,p.to);g&&!d.has(g)?(d.add(g),c.push(p)):g||c.push(p)}for(let p of s){let g=St(p.from,void 0,p.to);g&&!d.has(g)&&(d.add(g),c.push(p))}let u={...n,edges:c};return delete u.flow,u}function St(n,e,t){return typeof n!="string"||typeof t!="string"?null:`${n}::${typeof e=="string"?e:""}::${t}`}function E(n){return n.filePath?`${n.filePath}: `:""}function Mn(n){return Rt.dump(n,{noRefs:!0,lineWidth:100,sortKeys:!1})}import{Document as Ln,isMap as Y,isSeq as jn,isScalar as At,parseDocument as Hn}from"yaml";function $t(n,e){let t=Hn(n);if(!t.contents||!Y(t.contents)){let r=new Ln(e);return t.commentBefore&&(r.commentBefore=t.commentBefore),String(r)}return he(t,t.contents,e),String(t)}function he(n,e,t){let r=Object.keys(t),i=new Set(r),o=new Map;for(let a of e.items){let d=Bn(a);d!==null&&o.set(d,a)}let s=[];for(let a of r){let d=t[a],c=o.get(a);c?(Un(n,c,d),s.push(c)):s.push(n.createPair(a,d))}e.items=s}function Un(n,e,t){let r=e.value;if(t==null){e.value=n.createNode(null);return}if(typeof t!="object"){e.value=n.createNode(t);return}if(Array.isArray(t)){jn(r)?qn(n,r,t):e.value=n.createNode(t);return}Y(r)?he(n,r,t):e.value=n.createNode(t)}function qn(n,e,t){if(!(t.length>0&&t.every(s=>s&&typeof s=="object"&&typeof s.id=="string"))){let s=n.createNode(t);e.items=s.items;return}let i=new Map;for(let s of e.items)if(Y(s)){let a=s.get("id",!0);At(a)&&typeof a.value=="string"&&i.set(a.value,s)}let o=[];for(let s of t){let a=s.id,d=i.get(a);d&&Y(d)?(he(n,d,s),o.push(d)):o.push(n.createNode(s))}e.items=o}function Bn(n){let e=n.key;return At(e)&&typeof e.value=="string"?e.value:typeof e=="string"?e:null}var Tt=new Map,ke=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??R(process.cwd(),".agentx/workflows"),Kn(this.baseDir,{recursive:!0})}pathFor(e){return this.pathForJson(e)}pathForJson(e){return R(this.baseDir,`${e}.json`)}pathForYaml(e){return R(this.baseDir,`${e}.yaml`)}isWorkflowFile(e){return e.startsWith("_")?!1:e.endsWith(".json")||e.endsWith(".yaml")||e.endsWith(".yml")}idFromFilename(e){return e.replace(/\.(json|ya?ml)$/,"")}readAndParse(e){let t=R(this.baseDir,e),r=G(t,"utf-8");return e.endsWith(".json")?JSON.parse(r):z(r,{filePath:e})}list(){if(!S(this.baseDir))return[];let e=new Map,t=[];for(let a of J(this.baseDir,{withFileTypes:!0})){if(!a.isFile()||!this.isWorkflowFile(a.name))continue;let d=this.idFromFilename(a.name),c=e.get(d)??[];c.push(a.name),e.set(d,c);try{let u=zn(R(this.baseDir,a.name));t.push(`${a.name}:${u.mtimeMs}:${u.size}`)}catch{t.push(`${a.name}:?`)}}let r=t.sort().join("|"),i=Tt.get(this.baseDir);if(i&&i.signature===r)return i.workflows.slice();let o=[];for(let[,a]of e)if(!(a.length>1))try{let d=this.readAndParse(a[0]),c=T.safeParse(d);c.success&&o.push(c.data)}catch{}let s=o.sort((a,d)=>a.id.localeCompare(d.id));return Tt.set(this.baseDir,{signature:r,workflows:s}),s.slice()}validateAll(){let e=[];if(!S(this.baseDir))return e;let t=new Map;for(let r of J(this.baseDir,{withFileTypes:!0})){if(!r.isFile()||!this.isWorkflowFile(r.name))continue;let i=this.idFromFilename(r.name),o=t.get(i)??[];o.push(r.name),t.set(i,o)}for(let[r,i]of t){if(i.length>1){let p=[...i].sort();for(let g of p)e.push({id:r,path:we(this.baseDir,R(this.baseDir,g)),issues:[`duplicate workflow id "${r}" \u2014 found ${p.join(" and ")}; delete one to disambiguate`],isValid:!1});continue}let o=i[0],s=R(this.baseDir,o),a=we(this.baseDir,s),d;try{d=this.readAndParse(o)}catch(p){let g=p instanceof v?p.message:`parse error: ${p?.message??p}`;e.push({id:r,path:a,issues:[g],isValid:!1});continue}let c=T.safeParse(d);if(!c.success){let p=c.error.issues.map(g=>`${g.path.join(".")||"<root>"}: ${g.message}`);e.push({id:String(d?.id??r),path:a,issues:p,isValid:!1});continue}let u=me(c.data);e.push({workflow:c.data,issues:u,isValid:u.length===0})}return e}get(e){let t=this.pathForJson(e),r=this.pathForYaml(e),i=R(this.baseDir,`${e}.yml`),o=S(t),s=S(r)||S(i);if(o&&s)return null;if(o)try{let d=JSON.parse(G(t,"utf-8")),c=T.safeParse(d);return c.success?c.data:null}catch{return null}let a=S(r)?r:S(i)?i:null;if(a)try{let d=G(a,"utf-8"),c=z(d,{filePath:we(this.baseDir,a)}),u=T.safeParse(c);return u.success?u.data:null}catch{return null}if(!S(this.baseDir))return null;for(let d of J(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name)||this.idFromFilename(d.name)===e))try{let u=this.readAndParse(d.name),p=T.safeParse(u);if(p.success&&p.data.id===e)return p.data}catch{}return null}save(e,t={}){let r=new Date().toISOString().slice(0,10),i=T.parse({...e,created:e.created||r,updated:r}),o=this.pathForYaml(i.id),s=R(this.baseDir,`${i.id}.yml`),a=S(o)?o:S(s)?s:null;if(!a&&S(this.baseDir)){for(let d of J(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name))&&!d.name.endsWith(".json"))try{let c=this.readAndParse(d.name),u=T.safeParse(c);if(u.success&&u.data.id===i.id){a=R(this.baseDir,d.name);break}}catch{}}if(a&&t.convertFromYaml)return X(a),ye(this.pathForJson(i.id),JSON.stringify(i,null,2)+`
13
13
  `),i;if(a){let d=G(a,"utf-8");try{let c=$t(d,i);return ye(a,c),i}catch(c){let u=new Error(`yaml round-trip failed for "${i.id}" at ${a}: ${c?.message??c}`);throw u.yamlPath=a,u}}return ye(this.pathForJson(i.id),JSON.stringify(i,null,2)+`
14
- `),i}delete(e){let t=this.pathForJson(e),n=this.pathForYaml(e),i=I(this.baseDir,`${e}.yml`),o=!1;return S(t)&&(X(t),o=!0),S(n)&&(X(n),o=!0),S(i)&&(X(i),o=!0),o}};import{createHash as Yn,randomUUID as Jn}from"crypto";import{appendFileSync as Et,existsSync as F,mkdirSync as xt,readdirSync as Nt,readFileSync as be,statSync as Pt,unlinkSync as Ot,writeFileSync as Gn}from"fs";import{resolve as _}from"path";function Xn(r){return r.replace(/[^a-zA-Z0-9._:#@-]/g,"_").slice(0,200)}function N(r,e,t){return Yn("sha1").update(`${r}|${e}|${t}`).digest("hex").slice(0,16)}var ve=class{baseDir;runsDir;indexDir;nodeId;constructor(e){this.baseDir=e.baseDir??_(process.cwd(),".agentx/workflows"),this.runsDir=_(this.baseDir,"_runs"),this.indexDir=_(this.baseDir,"_index"),this.nodeId=e.nodeId,xt(this.runsDir,{recursive:!0}),xt(this.indexDir,{recursive:!0})}runPath(e){return _(this.runsDir,`${e}.jsonl`)}indexPath(e){return _(this.indexDir,`${e.backend}__${Xn(e.id)}.json`)}create(e){let t=new Date().toISOString(),n=Jn(),i={id:n,workflowId:e.workflowId,workflowVersion:2,homeNode:this.nodeId,status:"running",pausedAt:void 0,context:e.initialContext??{},pending:e.initialPending,entityRef:e.entityRef,history:[],parentRunId:e.parentRunId??null,parentNodeId:e.parentNodeId??null,rootRunId:e.rootRunId??n,depth:e.depth??0,eventRootId:e.eventRootId??Ge()?.rootId,joinCounters:{},createdAt:t,updatedAt:t};return this.appendSnapshot(i),this.writeIndex(e.entityRef,i.id),i}get(e){let t=this.runPath(e);if(!F(t))return null;let n=be(t,"utf-8").trim();if(!n)return null;let i=null;for(let o of n.split(`
15
- `)){let s;try{s=JSON.parse(o)}catch{continue}if(s.v===2){if(s.kind==="snapshot")i=s.run;else if(s.kind==="exec"&&i&&i.id===s.runId){let a=i;i={...a,history:[...a.history,s.entry],pending:s.pending,status:s.status??a.status,pausedAt:s.pausedAt===null?void 0:s.pausedAt??a.pausedAt,context:s.context??a.context,joinCounters:s.joinCounters??a.joinCounters,updatedAt:s.entry.at}}}}return i}getActiveByEntity(e){let t=this.indexPath(e);if(!F(t))return null;try{return JSON.parse(be(t,"utf-8")).runId}catch{return null}}getHomeNodeByEntity(e){let t=this.indexPath(e);if(!F(t))return null;try{return JSON.parse(be(t,"utf-8")).homeNode}catch{return null}}recordExecution(e){let t=this.get(e.runId);if(!t)return null;if(t.history.some(o=>o.idempotencyKey===e.entry.idempotencyKey))return t;let n={v:2,kind:"exec",runId:e.runId,entry:e.entry,pending:e.nextPending,status:e.status,pausedAt:e.pausedAt===null?null:e.pausedAt,context:e.context,joinCounters:e.joinCounters};Et(this.runPath(e.runId),JSON.stringify(n)+`
16
- `);let i=e.status??t.status;return i==="completed"||i==="failed"||i==="canceled"?this.clearIndex(t.entityRef):this.writeIndex(t.entityRef,t.id),this.get(e.runId)}setStatus(e,t){let n=this.get(e);if(!n)return null;let i={...n,status:t,updatedAt:new Date().toISOString()};return this.appendSnapshot(i),t!=="running"&&t!=="paused"&&this.clearIndex(i.entityRef),i}list(e={}){if(!F(this.runsDir))return[];let t=Nt(this.runsDir).filter(i=>i.endsWith(".jsonl")).map(i=>({name:i,mtime:Pt(_(this.runsDir,i)).mtimeMs})).sort((i,o)=>o.mtime-i.mtime),n=[];for(let i of t){let o=this.get(i.name.replace(/\.jsonl$/,""));if(o&&!(e.workflowId&&o.workflowId!==e.workflowId)&&(n.push(o),e.limit&&n.length>=e.limit))break}return n}prune(e){if(!F(this.runsDir))return 0;let t=Date.now()-e.maxDays*24*60*60*1e3,n=[];for(let o of Nt(this.runsDir)){if(!o.endsWith(".jsonl"))continue;let s=_(this.runsDir,o),a=Pt(s).mtimeMs,d=this.get(o.replace(/\.jsonl$/,""));d&&(d.status==="running"||d.status==="paused"||n.push({file:s,run:d,mtime:a}))}n.sort((o,s)=>s.mtime-o.mtime);let i=0;for(let o=0;o<n.length;o++){let s=n[o],a=s.mtime<t,d=o>=e.maxRuns;if(a||d)try{Ot(s.file),i++}catch{}}return i}appendSnapshot(e){let t={v:2,kind:"snapshot",run:e};Et(this.runPath(e.id),JSON.stringify(t)+`
14
+ `),i}delete(e){let t=this.pathForJson(e),r=this.pathForYaml(e),i=R(this.baseDir,`${e}.yml`),o=!1;return S(t)&&(X(t),o=!0),S(r)&&(X(r),o=!0),S(i)&&(X(i),o=!0),o}};import{createHash as Yn,randomUUID as Jn}from"crypto";import{appendFileSync as Et,existsSync as F,mkdirSync as xt,readdirSync as Nt,readFileSync as be,statSync as Pt,unlinkSync as Ot,writeFileSync as Gn}from"fs";import{resolve as _}from"path";function Xn(n){return n.replace(/[^a-zA-Z0-9._:#@-]/g,"_").slice(0,200)}function N(n,e,t){return Yn("sha1").update(`${n}|${e}|${t}`).digest("hex").slice(0,16)}var ve=class{baseDir;runsDir;indexDir;nodeId;constructor(e){this.baseDir=e.baseDir??_(process.cwd(),".agentx/workflows"),this.runsDir=_(this.baseDir,"_runs"),this.indexDir=_(this.baseDir,"_index"),this.nodeId=e.nodeId,xt(this.runsDir,{recursive:!0}),xt(this.indexDir,{recursive:!0})}runPath(e){return _(this.runsDir,`${e}.jsonl`)}indexPath(e){return _(this.indexDir,`${e.backend}__${Xn(e.id)}.json`)}create(e){let t=new Date().toISOString(),r=Jn(),i={id:r,workflowId:e.workflowId,workflowVersion:2,homeNode:this.nodeId,status:"running",pausedAt:void 0,context:e.initialContext??{},pending:e.initialPending,entityRef:e.entityRef,history:[],parentRunId:e.parentRunId??null,parentNodeId:e.parentNodeId??null,rootRunId:e.rootRunId??r,depth:e.depth??0,eventRootId:e.eventRootId??Ge()?.rootId,joinCounters:{},createdAt:t,updatedAt:t};return this.appendSnapshot(i),this.writeIndex(e.entityRef,i.id),i}get(e){let t=this.runPath(e);if(!F(t))return null;let r=be(t,"utf-8").trim();if(!r)return null;let i=null;for(let o of r.split(`
15
+ `)){let s;try{s=JSON.parse(o)}catch{continue}if(s.v===2){if(s.kind==="snapshot")i=s.run;else if(s.kind==="exec"&&i&&i.id===s.runId){let a=i;i={...a,history:[...a.history,s.entry],pending:s.pending,status:s.status??a.status,pausedAt:s.pausedAt===null?void 0:s.pausedAt??a.pausedAt,context:s.context??a.context,joinCounters:s.joinCounters??a.joinCounters,updatedAt:s.entry.at}}}}return i}getActiveByEntity(e){let t=this.indexPath(e);if(!F(t))return null;try{return JSON.parse(be(t,"utf-8")).runId}catch{return null}}getHomeNodeByEntity(e){let t=this.indexPath(e);if(!F(t))return null;try{return JSON.parse(be(t,"utf-8")).homeNode}catch{return null}}recordExecution(e){let t=this.get(e.runId);if(!t)return null;if(t.history.some(o=>o.idempotencyKey===e.entry.idempotencyKey))return t;let r={v:2,kind:"exec",runId:e.runId,entry:e.entry,pending:e.nextPending,status:e.status,pausedAt:e.pausedAt===null?null:e.pausedAt,context:e.context,joinCounters:e.joinCounters};Et(this.runPath(e.runId),JSON.stringify(r)+`
16
+ `);let i=e.status??t.status;return i==="completed"||i==="failed"||i==="canceled"?this.clearIndex(t.entityRef):this.writeIndex(t.entityRef,t.id),this.get(e.runId)}setStatus(e,t){let r=this.get(e);if(!r)return null;let i={...r,status:t,updatedAt:new Date().toISOString()};return this.appendSnapshot(i),t!=="running"&&t!=="paused"&&this.clearIndex(i.entityRef),i}list(e={}){if(!F(this.runsDir))return[];let t=Nt(this.runsDir).filter(i=>i.endsWith(".jsonl")).map(i=>({name:i,mtime:Pt(_(this.runsDir,i)).mtimeMs})).sort((i,o)=>o.mtime-i.mtime),r=[];for(let i of t){let o=this.get(i.name.replace(/\.jsonl$/,""));if(o&&!(e.workflowId&&o.workflowId!==e.workflowId)&&(r.push(o),e.limit&&r.length>=e.limit))break}return r}prune(e){if(!F(this.runsDir))return 0;let t=Date.now()-e.maxDays*24*60*60*1e3,r=[];for(let o of Nt(this.runsDir)){if(!o.endsWith(".jsonl"))continue;let s=_(this.runsDir,o),a=Pt(s).mtimeMs,d=this.get(o.replace(/\.jsonl$/,""));d&&(d.status==="running"||d.status==="paused"||r.push({file:s,run:d,mtime:a}))}r.sort((o,s)=>s.mtime-o.mtime);let i=0;for(let o=0;o<r.length;o++){let s=r[o],a=s.mtime<t,d=o>=e.maxRuns;if(a||d)try{Ot(s.file),i++}catch{}}return i}appendSnapshot(e){let t={v:2,kind:"snapshot",run:e};Et(this.runPath(e.id),JSON.stringify(t)+`
17
17
  `)}writeIndex(e,t){Gn(this.indexPath(e),JSON.stringify({runId:t,homeNode:this.nodeId,updatedAt:new Date().toISOString()},null,2)+`
18
- `)}clearIndex(e){let t=this.indexPath(e);if(F(t))try{Ot(t)}catch{}}};import{existsSync as _t,mkdirSync as Vn,readFileSync as Zn,unlinkSync as Qn,writeFileSync as er}from"fs";import{resolve as Se}from"path";import{z as C}from"zod";var Dt=C.object({version:C.literal(1),nodes:C.record(C.object({x:C.number(),y:C.number()}))}),Ie=class{baseDir;layoutsDir;constructor(e={}){this.baseDir=e.baseDir??Se(process.cwd(),".agentx/workflows"),this.layoutsDir=Se(this.baseDir,"_layouts"),Vn(this.layoutsDir,{recursive:!0})}pathFor(e){let t=e.replace(/[^a-zA-Z0-9._-]/g,"_");return Se(this.layoutsDir,`${t}.json`)}get(e){let t=this.pathFor(e);if(!_t(t))return null;try{let n=Dt.safeParse(JSON.parse(Zn(t,"utf-8")));return n.success?n.data:null}catch{return null}}save(e,t){let n=Dt.parse(t);return er(this.pathFor(e),JSON.stringify(n,null,2)+`
19
- `),n}sync(e,t){let n=this.get(e);if(!n)return null;let i={};for(let s of t)n.nodes[s]&&(i[s]=n.nodes[s]);let o={version:1,nodes:i};return this.save(e,o)}delete(e){let t=this.pathFor(e);return _t(t)?(Qn(t),!0):!1}};function Wt(r){return new Set(r.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(e=>e.length>3))}function tr(r,e){if(r.size===0||e.size===0)return 0;let t=0;for(let n of r)e.has(n)&&t++;return t/Math.max(r.size,e.size)}function nr(r,e){let t=Wt(r.message),n=e.filter(o=>o.state==="active"&&(o.status??"active")==="active"),i=null;for(let o of n){let s=0,a=[];if(o.ownerAgent&&o.ownerAgent===r.agentId&&(s+=.25,a.push("owner-agent")),r.channel&&o.tags.includes(r.channel)&&(s+=.15,a.push("channel-tag")),r.intentPath?.length&&o.intentPath.length){let p=r.intentPath.filter((g,f)=>o.intentPath[f]===g).length;p>0&&(s+=Math.min(.3,p*.1),a.push("intent-path"))}let d=[o.id,o.title,o.description??"",...o.tags].join(" "),c=tr(t,Wt(d));c>0&&(s+=Math.min(.35,c),a.push("text-similarity")),(o.matchCount??0)>0&&(s+=Math.min(.1,o.matchCount*.01),a.push("prior-matches"));let u=Math.max(0,Math.min(1,s));(!i||u>i.confidence)&&(i={workflow:o,confidence:u,reasons:a})}return i&&i.confidence>0?i:null}function Re(r){let{workflow:e,fromNodeId:t,selectedPort:n}=r,i=e.nodes.find(a=>a.id===t);if(!i)return{nextPending:[]};let o=e.edges.filter(a=>a.from===t);return{nextPending:(i.type==="branch"?o.filter(a=>(a.fromPort??"")===(n??"")):o).map(a=>a.to)}}function Ae(r,e){let t=r.config.cases??[],n=r.config.default??"";for(let i of t)if(V(i.when,e))return i.to;return n}function V(r,e){let t=r.params??{},n=String(t.path??""),i=L(e,n);switch(r.kind){case"equals":return i===t.value;case"contains":return typeof i=="string"?i.includes(String(t.value??"")):Array.isArray(i)?i.some(o=>o===t.value):!1;case"matches":{if(typeof i!="string")return!1;try{return new RegExp(String(t.regex??"")).test(i)}catch{return!1}}case"exists":return i!=null&&i!=="";default:return!1}}function L(r,e){if(!e)return;let t=e.split("."),n=r;for(let i of t){if(n==null||typeof n!="object")return;n=n[i]}return n}function Z(r){let e=r.nodes.find(n=>n.type.startsWith("trigger."));if(!e)return null;let t=r.edges.filter(n=>n.from===e.id).map(n=>n.to);return{triggerId:e.id,pending:t}}function P(r,e){return r.nodes.find(t=>t.id===e)}ln();un();function rr(r,e,t){let n=r.split(".");if(n[0]==="env"){if(n.length!==2)return"";let o=n[1];if(!t.has(o))return"";let s=process.env[o];return typeof s=="string"?s:""}let i=e;for(let o of n){if(i==null||typeof i!="object")return"";i=i[o]}return i==null?"":typeof i=="object"?JSON.stringify(i):String(i)}function R(r,e,t={}){let n=new Set(t.envAllow||[]);return r.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_.-]*)\s*\}\}/g,(i,o)=>rr(o,e,n))}function b(r,e,t={}){let n={};for(let[i,o]of Object.entries(r))typeof o=="string"?n[i]=R(o,e,t):Array.isArray(o)?n[i]=o.map(s=>typeof s=="string"?R(s,e,t):s):o&&typeof o=="object"?n[i]=b(o,e,t):n[i]=o;return n}var Ft="workflow-classify",Q="unsure",Ct=async r=>{let e=r.node.config,t=r.run.context,n={envAllow:r.workflow.envAllow},i=R(String(e.input??""),t,n).trim();if(!i)return{error:`classify node "${r.node.id}" missing config.input`};let o=e.labels,s=Array.isArray(o)?Object.fromEntries(o.map(m=>[String(m),null])):typeof o=="object"&&o?Object.fromEntries(Object.entries(o).map(([m,w])=>[m,w==null?null:String(w)])):{},a=Object.keys(s);if(a.length<2)return{error:`classify node "${r.node.id}" needs at least two labels`};if(a.includes(Q))return{error:`classify node "${r.node.id}": "${Q}" is reserved for the low-confidence port`};let d=typeof e.minConfidence=="number"?e.minConfidence:.7,c=e.instructions?R(String(e.instructions),t,n):void 0,u={input:i};if(e.state&&typeof e.state=="object")for(let[m,w]of Object.entries(e.state)){let y=typeof w=="string"?R(w,t,n):w;(y===null||["string","number","boolean"].includes(typeof y))&&(u[m]=y)}let p=await Me(Ft,u,{label:Le(s,c)},{features:{workflow:r.workflow.id,node:r.node.id}});if(!p)return{error:`classify node "${r.node.id}": decision seat unavailable (set decisions.seats.${Ft}.mode)`};let g=p.answers.label,f=g.confidence>=d,h=f?g.choice:Q;return r.log(`[node:${r.node.id}] classify \u2192 ${g.choice} (${g.confidence.toFixed(2)})${f?"":` \u2014 below ${d}, routing to ${Q}`}`),{output:{result:g.choice,label:g.choice,confidence:g.confidence,probabilities:g.probabilities,unsure:!f,port:h},port:h}};var $e=class{active=new Map;waiters=new Map;async acquire(e,t){let n=this.active.get(e)??0;if(n<t){this.active.set(e,n+1);return}return new Promise(i=>{let o=this.waiters.get(e)??[];o.push({resolve:()=>{this.active.set(e,(this.active.get(e)??0)+1),i()}}),this.waiters.set(e,o)})}release(e){let t=this.active.get(e)??0;this.active.set(e,Math.max(0,t-1));let n=this.waiters.get(e);n&&n.length>0&&n.shift().resolve()}stats(e){return{active:this.active.get(e)??0,waiting:this.waiters.get(e)?.length??0}}},ee=new $e;function Lt(r,e){return`${r}:${e}`}var M=async r=>({output:r.run.context[r.node.id]??{}}),ir=async r=>{let e=r.node.config,t=String(e.agentId??""),n=String(e.prompt??"");if(!t)return{error:`agent node "${r.node.id}" missing config.agentId`};let i=R(n,r.run.context,{envAllow:r.workflow.envAllow}),o=typeof e.timeoutMinutes=="number"?e.timeoutMinutes:void 0,s=e.autonomy===void 0||e.autonomy===null?void 0:String(e.autonomy);if(s!==void 0&&s!=="report"&&s!=="propose"&&s!=="act")return{error:`agent node "${r.node.id}" has invalid autonomy "${s}" (expected report, propose or act)`};let a=typeof e.maxConcurrent=="number"&&e.maxConcurrent>0?e.maxConcurrent:null,d=a?Lt(r.workflow.id,r.node.id):null;if(d&&a){let u=ee.stats(d);u.active>=a&&r.log(`[node:${r.node.id}] gated: ${u.active} active (cap ${a}), ${u.waiting+1} waiting`),await ee.acquire(d,a)}let c=Date.now();try{let u=await r.agents.execute({agentId:t,message:i,workflowRunId:r.run.id,timeoutMinutes:o,...s?{autonomy:s}:{}}),p=Date.now()-c;if(u.error){let h=u.errorKind??"unknown";return r.log(`[node:${r.node.id}] agent "${t}" failed (${h}): ${u.error}`),{error:`[${h}] ${u.error}`}}let f=String(e.resultParser??"acme-result-token")==="json"?Er(u.content):jt(u.content);return{output:{reply:u.content,result:f.result,json:f.json,taskId:u.taskId,durationMs:p,...u.autonomyBlocks?.length?{autonomyBlocks:u.autonomyBlocks}:{}}}}catch(u){return r.log(`[node:${r.node.id}] agent "${t}" threw: ${u.message}`),{error:u.message}}finally{d&&ee.release(d)}},or=async r=>{let e=Ae(r.node,r.run.context);return e?{output:{port:e},port:e}:(r.log(`[node:${r.node.id}] branch matched no case and no default port`),{output:{port:null}})},sr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??""),n=String(e.chatId??""),i=String(e.text??"");if(!t||!n){let a=String(r.node.config.chatId??""),d=String(r.node.config.channel??""),c=[];return t||c.push(`channel config="${d}" rendered=""`),n||c.push(`chatId config="${a}" rendered=""`),(/\{\{\s*env\./.test(a)||/\{\{\s*env\./.test(d))&&c.push("(env.* templates only resolve for names listed in workflow.envAllow and actually set in process.env)"),{error:`action.send "${r.node.id}" needs channel + chatId \u2014 ${c.join("; ")}`}}let o=Ee(r,e.accountId),s=r.channels[t];if(s?.send)try{return{output:{messageId:await s.send({channel:t,chatId:n,text:i,...o?{accountId:o}:{}})??null}}}catch(a){return{error:`action.send failed: ${a.message}`}}if(r.forwardChannelSend)try{return{output:{messageId:(await r.forwardChannelSend({channel:t,chatId:n,text:i,accountId:o})).messageId,viaMesh:!0}}}catch(a){return r.log(`[node:${r.node.id}] mesh-forward of "${t}" send failed: ${a.message}`),{error:`action.send via mesh failed: ${a.message}`}}return r.log(`[node:${r.node.id}] adapter "${t}" not available locally and no mesh forwarder`),{error:`channel "${t}" not available (no local adapter, no mesh route)`}},ar=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??"gitlab"),n=String(e.project??""),i=String(e.title??""),o=String(e.description??""),s=Array.isArray(e.labels)?e.labels.map(String):[],a=Array.isArray(e.assignees)?e.assignees.map(String):[];if(!n||!i)return{error:`action.createIssue "${r.node.id}" needs project + title`};let d=xe(r),c=r.channels[t];if(!c?.createIssue)return{error:`channel "${t}" does not support createIssue`};try{let u=await c.createIssue({project:n,title:i,description:o,labels:s,assignees:a,agentId:d});return u?{output:{issue:{iid:u.iid,url:u.url,webUrl:u.url}}}:{error:"createIssue returned null (see adapter log)"}}catch(u){return{error:`action.createIssue failed: ${u.message}`}}},dr=async()=>({output:{}}),cr=async r=>{let e=r.node.config,t=String(e.name??r.node.id),n=e.waitFor??{},i=e.resumeMatch??{};return{paused:!0,pausedAt:{kind:"checkpoint",nodeId:r.node.id,checkpointName:t,resumeMatch:{...n,...i}}}},lr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??"gitlab"),n=String(e.project??""),i=String(e.iid??""),o=Array.isArray(e.add)?e.add.map(String):[],s=Array.isArray(e.remove)?e.remove.map(String):[];if(!n||!i)return{error:`action.setLabel "${r.node.id}" needs project + iid (try {{trigger.project}} / {{trigger.issue.iid}})`};if(o.length===0&&s.length===0)return{output:{skipped:!0,reason:"no labels to add or remove"}};let a=r.channels[t];if(!a?.setLabels)return{error:`channel "${t}" does not support setLabels`};let d=xe(r),c=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await a.setLabels({project:n,kind:c,iid:i,add:o,remove:s,agentId:d})??[],add:o,remove:s}}},ur=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??"gitlab"),n=String(e.project??""),i=String(e.iid??"");if(!n||!i)return{error:`action.readLabel "${r.node.id}" needs project + iid`};let o=r.channels[t];if(!o?.getLabels)return{error:`channel "${t}" does not support getLabels`};let s=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await o.getLabels({project:n,kind:s,iid:i})??[]}}},pr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??""),n=String(e.chatId??""),i=String(e.messageId??""),o=String(e.emoji??"\u{1F440}");if(!t||!n||!i)return{error:`action.react "${r.node.id}" needs channel + chatId + messageId`};let s=Ee(r,e.accountId),a=r.channels[t];if(!a?.react)return{error:`channel "${t}" does not support react`};try{return await a.react(n,i,o,s),{output:{emoji:o}}}catch(d){return{error:`action.react failed: ${d.message}`}}},gr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??""),n=String(e.chatId??""),i=String(e.messageId??""),o=String(e.text??""),s=e.parseMode?String(e.parseMode):void 0;if(!t||!n||!i||!o)return{error:`action.editMessage "${r.node.id}" needs channel + chatId + messageId + text`};let a=Ee(r,e.accountId),d=r.channels[t];if(!d?.editMessage)return{error:`channel "${t}" does not support editMessage`};try{return{output:{edited:await d.editMessage(n,i,o,s,a)}}}catch(c){return{error:`action.editMessage failed: ${c.message}`}}},fr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.channel??"gitlab"),n=String(e.chatId??""),i=Number(e.durationMs??0);if(!n||!i)return{error:`action.logTime "${r.node.id}" needs chatId + durationMs`};let o=r.channels[t];if(!o?.logTimeSpent)return{error:`channel "${t}" does not support logTimeSpent`};let s=xe(r);try{return await o.logTimeSpent(n,i,s),{output:{durationMs:i}}}catch(a){return{error:`action.logTime failed: ${a.message}`}}},mr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.url??"");if(!t)return{error:`action.callHTTP "${r.node.id}" needs url`};let n=String(e.method??"POST").toUpperCase(),i=e.headers&&typeof e.headers=="object"?e.headers:{"Content-Type":"application/json"},o;e.body!==void 0&&(o=typeof e.body=="string"?e.body:JSON.stringify(e.body));try{let s=await fetch(t,{method:n,headers:i,body:o}),a=await s.text(),d=a;try{d=JSON.parse(a)}catch{}return{output:{ok:s.ok,status:s.status,body:d}}}catch(s){return{error:`action.callHTTP failed: ${s.message}`}}},hr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.actionId??e.id??"");if(!t)return{error:`action.run "${r.node.id}" needs actionId`};let n=e.inputs&&typeof e.inputs=="object"?e.inputs:{},{ActionStore:i}=await import("./store-TWQPEM5V.js"),{runAction:o}=await import("./runner-56G3N7M4.js"),s=new i().get(t);if(!s)return{error:`action.run "${r.node.id}": no action "${t}" in registry`};try{let a=await o(s,n),d={ok:a.ok,output:a.output,status:a.status,durationMs:a.durationMs};return a.errors!==void 0&&(d.errors=a.errors),a.ok?{output:d}:{output:d,error:`action "${t}" failed (status=${a.status})`}}catch(a){return{error:`action.run failed: ${a.message}`}}},yr=async r=>{let e=b(r.node.config,r.run.context,{envAllow:r.workflow.envAllow}),t=String(e.name??"");if(!t)return{error:`action.builtin "${r.node.id}" needs a "name" (e.g. "http.fetch")`};let n=e.input&&typeof e.input=="object"?e.input:{},{runBuiltin:i,getBuiltin:o}=await import("./builtin-W6KNX7RS.js");if(!o(t))return{error:`action.builtin "${r.node.id}": unknown built-in "${t}"`};try{return{output:await i(t,n)}}catch(s){let a=s?.name==="ZodError"?`validation: ${s.message}`:s?.message||String(s);return{error:`action.builtin "${t}" failed: ${a}`}}},wr=async r=>{let e=r.node.config,t=r.run.context;return typeof e.path=="string"&&e.path?{output:{value:L(t,e.path)}}:e.template&&typeof e.template=="object"?{output:b(e.template,t,{envAllow:r.workflow.envAllow})}:{output:{}}};function kr(r){if(r!=null){if(typeof r=="number")return new Date(Date.now()+r*6e4).toISOString();if(typeof r=="object"&&r&&"minutes"in r){let e=Number(r.minutes);if(Number.isFinite(e))return new Date(Date.now()+e*6e4).toISOString()}if(typeof r=="string"){let e=/^P(?:([0-9]+)D)?(?:T(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)S)?)?$/.exec(r);if(e){let t=Number(e[1]??0),n=Number(e[2]??0),i=Number(e[3]??0),o=Number(e[4]??0),s=((t*24+n)*60+i)*6e4+o*1e3;if(s>0)return new Date(Date.now()+s).toISOString()}}}}var br=async r=>{let e=r.node.config,t=b(e,r.run.context,{envAllow:r.workflow.envAllow}),n=String(t.workflowId??"");if(!n)return{error:`subProcess "${r.node.id}" missing config.workflowId`};let i=r.run.depth??0,o=r.workflow.maxChildDepth??5;if(i+1>=o)return{error:`max child workflow depth ${o} exceeded at ${r.workflow.id} \u2192 ${n} (parent depth ${i})`};let s=e.inputMap,a={};if(s==="*")a={...r.run.context};else if(s&&typeof s=="object")for(let[d,c]of Object.entries(s))c&&typeof c=="object"&&!Array.isArray(c)?a[d]=b(c,r.run.context,{envAllow:r.workflow.envAllow}):typeof c=="string"&&(a[d]={value:R(c,r.run.context,{envAllow:r.workflow.envAllow})});return{paused:!0,pausedAt:{kind:"subProcess",nodeId:r.node.id,childRunId:"",childWorkflowId:n},spawnChild:{workflowId:n,input:a}}},vr=M,Sr=async r=>{let e=r.node.config,t=b(e,r.run.context,{envAllow:r.workflow.envAllow}),n=String(t.name??"");if(!n)return{error:`signal.emit "${r.node.id}" missing config.name`};let i=t.scope==="global"?"global":"workflow",o=t.payload&&typeof t.payload=="object"?t.payload:{};return{output:{emittedAt:new Date().toISOString(),name:n,scope:i,payload:o},emitSignal:{name:n,scope:i,payload:o}}},Ir=async r=>{let e=r.node.config,t=b(e,r.run.context,{envAllow:r.workflow.envAllow}),n=String(t.name??"");if(!n)return{error:`signal.wait "${r.node.id}" missing config.name`};let i=t.scope==="global"?"global":"workflow",o=e.match&&typeof e.match=="object"?e.match:{};return{paused:!0,pausedAt:{kind:"signalWait",nodeId:r.node.id,signalName:n,match:o,scope:i}}},Rr=async r=>{let e=r.node.config,t=b(e,r.run.context,{envAllow:r.workflow.envAllow}),n=kr(t.after??e.after);return n?{paused:!0,pausedAt:{kind:"timerWait",nodeId:r.node.id,fireAt:n}}:{error:`timer.boundary "${r.node.id}" needs config.after (duration or minutes)`}},Ar=async()=>({output:{}}),$r=async r=>{let e=r.node.config,n=(Array.isArray(e.inputs)?e.inputs:[]).map(s=>typeof s=="string"?R(s,r.run.context,{envAllow:r.workflow.envAllow}):s),i=Array.isArray(e.rules)?e.rules:[];for(let s of i){let a=Array.isArray(s.when)?s.when:[];if(a.length!==n.length)continue;let d=!0;for(let c=0;c<a.length;c++)if(!Tr(a[c],n[c])){d=!1;break}if(d)return{output:{...s.output??{},matchedPort:s.to??""},port:s.to}}let o=e.default;return{output:{...o?.output??{},matchedPort:o?.to??""},port:o?.to}};function Tr(r,e){if(r==null||r==="*")return!0;let t=String(r),n=typeof e=="number"?e:String(e??""),i=/^(>=|<=|>|<)\s*(-?\d+(?:\.\d+)?)$/.exec(t);if(i){let o=i[1],s=Number(i[2]),a=typeof n=="number"?n:Number(n);if(Number.isNaN(a))return!1;switch(o){case">":return a>s;case"<":return a<s;case">=":return a>=s;case"<=":return a<=s}}if(t.startsWith("!="))return String(n)!==t.slice(2);if(t.startsWith("/")&&t.endsWith("/")&&t.length>2)try{return new RegExp(t.slice(1,-1)).test(String(n))}catch{return!1}return String(n)===t}var Mt={"trigger.channel":M,"trigger.manual":M,"trigger.cron":M,"trigger.hook":M,"trigger.form":vr,"trigger.poll":M,agent:ir,classify:Ct,branch:or,transform:wr,"gateway.parallel":Ar,rule:$r,"action.send":sr,"action.createIssue":ar,"action.setLabel":lr,"action.readLabel":ur,"action.react":pr,"action.editMessage":gr,"action.logTime":fr,"action.callHTTP":mr,"action.run":hr,"action.builtin":yr,subProcess:br,"signal.emit":Sr,"signal.wait":Ir,"timer.boundary":Rr,checkpoint:cr,end:dr};function Te(r){return Mt[r]}function Ee(r,e){if(typeof e=="string"&&e)return e;let t=r.workflow.nodes.find(o=>o.type.startsWith("trigger."));if(!t)return;let i=r.run.context[t.id]?.accountId;return typeof i=="string"&&i?i:void 0}function xe(r){for(let e=r.run.history.length-1;e>=0;e--){let t=r.run.history[e],n=r.workflow.nodes.find(i=>i.id===t.nodeId);if(n?.type==="agent")return n.config.agentId??void 0}}function jt(r){if(!r)return{};let e=r.match(/\bRESULT:\s*([a-z][a-z0-9_-]*)/i);if(e)return{result:e[1].toLowerCase()};let t=r.match(/\[(APPROVED|REJECTED|CHANGES[-_]REQUESTED|DONE|FAILED|SKIPPED)\]/i);return t?{result:t[1].toLowerCase().replace("_","-")}:{}}function Er(r){let{result:e}=jt(r);if(!r)return{result:e};let t=r.match(/```(?:json)?\s*([\s\S]*?)```/);if(!t)return{result:e};try{return{result:e,json:JSON.parse(t[1])}}catch{return{result:e}}}var H=class{handlers=new Set;subscribe(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){for(let t of this.handlers)try{Promise.resolve(t(e)).catch(()=>{})}catch{}}};function te(r,e){if(r.name!==e.name||r.scope==="workflow"&&r.workflowId!==e.workflowId)return!1;for(let[t,n]of Object.entries(r.match??{}))if(!(n===void 0||n===""||n==="*")&&e.payload[t]!==n)return!1;return!0}function xr(r,e,t=Date.now){return{ts:t(),source:"workflow",sourceEventId:`${r.workflowId}:${r.eventId}`,project:r.project,subject:`workflow:${r.workflowId}:entity:${r.entityRef.backend}:${r.entityRef.id}`,intent:`workflow.${r.triggerSource}`,rawJson:e}}function Nr(r){return r.claimed&&r.runId?{agentId:`workflow-run:${r.runId}`,outcome:"dispatched",reason:r.reason??"claimed"}:r.claimed&&!r.runId?{agentId:null,outcome:"halted",reason:r.reason??"claimed-but-no-run"}:{agentId:null,outcome:"halted",reason:r.reason??"not-claimed"}}function Pr(r){return{decidedBy:"workflow-dispatcher",decide:()=>({agentId:r.agentId,outcome:r.outcome==="deduped"?"halted":r.outcome,reason:r.outcome==="deduped"?`legacy-dedup: ${r.reason??""}`.trim():r.reason??null})}}function Ht(r,e,t,n,i=Date.now){let o=xr(e,t,i),s=Nr(n),a=Pr(s),d=et(r,o,a,i);return tt(r,"workflow",d,s,i),d}var Or=4e3,_r=8,Ne=class{store;runs;nodeId;forwarder;channels;agents;log;timers;signals;events;ackTypingTimers=new Map;commitChains=new Map;constructor(e){this.store=e.store,this.runs=e.runs,this.nodeId=e.nodeId,this.forwarder=e.forwarder,this.channels=e.channels,this.agents=e.agents,this.log=e.log??(()=>{}),this.timers=e.timers??new pe({log:t=>this.log(t)}),this.signals=e.signals??new H,this.events=e.events,this.timers.onFire(t=>this.resumeFromTimer(t)),this.signals.subscribe(t=>this.resumeFromSignal(t))}emitRunEvent(e){if(this.events)try{this.events.publish({kind:"run",runId:e.runId,workflowId:e.workflowId,nodeId:e.nodeId,phase:e.phase,status:e.status,note:e.note,homeNode:e.homeNode,rootId:e.rootId})}catch{}}async commit(e,t){let i=(this.commitChains.get(e)??Promise.resolve()).then(()=>t(),()=>t());return this.commitChains.set(e,i.then(()=>{},()=>{})),i}emitSignal(e){let t={name:e.name,scope:e.scope??"global",workflowId:e.workflowId??"",payload:e.payload??{},emittedAt:new Date().toISOString()};if(this.signals.emit(t),this.events)try{this.events.publish({kind:"signal",name:t.name,scope:t.scope,workflowId:t.workflowId||void 0,payload:t.payload})}catch{}return t}async resumeFromSignal(e){let t=this.runs.list({limit:500});for(let n of t){if(n.status!=="paused"||!n.pausedAt||n.pausedAt.kind!=="signalWait")continue;let i={name:n.pausedAt.signalName,scope:n.pausedAt.scope,workflowId:n.workflowId,match:n.pausedAt.match??{}};if(!te(i,e))continue;let o=this.store.list().find(s=>s.id===n.workflowId);o&&(await this.commit(n.id,()=>{let s=this.runs.get(n.id);if(!s||s.status!=="paused"||!s.pausedAt||s.pausedAt.kind!=="signalWait"||!te({name:s.pausedAt.signalName,scope:s.pausedAt.scope,workflowId:s.workflowId,match:s.pausedAt.match??{}},e))return;let a=P(o,s.pausedAt.nodeId),d=a?o.edges.filter(u=>u.from===a.id).map(u=>u.to):[],c={receivedAt:new Date().toISOString(),name:e.name,payload:e.payload};this.runs.recordExecution({runId:s.id,entry:{at:c.receivedAt,nodeId:s.pausedAt.nodeId,inputKeys:[],status:"resumed",output:c,idempotencyKey:N(s.id,s.pausedAt.nodeId,`signal:${e.name}:${e.emittedAt}`)},nextPending:d,status:"running",pausedAt:null,context:{...s.context,[s.pausedAt.nodeId]:c}}),this.log(`[workflow:${o.id}] run ${s.id} resumed from signal "${e.name}"`),this.emitRunEvent({runId:s.id,workflowId:o.id,nodeId:s.pausedAt.nodeId,phase:"resumed",status:"running",note:`signal:${e.name}`,rootId:s.eventRootId})}),this.walk(o,n.id,`signal:${e.name}`).catch(s=>this.log(`[workflow:${o.id}] walk-after-signal failed: ${s.message}`)))}}async resumeFromTimer(e){let t=this.store.list().find(n=>n.id===(this.runs.get(e.runId)?.workflowId??""));t&&(await this.commit(e.runId,()=>{let n=this.runs.get(e.runId);if(!n||n.status!=="paused"||!n.pausedAt||n.pausedAt.kind!=="timerWait"||n.pausedAt.nodeId!==e.nodeId)return;let i=P(t,e.nodeId),o=i?t.edges.filter(d=>d.from===i.id).map(d=>d.to):[],s=new Date().toISOString(),a={firedAt:s,scheduledFor:e.fireAt};this.runs.recordExecution({runId:n.id,entry:{at:s,nodeId:e.nodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:N(n.id,e.nodeId,`timer:${e.id}`)},nextPending:o,status:"running",pausedAt:null,context:{...n.context,[e.nodeId]:a}}),this.log(`[workflow:${t.id}] run ${n.id} resumed from timer "${e.nodeId}" (fired ${s})`),this.emitRunEvent({runId:n.id,workflowId:t.id,nodeId:e.nodeId,phase:"resumed",status:"running",note:`timer:${e.id}`,rootId:n.eventRootId})}),this.walk(t,e.runId,`timer:${e.id}`).catch(n=>this.log(`[workflow:${t.id}] walk-after-timer failed: ${n.message}`)))}async dispatchWorkflow(e){let t=this.store.list().find(d=>d.id===e.workflowId);if(!t)return this.log(`[workflows] dispatchWorkflow: workflow "${e.workflowId}" not found`),{claimed:!1,run:null};let n=this.runs.getActiveByEntity(e.entityRef),i=n?this.runs.get(n):null;if(i&&i.workflowId!==t.id)return this.log(`[workflow:${t.id}] entity ${e.entityRef.id} has run ${i.id} of workflow "${i.workflowId}" \u2014 not dispatching`),{claimed:!1,run:null};let s=t.nodes.find(d=>d.type.startsWith("trigger."))?.config??{},a={source:e.trigger?.source??s.source??"hook",project:e.trigger?.project,repo:e.trigger?.repo,chat:e.trigger?.chat,labels:e.trigger?.labels};return this.dispatchOne(t,e.entityRef,e.event,a)}startChannelAck(e,t){let n=String(t.channel??""),i=String(t.chatId??"");if(!n||!i)return;let o=this.channels[n];if(!o)return;let s=typeof t.accountId=="string"?t.accountId:void 0,a=t.event,d=typeof a?.id=="string"?a.id:a?.id!=null?String(a.id):void 0;if(d&&o.react)try{Promise.resolve(o.react(i,d,"\u{1F440}",s)).catch(()=>{})}catch{}if(this.ackTypingTimers.has(e)||!o.sendTyping)return;let c=()=>{try{Promise.resolve(o.sendTyping(i,s)).catch(()=>{})}catch{}};c();let u=setInterval(c,Or);this.ackTypingTimers.set(e,u)}stopChannelAck(e){let t=this.ackTypingTimers.get(e);t&&(clearInterval(t),this.ackTypingTimers.delete(e))}async dispatch(e){let t=this.matchByTrigger(e.trigger,e.fromRemote),i=t.some(a=>a.fanOut)?t:t.slice(0,1),o=[],s=[];for(let a of i){let d=await this.dispatchOne(a,e.entityRef,e.event,e.trigger);d.claimed&&o.push(a),d.run&&s.push(d.run)}return!e.fromRemote&&this.forwarder?.broadcastTrigger&&Promise.resolve(this.forwarder.broadcastTrigger({trigger:e.trigger,entityRef:e.entityRef,event:e.event})).catch(a=>this.log(`[mesh-broadcast] ${a?.message??a}`)),{claimed:o,runs:s}}matchByTrigger(e,t){let n=this.store.list(),i=[];for(let o of n){if(o.state&&o.state!=="active")continue;if(t){if(!o.mesh?.allowRemote)continue;let c=o.mesh.peers;if(c&&c.length>0&&!c.includes(t.peer))continue}let s=o.nodes.find(c=>c.type.startsWith("trigger."));if(!s)continue;let a=s.config;if(a.source!==e.source||o.project&&e.project&&o.project!==e.project)continue;let d=a.filter;if(d){if(d.project&&d.project!=="*"&&d.project!==e.project||d.repo&&d.repo!=="*"&&d.repo!==e.repo||d.chat&&d.chat!=="*"&&ne(e.source,d.chat)!==ne(e.source,e.chat))continue;if(d.labels?.length){let c=new Set(e.labels??[]);if(!d.labels.some(p=>c.has(p)))continue}}i.push(o)}return i.sort((o,s)=>s.priority-o.priority||o.id.localeCompare(s.id))}async dispatchOne(e,t,n,i){let o=await this.dispatchOneLegacy(e,t,n,i);if(Qe("workflow")!=="off")try{Ht(Je(),{workflowId:e.id,eventId:n.id,triggerSource:i.source,project:i.project??null,entityRef:t},JSON.stringify({event:n,trigger:i,entityRef:t}),{claimed:o.claimed,runId:o.run?.id??null})}catch(s){this.log(`[ledger] workflow ${e.id} run ${o.run?.id??"?"} record failed: ${s?.message??s}`)}return o}async dispatchOneLegacy(e,t,n,i){let o=this.runs.getActiveByEntity(t),s=o?this.runs.getHomeNodeByEntity(t):null;if(o&&s&&s!==this.nodeId){if(!this.forwarder)return this.log(`[workflow:${e.id}] run ${o} home'd on "${s}" but no forwarder \u2014 dropping`),{claimed:!1,run:null};try{await this.forwarder.forwardTransition(s,{workflowId:e.id,event:n,entityRef:t})}catch(d){this.log(`[workflow:${e.id}] forward to "${s}" failed: ${d.message}`)}return{claimed:!0,run:null}}let a=o?this.runs.get(o):null;if(a)if(a.status==="paused"&&a.pausedAt){if(a.pausedAt.kind!=="checkpoint")return this.log(`[workflow:${e.id}] run ${a.id} paused on ${a.pausedAt.kind} \u2014 channel event bypasses workflow`),{claimed:!1,run:null};if(!Wr(a.pausedAt.resumeMatch,i,n))return this.log(`[workflow:${e.id}] run ${a.id} paused but event doesn't match resumeMatch \u2014 dropping`),{claimed:!1,run:null};let d=P(e,a.pausedAt.nodeId),c=d?e.edges.filter(h=>h.from===d.id).map(h=>h.to):[],u={at:new Date().toISOString(),nodeId:a.pausedAt.nodeId,inputKeys:[],status:"resumed",output:{event:n.payload},idempotencyKey:N(a.id,a.pausedAt.nodeId,`resume:${n.id}`)},p={...a.context,[a.pausedAt.nodeId]:{event:n.payload}},g=a.pausedAt.checkpointName,f=this.runs.recordExecution({runId:a.id,entry:u,nextPending:c,status:"running",pausedAt:null,context:p});f&&(a=f),this.log(`[workflow:${e.id}] run ${a.id} resumed from checkpoint "${g}"`),i.source.endsWith("-message")&&this.startChannelAck(a.id,n.payload)}else return a.status==="running"?(this.log(`[workflow:${e.id}] run ${a.id} already running; dropping concurrent event ${n.id}`),{claimed:!0,run:null}):(this.log(`[workflow:${e.id}] run ${a.id} is ${a.status}; dropping event ${n.id}`),{claimed:!1,run:null});else{let d=Z(e);if(!d)return this.log(`[workflow:${e.id}] no trigger node found`),{claimed:!1,run:null};a=this.runs.create({workflowId:e.id,initialPending:d.pending,entityRef:t,initialContext:{[d.triggerId]:n.payload}}),this.log(`[workflow:${e.id}] run ${a.id} created from trigger "${d.triggerId}" for ${t.id}`),this.emitRunEvent({runId:a.id,workflowId:e.id,phase:"created",status:a.status,homeNode:a.homeNode,rootId:a.eventRootId}),i.source.endsWith("-message")&&this.startChannelAck(a.id,n.payload)}return this.walk(e,a.id,n.id),{claimed:!0,run:a}}async walk(e,t,n){let i=this.runs.get(t)?.eventRootId,o=()=>this.walkInner(e,t,n);try{await(i?Xe({rootId:i},o):o())}finally{this.stopChannelAck(t)}}async walkInner(e,t,n){let i=this.runs.get(t);if(i)for(;i.status==="running"&&i.pending.length>0;){let o=i.pending.slice(0,_r);await Promise.allSettled(o.map(a=>this.executeNodeAndCommit(e,t,a,n)));let s=this.runs.get(t);if(!s||(i=s,i.status!=="running"))return}}async executeNodeAndCommit(e,t,n,i){let o=N(t,n,i),s=await this.commit(t,()=>{let m=this.runs.get(t);if(!m)return{kind:"done"};if(m.status!=="running")return{kind:"done"};let w=P(e,n);if(!w)return this.log(`[workflow:${e.id}] missing node "${n}" \u2014 marking run failed`),this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:n,inputKeys:[],status:"failed",idempotencyKey:o,note:"node definition missing from workflow"},nextPending:m.pending.filter(A=>A!==n),status:"failed"}),{kind:"done"};let y=Te(w.type);return y?m.history.some(A=>A.idempotencyKey===o)?(this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:n,inputKeys:[],status:"skipped",idempotencyKey:o+"_dedup",note:"duplicate execution dropped"},nextPending:m.pending.filter(A=>A!==n)}),{kind:"done"}):{kind:"go",run:m,node:w,handler:y}:(this.log(`[workflow:${e.id}] no handler for node type "${w.type}"`),this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:n,inputKeys:[],status:"failed",idempotencyKey:o,note:`no handler for node type "${w.type}"`},nextPending:m.pending.filter(A=>A!==n),status:"failed"}),{kind:"done"})});if(s.kind==="done")return;let{run:a,node:d,handler:c}=s,u=e.edges.filter(m=>m.to===n).map(m=>m.from),p;if(d.type!=="agent"){let m=ae();if(m)try{p=nt(m,{agentId:`workflow:${d.type}`,channel:"workflow",chatId:`${e.id}:${n}`,workflowRunId:t,workflowId:e.id,workflowNodeId:n,messagePreview:`${d.type} ${n}`})}catch{}}let g=d.retry??{maxAttempts:1,backoffMs:1e3},f={error:"retry-loop did not run"},h=0;for(;h<g.maxAttempts;){h++;try{f=await c({workflow:e,run:a,node:d,channels:this.channels,agents:this.agents,forwardChannelSend:this.forwarder?.forwardChannelSend?.bind(this.forwarder),log:this.log})}catch(m){this.log(`[workflow:${e.id}] handler "${d.type}" threw: ${m.message}`),f={error:m.message}}if(!f.error||f.paused)break;if(h<g.maxAttempts){let m=g.backoffMs*Math.pow(2,h-1);this.log(`[workflow:${e.id}] node "${n}" failed (attempt ${h}/${g.maxAttempts}): ${f.error.slice(0,120)} \u2014 retrying in ${m}ms`),await new Promise(w=>setTimeout(w,m))}}if(p){let m=ae();if(m)try{rt(m,p,{status:f.error?"error":"ok",error:f.error??null})}catch{}}await this.commit(t,async()=>{let m=this.runs.get(t);if(!m)return;let w=new Date().toISOString(),y=m.pending.filter(k=>k!==n);if(f.error){let k=m.status==="running"?"failed":void 0;this.runs.recordExecution({runId:t,entry:{at:w,nodeId:n,inputKeys:u,status:"failed",idempotencyKey:o,note:f.error.slice(0,200)},nextPending:y,status:k}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:n,phase:"failed",status:k??m.status,note:f.error.slice(0,200)});return}if(f.paused&&f.pausedAt){let k=f.pausedAt,x=null;if(f.spawnChild&&k.kind==="subProcess"){if(x=await this.spawnChild({parent:m,parentNodeId:n,childWorkflowId:f.spawnChild.workflowId,input:f.spawnChild.input}),!x){this.runs.recordExecution({runId:t,entry:{at:w,nodeId:n,inputKeys:u,status:"failed",idempotencyKey:o,note:`subProcess: child workflow "${f.spawnChild.workflowId}" not found`},nextPending:y,status:"failed"});return}k={...k,childRunId:x.id}}if(this.runs.recordExecution({runId:t,entry:{at:w,nodeId:n,inputKeys:u,status:"paused",idempotencyKey:o},nextPending:y,status:"paused",pausedAt:k}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:n,phase:"paused",status:"paused",note:k.kind}),x&&this.kickChildWalk(x),k.kind==="timerWait")try{this.timers.schedule({runId:t,workflowId:e.id,nodeId:k.nodeId,fireAt:k.fireAt,cancelKey:`${t}:${k.nodeId}`})}catch(We){this.log(`[workflow:${e.id}] timer schedule failed: ${We.message}`)}return}let A=f.output??{},rn={...m.context,[n]:A},{nextPending:on}=Re({workflow:e,fromNodeId:n,selectedPort:f.port}),se=[],U={...m.joinCounters??{}};for(let k of on){let x=P(e,k);if(!(x?.type==="gateway.parallel"&&String(x.config?.mode??"fanOut")==="join")){se.push(k);continue}let B=U[k]??[];B.includes(n)||B.push(n),U[k]=B;let dn=e.edges.filter(cn=>cn.to===k).length;B.length>=dn&&(se.push(k),delete U[k])}let sn=[...y,...se],q=d.type==="end",an=m.status==="running"?q?String(d.config.status??"completed"):"running":void 0,O=this.runs.recordExecution({runId:t,entry:{at:w,nodeId:n,inputKeys:u,status:"ok",output:A,idempotencyKey:o},nextPending:q?[]:sn,status:an,context:rn,joinCounters:U});this.emitRunEvent({runId:t,workflowId:e.id,nodeId:n,phase:q?"completed":"ok",status:O?.status??m.status}),f.emitSignal&&this.emitSignal({name:f.emitSignal.name,scope:f.emitSignal.scope,workflowId:e.id,payload:f.emitSignal.payload}),q&&O&&O.parentRunId&&O.parentNodeId&&this.resumeParent({parentRunId:O.parentRunId,parentNodeId:O.parentNodeId,childRun:O}).catch(k=>this.log(`[workflow:${e.id}] resumeParent failed: ${k.message}`))})}async spawnChild(e){let t=this.store.list().find(a=>a.id===e.childWorkflowId);if(!t)return null;let n=Z(t);if(!n)return this.log(`[workflow:${t.id}] no trigger node \u2014 cannot spawn as child`),null;let i={...e.input};i[n.triggerId]={...i[n.triggerId]??{},parentRunId:e.parent.id,parentNodeId:e.parentNodeId};let o={backend:"agentx-internal",id:`subprocess:${e.parent.id}:${e.parentNodeId}`},s=this.runs.create({workflowId:t.id,initialPending:n.pending,entityRef:o,initialContext:i,parentRunId:e.parent.id,parentNodeId:e.parentNodeId,rootRunId:e.parent.rootRunId??e.parent.id,depth:(e.parent.depth??0)+1});return this.log(`[workflow:${t.id}] child run ${s.id} spawned from ${e.parent.id}/${e.parentNodeId} (depth ${s.depth})`),s}kickChildWalk(e){let t=this.store.list().find(n=>n.id===e.workflowId);t&&this.walk(t,e.id,`spawn:${e.parentRunId}:${e.parentNodeId}`).catch(n=>this.log(`[workflow:${t.id}] child walk failed: ${n.message}`))}async resumeParent(e){let t=this.runs.get(e.parentRunId);if(!t)return;let n=this.store.list().find(i=>i.id===t.workflowId);n&&(await this.commit(e.parentRunId,()=>{let i=this.runs.get(e.parentRunId);if(!i||i.status!=="paused"||!i.pausedAt||i.pausedAt.kind!=="subProcess"||i.pausedAt.nodeId!==e.parentNodeId||i.pausedAt.childRunId!==e.childRun.id)return;let o=P(n,e.parentNodeId),s=o?n.edges.filter(d=>d.from===o.id).map(d=>d.to):[],a={childRunId:e.childRun.id,status:e.childRun.status,output:Dr(e.childRun)};this.runs.recordExecution({runId:i.id,entry:{at:new Date().toISOString(),nodeId:e.parentNodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:N(i.id,e.parentNodeId,`child:${e.childRun.id}`)},nextPending:s,status:"running",pausedAt:null,context:{...i.context,[e.parentNodeId]:a}}),this.log(`[workflow:${n.id}] parent run ${i.id} resumed from subProcess child ${e.childRun.id}`),this.emitRunEvent({runId:i.id,workflowId:n.id,nodeId:e.parentNodeId,phase:"resumed",status:"running",note:`child:${e.childRun.id}`,rootId:i.eventRootId})}),this.walk(n,e.parentRunId,`child:${e.childRun.id}`))}};function Dr(r){for(let e=r.history.length-1;e>=0;e--){let t=r.history[e];if(t.status==="ok"&&t.output&&Object.keys(t.output).length>0)return t.output}return{}}function Wr(r,e,t){let n=o=>{let s=r[o];if(s===void 0||s===""||s==="*")return!0;if(Array.isArray(s)){let a=new Set(e.labels??[]);return s.some(d=>a.has(String(d)))}return o==="chat"?ne(e.source,String(s))===ne(e.source,e.chat):e[o]===s};if(!n("source")||!n("project")||!n("repo")||!n("chat"))return!1;let i=r.eventIdLike;return!(typeof i=="string"&&i&&!t.id.includes(i))}function ne(r,e){return e==null?"":r==="whatsapp-message"?e.replace(/@s\.whatsapp\.net$|@g\.us$/i,"").replace(/[\s+()]/g,""):e}function Fr(r){return{"pre:channel-message":async e=>{let t=e.msg;if(!t)return{};let n=Cr(t.channel);if(!n)return{};let i=t.group?.id??t.sender.id,o={backend:t.channel,id:`${t.channel}:${i}`},{claimed:s}=await r.dispatch({trigger:{source:n,chat:i},entityRef:o,event:{id:`${t.channel}:${t.accountId}:${t.id}`,payload:Lr(t)}});return s.length===0?{}:s.every(d=>d.nodes.find(u=>u.type.startsWith("trigger."))?.config?.passthrough===!0)?{}:{blocked:!0,message:`handled by workflow${s.length>1?"s":""}: ${s.map(d=>d.id).join(", ")}`}},"on:gitlab-issue":async e=>{let t=e.project,n=e.iid,i=e.issueEvent;if(!t||n===void 0)return{};let o=Array.isArray(i?.object_attributes?.labels)?i.object_attributes.labels.map(d=>typeof d=="string"?d:d?.title).filter(Boolean):i?.labels?.map(d=>d?.title)??[],s=i?.assignees??i?.object_attributes?.assignee_ids??[],a={backend:"gitlab",id:`${t}#${n}`};return await r.dispatch({trigger:{source:"gitlab-issue",project:t,labels:o},entityRef:a,event:{id:`gitlab-issue:${t}:${n}:${i?.object_attributes?.updated_at||i?.object_attributes?.action||"evt"}`,payload:{issue:{iid:n,title:i?.object_attributes?.title,description:i?.object_attributes?.description,url:i?.object_attributes?.url,action:i?.object_attributes?.action,labels:o,assignees:s},project:t,channel:"gitlab",chatId:`${t}:issue:${n}`}}}),{}},"on:gitlab-mr":async e=>{let t=e.project,n=e.iid,i=e.mrEvent;if(!t||n===void 0)return{};let o=Array.isArray(e.labels)?e.labels:Array.isArray(i?.object_attributes?.labels)?i.object_attributes.labels.map(c=>typeof c=="string"?c:c?.title).filter(Boolean):[],s=i?.assignees??i?.object_attributes?.assignee_ids??[],a=i?.reviewers??[],d={backend:"gitlab",id:`${t}!${n}`};return await r.dispatch({trigger:{source:"gitlab-mr",project:t,labels:o},entityRef:d,event:{id:`gitlab-mr:${t}:${n}:${i?.object_attributes?.updated_at||i?.object_attributes?.action||"evt"}`,payload:{mr:{iid:n,title:e.title,description:e.description,url:e.url,action:e.action,state:e.state,source_branch:e.source_branch,target_branch:e.target_branch,labels:o,assignees:s,reviewers:a},project:t,channel:"gitlab",chatId:`${t}:merge_request:${n}`,iid:n,title:e.title,description:e.description,url:e.url,action:e.action,state:e.state,source_branch:e.source_branch,target_branch:e.target_branch,labels:o}}}),{}},"on:gitlab-note":async e=>{let t=e.project,n=e.noteId,i=e.noteableType,o=e.noteableIid,s=e.text,a=e.authorUsername,d=e.mentions??[];if(!t||!n||!i||!o)return{};let c=i==="merge_request"?{backend:"gitlab",id:`${t}!${o}`}:{backend:"gitlab",id:`${t}#${o}`};return await r.dispatch({trigger:{source:"gitlab-note",project:t},entityRef:c,event:{id:`gitlab-note:${t}:${i}:${o}:${n}`,payload:{note:{id:n,text:s,author:a,mentions:d,noteableType:i,noteableIid:o,noteableTitle:e.noteableTitle},project:t,channel:"gitlab",chatId:`${t}:${i}:${o}`,noteId:n,noteableType:i,noteableIid:o,text:s,author:a,mentions:d}}}),{}},"on:gitlab-pipeline":async e=>{let t=e.project,n=e.pipelineId,i=e.status,o=e.ref;if(!t||!i)return{};let a=e.raw?.merge_request?.iid;if(!a)return{};let d={backend:"gitlab",id:`${t}!${a}`};return await r.dispatch({trigger:{source:"gitlab-pipeline",project:t},entityRef:d,event:{id:`gitlab-pipeline:${t}:${n}:${i}`,payload:{pipeline:{id:n,status:i,ref:o},project:t,channel:"gitlab",chatId:`${t}:merge_request:${a}`}}}),{}}}}function Cr(r){switch(r){case"telegram":return"telegram-message";case"whatsapp":return"whatsapp-message";case"discord":return"discord-message";case"slack":return"slack-message";default:return null}}function Lr(r){let e=r.group?.id??r.sender.id;return{channel:r.channel,chatId:e,accountId:r.accountId,text:r.text,fromJid:r.sender.id,sender:{id:r.sender.id,name:r.sender.name,username:r.sender.username},contact:r.channelMeta?.facts?{facts:r.channelMeta.facts}:void 0,group:r.group?{id:r.group.id,name:r.group.name}:void 0,channelMeta:r.channelMeta,replyTo:r.replyTo,replyToText:r.replyToText,media:r.media,event:{id:r.id,timestamp:r.timestamp?.toISOString?.()??new Date().toISOString()}}}var re=r=>r.trim().toLowerCase().replace(/^@/,"");function Mr(r){let e=typeof r.author=="string"?r.author:typeof r.authorUsername=="string"?r.authorUsername:void 0;if(e)return re(e);let n=r.payload?.sender?.login;return typeof n=="string"&&n?re(n):void 0}function jr(r,e){let t=typeof e.project=="string"?e.project:"";if(r==="on:gitlab-issue"||r==="on:gitlab-mr")return!t||e.iid==null?void 0:`gitlab:${t}${r==="on:gitlab-issue"?"#":"!"}${String(e.iid)}`;if(r==="on:gitlab-note"){let n=e.noteableIid!=null?String(e.noteableIid):"",i=typeof e.noteableType=="string"?e.noteableType:"";return!t||!n||!i?void 0:`gitlab:${t}${i==="issue"?"#":"!"}${n}`}if(r==="on:github-issue"||r==="on:github-pr"){let n=e.payload??{},i=typeof e.repo=="string"?e.repo:n.repository?.full_name,o=e.number??n.issue?.number??n.pull_request?.number;return typeof i!="string"||!i||o==null?void 0:`github:${i}#${String(o)}`}}function Hr(r){let e=new Set;for(let t of r.nodes){let n=t.type==="agent"?t.config.agentId:void 0;typeof n=="string"&&n&&e.add(n)}return[...e]}var ie=class{constructor(e=2e3){this.maxKeys=e}fires=new Map;tryFire(e,t,n,i=Date.now()){let o=(this.fires.get(e)??[]).filter(s=>i-s<n);if(o.length>=t)return this.fires.set(e,o),!1;for(o.push(i),this.fires.delete(e),this.fires.set(e,o);this.fires.size>this.maxKeys;){let s=this.fires.keys().next().value;if(s===void 0)break;this.fires.delete(s)}return!0}get size(){return this.fires.size}};function Pe(r,e,t){let n=r.logged??(r.logged=new Set);n.has(e)||(n.add(e),r.log(t))}function Ut(r,e,t,n,i){let o=Mr(t);if(o&&Array.isArray(n?.ignoreAuthors)&&n.ignoreAuthors.length>0&&n.ignoreAuthors.map(re).includes(o))return{skip:!0,reason:"ignored-author",detail:`author @${o} is in filter.ignoreAuthors`};if(n?.skipSelfAuthored===!0){let a=Hr(r),d=typeof t.authorAgent=="string"?t.authorAgent:void 0;if(d&&a.includes(d))return{skip:!0,reason:"self-authored",detail:`author @${o??"?"} is agent "${d}" which this workflow runs`};if(o){let c=new Set(a.flatMap(u=>(i.forgeUsernames?.(u)??[]).map(re)));if(c.has(o))return{skip:!0,reason:"self-authored",detail:`author @${o} is this workflow's own bot identity`};a.length===0?Pe(i,`noagents:${r.id}`,`[workflows] ${r.id} has no agent node \u2014 self-authored skip can't resolve a bot identity; only filter.ignoreAuthors applies`):c.size===0&&!("authorAgent"in t)&&Pe(i,`noident:${r.id}:${e}`,`[workflows] ${r.id} no forge username known for agent(s) ${a.join(", ")} on ${e} \u2014 self-authored skip inactive; only filter.ignoreAuthors applies`)}}let s=n?.maxFiresPerTarget;if(s&&typeof s.count=="number"&&s.count>0){let a=jr(e,t);if(a){let d=typeof s.windowMinutes=="number"&&s.windowMinutes>0?s.windowMinutes:60,c=i.now?.()??Date.now();if(!i.fireWindow.tryFire(`${r.id}|${a}`,s.count,d*6e4,c))return{skip:!0,reason:"chain-limit",detail:`${a} already fired ${s.count}x within ${d}m (filter.maxFiresPerTarget)`}}else Pe(i,`notarget:${r.id}:${e}`,`[workflows] ${r.id} filter.maxFiresPerTarget has no target key for ${e} \u2014 limit not applied`)}return{skip:!1}}function Ur(r){let e=r.store.list(),t={fireWindow:new ie,log:r.log,forgeUsernames:r.forgeUsernames,logged:new Set},n=0,i=0;for(let o of e){if(o.state&&o.state!=="active"){r.log(`[workflows] ${o.id} state=${o.state} \u2014 skipping trigger registration`);continue}let s=o.nodes.find(a=>a.type.startsWith("trigger."));if(s){if(s.type==="trigger.cron"){let a=s.config;if(!a.spec){r.log(`[workflows] ${o.id} trigger.cron missing config.spec \u2014 skipping`);continue}Br({workflowId:o.id,triggerNodeId:s.id,spec:a.spec,timezone:a.timezone??"UTC"},r.dispatcher,r.log),n++}else if(s.type==="trigger.hook"){let a=s.config;if(!a.event||!a.event.startsWith("on:")){r.log(`[workflows] ${o.id} trigger.hook config.event must start with "on:" \u2014 skipping`);continue}r.hooks.registerHandler(a.event,`workflows:${o.id}`,async d=>{try{let c=typeof d.project=="string"?d.project:void 0;if(o.project&&c&&o.project!==c)return{};if(a.filter){if(Array.isArray(a.filter.topic)&&a.filter.topic.length>0){let h=typeof d.topic=="string"?d.topic.toLowerCase():void 0;if(!h||!a.filter.topic.map(m=>m.toLowerCase()).includes(h))return{}}if(Array.isArray(a.filter.action)&&a.filter.action.length>0){let h=typeof d.action=="string"?d.action:void 0;if(!h||!a.filter.action.includes(h))return{}}if(Array.isArray(a.filter.mentions)&&a.filter.mentions.length>0){let h=Array.isArray(d.mentions)?d.mentions.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.mentions.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.noteableType)&&a.filter.noteableType.length>0){let h=typeof d.noteableType=="string"?d.noteableType.toLowerCase():void 0,m=a.filter.noteableType.map(w=>w.toLowerCase());if(!h||!m.includes(h))return{}}if(Array.isArray(a.filter.assigneesAdded)&&a.filter.assigneesAdded.length>0){let h=Array.isArray(d.assigneesAdded)?d.assigneesAdded.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.assigneesAdded.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.reviewersAdded)&&a.filter.reviewersAdded.length>0){let h=Array.isArray(d.reviewersAdded)?d.reviewersAdded.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.reviewersAdded.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.labelsAdded)&&a.filter.labelsAdded.length>0){let h=Array.isArray(d.labelsAdded)?d.labelsAdded.map(y=>y.toLowerCase()):[];if(!a.filter.labelsAdded.map(y=>y.toLowerCase()).some(y=>h.includes(y)))return{}}}let u=Ut(o,a.event,d,a.filter,t);if(u.skip){if(r.log(`[workflows] ${o.id} skipping ${a.event} (${u.reason}): ${u.detail}`),a.passthrough)return{};let h=d.__workflowClaimed;return{modified:{__workflowClaimed:[...Array.isArray(h)?h:[],o.id]}}}let p=qr(o.id,a.event,d);if(await r.dispatcher.dispatchWorkflow({workflowId:o.id,entityRef:{backend:"hook",id:p},event:{id:`hook:${a.event}:${Date.now().toString(36)}`,payload:{hookEvent:a.event,...d}}}),a.passthrough)return{};let g=d.__workflowClaimed;return{modified:{__workflowClaimed:[...Array.isArray(g)?g:[],o.id]}}}catch(c){return r.log(`[workflows] ${o.id} hook dispatch failed: ${c.message}`),{}}},60),i++}}}return{cronTimers:n,hookSubscribers:i}}function qr(r,e,t){let n=typeof t.project=="string"?t.project:"",i=t.iid!=null?String(t.iid):"";if(e==="on:gitlab-issue"&&n&&i)return`${r}:${e}:${n}#${i}`;if(e==="on:gitlab-mr"&&n&&i)return`${r}:${e}:${n}!${i}`;if(e==="on:gitlab-pipeline"&&n){let o=t.pipelineId!=null?String(t.pipelineId):"";if(o)return`${r}:${e}:${n}@pipeline:${o}`}return`${r}:${e}:${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Br(r,e,t){let n=()=>{let i;try{i=it(r.spec,new Date,r.timezone)}catch(s){t(`[workflows] ${r.workflowId} cron spec invalid: ${s.message}`);return}let o=Math.max(1e3,i.getTime()-Date.now());setTimeout(()=>{(async()=>{let s=`cron:${r.workflowId}:${i.toISOString()}`;try{await e.dispatchWorkflow({workflowId:r.workflowId,trigger:{source:"cron"},entityRef:{backend:"cron",id:`${r.workflowId}@${i.toISOString()}`},event:{id:s,payload:{now:i.toISOString(),spec:r.spec,workflowId:r.workflowId}}})}catch(a){t(`[workflows] ${r.workflowId} cron dispatch failed: ${a.message}`)}finally{n()}})()},o)};n()}import{createHash as Kr}from"crypto";import{existsSync as zr,mkdirSync as Yr,readFileSync as Jr,renameSync as Gr,writeFileSync as Xr}from"fs";import{resolve as qt}from"path";import{z as j}from"zod";var Bt=j.object({actionId:j.string().min(1),everySeconds:j.number().int().min(5).max(86400).default(60),key:j.string().min(1).default("id"),filter:j.array(fe).default([]),maxPerPoll:j.number().int().min(1).max(500).default(20)}),Vr=5e3,Zr=30;async function Qr(r){let e=new Ve().get(r);if(!e)throw new Error(`no action "${r}" in registry`);return Ze(e)}function Kt(r,e){let t=[],n=0;for(let i of r.split(`
20
- `)){let o=i.trim();if(!o)continue;let s;try{s=JSON.parse(o)}catch{n++;continue}if(!s||typeof s!="object"||Array.isArray(s)){n++;continue}let a=L(s,e);if((typeof a!="string"||!a)&&typeof a!="number"){n++;continue}t.push({key:String(a),value:s})}return{items:t,skipped:n}}function ei(r,e){let t=`${r}:${e}`;return/^[a-zA-Z0-9._:@-]+$/.test(e)&&t.length<=200?t:`${r}:#${Kr("sha256").update(e).digest("hex").slice(0,32)}`}var Oe=class{constructor(e){this.opts=e;this.stateDir=qt(e.store.baseDir,"_poll"),this.runAction=e.runAction??Qr}timers=new Map;warned=new Map;stateDir;runAction;resync;start(){return this.resync??=setInterval(()=>{try{this.sync()}catch(e){this.opts.log(`[workflows] poll sync failed: ${e.message}`)}},Zr*1e3),this.sync()}sync(){let e=new Map;for(let t of this.opts.store.list()){let n=this.configOf(t);n&&e.set(t.id,n)}for(let[t,n]of this.timers)e.has(t)||(clearTimeout(n),this.timers.delete(t),this.opts.log(`[workflows] ${t} poll stopped`));for(let[t,n]of e)this.timers.has(t)||(this.schedule(t,n.everySeconds),this.opts.log(`[workflows] ${t} polls action "${n.actionId}" every ${n.everySeconds}s`));return this.timers.size}stop(){this.resync&&clearInterval(this.resync),this.resync=void 0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}async pollOnce(e){let t=this.opts.store.get(e),n=t?this.configOf(t):null;if(!n)return 0;let i;try{i=await this.runAction(n.actionId)}catch(g){return this.warnOnce(e,`poll failed: ${g.message}`),0}if(!i.ok)return this.warnOnce(e,`poll failed (status=${i.status??"?"}): ${(i.errors??"").slice(0,200)}`),0;let{items:o,skipped:s}=Kt(i.output,n.key);this.warnOnce(e,s>0?`poll skipped ${s} line(s) that are not a JSON object with "${n.key}"`:"");let a=new Set(o.map(g=>g.key)),d=this.readState(e);if(!d||d.actionId!==n.actionId||d.key!==n.key)return this.writeState(e,{actionId:n.actionId,key:n.key,seen:[...a]},a),this.opts.log(`[workflows] ${e} poll baseline: ${a.size} existing item(s) recorded, no runs started`),0;let c=new Set(d.seen),u=0,p=!1;for(let g of o){if(c.has(g.key))continue;let f=n.filter.every(h=>V(h,g.value));if(!(f&&u>=n.maxPerPoll)){if(c.add(g.key),d.seen.push(g.key),!f){p=!0;continue}this.writeState(e,d,a),p=!1;try{let{run:h}=await this.opts.dispatcher.dispatchWorkflow({workflowId:e,trigger:{source:"poll"},entityRef:{backend:"poll",id:ei(e,g.key)},event:{id:`poll:${e}:${g.key}`,payload:g.value}});h?u++:this.opts.log(`[workflows] ${e} poll item "${g.key}" started no run`)}catch(h){this.opts.log(`[workflows] ${e} poll dispatch failed for "${g.key}": ${h.message}`)}}}return p&&this.writeState(e,d,a),u}schedule(e,t){let n=setTimeout(()=>{(async()=>{try{await this.pollOnce(e)}catch(s){this.opts.log(`[workflows] ${e} poll failed: ${s.message}`)}if(this.timers.get(e)!==n)return;let i=this.opts.store.get(e),o=i?this.configOf(i):null;o?this.schedule(e,o.everySeconds):this.timers.delete(e)})()},t*1e3);this.timers.set(e,n)}configOf(e){if(e.state&&e.state!=="active")return null;let t=e.nodes.find(i=>i.type.startsWith("trigger."));if(!t||t.type!=="trigger.poll")return null;let n=Bt.safeParse(t.config);if(!n.success){let i=n.error.issues.map(o=>`${o.path.join(".")||"config"}: ${o.message}`).join("; ");return this.warnOnce(e.id,`trigger.poll config invalid, not polling (${i})`),null}return n.data}warnOnce(e,t){this.warned.get(e)!==t&&(this.warned.set(e,t),t&&this.opts.log(`[workflows] ${e} ${t}`))}statePath(e){return qt(this.stateDir,`${e}.json`)}readState(e){let t=this.statePath(e);if(!zr(t))return null;try{let n=JSON.parse(Jr(t,"utf-8"));return typeof n.actionId!="string"||typeof n.key!="string"||!Array.isArray(n.seen)?null:{actionId:n.actionId,key:n.key,seen:n.seen.map(String)}}catch{return null}}writeState(e,t,n){let i=t.seen.length-Vr;i>0&&(t.seen=t.seen.filter(s=>n.has(s)||i--<=0)),Yr(this.stateDir,{recursive:!0});let o=this.statePath(e);Xr(`${o}.tmp`,JSON.stringify(t)),Gr(`${o}.tmp`,o)}};function zt(r){return r.nodes.find(n=>n.type.startsWith("trigger."))?.config?.inputSchema??null}function Yt(r,e){if(!r||!e?.properties)return{};let t=r.match(/^([^:]+\/[^:]+):([^:]+):(.+)$/);if(!t)return{};let[,n,i,o]=t,s={};if(e.properties.project&&(s.project=n),i==="push"){let a=o.match(/^refs\/heads\/(.+)$/);a&&e.properties.ref&&(s.ref=a[1])}else{let a=Number(o);Number.isFinite(a)&&(e.properties.id&&(s.id=a),e.properties.iid&&(s.iid=a),e.properties.mrId&&(s.mrId=a),e.properties.issueId&&(s.issueId=a),e.properties.prId&&(s.prId=a))}return s}function Jt(r,e){if(!r?.properties)return e;let t={...e};for(let[n,i]of Object.entries(r.properties))t[n]===void 0&&i&&"default"in i&&(t[n]=i.default);return t}function Gt(r,e){return!r?.required||!Array.isArray(r.required)?[]:r.required.filter(t=>{let n=e[t];return n===void 0||n===""||n===null})}function ni(r,e){let t=zt(r);if(!t?.properties){let d={};for(let[c,u]of Object.entries(e))u!==void 0&&(d[c]=u);return{inputs:d,missing:[],filledFrom:{passthrough:Object.keys(d),chatId:[],defaults:[]}}}let n={};for(let d of["message","agentId","channel","chatId","senderId","senderUsername"])t.properties[d]&&e[d]!==void 0&&(n[d]=e[d]);let i=Yt(e.chatId,t),o={...n,...i},s={...o};o=Jt(t,o);let a=Object.keys(o).filter(d=>s[d]===void 0&&o[d]!==void 0);return{inputs:o,missing:Gt(t,o),filledFrom:{passthrough:Object.keys(n),chatId:Object.keys(i),defaults:a}}}import{extname as ri}from"path";var Xt=/<agentx-artifact>([\s\S]*?)<\/agentx-artifact>/gi,Vt=/<agentx-artifact>[\s\S]*$/i;function ys(r,e=1/0,t=!1){let n=[],i=String(r??"");if(!/<agentx-artifact>/i.test(i))return{text:i,artifacts:n};let o=i.replace(Xt,(s,a)=>{try{let d=JSON.parse(a.trim());if(d&&typeof d.filename=="string"&&typeof d.mime=="string"&&n.length<e){let c=d.mime,u=c.startsWith("image/")?"image":c==="application/pdf"?"pdf":c.startsWith("text/")?"text":"file";n.push({type:u,filename:d.filename,mime:c})}}catch{}return""});return{text:(t?o.replace(Vt,""):o).trim(),artifacts:n}}function ws(r,e=!1){let t=String(r??""),n=t;if(/<agentx-artifact>/i.test(t)){let i=t.replace(Xt,(o,s)=>{try{let a=JSON.parse(s.trim());return a&&typeof a.filename=="string"?a.filename:""}catch{return""}});n=(e?i.replace(Vt,""):i).trim()}return n.replace(/```[\s\S]*?```|`[^`\n]*`|!\[([^\]\n]*)\]\(([^)\s]+)\)/g,(i,o,s)=>o===void 0||s===void 0?i:`[${o||s}](${s})`)}var ii={".png":{mime:"image/png",kind:"image"},".jpg":{mime:"image/jpeg",kind:"image"},".jpeg":{mime:"image/jpeg",kind:"image"},".gif":{mime:"image/gif",kind:"image"},".webp":{mime:"image/webp",kind:"image"},".svg":{mime:"image/svg+xml",kind:"file"},".pdf":{mime:"application/pdf",kind:"file"},".txt":{mime:"text/plain; charset=utf-8",kind:"file"},".md":{mime:"text/markdown; charset=utf-8",kind:"file"},".csv":{mime:"text/csv; charset=utf-8",kind:"file"},".json":{mime:"application/json",kind:"file"},".mp3":{mime:"audio/mpeg",kind:"audio"},".m4a":{mime:"audio/mp4",kind:"audio"},".wav":{mime:"audio/wav",kind:"audio"},".mp4":{mime:"video/mp4",kind:"video"},".webm":{mime:"video/webm",kind:"video"}},ks={bytes:20*1024*1024,perMessage:20,pathChars:512};function bs(r){return ii[ri(r).toLowerCase()]??null}var oi=["[Phone app: showing files]","To show the owner a file you created (a chart, a screenshot, a PDF, a recording), save or copy it into .agentx/outbox/ in your workspace and end your reply with one line per file:",'<agentx-artifact>{"filename":".agentx/outbox/<name.ext>","mime":"<mime/type>"}</agentx-artifact>',"Files outside your workspace (/tmp, your home folder) are refused. Outbox files are removed after 7 days.","The line is removed from the text. Images show in the reply, audio and video get a player, other files an Open link. Allowed: png, jpg, gif, webp, svg, pdf, txt, md, csv, json, mp3, m4a, wav, mp4, webm; up to 20 MB and 20 files per reply.","A picture already on the web can go inline as ![what it shows](https://...)."].join(`
21
- `);function vs(r,e,t){return r==="app"&&e&&t!==!1?oi:void 0}import{lstatSync as De,mkdirSync as si,readdirSync as ai,realpathSync as _e,unlinkSync as di}from"fs";import{join as oe,resolve as Zt}from"path";var Qt=".agentx/outbox",ci=7*24*60*60*1e3;function li(r,e){try{let t=_e(Zt(e,r)),n=oe(t,Qt);return _e(n)===n&&De(n).isDirectory()?n:null}catch{return null}}function As(r,e={}){let t=e.cwd??process.cwd();if(e.create!==!1)try{let i=_e(Zt(t,r));De(oe(i,".agentx"),{throwIfNoEntry:!1})?.isSymbolicLink()||si(oe(i,Qt),{recursive:!0})}catch{return 0}let n=li(r,t);return n?en(n,(e.now??Date.now())-(e.maxAgeMs??ci)):0}function en(r,e){let t=0;for(let n of ai(r)){let i=oe(r,n);try{let o=De(i);o.isDirectory()?t+=en(i,e):Math.max(o.mtimeMs,o.ctimeMs)<e&&(di(i),t++)}catch{}}return t}var tn=["in_progress","waiting_owner","waiting_other","needs_attention"],$=["done","declined","dropped"];function ui(r){r.exec(`
18
+ `)}clearIndex(e){let t=this.indexPath(e);if(F(t))try{Ot(t)}catch{}}};import{existsSync as _t,mkdirSync as Vn,readFileSync as Zn,unlinkSync as Qn,writeFileSync as er}from"fs";import{resolve as Se}from"path";import{z as C}from"zod";var Dt=C.object({version:C.literal(1),nodes:C.record(C.object({x:C.number(),y:C.number()}))}),Re=class{baseDir;layoutsDir;constructor(e={}){this.baseDir=e.baseDir??Se(process.cwd(),".agentx/workflows"),this.layoutsDir=Se(this.baseDir,"_layouts"),Vn(this.layoutsDir,{recursive:!0})}pathFor(e){let t=e.replace(/[^a-zA-Z0-9._-]/g,"_");return Se(this.layoutsDir,`${t}.json`)}get(e){let t=this.pathFor(e);if(!_t(t))return null;try{let r=Dt.safeParse(JSON.parse(Zn(t,"utf-8")));return r.success?r.data:null}catch{return null}}save(e,t){let r=Dt.parse(t);return er(this.pathFor(e),JSON.stringify(r,null,2)+`
19
+ `),r}sync(e,t){let r=this.get(e);if(!r)return null;let i={};for(let s of t)r.nodes[s]&&(i[s]=r.nodes[s]);let o={version:1,nodes:i};return this.save(e,o)}delete(e){let t=this.pathFor(e);return _t(t)?(Qn(t),!0):!1}};function Wt(n){return new Set(n.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(e=>e.length>3))}function tr(n,e){if(n.size===0||e.size===0)return 0;let t=0;for(let r of n)e.has(r)&&t++;return t/Math.max(n.size,e.size)}function nr(n,e){let t=Wt(n.message),r=e.filter(o=>o.state==="active"&&(o.status??"active")==="active"),i=null;for(let o of r){let s=0,a=[];if(o.ownerAgent&&o.ownerAgent===n.agentId&&(s+=.25,a.push("owner-agent")),n.channel&&o.tags.includes(n.channel)&&(s+=.15,a.push("channel-tag")),n.intentPath?.length&&o.intentPath.length){let p=n.intentPath.filter((g,f)=>o.intentPath[f]===g).length;p>0&&(s+=Math.min(.3,p*.1),a.push("intent-path"))}let d=[o.id,o.title,o.description??"",...o.tags].join(" "),c=tr(t,Wt(d));c>0&&(s+=Math.min(.35,c),a.push("text-similarity")),(o.matchCount??0)>0&&(s+=Math.min(.1,o.matchCount*.01),a.push("prior-matches"));let u=Math.max(0,Math.min(1,s));(!i||u>i.confidence)&&(i={workflow:o,confidence:u,reasons:a})}return i&&i.confidence>0?i:null}function Ie(n){let{workflow:e,fromNodeId:t,selectedPort:r}=n,i=e.nodes.find(a=>a.id===t);if(!i)return{nextPending:[]};let o=e.edges.filter(a=>a.from===t);return{nextPending:(i.type==="branch"?o.filter(a=>(a.fromPort??"")===(r??"")):o).map(a=>a.to)}}function Ae(n,e){let t=n.config.cases??[],r=n.config.default??"";for(let i of t)if(V(i.when,e))return i.to;return r}function V(n,e){let t=n.params??{},r=String(t.path??""),i=M(e,r);switch(n.kind){case"equals":return i===t.value;case"contains":return typeof i=="string"?i.includes(String(t.value??"")):Array.isArray(i)?i.some(o=>o===t.value):!1;case"matches":{if(typeof i!="string")return!1;try{return new RegExp(String(t.regex??"")).test(i)}catch{return!1}}case"exists":return i!=null&&i!=="";default:return!1}}function M(n,e){if(!e)return;let t=e.split("."),r=n;for(let i of t){if(r==null||typeof r!="object")return;r=r[i]}return r}function Z(n){let e=n.nodes.find(r=>r.type.startsWith("trigger."));if(!e)return null;let t=n.edges.filter(r=>r.from===e.id).map(r=>r.to);return{triggerId:e.id,pending:t}}function P(n,e){return n.nodes.find(t=>t.id===e)}ln();un();function rr(n,e,t){let r=n.split(".");if(r[0]==="env"){if(r.length!==2)return"";let o=r[1];if(!t.has(o))return"";let s=process.env[o];return typeof s=="string"?s:""}let i=e;for(let o of r){if(i==null||typeof i!="object")return"";i=i[o]}return i==null?"":typeof i=="object"?JSON.stringify(i):String(i)}function I(n,e,t={}){let r=new Set(t.envAllow||[]);return n.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_.-]*)\s*\}\}/g,(i,o)=>rr(o,e,r))}function b(n,e,t={}){let r={};for(let[i,o]of Object.entries(n))typeof o=="string"?r[i]=I(o,e,t):Array.isArray(o)?r[i]=o.map(s=>typeof s=="string"?I(s,e,t):s):o&&typeof o=="object"?r[i]=b(o,e,t):r[i]=o;return r}var Ft="workflow-classify",Q="unsure",Ct=async n=>{let e=n.node.config,t=n.run.context,r={envAllow:n.workflow.envAllow},i=I(String(e.input??""),t,r).trim();if(!i)return{error:`classify node "${n.node.id}" missing config.input`};let o=e.labels,s=Array.isArray(o)?Object.fromEntries(o.map(m=>[String(m),null])):typeof o=="object"&&o?Object.fromEntries(Object.entries(o).map(([m,w])=>[m,w==null?null:String(w)])):{},a=Object.keys(s);if(a.length<2)return{error:`classify node "${n.node.id}" needs at least two labels`};if(a.includes(Q))return{error:`classify node "${n.node.id}": "${Q}" is reserved for the low-confidence port`};let d=typeof e.minConfidence=="number"?e.minConfidence:.7,c=e.instructions?I(String(e.instructions),t,r):void 0,u={input:i};if(e.state&&typeof e.state=="object")for(let[m,w]of Object.entries(e.state)){let y=typeof w=="string"?I(w,t,r):w;(y===null||["string","number","boolean"].includes(typeof y))&&(u[m]=y)}let p=await Le(Ft,u,{label:Me(s,c)},{features:{workflow:n.workflow.id,node:n.node.id}});if(!p)return{error:`classify node "${n.node.id}": decision seat unavailable (set decisions.seats.${Ft}.mode)`};let g=p.answers.label,f=g.confidence>=d,h=f?g.choice:Q;return n.log(`[node:${n.node.id}] classify \u2192 ${g.choice} (${g.confidence.toFixed(2)})${f?"":` \u2014 below ${d}, routing to ${Q}`}`),{output:{result:g.choice,label:g.choice,confidence:g.confidence,probabilities:g.probabilities,unsure:!f,port:h},port:h}};var $e=class{active=new Map;waiters=new Map;async acquire(e,t){let r=this.active.get(e)??0;if(r<t){this.active.set(e,r+1);return}return new Promise(i=>{let o=this.waiters.get(e)??[];o.push({resolve:()=>{this.active.set(e,(this.active.get(e)??0)+1),i()}}),this.waiters.set(e,o)})}release(e){let t=this.active.get(e)??0;this.active.set(e,Math.max(0,t-1));let r=this.waiters.get(e);r&&r.length>0&&r.shift().resolve()}stats(e){return{active:this.active.get(e)??0,waiting:this.waiters.get(e)?.length??0}}},ee=new $e;function Mt(n,e){return`${n}:${e}`}var L=async n=>({output:n.run.context[n.node.id]??{}}),ir=async n=>{let e=n.node.config,t=String(e.agentId??""),r=String(e.prompt??"");if(!t)return{error:`agent node "${n.node.id}" missing config.agentId`};let i=I(r,n.run.context,{envAllow:n.workflow.envAllow}),o=typeof e.timeoutMinutes=="number"?e.timeoutMinutes:void 0,s=e.autonomy===void 0||e.autonomy===null?void 0:String(e.autonomy);if(s!==void 0&&s!=="report"&&s!=="propose"&&s!=="act")return{error:`agent node "${n.node.id}" has invalid autonomy "${s}" (expected report, propose or act)`};let a=typeof e.maxConcurrent=="number"&&e.maxConcurrent>0?e.maxConcurrent:null,d=a?Mt(n.workflow.id,n.node.id):null;if(d&&a){let u=ee.stats(d);u.active>=a&&n.log(`[node:${n.node.id}] gated: ${u.active} active (cap ${a}), ${u.waiting+1} waiting`),await ee.acquire(d,a)}let c=Date.now();try{let u=await n.agents.execute({agentId:t,message:i,workflowRunId:n.run.id,timeoutMinutes:o,...s?{autonomy:s}:{}}),p=Date.now()-c;if(u.error){let h=u.errorKind??"unknown";return n.log(`[node:${n.node.id}] agent "${t}" failed (${h}): ${u.error}`),{error:`[${h}] ${u.error}`}}let f=String(e.resultParser??"acme-result-token")==="json"?Er(u.content):jt(u.content);return{output:{reply:u.content,result:f.result,json:f.json,taskId:u.taskId,durationMs:p,...u.autonomyBlocks?.length?{autonomyBlocks:u.autonomyBlocks}:{}}}}catch(u){return n.log(`[node:${n.node.id}] agent "${t}" threw: ${u.message}`),{error:u.message}}finally{d&&ee.release(d)}},or=async n=>{let e=Ae(n.node,n.run.context);return e?{output:{port:e},port:e}:(n.log(`[node:${n.node.id}] branch matched no case and no default port`),{output:{port:null}})},sr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),i=String(e.text??"");if(!t||!r){let a=String(n.node.config.chatId??""),d=String(n.node.config.channel??""),c=[];return t||c.push(`channel config="${d}" rendered=""`),r||c.push(`chatId config="${a}" rendered=""`),(/\{\{\s*env\./.test(a)||/\{\{\s*env\./.test(d))&&c.push("(env.* templates only resolve for names listed in workflow.envAllow and actually set in process.env)"),{error:`action.send "${n.node.id}" needs channel + chatId \u2014 ${c.join("; ")}`}}let o=Ee(n,e.accountId),s=n.channels[t];if(s?.send)try{return{output:{messageId:await s.send({channel:t,chatId:r,text:i,...o?{accountId:o}:{}})??null}}}catch(a){return{error:`action.send failed: ${a.message}`}}if(n.forwardChannelSend)try{return{output:{messageId:(await n.forwardChannelSend({channel:t,chatId:r,text:i,accountId:o})).messageId,viaMesh:!0}}}catch(a){return n.log(`[node:${n.node.id}] mesh-forward of "${t}" send failed: ${a.message}`),{error:`action.send via mesh failed: ${a.message}`}}return n.log(`[node:${n.node.id}] adapter "${t}" not available locally and no mesh forwarder`),{error:`channel "${t}" not available (no local adapter, no mesh route)`}},ar=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),i=String(e.title??""),o=String(e.description??""),s=Array.isArray(e.labels)?e.labels.map(String):[],a=Array.isArray(e.assignees)?e.assignees.map(String):[];if(!r||!i)return{error:`action.createIssue "${n.node.id}" needs project + title`};let d=xe(n),c=n.channels[t];if(!c?.createIssue)return{error:`channel "${t}" does not support createIssue`};try{let u=await c.createIssue({project:r,title:i,description:o,labels:s,assignees:a,agentId:d});return u?{output:{issue:{iid:u.iid,url:u.url,webUrl:u.url}}}:{error:"createIssue returned null (see adapter log)"}}catch(u){return{error:`action.createIssue failed: ${u.message}`}}},dr=async()=>({output:{}}),cr=async n=>{let e=n.node.config,t=String(e.name??n.node.id),r=e.waitFor??{},i=e.resumeMatch??{};return{paused:!0,pausedAt:{kind:"checkpoint",nodeId:n.node.id,checkpointName:t,resumeMatch:{...r,...i}}}},lr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),i=String(e.iid??""),o=Array.isArray(e.add)?e.add.map(String):[],s=Array.isArray(e.remove)?e.remove.map(String):[];if(!r||!i)return{error:`action.setLabel "${n.node.id}" needs project + iid (try {{trigger.project}} / {{trigger.issue.iid}})`};if(o.length===0&&s.length===0)return{output:{skipped:!0,reason:"no labels to add or remove"}};let a=n.channels[t];if(!a?.setLabels)return{error:`channel "${t}" does not support setLabels`};let d=xe(n),c=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await a.setLabels({project:r,kind:c,iid:i,add:o,remove:s,agentId:d})??[],add:o,remove:s}}},ur=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),i=String(e.iid??"");if(!r||!i)return{error:`action.readLabel "${n.node.id}" needs project + iid`};let o=n.channels[t];if(!o?.getLabels)return{error:`channel "${t}" does not support getLabels`};let s=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await o.getLabels({project:r,kind:s,iid:i})??[]}}},pr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),i=String(e.messageId??""),o=String(e.emoji??"\u{1F440}");if(!t||!r||!i)return{error:`action.react "${n.node.id}" needs channel + chatId + messageId`};let s=Ee(n,e.accountId),a=n.channels[t];if(!a?.react)return{error:`channel "${t}" does not support react`};try{return await a.react(r,i,o,s),{output:{emoji:o}}}catch(d){return{error:`action.react failed: ${d.message}`}}},gr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),i=String(e.messageId??""),o=String(e.text??""),s=e.parseMode?String(e.parseMode):void 0;if(!t||!r||!i||!o)return{error:`action.editMessage "${n.node.id}" needs channel + chatId + messageId + text`};let a=Ee(n,e.accountId),d=n.channels[t];if(!d?.editMessage)return{error:`channel "${t}" does not support editMessage`};try{return{output:{edited:await d.editMessage(r,i,o,s,a)}}}catch(c){return{error:`action.editMessage failed: ${c.message}`}}},fr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.chatId??""),i=Number(e.durationMs??0);if(!r||!i)return{error:`action.logTime "${n.node.id}" needs chatId + durationMs`};let o=n.channels[t];if(!o?.logTimeSpent)return{error:`channel "${t}" does not support logTimeSpent`};let s=xe(n);try{return await o.logTimeSpent(r,i,s),{output:{durationMs:i}}}catch(a){return{error:`action.logTime failed: ${a.message}`}}},mr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.url??"");if(!t)return{error:`action.callHTTP "${n.node.id}" needs url`};let r=String(e.method??"POST").toUpperCase(),i=e.headers&&typeof e.headers=="object"?e.headers:{"Content-Type":"application/json"},o;e.body!==void 0&&(o=typeof e.body=="string"?e.body:JSON.stringify(e.body));try{let s=await fetch(t,{method:r,headers:i,body:o}),a=await s.text(),d=a;try{d=JSON.parse(a)}catch{}return{output:{ok:s.ok,status:s.status,body:d}}}catch(s){return{error:`action.callHTTP failed: ${s.message}`}}},hr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.actionId??e.id??"");if(!t)return{error:`action.run "${n.node.id}" needs actionId`};let r=e.inputs&&typeof e.inputs=="object"?e.inputs:{},{ActionStore:i}=await import("./store-TWQPEM5V.js"),{runAction:o}=await import("./runner-56G3N7M4.js"),s=new i().get(t);if(!s)return{error:`action.run "${n.node.id}": no action "${t}" in registry`};try{let a=await o(s,r),d={ok:a.ok,output:a.output,status:a.status,durationMs:a.durationMs};return a.errors!==void 0&&(d.errors=a.errors),a.ok?{output:d}:{output:d,error:`action "${t}" failed (status=${a.status})`}}catch(a){return{error:`action.run failed: ${a.message}`}}},yr=async n=>{let e=b(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.name??"");if(!t)return{error:`action.builtin "${n.node.id}" needs a "name" (e.g. "http.fetch")`};let r=e.input&&typeof e.input=="object"?e.input:{},{runBuiltin:i,getBuiltin:o}=await import("./builtin-W6KNX7RS.js");if(!o(t))return{error:`action.builtin "${n.node.id}": unknown built-in "${t}"`};try{return{output:await i(t,r)}}catch(s){let a=s?.name==="ZodError"?`validation: ${s.message}`:s?.message||String(s);return{error:`action.builtin "${t}" failed: ${a}`}}},wr=async n=>{let e=n.node.config,t=n.run.context;return typeof e.path=="string"&&e.path?{output:{value:M(t,e.path)}}:e.template&&typeof e.template=="object"?{output:b(e.template,t,{envAllow:n.workflow.envAllow})}:{output:{}}};function kr(n){if(n!=null){if(typeof n=="number")return new Date(Date.now()+n*6e4).toISOString();if(typeof n=="object"&&n&&"minutes"in n){let e=Number(n.minutes);if(Number.isFinite(e))return new Date(Date.now()+e*6e4).toISOString()}if(typeof n=="string"){let e=/^P(?:([0-9]+)D)?(?:T(?:([0-9]+)H)?(?:([0-9]+)M)?(?:([0-9]+)S)?)?$/.exec(n);if(e){let t=Number(e[1]??0),r=Number(e[2]??0),i=Number(e[3]??0),o=Number(e[4]??0),s=((t*24+r)*60+i)*6e4+o*1e3;if(s>0)return new Date(Date.now()+s).toISOString()}}}}var br=async n=>{let e=n.node.config,t=b(e,n.run.context,{envAllow:n.workflow.envAllow}),r=String(t.workflowId??"");if(!r)return{error:`subProcess "${n.node.id}" missing config.workflowId`};let i=n.run.depth??0,o=n.workflow.maxChildDepth??5;if(i+1>=o)return{error:`max child workflow depth ${o} exceeded at ${n.workflow.id} \u2192 ${r} (parent depth ${i})`};let s=e.inputMap,a={};if(s==="*")a={...n.run.context};else if(s&&typeof s=="object")for(let[d,c]of Object.entries(s))c&&typeof c=="object"&&!Array.isArray(c)?a[d]=b(c,n.run.context,{envAllow:n.workflow.envAllow}):typeof c=="string"&&(a[d]={value:I(c,n.run.context,{envAllow:n.workflow.envAllow})});return{paused:!0,pausedAt:{kind:"subProcess",nodeId:n.node.id,childRunId:"",childWorkflowId:r},spawnChild:{workflowId:r,input:a}}},vr=L,Sr=async n=>{let e=n.node.config,t=b(e,n.run.context,{envAllow:n.workflow.envAllow}),r=String(t.name??"");if(!r)return{error:`signal.emit "${n.node.id}" missing config.name`};let i=t.scope==="global"?"global":"workflow",o=t.payload&&typeof t.payload=="object"?t.payload:{};return{output:{emittedAt:new Date().toISOString(),name:r,scope:i,payload:o},emitSignal:{name:r,scope:i,payload:o}}},Rr=async n=>{let e=n.node.config,t=b(e,n.run.context,{envAllow:n.workflow.envAllow}),r=String(t.name??"");if(!r)return{error:`signal.wait "${n.node.id}" missing config.name`};let i=t.scope==="global"?"global":"workflow",o=e.match&&typeof e.match=="object"?e.match:{};return{paused:!0,pausedAt:{kind:"signalWait",nodeId:n.node.id,signalName:r,match:o,scope:i}}},Ir=async n=>{let e=n.node.config,t=b(e,n.run.context,{envAllow:n.workflow.envAllow}),r=kr(t.after??e.after);return r?{paused:!0,pausedAt:{kind:"timerWait",nodeId:n.node.id,fireAt:r}}:{error:`timer.boundary "${n.node.id}" needs config.after (duration or minutes)`}},Ar=async()=>({output:{}}),$r=async n=>{let e=n.node.config,r=(Array.isArray(e.inputs)?e.inputs:[]).map(s=>typeof s=="string"?I(s,n.run.context,{envAllow:n.workflow.envAllow}):s),i=Array.isArray(e.rules)?e.rules:[];for(let s of i){let a=Array.isArray(s.when)?s.when:[];if(a.length!==r.length)continue;let d=!0;for(let c=0;c<a.length;c++)if(!Tr(a[c],r[c])){d=!1;break}if(d)return{output:{...s.output??{},matchedPort:s.to??""},port:s.to}}let o=e.default;return{output:{...o?.output??{},matchedPort:o?.to??""},port:o?.to}};function Tr(n,e){if(n==null||n==="*")return!0;let t=String(n),r=typeof e=="number"?e:String(e??""),i=/^(>=|<=|>|<)\s*(-?\d+(?:\.\d+)?)$/.exec(t);if(i){let o=i[1],s=Number(i[2]),a=typeof r=="number"?r:Number(r);if(Number.isNaN(a))return!1;switch(o){case">":return a>s;case"<":return a<s;case">=":return a>=s;case"<=":return a<=s}}if(t.startsWith("!="))return String(r)!==t.slice(2);if(t.startsWith("/")&&t.endsWith("/")&&t.length>2)try{return new RegExp(t.slice(1,-1)).test(String(r))}catch{return!1}return String(r)===t}var Lt={"trigger.channel":L,"trigger.manual":L,"trigger.cron":L,"trigger.hook":L,"trigger.form":vr,"trigger.poll":L,agent:ir,classify:Ct,branch:or,transform:wr,"gateway.parallel":Ar,rule:$r,"action.send":sr,"action.createIssue":ar,"action.setLabel":lr,"action.readLabel":ur,"action.react":pr,"action.editMessage":gr,"action.logTime":fr,"action.callHTTP":mr,"action.run":hr,"action.builtin":yr,subProcess:br,"signal.emit":Sr,"signal.wait":Rr,"timer.boundary":Ir,checkpoint:cr,end:dr};function Te(n){return Lt[n]}function Ee(n,e){if(typeof e=="string"&&e)return e;let t=n.workflow.nodes.find(o=>o.type.startsWith("trigger."));if(!t)return;let i=n.run.context[t.id]?.accountId;return typeof i=="string"&&i?i:void 0}function xe(n){for(let e=n.run.history.length-1;e>=0;e--){let t=n.run.history[e],r=n.workflow.nodes.find(i=>i.id===t.nodeId);if(r?.type==="agent")return r.config.agentId??void 0}}function jt(n){if(!n)return{};let e=n.match(/\bRESULT:\s*([a-z][a-z0-9_-]*)/i);if(e)return{result:e[1].toLowerCase()};let t=n.match(/\[(APPROVED|REJECTED|CHANGES[-_]REQUESTED|DONE|FAILED|SKIPPED)\]/i);return t?{result:t[1].toLowerCase().replace("_","-")}:{}}function Er(n){let{result:e}=jt(n);if(!n)return{result:e};let t=n.match(/```(?:json)?\s*([\s\S]*?)```/);if(!t)return{result:e};try{return{result:e,json:JSON.parse(t[1])}}catch{return{result:e}}}var H=class{handlers=new Set;subscribe(e){return this.handlers.add(e),()=>this.handlers.delete(e)}emit(e){for(let t of this.handlers)try{Promise.resolve(t(e)).catch(()=>{})}catch{}}};function te(n,e){if(n.name!==e.name||n.scope==="workflow"&&n.workflowId!==e.workflowId)return!1;for(let[t,r]of Object.entries(n.match??{}))if(!(r===void 0||r===""||r==="*")&&e.payload[t]!==r)return!1;return!0}function xr(n,e,t=Date.now){return{ts:t(),source:"workflow",sourceEventId:`${n.workflowId}:${n.eventId}`,project:n.project,subject:`workflow:${n.workflowId}:entity:${n.entityRef.backend}:${n.entityRef.id}`,intent:`workflow.${n.triggerSource}`,rawJson:e}}function Nr(n){return n.claimed&&n.runId?{agentId:`workflow-run:${n.runId}`,outcome:"dispatched",reason:n.reason??"claimed"}:n.claimed&&!n.runId?{agentId:null,outcome:"halted",reason:n.reason??"claimed-but-no-run"}:{agentId:null,outcome:"halted",reason:n.reason??"not-claimed"}}function Pr(n){return{decidedBy:"workflow-dispatcher",decide:()=>({agentId:n.agentId,outcome:n.outcome==="deduped"?"halted":n.outcome,reason:n.outcome==="deduped"?`legacy-dedup: ${n.reason??""}`.trim():n.reason??null})}}function Ht(n,e,t,r,i=Date.now){let o=xr(e,t,i),s=Nr(r),a=Pr(s),d=et(n,o,a,i);return tt(n,"workflow",d,s,i),d}var Or=4e3,_r=8,Ne=class{store;runs;nodeId;forwarder;channels;agents;log;timers;signals;events;ackTypingTimers=new Map;commitChains=new Map;constructor(e){this.store=e.store,this.runs=e.runs,this.nodeId=e.nodeId,this.forwarder=e.forwarder,this.channels=e.channels,this.agents=e.agents,this.log=e.log??(()=>{}),this.timers=e.timers??new pe({log:t=>this.log(t)}),this.signals=e.signals??new H,this.events=e.events,this.timers.onFire(t=>this.resumeFromTimer(t)),this.signals.subscribe(t=>this.resumeFromSignal(t))}emitRunEvent(e){if(this.events)try{this.events.publish({kind:"run",runId:e.runId,workflowId:e.workflowId,nodeId:e.nodeId,phase:e.phase,status:e.status,note:e.note,homeNode:e.homeNode,rootId:e.rootId})}catch{}}async commit(e,t){let i=(this.commitChains.get(e)??Promise.resolve()).then(()=>t(),()=>t());return this.commitChains.set(e,i.then(()=>{},()=>{})),i}emitSignal(e){let t={name:e.name,scope:e.scope??"global",workflowId:e.workflowId??"",payload:e.payload??{},emittedAt:new Date().toISOString()};if(this.signals.emit(t),this.events)try{this.events.publish({kind:"signal",name:t.name,scope:t.scope,workflowId:t.workflowId||void 0,payload:t.payload})}catch{}return t}async resumeFromSignal(e){let t=this.runs.list({limit:500});for(let r of t){if(r.status!=="paused"||!r.pausedAt||r.pausedAt.kind!=="signalWait")continue;let i={name:r.pausedAt.signalName,scope:r.pausedAt.scope,workflowId:r.workflowId,match:r.pausedAt.match??{}};if(!te(i,e))continue;let o=this.store.list().find(s=>s.id===r.workflowId);o&&(await this.commit(r.id,()=>{let s=this.runs.get(r.id);if(!s||s.status!=="paused"||!s.pausedAt||s.pausedAt.kind!=="signalWait"||!te({name:s.pausedAt.signalName,scope:s.pausedAt.scope,workflowId:s.workflowId,match:s.pausedAt.match??{}},e))return;let a=P(o,s.pausedAt.nodeId),d=a?o.edges.filter(u=>u.from===a.id).map(u=>u.to):[],c={receivedAt:new Date().toISOString(),name:e.name,payload:e.payload};this.runs.recordExecution({runId:s.id,entry:{at:c.receivedAt,nodeId:s.pausedAt.nodeId,inputKeys:[],status:"resumed",output:c,idempotencyKey:N(s.id,s.pausedAt.nodeId,`signal:${e.name}:${e.emittedAt}`)},nextPending:d,status:"running",pausedAt:null,context:{...s.context,[s.pausedAt.nodeId]:c}}),this.log(`[workflow:${o.id}] run ${s.id} resumed from signal "${e.name}"`),this.emitRunEvent({runId:s.id,workflowId:o.id,nodeId:s.pausedAt.nodeId,phase:"resumed",status:"running",note:`signal:${e.name}`,rootId:s.eventRootId})}),this.walk(o,r.id,`signal:${e.name}`).catch(s=>this.log(`[workflow:${o.id}] walk-after-signal failed: ${s.message}`)))}}async resumeFromTimer(e){let t=this.store.list().find(r=>r.id===(this.runs.get(e.runId)?.workflowId??""));t&&(await this.commit(e.runId,()=>{let r=this.runs.get(e.runId);if(!r||r.status!=="paused"||!r.pausedAt||r.pausedAt.kind!=="timerWait"||r.pausedAt.nodeId!==e.nodeId)return;let i=P(t,e.nodeId),o=i?t.edges.filter(d=>d.from===i.id).map(d=>d.to):[],s=new Date().toISOString(),a={firedAt:s,scheduledFor:e.fireAt};this.runs.recordExecution({runId:r.id,entry:{at:s,nodeId:e.nodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:N(r.id,e.nodeId,`timer:${e.id}`)},nextPending:o,status:"running",pausedAt:null,context:{...r.context,[e.nodeId]:a}}),this.log(`[workflow:${t.id}] run ${r.id} resumed from timer "${e.nodeId}" (fired ${s})`),this.emitRunEvent({runId:r.id,workflowId:t.id,nodeId:e.nodeId,phase:"resumed",status:"running",note:`timer:${e.id}`,rootId:r.eventRootId})}),this.walk(t,e.runId,`timer:${e.id}`).catch(r=>this.log(`[workflow:${t.id}] walk-after-timer failed: ${r.message}`)))}async dispatchWorkflow(e){let t=this.store.list().find(d=>d.id===e.workflowId);if(!t)return this.log(`[workflows] dispatchWorkflow: workflow "${e.workflowId}" not found`),{claimed:!1,run:null};let r=this.runs.getActiveByEntity(e.entityRef),i=r?this.runs.get(r):null;if(i&&i.workflowId!==t.id)return this.log(`[workflow:${t.id}] entity ${e.entityRef.id} has run ${i.id} of workflow "${i.workflowId}" \u2014 not dispatching`),{claimed:!1,run:null};let s=t.nodes.find(d=>d.type.startsWith("trigger."))?.config??{},a={source:e.trigger?.source??s.source??"hook",project:e.trigger?.project,repo:e.trigger?.repo,chat:e.trigger?.chat,labels:e.trigger?.labels};return this.dispatchOne(t,e.entityRef,e.event,a)}startChannelAck(e,t){let r=String(t.channel??""),i=String(t.chatId??"");if(!r||!i)return;let o=this.channels[r];if(!o)return;let s=typeof t.accountId=="string"?t.accountId:void 0,a=t.event,d=typeof a?.id=="string"?a.id:a?.id!=null?String(a.id):void 0;if(d&&o.react)try{Promise.resolve(o.react(i,d,"\u{1F440}",s)).catch(()=>{})}catch{}if(this.ackTypingTimers.has(e)||!o.sendTyping)return;let c=()=>{try{Promise.resolve(o.sendTyping(i,s)).catch(()=>{})}catch{}};c();let u=setInterval(c,Or);this.ackTypingTimers.set(e,u)}stopChannelAck(e){let t=this.ackTypingTimers.get(e);t&&(clearInterval(t),this.ackTypingTimers.delete(e))}async dispatch(e){let t=this.matchByTrigger(e.trigger,e.fromRemote),i=t.some(a=>a.fanOut)?t:t.slice(0,1),o=[],s=[];for(let a of i){let d=await this.dispatchOne(a,e.entityRef,e.event,e.trigger);d.claimed&&o.push(a),d.run&&s.push(d.run)}return!e.fromRemote&&this.forwarder?.broadcastTrigger&&Promise.resolve(this.forwarder.broadcastTrigger({trigger:e.trigger,entityRef:e.entityRef,event:e.event})).catch(a=>this.log(`[mesh-broadcast] ${a?.message??a}`)),{claimed:o,runs:s}}matchByTrigger(e,t){let r=this.store.list(),i=[];for(let o of r){if(o.state&&o.state!=="active")continue;if(t){if(!o.mesh?.allowRemote)continue;let c=o.mesh.peers;if(c&&c.length>0&&!c.includes(t.peer))continue}let s=o.nodes.find(c=>c.type.startsWith("trigger."));if(!s)continue;let a=s.config;if(a.source!==e.source||o.project&&e.project&&o.project!==e.project)continue;let d=a.filter;if(d){if(d.project&&d.project!=="*"&&d.project!==e.project||d.repo&&d.repo!=="*"&&d.repo!==e.repo||d.chat&&d.chat!=="*"&&ne(e.source,d.chat)!==ne(e.source,e.chat))continue;if(d.labels?.length){let c=new Set(e.labels??[]);if(!d.labels.some(p=>c.has(p)))continue}}i.push(o)}return i.sort((o,s)=>s.priority-o.priority||o.id.localeCompare(s.id))}async dispatchOne(e,t,r,i){let o=await this.dispatchOneLegacy(e,t,r,i);if(Qe("workflow")!=="off")try{Ht(Je(),{workflowId:e.id,eventId:r.id,triggerSource:i.source,project:i.project??null,entityRef:t},JSON.stringify({event:r,trigger:i,entityRef:t}),{claimed:o.claimed,runId:o.run?.id??null})}catch(s){this.log(`[ledger] workflow ${e.id} run ${o.run?.id??"?"} record failed: ${s?.message??s}`)}return o}async dispatchOneLegacy(e,t,r,i){let o=this.runs.getActiveByEntity(t),s=o?this.runs.getHomeNodeByEntity(t):null;if(o&&s&&s!==this.nodeId){if(!this.forwarder)return this.log(`[workflow:${e.id}] run ${o} home'd on "${s}" but no forwarder \u2014 dropping`),{claimed:!1,run:null};try{await this.forwarder.forwardTransition(s,{workflowId:e.id,event:r,entityRef:t})}catch(d){this.log(`[workflow:${e.id}] forward to "${s}" failed: ${d.message}`)}return{claimed:!0,run:null}}let a=o?this.runs.get(o):null;if(a)if(a.status==="paused"&&a.pausedAt){if(a.pausedAt.kind!=="checkpoint")return this.log(`[workflow:${e.id}] run ${a.id} paused on ${a.pausedAt.kind} \u2014 channel event bypasses workflow`),{claimed:!1,run:null};if(!Wr(a.pausedAt.resumeMatch,i,r))return this.log(`[workflow:${e.id}] run ${a.id} paused but event doesn't match resumeMatch \u2014 dropping`),{claimed:!1,run:null};let d=P(e,a.pausedAt.nodeId),c=d?e.edges.filter(h=>h.from===d.id).map(h=>h.to):[],u={at:new Date().toISOString(),nodeId:a.pausedAt.nodeId,inputKeys:[],status:"resumed",output:{event:r.payload},idempotencyKey:N(a.id,a.pausedAt.nodeId,`resume:${r.id}`)},p={...a.context,[a.pausedAt.nodeId]:{event:r.payload}},g=a.pausedAt.checkpointName,f=this.runs.recordExecution({runId:a.id,entry:u,nextPending:c,status:"running",pausedAt:null,context:p});f&&(a=f),this.log(`[workflow:${e.id}] run ${a.id} resumed from checkpoint "${g}"`),i.source.endsWith("-message")&&this.startChannelAck(a.id,r.payload)}else return a.status==="running"?(this.log(`[workflow:${e.id}] run ${a.id} already running; dropping concurrent event ${r.id}`),{claimed:!0,run:null}):(this.log(`[workflow:${e.id}] run ${a.id} is ${a.status}; dropping event ${r.id}`),{claimed:!1,run:null});else{let d=Z(e);if(!d)return this.log(`[workflow:${e.id}] no trigger node found`),{claimed:!1,run:null};a=this.runs.create({workflowId:e.id,initialPending:d.pending,entityRef:t,initialContext:{[d.triggerId]:r.payload}}),this.log(`[workflow:${e.id}] run ${a.id} created from trigger "${d.triggerId}" for ${t.id}`),this.emitRunEvent({runId:a.id,workflowId:e.id,phase:"created",status:a.status,homeNode:a.homeNode,rootId:a.eventRootId}),i.source.endsWith("-message")&&this.startChannelAck(a.id,r.payload)}return this.walk(e,a.id,r.id),{claimed:!0,run:a}}async walk(e,t,r){let i=this.runs.get(t)?.eventRootId,o=()=>this.walkInner(e,t,r);try{await(i?Xe({rootId:i},o):o())}finally{this.stopChannelAck(t)}}async walkInner(e,t,r){let i=this.runs.get(t);if(i)for(;i.status==="running"&&i.pending.length>0;){let o=i.pending.slice(0,_r);await Promise.allSettled(o.map(a=>this.executeNodeAndCommit(e,t,a,r)));let s=this.runs.get(t);if(!s||(i=s,i.status!=="running"))return}}async executeNodeAndCommit(e,t,r,i){let o=N(t,r,i),s=await this.commit(t,()=>{let m=this.runs.get(t);if(!m)return{kind:"done"};if(m.status!=="running")return{kind:"done"};let w=P(e,r);if(!w)return this.log(`[workflow:${e.id}] missing node "${r}" \u2014 marking run failed`),this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:r,inputKeys:[],status:"failed",idempotencyKey:o,note:"node definition missing from workflow"},nextPending:m.pending.filter(A=>A!==r),status:"failed"}),{kind:"done"};let y=Te(w.type);return y?m.history.some(A=>A.idempotencyKey===o)?(this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:r,inputKeys:[],status:"skipped",idempotencyKey:o+"_dedup",note:"duplicate execution dropped"},nextPending:m.pending.filter(A=>A!==r)}),{kind:"done"}):{kind:"go",run:m,node:w,handler:y}:(this.log(`[workflow:${e.id}] no handler for node type "${w.type}"`),this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:r,inputKeys:[],status:"failed",idempotencyKey:o,note:`no handler for node type "${w.type}"`},nextPending:m.pending.filter(A=>A!==r),status:"failed"}),{kind:"done"})});if(s.kind==="done")return;let{run:a,node:d,handler:c}=s,u=e.edges.filter(m=>m.to===r).map(m=>m.from),p;if(d.type!=="agent"){let m=ae();if(m)try{p=nt(m,{agentId:`workflow:${d.type}`,channel:"workflow",chatId:`${e.id}:${r}`,workflowRunId:t,workflowId:e.id,workflowNodeId:r,messagePreview:`${d.type} ${r}`})}catch{}}let g=d.retry??{maxAttempts:1,backoffMs:1e3},f={error:"retry-loop did not run"},h=0;for(;h<g.maxAttempts;){h++;try{f=await c({workflow:e,run:a,node:d,channels:this.channels,agents:this.agents,forwardChannelSend:this.forwarder?.forwardChannelSend?.bind(this.forwarder),log:this.log})}catch(m){this.log(`[workflow:${e.id}] handler "${d.type}" threw: ${m.message}`),f={error:m.message}}if(!f.error||f.paused)break;if(h<g.maxAttempts){let m=g.backoffMs*Math.pow(2,h-1);this.log(`[workflow:${e.id}] node "${r}" failed (attempt ${h}/${g.maxAttempts}): ${f.error.slice(0,120)} \u2014 retrying in ${m}ms`),await new Promise(w=>setTimeout(w,m))}}if(p){let m=ae();if(m)try{rt(m,p,{status:f.error?"error":"ok",error:f.error??null})}catch{}}await this.commit(t,async()=>{let m=this.runs.get(t);if(!m)return;let w=new Date().toISOString(),y=m.pending.filter(k=>k!==r);if(f.error){let k=m.status==="running"?"failed":void 0;this.runs.recordExecution({runId:t,entry:{at:w,nodeId:r,inputKeys:u,status:"failed",idempotencyKey:o,note:f.error.slice(0,200)},nextPending:y,status:k}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:"failed",status:k??m.status,note:f.error.slice(0,200)});return}if(f.paused&&f.pausedAt){let k=f.pausedAt,x=null;if(f.spawnChild&&k.kind==="subProcess"){if(x=await this.spawnChild({parent:m,parentNodeId:r,childWorkflowId:f.spawnChild.workflowId,input:f.spawnChild.input}),!x){this.runs.recordExecution({runId:t,entry:{at:w,nodeId:r,inputKeys:u,status:"failed",idempotencyKey:o,note:`subProcess: child workflow "${f.spawnChild.workflowId}" not found`},nextPending:y,status:"failed"});return}k={...k,childRunId:x.id}}if(this.runs.recordExecution({runId:t,entry:{at:w,nodeId:r,inputKeys:u,status:"paused",idempotencyKey:o},nextPending:y,status:"paused",pausedAt:k}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:"paused",status:"paused",note:k.kind}),x&&this.kickChildWalk(x),k.kind==="timerWait")try{this.timers.schedule({runId:t,workflowId:e.id,nodeId:k.nodeId,fireAt:k.fireAt,cancelKey:`${t}:${k.nodeId}`})}catch(We){this.log(`[workflow:${e.id}] timer schedule failed: ${We.message}`)}return}let A=f.output??{},rn={...m.context,[r]:A},{nextPending:on}=Ie({workflow:e,fromNodeId:r,selectedPort:f.port}),se=[],U={...m.joinCounters??{}};for(let k of on){let x=P(e,k);if(!(x?.type==="gateway.parallel"&&String(x.config?.mode??"fanOut")==="join")){se.push(k);continue}let B=U[k]??[];B.includes(r)||B.push(r),U[k]=B;let dn=e.edges.filter(cn=>cn.to===k).length;B.length>=dn&&(se.push(k),delete U[k])}let sn=[...y,...se],q=d.type==="end",an=m.status==="running"?q?String(d.config.status??"completed"):"running":void 0,O=this.runs.recordExecution({runId:t,entry:{at:w,nodeId:r,inputKeys:u,status:"ok",output:A,idempotencyKey:o},nextPending:q?[]:sn,status:an,context:rn,joinCounters:U});this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:q?"completed":"ok",status:O?.status??m.status}),f.emitSignal&&this.emitSignal({name:f.emitSignal.name,scope:f.emitSignal.scope,workflowId:e.id,payload:f.emitSignal.payload}),q&&O&&O.parentRunId&&O.parentNodeId&&this.resumeParent({parentRunId:O.parentRunId,parentNodeId:O.parentNodeId,childRun:O}).catch(k=>this.log(`[workflow:${e.id}] resumeParent failed: ${k.message}`))})}async spawnChild(e){let t=this.store.list().find(a=>a.id===e.childWorkflowId);if(!t)return null;let r=Z(t);if(!r)return this.log(`[workflow:${t.id}] no trigger node \u2014 cannot spawn as child`),null;let i={...e.input};i[r.triggerId]={...i[r.triggerId]??{},parentRunId:e.parent.id,parentNodeId:e.parentNodeId};let o={backend:"agentx-internal",id:`subprocess:${e.parent.id}:${e.parentNodeId}`},s=this.runs.create({workflowId:t.id,initialPending:r.pending,entityRef:o,initialContext:i,parentRunId:e.parent.id,parentNodeId:e.parentNodeId,rootRunId:e.parent.rootRunId??e.parent.id,depth:(e.parent.depth??0)+1});return this.log(`[workflow:${t.id}] child run ${s.id} spawned from ${e.parent.id}/${e.parentNodeId} (depth ${s.depth})`),s}kickChildWalk(e){let t=this.store.list().find(r=>r.id===e.workflowId);t&&this.walk(t,e.id,`spawn:${e.parentRunId}:${e.parentNodeId}`).catch(r=>this.log(`[workflow:${t.id}] child walk failed: ${r.message}`))}async resumeParent(e){let t=this.runs.get(e.parentRunId);if(!t)return;let r=this.store.list().find(i=>i.id===t.workflowId);r&&(await this.commit(e.parentRunId,()=>{let i=this.runs.get(e.parentRunId);if(!i||i.status!=="paused"||!i.pausedAt||i.pausedAt.kind!=="subProcess"||i.pausedAt.nodeId!==e.parentNodeId||i.pausedAt.childRunId!==e.childRun.id)return;let o=P(r,e.parentNodeId),s=o?r.edges.filter(d=>d.from===o.id).map(d=>d.to):[],a={childRunId:e.childRun.id,status:e.childRun.status,output:Dr(e.childRun)};this.runs.recordExecution({runId:i.id,entry:{at:new Date().toISOString(),nodeId:e.parentNodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:N(i.id,e.parentNodeId,`child:${e.childRun.id}`)},nextPending:s,status:"running",pausedAt:null,context:{...i.context,[e.parentNodeId]:a}}),this.log(`[workflow:${r.id}] parent run ${i.id} resumed from subProcess child ${e.childRun.id}`),this.emitRunEvent({runId:i.id,workflowId:r.id,nodeId:e.parentNodeId,phase:"resumed",status:"running",note:`child:${e.childRun.id}`,rootId:i.eventRootId})}),this.walk(r,e.parentRunId,`child:${e.childRun.id}`))}};function Dr(n){for(let e=n.history.length-1;e>=0;e--){let t=n.history[e];if(t.status==="ok"&&t.output&&Object.keys(t.output).length>0)return t.output}return{}}function Wr(n,e,t){let r=o=>{let s=n[o];if(s===void 0||s===""||s==="*")return!0;if(Array.isArray(s)){let a=new Set(e.labels??[]);return s.some(d=>a.has(String(d)))}return o==="chat"?ne(e.source,String(s))===ne(e.source,e.chat):e[o]===s};if(!r("source")||!r("project")||!r("repo")||!r("chat"))return!1;let i=n.eventIdLike;return!(typeof i=="string"&&i&&!t.id.includes(i))}function ne(n,e){return e==null?"":n==="whatsapp-message"?e.replace(/@s\.whatsapp\.net$|@g\.us$/i,"").replace(/[\s+()]/g,""):e}function Fr(n){return{"pre:channel-message":async e=>{let t=e.msg;if(!t)return{};let r=Cr(t.channel);if(!r)return{};let i=t.group?.id??t.sender.id,o={backend:t.channel,id:`${t.channel}:${i}`},{claimed:s}=await n.dispatch({trigger:{source:r,chat:i},entityRef:o,event:{id:`${t.channel}:${t.accountId}:${t.id}`,payload:Mr(t)}});return s.length===0?{}:s.every(d=>d.nodes.find(u=>u.type.startsWith("trigger."))?.config?.passthrough===!0)?{}:{blocked:!0,message:`handled by workflow${s.length>1?"s":""}: ${s.map(d=>d.id).join(", ")}`}},"on:gitlab-issue":async e=>{let t=e.project,r=e.iid,i=e.issueEvent;if(!t||r===void 0)return{};let o=Array.isArray(i?.object_attributes?.labels)?i.object_attributes.labels.map(d=>typeof d=="string"?d:d?.title).filter(Boolean):i?.labels?.map(d=>d?.title)??[],s=i?.assignees??i?.object_attributes?.assignee_ids??[],a={backend:"gitlab",id:`${t}#${r}`};return await n.dispatch({trigger:{source:"gitlab-issue",project:t,labels:o},entityRef:a,event:{id:`gitlab-issue:${t}:${r}:${i?.object_attributes?.updated_at||i?.object_attributes?.action||"evt"}`,payload:{issue:{iid:r,title:i?.object_attributes?.title,description:i?.object_attributes?.description,url:i?.object_attributes?.url,action:i?.object_attributes?.action,labels:o,assignees:s},project:t,channel:"gitlab",chatId:`${t}:issue:${r}`}}}),{}},"on:gitlab-mr":async e=>{let t=e.project,r=e.iid,i=e.mrEvent;if(!t||r===void 0)return{};let o=Array.isArray(e.labels)?e.labels:Array.isArray(i?.object_attributes?.labels)?i.object_attributes.labels.map(c=>typeof c=="string"?c:c?.title).filter(Boolean):[],s=i?.assignees??i?.object_attributes?.assignee_ids??[],a=i?.reviewers??[],d={backend:"gitlab",id:`${t}!${r}`};return await n.dispatch({trigger:{source:"gitlab-mr",project:t,labels:o},entityRef:d,event:{id:`gitlab-mr:${t}:${r}:${i?.object_attributes?.updated_at||i?.object_attributes?.action||"evt"}`,payload:{mr:{iid:r,title:e.title,description:e.description,url:e.url,action:e.action,state:e.state,source_branch:e.source_branch,target_branch:e.target_branch,labels:o,assignees:s,reviewers:a},project:t,channel:"gitlab",chatId:`${t}:merge_request:${r}`,iid:r,title:e.title,description:e.description,url:e.url,action:e.action,state:e.state,source_branch:e.source_branch,target_branch:e.target_branch,labels:o}}}),{}},"on:gitlab-note":async e=>{let t=e.project,r=e.noteId,i=e.noteableType,o=e.noteableIid,s=e.text,a=e.authorUsername,d=e.mentions??[];if(!t||!r||!i||!o)return{};let c=i==="merge_request"?{backend:"gitlab",id:`${t}!${o}`}:{backend:"gitlab",id:`${t}#${o}`};return await n.dispatch({trigger:{source:"gitlab-note",project:t},entityRef:c,event:{id:`gitlab-note:${t}:${i}:${o}:${r}`,payload:{note:{id:r,text:s,author:a,mentions:d,noteableType:i,noteableIid:o,noteableTitle:e.noteableTitle},project:t,channel:"gitlab",chatId:`${t}:${i}:${o}`,noteId:r,noteableType:i,noteableIid:o,text:s,author:a,mentions:d}}}),{}},"on:gitlab-pipeline":async e=>{let t=e.project,r=e.pipelineId,i=e.status,o=e.ref;if(!t||!i)return{};let a=e.raw?.merge_request?.iid;if(!a)return{};let d={backend:"gitlab",id:`${t}!${a}`};return await n.dispatch({trigger:{source:"gitlab-pipeline",project:t},entityRef:d,event:{id:`gitlab-pipeline:${t}:${r}:${i}`,payload:{pipeline:{id:r,status:i,ref:o},project:t,channel:"gitlab",chatId:`${t}:merge_request:${a}`}}}),{}}}}function Cr(n){switch(n){case"telegram":return"telegram-message";case"whatsapp":return"whatsapp-message";case"discord":return"discord-message";case"slack":return"slack-message";default:return null}}function Mr(n){let e=n.group?.id??n.sender.id;return{channel:n.channel,chatId:e,accountId:n.accountId,text:n.text,fromJid:n.sender.id,sender:{id:n.sender.id,name:n.sender.name,username:n.sender.username},contact:n.channelMeta?.facts?{facts:n.channelMeta.facts}:void 0,group:n.group?{id:n.group.id,name:n.group.name}:void 0,channelMeta:n.channelMeta,replyTo:n.replyTo,replyToText:n.replyToText,media:n.media,event:{id:n.id,timestamp:n.timestamp?.toISOString?.()??new Date().toISOString()}}}var re=n=>n.trim().toLowerCase().replace(/^@/,"");function Lr(n){let e=typeof n.author=="string"?n.author:typeof n.authorUsername=="string"?n.authorUsername:void 0;if(e)return re(e);let r=n.payload?.sender?.login;return typeof r=="string"&&r?re(r):void 0}function jr(n,e){let t=typeof e.project=="string"?e.project:"";if(n==="on:gitlab-issue"||n==="on:gitlab-mr")return!t||e.iid==null?void 0:`gitlab:${t}${n==="on:gitlab-issue"?"#":"!"}${String(e.iid)}`;if(n==="on:gitlab-note"){let r=e.noteableIid!=null?String(e.noteableIid):"",i=typeof e.noteableType=="string"?e.noteableType:"";return!t||!r||!i?void 0:`gitlab:${t}${i==="issue"?"#":"!"}${r}`}if(n==="on:github-issue"||n==="on:github-pr"){let r=e.payload??{},i=typeof e.repo=="string"?e.repo:r.repository?.full_name,o=e.number??r.issue?.number??r.pull_request?.number;return typeof i!="string"||!i||o==null?void 0:`github:${i}#${String(o)}`}}function Hr(n){let e=new Set;for(let t of n.nodes){let r=t.type==="agent"?t.config.agentId:void 0;typeof r=="string"&&r&&e.add(r)}return[...e]}var ie=class{constructor(e=2e3){this.maxKeys=e}fires=new Map;tryFire(e,t,r,i=Date.now()){let o=(this.fires.get(e)??[]).filter(s=>i-s<r);if(o.length>=t)return this.fires.set(e,o),!1;for(o.push(i),this.fires.delete(e),this.fires.set(e,o);this.fires.size>this.maxKeys;){let s=this.fires.keys().next().value;if(s===void 0)break;this.fires.delete(s)}return!0}get size(){return this.fires.size}};function Pe(n,e,t){let r=n.logged??(n.logged=new Set);r.has(e)||(r.add(e),n.log(t))}function Ut(n,e,t,r,i){let o=Lr(t);if(o&&Array.isArray(r?.ignoreAuthors)&&r.ignoreAuthors.length>0&&r.ignoreAuthors.map(re).includes(o))return{skip:!0,reason:"ignored-author",detail:`author @${o} is in filter.ignoreAuthors`};if(r?.skipSelfAuthored===!0){let a=Hr(n),d=typeof t.authorAgent=="string"?t.authorAgent:void 0;if(d&&a.includes(d))return{skip:!0,reason:"self-authored",detail:`author @${o??"?"} is agent "${d}" which this workflow runs`};if(o){let c=new Set(a.flatMap(u=>(i.forgeUsernames?.(u)??[]).map(re)));if(c.has(o))return{skip:!0,reason:"self-authored",detail:`author @${o} is this workflow's own bot identity`};a.length===0?Pe(i,`noagents:${n.id}`,`[workflows] ${n.id} has no agent node \u2014 self-authored skip can't resolve a bot identity; only filter.ignoreAuthors applies`):c.size===0&&!("authorAgent"in t)&&Pe(i,`noident:${n.id}:${e}`,`[workflows] ${n.id} no forge username known for agent(s) ${a.join(", ")} on ${e} \u2014 self-authored skip inactive; only filter.ignoreAuthors applies`)}}let s=r?.maxFiresPerTarget;if(s&&typeof s.count=="number"&&s.count>0){let a=jr(e,t);if(a){let d=typeof s.windowMinutes=="number"&&s.windowMinutes>0?s.windowMinutes:60,c=i.now?.()??Date.now();if(!i.fireWindow.tryFire(`${n.id}|${a}`,s.count,d*6e4,c))return{skip:!0,reason:"chain-limit",detail:`${a} already fired ${s.count}x within ${d}m (filter.maxFiresPerTarget)`}}else Pe(i,`notarget:${n.id}:${e}`,`[workflows] ${n.id} filter.maxFiresPerTarget has no target key for ${e} \u2014 limit not applied`)}return{skip:!1}}function Ur(n){let e=n.store.list(),t={fireWindow:new ie,log:n.log,forgeUsernames:n.forgeUsernames,logged:new Set},r=0,i=0;for(let o of e){if(o.state&&o.state!=="active"){n.log(`[workflows] ${o.id} state=${o.state} \u2014 skipping trigger registration`);continue}let s=o.nodes.find(a=>a.type.startsWith("trigger."));if(s){if(s.type==="trigger.cron"){let a=s.config;if(!a.spec){n.log(`[workflows] ${o.id} trigger.cron missing config.spec \u2014 skipping`);continue}Br({workflowId:o.id,triggerNodeId:s.id,spec:a.spec,timezone:a.timezone??"UTC"},n.dispatcher,n.log),r++}else if(s.type==="trigger.hook"){let a=s.config;if(!a.event||!a.event.startsWith("on:")){n.log(`[workflows] ${o.id} trigger.hook config.event must start with "on:" \u2014 skipping`);continue}n.hooks.registerHandler(a.event,`workflows:${o.id}`,async d=>{try{let c=typeof d.project=="string"?d.project:void 0;if(o.project&&c&&o.project!==c)return{};if(a.filter){if(Array.isArray(a.filter.topic)&&a.filter.topic.length>0){let h=typeof d.topic=="string"?d.topic.toLowerCase():void 0;if(!h||!a.filter.topic.map(m=>m.toLowerCase()).includes(h))return{}}if(Array.isArray(a.filter.action)&&a.filter.action.length>0){let h=typeof d.action=="string"?d.action:void 0;if(!h||!a.filter.action.includes(h))return{}}if(Array.isArray(a.filter.mentions)&&a.filter.mentions.length>0){let h=Array.isArray(d.mentions)?d.mentions.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.mentions.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.noteableType)&&a.filter.noteableType.length>0){let h=typeof d.noteableType=="string"?d.noteableType.toLowerCase():void 0,m=a.filter.noteableType.map(w=>w.toLowerCase());if(!h||!m.includes(h))return{}}if(Array.isArray(a.filter.assigneesAdded)&&a.filter.assigneesAdded.length>0){let h=Array.isArray(d.assigneesAdded)?d.assigneesAdded.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.assigneesAdded.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.reviewersAdded)&&a.filter.reviewersAdded.length>0){let h=Array.isArray(d.reviewersAdded)?d.reviewersAdded.map(y=>y.toLowerCase().replace(/^@/,"")):[];if(!a.filter.reviewersAdded.map(y=>y.toLowerCase().replace(/^@/,"")).some(y=>h.includes(y)))return{}}if(Array.isArray(a.filter.labelsAdded)&&a.filter.labelsAdded.length>0){let h=Array.isArray(d.labelsAdded)?d.labelsAdded.map(y=>y.toLowerCase()):[];if(!a.filter.labelsAdded.map(y=>y.toLowerCase()).some(y=>h.includes(y)))return{}}}let u=Ut(o,a.event,d,a.filter,t);if(u.skip){if(n.log(`[workflows] ${o.id} skipping ${a.event} (${u.reason}): ${u.detail}`),a.passthrough)return{};let h=d.__workflowClaimed;return{modified:{__workflowClaimed:[...Array.isArray(h)?h:[],o.id]}}}let p=qr(o.id,a.event,d);if(await n.dispatcher.dispatchWorkflow({workflowId:o.id,entityRef:{backend:"hook",id:p},event:{id:`hook:${a.event}:${Date.now().toString(36)}`,payload:{hookEvent:a.event,...d}}}),a.passthrough)return{};let g=d.__workflowClaimed;return{modified:{__workflowClaimed:[...Array.isArray(g)?g:[],o.id]}}}catch(c){return n.log(`[workflows] ${o.id} hook dispatch failed: ${c.message}`),{}}},60),i++}}}return{cronTimers:r,hookSubscribers:i}}function qr(n,e,t){let r=typeof t.project=="string"?t.project:"",i=t.iid!=null?String(t.iid):"";if(e==="on:gitlab-issue"&&r&&i)return`${n}:${e}:${r}#${i}`;if(e==="on:gitlab-mr"&&r&&i)return`${n}:${e}:${r}!${i}`;if(e==="on:gitlab-pipeline"&&r){let o=t.pipelineId!=null?String(t.pipelineId):"";if(o)return`${n}:${e}:${r}@pipeline:${o}`}return`${n}:${e}:${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Br(n,e,t){let r=()=>{let i;try{i=it(n.spec,new Date,n.timezone)}catch(s){t(`[workflows] ${n.workflowId} cron spec invalid: ${s.message}`);return}let o=Math.max(1e3,i.getTime()-Date.now());setTimeout(()=>{(async()=>{let s=`cron:${n.workflowId}:${i.toISOString()}`;try{await e.dispatchWorkflow({workflowId:n.workflowId,trigger:{source:"cron"},entityRef:{backend:"cron",id:`${n.workflowId}@${i.toISOString()}`},event:{id:s,payload:{now:i.toISOString(),spec:n.spec,workflowId:n.workflowId}}})}catch(a){t(`[workflows] ${n.workflowId} cron dispatch failed: ${a.message}`)}finally{r()}})()},o)};r()}import{createHash as Kr}from"crypto";import{existsSync as zr,mkdirSync as Yr,readFileSync as Jr,renameSync as Gr,writeFileSync as Xr}from"fs";import{resolve as qt}from"path";import{z as j}from"zod";var Bt=j.object({actionId:j.string().min(1),everySeconds:j.number().int().min(5).max(86400).default(60),key:j.string().min(1).default("id"),filter:j.array(fe).default([]),maxPerPoll:j.number().int().min(1).max(500).default(20)}),Vr=5e3,Zr=30;async function Qr(n){let e=new Ve().get(n);if(!e)throw new Error(`no action "${n}" in registry`);return Ze(e)}function Kt(n,e){let t=[],r=0;for(let i of n.split(`
20
+ `)){let o=i.trim();if(!o)continue;let s;try{s=JSON.parse(o)}catch{r++;continue}if(!s||typeof s!="object"||Array.isArray(s)){r++;continue}let a=M(s,e);if((typeof a!="string"||!a)&&typeof a!="number"){r++;continue}t.push({key:String(a),value:s})}return{items:t,skipped:r}}function ei(n,e){let t=`${n}:${e}`;return/^[a-zA-Z0-9._:@-]+$/.test(e)&&t.length<=200?t:`${n}:#${Kr("sha256").update(e).digest("hex").slice(0,32)}`}var Oe=class{constructor(e){this.opts=e;this.stateDir=qt(e.store.baseDir,"_poll"),this.runAction=e.runAction??Qr}timers=new Map;warned=new Map;stateDir;runAction;resync;start(){return this.resync??=setInterval(()=>{try{this.sync()}catch(e){this.opts.log(`[workflows] poll sync failed: ${e.message}`)}},Zr*1e3),this.sync()}sync(){let e=new Map;for(let t of this.opts.store.list()){let r=this.configOf(t);r&&e.set(t.id,r)}for(let[t,r]of this.timers)e.has(t)||(clearTimeout(r),this.timers.delete(t),this.opts.log(`[workflows] ${t} poll stopped`));for(let[t,r]of e)this.timers.has(t)||(this.schedule(t,r.everySeconds),this.opts.log(`[workflows] ${t} polls action "${r.actionId}" every ${r.everySeconds}s`));return this.timers.size}stop(){this.resync&&clearInterval(this.resync),this.resync=void 0;for(let e of this.timers.values())clearTimeout(e);this.timers.clear()}async pollOnce(e){let t=this.opts.store.get(e),r=t?this.configOf(t):null;if(!r)return 0;let i;try{i=await this.runAction(r.actionId)}catch(g){return this.warnOnce(e,`poll failed: ${g.message}`),0}if(!i.ok)return this.warnOnce(e,`poll failed (status=${i.status??"?"}): ${(i.errors??"").slice(0,200)}`),0;let{items:o,skipped:s}=Kt(i.output,r.key);this.warnOnce(e,s>0?`poll skipped ${s} line(s) that are not a JSON object with "${r.key}"`:"");let a=new Set(o.map(g=>g.key)),d=this.readState(e);if(!d||d.actionId!==r.actionId||d.key!==r.key)return this.writeState(e,{actionId:r.actionId,key:r.key,seen:[...a]},a),this.opts.log(`[workflows] ${e} poll baseline: ${a.size} existing item(s) recorded, no runs started`),0;let c=new Set(d.seen),u=0,p=!1;for(let g of o){if(c.has(g.key))continue;let f=r.filter.every(h=>V(h,g.value));if(!(f&&u>=r.maxPerPoll)){if(c.add(g.key),d.seen.push(g.key),!f){p=!0;continue}this.writeState(e,d,a),p=!1;try{let{run:h}=await this.opts.dispatcher.dispatchWorkflow({workflowId:e,trigger:{source:"poll"},entityRef:{backend:"poll",id:ei(e,g.key)},event:{id:`poll:${e}:${g.key}`,payload:g.value}});h?u++:this.opts.log(`[workflows] ${e} poll item "${g.key}" started no run`)}catch(h){this.opts.log(`[workflows] ${e} poll dispatch failed for "${g.key}": ${h.message}`)}}}return p&&this.writeState(e,d,a),u}schedule(e,t){let r=setTimeout(()=>{(async()=>{try{await this.pollOnce(e)}catch(s){this.opts.log(`[workflows] ${e} poll failed: ${s.message}`)}if(this.timers.get(e)!==r)return;let i=this.opts.store.get(e),o=i?this.configOf(i):null;o?this.schedule(e,o.everySeconds):this.timers.delete(e)})()},t*1e3);this.timers.set(e,r)}configOf(e){if(e.state&&e.state!=="active")return null;let t=e.nodes.find(i=>i.type.startsWith("trigger."));if(!t||t.type!=="trigger.poll")return null;let r=Bt.safeParse(t.config);if(!r.success){let i=r.error.issues.map(o=>`${o.path.join(".")||"config"}: ${o.message}`).join("; ");return this.warnOnce(e.id,`trigger.poll config invalid, not polling (${i})`),null}return r.data}warnOnce(e,t){this.warned.get(e)!==t&&(this.warned.set(e,t),t&&this.opts.log(`[workflows] ${e} ${t}`))}statePath(e){return qt(this.stateDir,`${e}.json`)}readState(e){let t=this.statePath(e);if(!zr(t))return null;try{let r=JSON.parse(Jr(t,"utf-8"));return typeof r.actionId!="string"||typeof r.key!="string"||!Array.isArray(r.seen)?null:{actionId:r.actionId,key:r.key,seen:r.seen.map(String)}}catch{return null}}writeState(e,t,r){let i=t.seen.length-Vr;i>0&&(t.seen=t.seen.filter(s=>r.has(s)||i--<=0)),Yr(this.stateDir,{recursive:!0});let o=this.statePath(e);Xr(`${o}.tmp`,JSON.stringify(t)),Gr(`${o}.tmp`,o)}};function zt(n){return n.nodes.find(r=>r.type.startsWith("trigger."))?.config?.inputSchema??null}function Yt(n,e){if(!n||!e?.properties)return{};let t=n.match(/^([^:]+\/[^:]+):([^:]+):(.+)$/);if(!t)return{};let[,r,i,o]=t,s={};if(e.properties.project&&(s.project=r),i==="push"){let a=o.match(/^refs\/heads\/(.+)$/);a&&e.properties.ref&&(s.ref=a[1])}else{let a=Number(o);Number.isFinite(a)&&(e.properties.id&&(s.id=a),e.properties.iid&&(s.iid=a),e.properties.mrId&&(s.mrId=a),e.properties.issueId&&(s.issueId=a),e.properties.prId&&(s.prId=a))}return s}function Jt(n,e){if(!n?.properties)return e;let t={...e};for(let[r,i]of Object.entries(n.properties))t[r]===void 0&&i&&"default"in i&&(t[r]=i.default);return t}function Gt(n,e){return!n?.required||!Array.isArray(n.required)?[]:n.required.filter(t=>{let r=e[t];return r===void 0||r===""||r===null})}function ni(n,e){let t=zt(n);if(!t?.properties){let d={};for(let[c,u]of Object.entries(e))u!==void 0&&(d[c]=u);return{inputs:d,missing:[],filledFrom:{passthrough:Object.keys(d),chatId:[],defaults:[]}}}let r={};for(let d of["message","agentId","channel","chatId","senderId","senderUsername"])t.properties[d]&&e[d]!==void 0&&(r[d]=e[d]);let i=Yt(e.chatId,t),o={...r,...i},s={...o};o=Jt(t,o);let a=Object.keys(o).filter(d=>s[d]===void 0&&o[d]!==void 0);return{inputs:o,missing:Gt(t,o),filledFrom:{passthrough:Object.keys(r),chatId:Object.keys(i),defaults:a}}}import{extname as ri}from"path";var Xt=/<agentx-artifact>([\s\S]*?)<\/agentx-artifact>/gi,Vt=/<agentx-artifact>[\s\S]*$/i;function ys(n,e=1/0,t=!1){let r=[],i=String(n??"");if(!/<agentx-artifact>/i.test(i))return{text:i,artifacts:r};let o=i.replace(Xt,(s,a)=>{try{let d=JSON.parse(a.trim());if(d&&typeof d.filename=="string"&&typeof d.mime=="string"&&r.length<e){let c=d.mime,u=c.startsWith("image/")?"image":c==="application/pdf"?"pdf":c.startsWith("text/")?"text":"file";r.push({type:u,filename:d.filename,mime:c})}}catch{}return""});return{text:(t?o.replace(Vt,""):o).trim(),artifacts:r}}function ws(n,e=!1){let t=String(n??""),r=t;if(/<agentx-artifact>/i.test(t)){let i=t.replace(Xt,(o,s)=>{try{let a=JSON.parse(s.trim());return a&&typeof a.filename=="string"?a.filename:""}catch{return""}});r=(e?i.replace(Vt,""):i).trim()}return r.replace(/```[\s\S]*?```|`[^`\n]*`|!\[([^\]\n]*)\]\(([^)\s]+)\)/g,(i,o,s)=>o===void 0||s===void 0?i:`[${o||s}](${s})`)}var ii={".png":{mime:"image/png",kind:"image"},".jpg":{mime:"image/jpeg",kind:"image"},".jpeg":{mime:"image/jpeg",kind:"image"},".gif":{mime:"image/gif",kind:"image"},".webp":{mime:"image/webp",kind:"image"},".svg":{mime:"image/svg+xml",kind:"file"},".pdf":{mime:"application/pdf",kind:"file"},".txt":{mime:"text/plain; charset=utf-8",kind:"file"},".md":{mime:"text/markdown; charset=utf-8",kind:"file"},".csv":{mime:"text/csv; charset=utf-8",kind:"file"},".json":{mime:"application/json",kind:"file"},".mp3":{mime:"audio/mpeg",kind:"audio"},".m4a":{mime:"audio/mp4",kind:"audio"},".wav":{mime:"audio/wav",kind:"audio"},".mp4":{mime:"video/mp4",kind:"video"},".webm":{mime:"video/webm",kind:"video"}},ks={bytes:20*1024*1024,perMessage:20,pathChars:512};function bs(n){return ii[ri(n).toLowerCase()]??null}var oi=["[Phone app: showing files]","To show the owner a file you created (a chart, a screenshot, a PDF, a recording), save or copy it into .agentx/outbox/ in your workspace and end your reply with one line per file:",'<agentx-artifact>{"filename":".agentx/outbox/<name.ext>","mime":"<mime/type>"}</agentx-artifact>',"Files outside your workspace (/tmp, your home folder) are refused. Outbox files are removed after 7 days.","The line is removed from the text. Images show in the reply, audio and video get a player, other files an Open link. Allowed: png, jpg, gif, webp, svg, pdf, txt, md, csv, json, mp3, m4a, wav, mp4, webm; up to 20 MB and 20 files per reply.","A picture already on the web can go inline as ![what it shows](https://...)."].join(`
21
+ `);function vs(n,e,t){return n==="app"&&e&&t!==!1?oi:void 0}import{lstatSync as De,mkdirSync as si,readdirSync as ai,realpathSync as _e,unlinkSync as di}from"fs";import{join as oe,resolve as Zt}from"path";var Qt=".agentx/outbox",ci=7*24*60*60*1e3;function li(n,e){try{let t=_e(Zt(e,n)),r=oe(t,Qt);return _e(r)===r&&De(r).isDirectory()?r:null}catch{return null}}function As(n,e={}){let t=e.cwd??process.cwd();if(e.create!==!1)try{let i=_e(Zt(t,n));De(oe(i,".agentx"),{throwIfNoEntry:!1})?.isSymbolicLink()||si(oe(i,Qt),{recursive:!0})}catch{return 0}let r=li(n,t);return r?en(r,(e.now??Date.now())-(e.maxAgeMs??ci)):0}function en(n,e){let t=0;for(let r of ai(n)){let i=oe(n,r);try{let o=De(i);o.isDirectory()?t+=en(i,e):Math.max(o.mtimeMs,o.ctimeMs)<e&&(di(i),t++)}catch{}}return t}var tn=["in_progress","waiting_owner","waiting_other","needs_attention"],$=["done","declined","dropped"];function ui(n){if(n.exec(`
22
22
  CREATE TABLE IF NOT EXISTS requests (
23
23
  id TEXT PRIMARY KEY,
24
24
  state TEXT NOT NULL,
@@ -47,11 +47,11 @@ import{b as nt,c as rt}from"./chunk-WP6KLXTP.js";import{a as ae}from"./chunk-N6E
47
47
  FOREIGN KEY (request_id) REFERENCES requests(id) ON DELETE CASCADE
48
48
  );
49
49
  CREATE INDEX IF NOT EXISTS idx_request_links_request ON request_links(request_id);
50
- `),r.prepare("PRAGMA table_info(requests)").all().some(t=>t.name==="pickup_at")||r.exec("ALTER TABLE requests ADD COLUMN pickup_at INTEGER")}function D(r){return{id:r.id,state:r.state,channel:r.channel,chatId:r.chat_id,sender:r.sender??null,agentId:r.agent_id,text:r.text,createdAt:r.created_at,updatedAt:r.updated_at,attentionReason:r.attention_reason??null,notifiedAt:r.notified_at??null,question:r.question??null,closedAt:r.closed_at??null,evidence:r.evidence??null,closeReason:r.close_reason??null}}var W=r=>Array(r).fill("?").join(","),nn=class{constructor(e){this.db=e;ui(e),e.pragma("foreign_keys = ON")}addCandidate(e){this.db.prepare(`INSERT OR IGNORE INTO requests (id, state, channel, chat_id, sender, agent_id, text, created_at, updated_at)
51
- VALUES (?, 'candidate', ?, ?, ?, ?, ?, ?, ?)`).run(e.id,e.channel,e.chatId,e.sender??null,e.agentId,e.text.slice(0,4e3),e.now,e.now),this.link(e.id,"run",e.runId,e.now)}get(e){let t=this.db.prepare("SELECT * FROM requests WHERE id = ?").get(e);return t?D(t):null}byLink(e,t){let n=this.db.prepare("SELECT r.* FROM requests r JOIN request_links l ON l.request_id = r.id WHERE l.kind = ? AND l.ref = ?").get(e,t);return n?D(n):null}link(e,t,n,i){this.db.prepare("INSERT OR IGNORE INTO request_links (request_id, kind, ref, at) VALUES (?, ?, ?, ?)").run(e,t,n,i)}links(e){return this.db.prepare("SELECT kind, ref, at FROM request_links WHERE request_id = ? ORDER BY at, rowid").all(e)}touch(e,t){this.db.prepare("UPDATE requests SET updated_at = ? WHERE id = ?").run(t,e)}progress(e,t,n="in_progress"){this.db.prepare(`UPDATE requests SET state = ?, updated_at = ?, attention_reason = NULL, notified_at = NULL, question = NULL
52
- WHERE id = ? AND state NOT IN (${W($.length)})`).run(n,t,e,...$)}waitOnOwner(e,t,n){this.db.prepare(`UPDATE requests SET state = 'waiting_owner', updated_at = ?, question = ?, attention_reason = NULL, notified_at = NULL
53
- WHERE id = ? AND state NOT IN (${W($.length)})`).run(n,t.slice(0,4e3),e,...$)}needsAttention(e,t,n){return this.db.prepare(`UPDATE requests SET state = 'needs_attention', updated_at = ?, attention_reason = ?, notified_at = NULL
54
- WHERE id = ? AND state NOT IN ('needs_attention', ${W($.length)})`).run(n,t.replace(/\s+/g," ").trim().slice(0,500),e,...$).changes>0}close(e,t,n,i){let o=n.trim();if(!o)throw new Error(t==="done"?"a finished request needs a link to the evidence":`a ${t} request needs a reason`);return this.db.prepare(`UPDATE requests SET state = ?, closed_at = ?, updated_at = ?, evidence = ?, close_reason = ?
50
+ `),!n.prepare("PRAGMA table_info(requests)").all().some(t=>t.name==="pickup_at"))try{n.exec("ALTER TABLE requests ADD COLUMN pickup_at INTEGER")}catch(t){if(!/duplicate column name/i.test(String(t?.message)))throw t}}function Ts(n){return!!n.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'requests'").get()}function D(n){return{id:n.id,state:n.state,channel:n.channel,chatId:n.chat_id,sender:n.sender??null,agentId:n.agent_id,text:n.text,createdAt:n.created_at,updatedAt:n.updated_at,attentionReason:n.attention_reason??null,notifiedAt:n.notified_at??null,question:n.question??null,closedAt:n.closed_at??null,evidence:n.evidence??null,closeReason:n.close_reason??null}}var W=n=>Array(n).fill("?").join(","),nn=class{constructor(e){this.db=e;ui(e),e.pragma("foreign_keys = ON")}addCandidate(e){this.db.prepare(`INSERT OR IGNORE INTO requests (id, state, channel, chat_id, sender, agent_id, text, created_at, updated_at)
51
+ VALUES (?, 'candidate', ?, ?, ?, ?, ?, ?, ?)`).run(e.id,e.channel,e.chatId,e.sender??null,e.agentId,e.text.slice(0,4e3),e.now,e.now),this.link(e.id,"run",e.runId,e.now)}get(e){let t=this.db.prepare("SELECT * FROM requests WHERE id = ?").get(e);return t?D(t):null}byLink(e,t){let r=this.db.prepare("SELECT r.* FROM requests r JOIN request_links l ON l.request_id = r.id WHERE l.kind = ? AND l.ref = ?").get(e,t);return r?D(r):null}link(e,t,r,i){this.db.prepare("INSERT OR IGNORE INTO request_links (request_id, kind, ref, at) VALUES (?, ?, ?, ?)").run(e,t,r,i)}links(e){return this.db.prepare("SELECT kind, ref, at FROM request_links WHERE request_id = ? ORDER BY at, rowid").all(e)}touch(e,t){this.db.prepare("UPDATE requests SET updated_at = ? WHERE id = ?").run(t,e)}progress(e,t,r="in_progress"){this.db.prepare(`UPDATE requests SET state = ?, updated_at = ?, attention_reason = NULL, notified_at = NULL, question = NULL
52
+ WHERE id = ? AND state NOT IN (${W($.length)})`).run(r,t,e,...$)}waitOnOwner(e,t,r){this.db.prepare(`UPDATE requests SET state = 'waiting_owner', updated_at = ?, question = ?, attention_reason = NULL, notified_at = NULL
53
+ WHERE id = ? AND state NOT IN (${W($.length)})`).run(r,t.slice(0,4e3),e,...$)}needsAttention(e,t,r){return this.db.prepare(`UPDATE requests SET state = 'needs_attention', updated_at = ?, attention_reason = ?, notified_at = NULL
54
+ WHERE id = ? AND state NOT IN ('needs_attention', ${W($.length)})`).run(r,t.replace(/\s+/g," ").trim().slice(0,500),e,...$).changes>0}close(e,t,r,i){let o=r.trim();if(!o)throw new Error(t==="done"?"a finished request needs a link to the evidence":`a ${t} request needs a reason`);return this.db.prepare(`UPDATE requests SET state = ?, closed_at = ?, updated_at = ?, evidence = ?, close_reason = ?
55
55
  WHERE id = ? AND state NOT IN (${W($.length)})`).run(t,i,i,t==="done"?o.slice(0,500):null,t==="done"?null:o.slice(0,500),e,...$).changes>0}discardCandidate(e){return this.db.prepare("DELETE FROM requests WHERE id = ? AND state = 'candidate'").run(e).changes>0}listOpen(){return this.db.prepare(`SELECT * FROM requests WHERE state IN (${W(tn.length)}) ORDER BY created_at, rowid`).all(...tn).map(D)}quietSince(e,t){return this.db.prepare(`SELECT * FROM requests WHERE state IN (${W(e.length)}) AND updated_at < ? ORDER BY created_at, rowid`).all(...e,t).map(D)}awaitingNotice(){return this.db.prepare("SELECT * FROM requests WHERE state = 'needs_attention' AND notified_at IS NULL ORDER BY created_at, rowid").all().map(D)}markNotified(e,t){this.db.prepare("UPDATE requests SET notified_at = ? WHERE id = ?").run(t,e)}listByState(e){return this.db.prepare("SELECT * FROM requests WHERE state = ? ORDER BY created_at, rowid").all(e).map(D)}requestPickup(e,t){return this.db.prepare(`UPDATE requests SET state = 'in_progress', updated_at = ?, attention_reason = NULL, notified_at = NULL, pickup_at = ?
56
- WHERE id = ? AND state = 'needs_attention'`).run(t,t,e).changes>0}takePickups(){let e=this.db.prepare("SELECT * FROM requests WHERE pickup_at IS NOT NULL AND state = 'in_progress' ORDER BY created_at, rowid").all().map(D);return this.db.prepare("UPDATE requests SET pickup_at = NULL WHERE pickup_at IS NOT NULL").run(),e}pruneClosed(e){return this.db.prepare(`DELETE FROM requests WHERE state IN (${W($.length)}) AND closed_at < ?`).run(...$,e).changes}};export{at as a,mt as b,ht as c,Ti as d,$n as e,Ei as f,T as g,me as h,v as i,z as j,Ln as k,ke as l,ve as m,Ie as n,Ne as o,Fr as p,Ur as q,Oe as r,nr as s,ni as t,tn as u,nn as v,ys as w,ws as x,ks as y,bs as z,vs as A,Qt as B,As as C};
57
- //# sourceMappingURL=chunk-6TLQ4I32.js.map
56
+ WHERE id = ? AND state = 'needs_attention'`).run(t,t,e).changes>0}takePickups(){return this.db.prepare("UPDATE requests SET pickup_at = NULL WHERE pickup_at IS NOT NULL RETURNING *").all().map(D).filter(e=>e.state==="in_progress").sort((e,t)=>e.createdAt-t.createdAt)}pruneClosed(e){return this.db.prepare(`DELETE FROM requests WHERE state IN (${W($.length)}) AND closed_at < ?`).run(...$,e).changes}};export{at as a,mt as b,ht as c,Ti as d,$n as e,Ei as f,T as g,me as h,v as i,z as j,Mn as k,ke as l,ve as m,Re as n,Ne as o,Fr as p,Ur as q,Oe as r,nr as s,ni as t,tn as u,Ts as v,nn as w,ys as x,ws as y,ks as z,bs as A,vs as B,Qt as C,As as D};
57
+ //# sourceMappingURL=chunk-6JJ3GODZ.js.map