agentix-cli 0.30.0 → 0.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{App-IEQXWJ7B.js → App-2LAWZNMG.js} +2 -2
- package/dist/{ChatApp-NWOSAP5U.js → ChatApp-2KRDHMTV.js} +2 -2
- package/dist/{agent-SPE7Q7MD.js → agent-ZRRIMLTX.js} +2 -2
- package/dist/{board-dashboard-K4DM32SO.js → board-dashboard-LL3YVODL.js} +192 -171
- package/dist/board-dashboard-LL3YVODL.js.map +1 -0
- package/dist/{chunk-MGNJWBVP.js → chunk-2DBGOCCW.js} +2 -2
- package/dist/{chunk-MGNJWBVP.js.map → chunk-2DBGOCCW.js.map} +1 -1
- package/dist/chunk-2DMVKLLE.js +13 -0
- package/dist/chunk-2DMVKLLE.js.map +1 -0
- package/dist/chunk-2GIDVZ4H.js +3 -0
- package/dist/{chunk-EVWEG3VD.js.map → chunk-2GIDVZ4H.js.map} +1 -1
- package/dist/{chunk-UCQ2N3KO.js → chunk-2TJ5L7CB.js} +2 -2
- package/dist/{chunk-FKBGJYWQ.js → chunk-3RHPZXCR.js} +2 -2
- package/dist/{chunk-DI7FMCDK.js → chunk-4CR463C6.js} +2 -2
- package/dist/{chunk-IVQO43U2.js → chunk-5FEQI22L.js} +2 -2
- package/dist/{chunk-45BLFNDG.js → chunk-6VQKHMEQ.js} +47 -47
- package/dist/chunk-6VQKHMEQ.js.map +1 -0
- package/dist/{chunk-52ZPELD2.js → chunk-7CVJ4JOE.js} +2 -2
- package/dist/{chunk-4KXBUORV.js → chunk-A4YR3PQY.js} +2 -2
- package/dist/{chunk-Q7CZIRBB.js → chunk-B2XTYYXV.js} +2 -2
- package/dist/{chunk-JKYMXLYL.js → chunk-G5MFPNGJ.js} +2 -2
- package/dist/{chunk-EL3J74N2.js → chunk-GWQIMAJ7.js} +2 -2
- package/dist/{chunk-42DCRKUD.js → chunk-H57XXGMF.js} +96 -94
- package/dist/chunk-H57XXGMF.js.map +1 -0
- package/dist/{chunk-V4HURNMX.js → chunk-JGJE5Y2J.js} +2 -2
- package/dist/{chunk-SC5DIKBB.js → chunk-JWKIFAXA.js} +2 -2
- package/dist/{chunk-UU4WOZNR.js → chunk-K6E7WJ7O.js} +2 -2
- package/dist/{chunk-AUNDQPDR.js → chunk-MFVI5FOM.js} +2 -2
- package/dist/{chunk-M4AMWP3H.js → chunk-QLTM3F7M.js} +17 -8
- package/dist/{chunk-M4AMWP3H.js.map → chunk-QLTM3F7M.js.map} +1 -1
- package/dist/{chunk-IWMW5432.js → chunk-V7FYSZSV.js} +1 -1
- package/dist/{chunk-IWMW5432.js.map → chunk-V7FYSZSV.js.map} +1 -1
- package/dist/chunk-VMDA2SX2.js +43 -0
- package/dist/chunk-VMDA2SX2.js.map +1 -0
- package/dist/{chunk-GK7XAM3D.js → chunk-W3YGESNK.js} +2 -2
- package/dist/{chunk-GUBMLV34.js → chunk-WFIBOAXN.js} +8 -8
- package/dist/chunk-WFIBOAXN.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/client-IP643GRO.js +2 -0
- package/dist/config-IVDP46ZG.js +2 -0
- package/dist/config-mutator-UCGAV3SP.js +2 -0
- package/dist/doctor-MMT4SREV.js +2 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +1 -1
- package/dist/processes-I3XAPHG7.js +2 -0
- package/dist/program-7ULXLTD6.js +2 -0
- package/dist/query-RHVR6QUZ.js +2 -0
- package/dist/registry-OB6S66XX.js +2 -0
- package/dist/request-planner-F5NVL2G7.js +2 -0
- package/dist/request-planner-F5NVL2G7.js.map +1 -0
- package/dist/{review-candidates-O2PS7L3B.js → review-candidates-IRPKFWL2.js} +2 -2
- package/dist/{rotation-memo-7T75BLEX.js → rotation-memo-QEO3COFH.js} +3 -3
- package/dist/rotation-memo-QEO3COFH.js.map +1 -0
- package/dist/{routing-5K7PGHPL.js → routing-OSPRKRAY.js} +2 -2
- package/dist/scheduler-JL6K5HHI.js +2 -0
- package/dist/{seat-FZRNRAHQ.js → seat-2MHKVMW2.js} +2 -2
- package/dist/{select-SOJYFAMI.js → select-7LCHJVPK.js} +2 -2
- package/dist/{surface-usage-NS74AXSE.js → surface-usage-UREILT2E.js} +2 -2
- package/dist/web/activity-graph.global.js +901 -368
- package/dist/web/activity-graph.global.js.map +1 -1
- package/dist/wiki-MY32MON3.js +2 -0
- package/package.json +2 -1
- package/dist/board-dashboard-K4DM32SO.js.map +0 -1
- package/dist/chunk-42DCRKUD.js.map +0 -1
- package/dist/chunk-45BLFNDG.js.map +0 -1
- package/dist/chunk-4BR7D2OU.js +0 -36
- package/dist/chunk-4BR7D2OU.js.map +0 -1
- package/dist/chunk-EVWEG3VD.js +0 -3
- package/dist/chunk-GMNKJXTR.js +0 -13
- package/dist/chunk-GMNKJXTR.js.map +0 -1
- package/dist/chunk-GUBMLV34.js.map +0 -1
- package/dist/client-5Z3URGPY.js +0 -2
- package/dist/config-ORSGLVRW.js +0 -2
- package/dist/config-mutator-JB3S2E7H.js +0 -2
- package/dist/doctor-FS2BX6H4.js +0 -2
- package/dist/processes-WU23U2OJ.js +0 -2
- package/dist/program-DWZAI4GY.js +0 -2
- package/dist/query-3HXGBKGM.js +0 -2
- package/dist/registry-EJRWAJYG.js +0 -2
- package/dist/request-planner-BCOXUAPA.js +0 -2
- package/dist/request-planner-BCOXUAPA.js.map +0 -1
- package/dist/rotation-memo-7T75BLEX.js.map +0 -1
- package/dist/scheduler-DSAOMV4O.js +0 -2
- package/dist/wiki-34XVI32N.js +0 -2
- /package/dist/{App-IEQXWJ7B.js.map → App-2LAWZNMG.js.map} +0 -0
- /package/dist/{ChatApp-NWOSAP5U.js.map → ChatApp-2KRDHMTV.js.map} +0 -0
- /package/dist/{agent-SPE7Q7MD.js.map → agent-ZRRIMLTX.js.map} +0 -0
- /package/dist/{chunk-UCQ2N3KO.js.map → chunk-2TJ5L7CB.js.map} +0 -0
- /package/dist/{chunk-FKBGJYWQ.js.map → chunk-3RHPZXCR.js.map} +0 -0
- /package/dist/{chunk-DI7FMCDK.js.map → chunk-4CR463C6.js.map} +0 -0
- /package/dist/{chunk-IVQO43U2.js.map → chunk-5FEQI22L.js.map} +0 -0
- /package/dist/{chunk-52ZPELD2.js.map → chunk-7CVJ4JOE.js.map} +0 -0
- /package/dist/{chunk-4KXBUORV.js.map → chunk-A4YR3PQY.js.map} +0 -0
- /package/dist/{chunk-Q7CZIRBB.js.map → chunk-B2XTYYXV.js.map} +0 -0
- /package/dist/{chunk-JKYMXLYL.js.map → chunk-G5MFPNGJ.js.map} +0 -0
- /package/dist/{chunk-EL3J74N2.js.map → chunk-GWQIMAJ7.js.map} +0 -0
- /package/dist/{chunk-V4HURNMX.js.map → chunk-JGJE5Y2J.js.map} +0 -0
- /package/dist/{chunk-SC5DIKBB.js.map → chunk-JWKIFAXA.js.map} +0 -0
- /package/dist/{chunk-UU4WOZNR.js.map → chunk-K6E7WJ7O.js.map} +0 -0
- /package/dist/{chunk-AUNDQPDR.js.map → chunk-MFVI5FOM.js.map} +0 -0
- /package/dist/{chunk-GK7XAM3D.js.map → chunk-W3YGESNK.js.map} +0 -0
- /package/dist/{client-5Z3URGPY.js.map → client-IP643GRO.js.map} +0 -0
- /package/dist/{config-ORSGLVRW.js.map → config-IVDP46ZG.js.map} +0 -0
- /package/dist/{config-mutator-JB3S2E7H.js.map → config-mutator-UCGAV3SP.js.map} +0 -0
- /package/dist/{doctor-FS2BX6H4.js.map → doctor-MMT4SREV.js.map} +0 -0
- /package/dist/{processes-WU23U2OJ.js.map → processes-I3XAPHG7.js.map} +0 -0
- /package/dist/{program-DWZAI4GY.js.map → program-7ULXLTD6.js.map} +0 -0
- /package/dist/{query-3HXGBKGM.js.map → query-RHVR6QUZ.js.map} +0 -0
- /package/dist/{registry-EJRWAJYG.js.map → registry-OB6S66XX.js.map} +0 -0
- /package/dist/{review-candidates-O2PS7L3B.js.map → review-candidates-IRPKFWL2.js.map} +0 -0
- /package/dist/{routing-5K7PGHPL.js.map → routing-OSPRKRAY.js.map} +0 -0
- /package/dist/{scheduler-DSAOMV4O.js.map → scheduler-JL6K5HHI.js.map} +0 -0
- /package/dist/{seat-FZRNRAHQ.js.map → seat-2MHKVMW2.js.map} +0 -0
- /package/dist/{select-SOJYFAMI.js.map → select-7LCHJVPK.js.map} +0 -0
- /package/dist/{surface-usage-NS74AXSE.js.map → surface-usage-UREILT2E.js.map} +0 -0
- /package/dist/{wiki-34XVI32N.js.map → wiki-MY32MON3.js.map} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{a as Se,b as Ae}from"./chunk-4BR7D2OU.js";import{a as X}from"./chunk-M4AMWP3H.js";import{b as ke,c as be,e as ve,f as Ie,g as Re}from"./chunk-4KXBUORV.js";import{b as Q}from"./chunk-AFRHKA7B.js";import{v as we,w as lt}from"./chunk-MGNJWBVP.js";import{b as ye,f as ct}from"./chunk-F4HZTZHW.js";import{existsSync as ut,mkdirSync as $e,readFileSync as pt,writeFileSync as ft,renameSync as gt}from"fs";import{resolve as Pe,dirname as mt}from"path";var Te=class{filePath;log;constructor(e={}){let t=e.baseDir??Pe(process.cwd(),".agentx");this.filePath=Pe(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),$e(t,{recursive:!0})}key(e,t,r){return`${e}::${t}::${r||"-"}`}load(){if(!ut(this.filePath))return{version:1,overrides:{}};try{let e=pt(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){$e(mt(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;ft(t,JSON.stringify(e,null,2)),gt(t,this.filePath)}get(e,t,r){let s=this.load().overrides[this.key(e,t,r)];if(s&&!(s.expiresAt&&Date.parse(s.expiresAt)<Date.now()))return s}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 o=this.load(),s=this.key(e,t,r);return s in o.overrides?(delete o.overrides[s],this.save(o),!0):!1}consumeSummary(e,t,r){let o=this.load(),s=o.overrides[this.key(e,t,r)];if(!s||!s.summary||s.summaryConsumedAt)return;let i=s.summary;return s.summaryConsumedAt=new Date().toISOString(),this.save(o),i}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{existsSync as v,mkdirSync as Ct,readdirSync as U,readFileSync as K,unlinkSync as B,writeFileSync as ne}from"fs";import{resolve as R,relative as re}from"path";import{z as l}from"zod";var ht=l.enum(["trigger.channel","trigger.manual","trigger.cron","trigger.hook","trigger.form","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"]),yt=l.enum(["equals","contains","matches","exists"]),wt=l.object({kind:yt,params:l.record(l.unknown()).default({})}),Ne=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}),We=l.object({id:l.string().min(1).regex(/^[a-zA-Z_][a-zA-Z0-9_-]*$/,"node id must be identifier-safe"),type:ht,config:l.record(l.unknown()).default({}),retry:Ne,position:l.object({x:l.number(),y:l.number()}).optional()}),Oe=l.object({from:l.string(),fromPort:l.string().optional(),to:l.string(),toPort:l.string().optional(),label:l.string().optional()}),xe=l.union([l.string(),l.date().transform(n=>n.toISOString())]),$=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(We).refine(n=>n.length>0,{message:"workflow must have at least one node"}),edges:l.array(Oe).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:xe.optional(),updated:xe.optional()});function ee(n){let e=[],t=new Map(n.nodes.map(i=>[i.id,i])),r=n.nodes.filter(i=>i.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 i of n.edges)t.has(i.from)||e.push(`edge references missing node: from="${i.from}"`),t.has(i.to)||e.push(`edge references missing node: to="${i.to}"`);let o=r[0];if(o){let i=new Map;for(let c of n.edges)i.has(c.from)||i.set(c.from,[]),i.get(c.from).push(c.to);let a=new Set,d=[o.id];for(;d.length;){let c=d.pop();if(!a.has(c)){a.add(c);for(let g of i.get(c)??[])d.push(g)}}for(let c of n.nodes)a.has(c.id)||e.push(`node "${c.id}" is unreachable from trigger "${o.id}"`);n.nodes.some(c=>a.has(c.id)&&kt(c.type))||e.push("no reachable `end`, `checkpoint`, `subProcess`, `signal.wait`, or `timer.boundary` node \u2014 the run cannot terminate or pause")}for(let i of n.nodes){if(i.type!=="branch"&&i.type!=="rule")continue;let a=i.type==="branch"?i.config.cases??[]:(i.config.rules??[]).filter(u=>typeof u.to=="string"),d=i.type==="branch"?i.config.default:i.config.default?.to,c=new Set(a.map(u=>u.to));d&&c.add(d);let g=n.edges.filter(u=>u.from===i.id);for(let u of g){let p=u.fromPort??"";c.has(p)||e.push(`${i.type} "${i.id}" has outgoing edge with port "${p}" not declared in cases or default`)}}let s=vt(n);for(let i of s)e.push(`cycle without agent/checkpoint: ${i.join(" -> ")}`);return e}function kt(n){return n==="end"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function bt(n){return n==="agent"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function vt(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=[],o=new Map,s=[],i=a=>{if(o.get(a)===1){let d=s.indexOf(a);if(d>=0){let c=s.slice(d).concat(a);c.some(u=>{let p=t.get(u)?.type;return p?bt(p):!1})||r.push(c)}return}if(o.get(a)!==2){o.set(a,1),s.push(a);for(let d of e.get(a)??[])i(d);s.pop(),o.set(a,2)}};for(let a of n.nodes)o.get(a.id)!==2&&i(a.id);return r}var Ee=l.enum(["running","paused","completed","failed","canceled"]),It=l.enum(["ok","failed","timeout","skipped","paused","resumed"]),St=l.object({at:l.string(),nodeId:l.string(),inputKeys:l.array(l.string()).default([]),status:It,output:l.record(l.unknown()).optional(),idempotencyKey:l.string(),note:l.string().optional()}),At=l.object({backend:l.string(),id:l.string()}),Rt=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()})]),$t=l.object({id:l.string(),workflowId:l.string(),workflowVersion:l.literal(2),homeNode:l.string(),status:Ee,pausedAt:Rt.optional(),context:l.record(l.record(l.unknown())).default({}),pending:l.array(l.string()).default([]),joinCounters:l.record(l.array(l.string())).default({}),entityRef:At,history:l.array(St).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),createdAt:l.string(),updatedAt:l.string()});import Ce from"js-yaml";var Pt=new Set(["branch","gateway.parallel","rule","signal.wait","subProcess","timer.boundary","checkpoint"]),b=class extends Error{constructor(t,r){super(t);this.mark=r;this.name="WorkflowYamlError"}};function L(n,e={}){if(!n||n.trim()==="")throw new b(`${P(e)}empty file \u2014 workflow YAML must contain at least an id, version, title, and one node.`);let t;try{t=Ce.loadAll(n)}catch(o){let s=o?.mark;throw new b(`${P(e)}YAML parse error: ${o?.reason??o?.message??o}`+(s?` (line ${s.line+1}, column ${s.column+1})`:""),s)}if(t.length===0||t.length===1&&t[0]==null)throw new b(`${P(e)}YAML produced no document.`);if(t.length>1)throw new b(`${P(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 o=Array.isArray(r)?"array":typeof r;throw new b(`${P(e)}top-level YAML must be a mapping (got ${o}).`)}return Fe(r,e)}function Fe(n,e={}){if(!("flow"in n))return n;let t=n.flow;if(t==null){let u={...n};return delete u.flow,u}if(!Array.isArray(t))throw new b(`${P(e)}flow must be an array of node ids (got ${typeof t}).`);for(let u of t)if(typeof u!="string")throw new b(`${P(e)}flow entries must be strings (got ${typeof u}).`);let r=t,o=Array.isArray(n.nodes)?n.nodes:[],s=new Map;for(let u of o)u&&typeof u=="object"&&typeof u.id=="string"&&typeof u.type=="string"&&s.set(u.id,u.type);for(let u of r){if(!s.has(u))throw new b(`${P(e)}flow references unknown node "${u}".`);let p=s.get(u);if(Pt.has(p))throw new b(`${P(e)}flow cannot include ${p} node "${u}"; use explicit edges for ${p} nodes.`)}let i=[];for(let u=0;u<r.length-1;u++)i.push({from:r[u],to:r[u+1]});let a=Array.isArray(n.edges)?n.edges:[],d=new Set,c=[];for(let u of a){if(!u||typeof u!="object")continue;let p=je(u.from,u.fromPort,u.to);p&&!d.has(p)?(d.add(p),c.push(u)):p||c.push(u)}for(let u of i){let p=je(u.from,void 0,u.to);p&&!d.has(p)&&(d.add(p),c.push(u))}let g={...n,edges:c};return delete g.flow,g}function je(n,e,t){return typeof n!="string"||typeof t!="string"?null:`${n}::${typeof e=="string"?e:""}::${t}`}function P(n){return n.filePath?`${n.filePath}: `:""}function Tt(n){return Ce.dump(n,{noRefs:!0,lineWidth:100,sortKeys:!1})}import{Document as xt,isMap as H,isSeq as Nt,isScalar as De,parseDocument as Wt}from"yaml";function Me(n,e){let t=Wt(n);if(!t.contents||!H(t.contents)){let r=new xt(e);return t.commentBefore&&(r.commentBefore=t.commentBefore),String(r)}return te(t,t.contents,e),String(t)}function te(n,e,t){let r=Object.keys(t),o=new Set(r),s=new Map;for(let a of e.items){let d=jt(a);d!==null&&s.set(d,a)}let i=[];for(let a of r){let d=t[a],c=s.get(a);c?(Ot(n,c,d),i.push(c)):i.push(n.createPair(a,d))}e.items=i}function Ot(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)){Nt(r)?Et(n,r,t):e.value=n.createNode(t);return}H(r)?te(n,r,t):e.value=n.createNode(t)}function Et(n,e,t){if(!(t.length>0&&t.every(i=>i&&typeof i=="object"&&typeof i.id=="string"))){let i=n.createNode(t);e.items=i.items;return}let o=new Map;for(let i of e.items)if(H(i)){let a=i.get("id",!0);De(a)&&typeof a.value=="string"&&o.set(a.value,i)}let s=[];for(let i of t){let a=i.id,d=o.get(a);d&&H(d)?(te(n,d,i),s.push(d)):s.push(n.createNode(i))}e.items=s}function jt(n){let e=n.key;return De(e)&&typeof e.value=="string"?e.value:typeof e=="string"?e:null}var oe=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??R(process.cwd(),".agentx/workflows"),Ct(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=K(t,"utf-8");return e.endsWith(".json")?JSON.parse(r):L(r,{filePath:e})}list(){if(!v(this.baseDir))return[];let e=new Map;for(let r of U(this.baseDir,{withFileTypes:!0})){if(!r.isFile()||!this.isWorkflowFile(r.name))continue;let o=this.idFromFilename(r.name),s=e.get(o)??[];s.push(r.name),e.set(o,s)}let t=[];for(let[,r]of e)if(!(r.length>1))try{let o=this.readAndParse(r[0]),s=$.safeParse(o);s.success&&t.push(s.data)}catch{}return t.sort((r,o)=>r.id.localeCompare(o.id))}validateAll(){let e=[];if(!v(this.baseDir))return e;let t=new Map;for(let r of U(this.baseDir,{withFileTypes:!0})){if(!r.isFile()||!this.isWorkflowFile(r.name))continue;let o=this.idFromFilename(r.name),s=t.get(o)??[];s.push(r.name),t.set(o,s)}for(let[r,o]of t){if(o.length>1){let u=[...o].sort();for(let p of u)e.push({id:r,path:re(this.baseDir,R(this.baseDir,p)),issues:[`duplicate workflow id "${r}" \u2014 found ${u.join(" and ")}; delete one to disambiguate`],isValid:!1});continue}let s=o[0],i=R(this.baseDir,s),a=re(this.baseDir,i),d;try{d=this.readAndParse(s)}catch(u){let p=u instanceof b?u.message:`parse error: ${u?.message??u}`;e.push({id:r,path:a,issues:[p],isValid:!1});continue}let c=$.safeParse(d);if(!c.success){let u=c.error.issues.map(p=>`${p.path.join(".")||"<root>"}: ${p.message}`);e.push({id:String(d?.id??r),path:a,issues:u,isValid:!1});continue}let g=ee(c.data);e.push({workflow:c.data,issues:g,isValid:g.length===0})}return e}get(e){let t=this.pathForJson(e),r=this.pathForYaml(e),o=R(this.baseDir,`${e}.yml`),s=v(t),i=v(r)||v(o);if(s&&i)return null;if(s)try{let d=JSON.parse(K(t,"utf-8")),c=$.safeParse(d);return c.success?c.data:null}catch{return null}let a=v(r)?r:v(o)?o:null;if(a)try{let d=K(a,"utf-8"),c=L(d,{filePath:re(this.baseDir,a)}),g=$.safeParse(c);return g.success?g.data:null}catch{return null}if(!v(this.baseDir))return null;for(let d of U(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name)||this.idFromFilename(d.name)===e))try{let g=this.readAndParse(d.name),u=$.safeParse(g);if(u.success&&u.data.id===e)return u.data}catch{}return null}save(e,t={}){let r=new Date().toISOString().slice(0,10),o=$.parse({...e,created:e.created||r,updated:r}),s=this.pathForYaml(o.id),i=R(this.baseDir,`${o.id}.yml`),a=v(s)?s:v(i)?i:null;if(!a&&v(this.baseDir)){for(let d of U(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name))&&!d.name.endsWith(".json"))try{let c=this.readAndParse(d.name),g=$.safeParse(c);if(g.success&&g.data.id===o.id){a=R(this.baseDir,d.name);break}}catch{}}if(a&&t.convertFromYaml)return B(a),ne(this.pathForJson(o.id),JSON.stringify(o,null,2)+`
|
|
1
|
+
import{a as Se,b as Ae}from"./chunk-VMDA2SX2.js";import{a as X}from"./chunk-QLTM3F7M.js";import{b as ke,c as be,e as ve,f as Ie,g as Re}from"./chunk-A4YR3PQY.js";import{b as Q}from"./chunk-AFRHKA7B.js";import{v as we,w as lt}from"./chunk-2DBGOCCW.js";import{b as ye,f as ct}from"./chunk-F4HZTZHW.js";import{existsSync as ut,mkdirSync as $e,readFileSync as pt,writeFileSync as ft,renameSync as gt}from"fs";import{resolve as Pe,dirname as mt}from"path";var Te=class{filePath;log;constructor(e={}){let t=e.baseDir??Pe(process.cwd(),".agentx");this.filePath=Pe(t,"handover.json"),this.log=e.log??console.error.bind(console,"[handover]"),$e(t,{recursive:!0})}key(e,t,r){return`${e}::${t}::${r||"-"}`}load(){if(!ut(this.filePath))return{version:1,overrides:{}};try{let e=pt(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){$e(mt(this.filePath),{recursive:!0});let t=`${this.filePath}.tmp-${process.pid}`;ft(t,JSON.stringify(e,null,2)),gt(t,this.filePath)}get(e,t,r){let s=this.load().overrides[this.key(e,t,r)];if(s&&!(s.expiresAt&&Date.parse(s.expiresAt)<Date.now()))return s}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 o=this.load(),s=this.key(e,t,r);return s in o.overrides?(delete o.overrides[s],this.save(o),!0):!1}consumeSummary(e,t,r){let o=this.load(),s=o.overrides[this.key(e,t,r)];if(!s||!s.summary||s.summaryConsumedAt)return;let i=s.summary;return s.summaryConsumedAt=new Date().toISOString(),this.save(o),i}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{existsSync as v,mkdirSync as Ct,readdirSync as U,readFileSync as K,unlinkSync as B,writeFileSync as ne}from"fs";import{resolve as R,relative as re}from"path";import{z as l}from"zod";var ht=l.enum(["trigger.channel","trigger.manual","trigger.cron","trigger.hook","trigger.form","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"]),yt=l.enum(["equals","contains","matches","exists"]),wt=l.object({kind:yt,params:l.record(l.unknown()).default({})}),Ne=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}),We=l.object({id:l.string().min(1).regex(/^[a-zA-Z_][a-zA-Z0-9_-]*$/,"node id must be identifier-safe"),type:ht,config:l.record(l.unknown()).default({}),retry:Ne,position:l.object({x:l.number(),y:l.number()}).optional()}),Oe=l.object({from:l.string(),fromPort:l.string().optional(),to:l.string(),toPort:l.string().optional(),label:l.string().optional()}),xe=l.union([l.string(),l.date().transform(n=>n.toISOString())]),$=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(We).refine(n=>n.length>0,{message:"workflow must have at least one node"}),edges:l.array(Oe).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:xe.optional(),updated:xe.optional()});function ee(n){let e=[],t=new Map(n.nodes.map(i=>[i.id,i])),r=n.nodes.filter(i=>i.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 i of n.edges)t.has(i.from)||e.push(`edge references missing node: from="${i.from}"`),t.has(i.to)||e.push(`edge references missing node: to="${i.to}"`);let o=r[0];if(o){let i=new Map;for(let c of n.edges)i.has(c.from)||i.set(c.from,[]),i.get(c.from).push(c.to);let a=new Set,d=[o.id];for(;d.length;){let c=d.pop();if(!a.has(c)){a.add(c);for(let g of i.get(c)??[])d.push(g)}}for(let c of n.nodes)a.has(c.id)||e.push(`node "${c.id}" is unreachable from trigger "${o.id}"`);n.nodes.some(c=>a.has(c.id)&&kt(c.type))||e.push("no reachable `end`, `checkpoint`, `subProcess`, `signal.wait`, or `timer.boundary` node \u2014 the run cannot terminate or pause")}for(let i of n.nodes){if(i.type!=="branch"&&i.type!=="rule")continue;let a=i.type==="branch"?i.config.cases??[]:(i.config.rules??[]).filter(u=>typeof u.to=="string"),d=i.type==="branch"?i.config.default:i.config.default?.to,c=new Set(a.map(u=>u.to));d&&c.add(d);let g=n.edges.filter(u=>u.from===i.id);for(let u of g){let p=u.fromPort??"";c.has(p)||e.push(`${i.type} "${i.id}" has outgoing edge with port "${p}" not declared in cases or default`)}}let s=vt(n);for(let i of s)e.push(`cycle without agent/checkpoint: ${i.join(" -> ")}`);return e}function kt(n){return n==="end"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function bt(n){return n==="agent"||n==="checkpoint"||n==="subProcess"||n==="signal.wait"||n==="timer.boundary"}function vt(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=[],o=new Map,s=[],i=a=>{if(o.get(a)===1){let d=s.indexOf(a);if(d>=0){let c=s.slice(d).concat(a);c.some(u=>{let p=t.get(u)?.type;return p?bt(p):!1})||r.push(c)}return}if(o.get(a)!==2){o.set(a,1),s.push(a);for(let d of e.get(a)??[])i(d);s.pop(),o.set(a,2)}};for(let a of n.nodes)o.get(a.id)!==2&&i(a.id);return r}var Ee=l.enum(["running","paused","completed","failed","canceled"]),It=l.enum(["ok","failed","timeout","skipped","paused","resumed"]),St=l.object({at:l.string(),nodeId:l.string(),inputKeys:l.array(l.string()).default([]),status:It,output:l.record(l.unknown()).optional(),idempotencyKey:l.string(),note:l.string().optional()}),At=l.object({backend:l.string(),id:l.string()}),Rt=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()})]),$t=l.object({id:l.string(),workflowId:l.string(),workflowVersion:l.literal(2),homeNode:l.string(),status:Ee,pausedAt:Rt.optional(),context:l.record(l.record(l.unknown())).default({}),pending:l.array(l.string()).default([]),joinCounters:l.record(l.array(l.string())).default({}),entityRef:At,history:l.array(St).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),createdAt:l.string(),updatedAt:l.string()});import Ce from"js-yaml";var Pt=new Set(["branch","gateway.parallel","rule","signal.wait","subProcess","timer.boundary","checkpoint"]),b=class extends Error{constructor(t,r){super(t);this.mark=r;this.name="WorkflowYamlError"}};function L(n,e={}){if(!n||n.trim()==="")throw new b(`${P(e)}empty file \u2014 workflow YAML must contain at least an id, version, title, and one node.`);let t;try{t=Ce.loadAll(n)}catch(o){let s=o?.mark;throw new b(`${P(e)}YAML parse error: ${o?.reason??o?.message??o}`+(s?` (line ${s.line+1}, column ${s.column+1})`:""),s)}if(t.length===0||t.length===1&&t[0]==null)throw new b(`${P(e)}YAML produced no document.`);if(t.length>1)throw new b(`${P(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 o=Array.isArray(r)?"array":typeof r;throw new b(`${P(e)}top-level YAML must be a mapping (got ${o}).`)}return Fe(r,e)}function Fe(n,e={}){if(!("flow"in n))return n;let t=n.flow;if(t==null){let u={...n};return delete u.flow,u}if(!Array.isArray(t))throw new b(`${P(e)}flow must be an array of node ids (got ${typeof t}).`);for(let u of t)if(typeof u!="string")throw new b(`${P(e)}flow entries must be strings (got ${typeof u}).`);let r=t,o=Array.isArray(n.nodes)?n.nodes:[],s=new Map;for(let u of o)u&&typeof u=="object"&&typeof u.id=="string"&&typeof u.type=="string"&&s.set(u.id,u.type);for(let u of r){if(!s.has(u))throw new b(`${P(e)}flow references unknown node "${u}".`);let p=s.get(u);if(Pt.has(p))throw new b(`${P(e)}flow cannot include ${p} node "${u}"; use explicit edges for ${p} nodes.`)}let i=[];for(let u=0;u<r.length-1;u++)i.push({from:r[u],to:r[u+1]});let a=Array.isArray(n.edges)?n.edges:[],d=new Set,c=[];for(let u of a){if(!u||typeof u!="object")continue;let p=je(u.from,u.fromPort,u.to);p&&!d.has(p)?(d.add(p),c.push(u)):p||c.push(u)}for(let u of i){let p=je(u.from,void 0,u.to);p&&!d.has(p)&&(d.add(p),c.push(u))}let g={...n,edges:c};return delete g.flow,g}function je(n,e,t){return typeof n!="string"||typeof t!="string"?null:`${n}::${typeof e=="string"?e:""}::${t}`}function P(n){return n.filePath?`${n.filePath}: `:""}function Tt(n){return Ce.dump(n,{noRefs:!0,lineWidth:100,sortKeys:!1})}import{Document as xt,isMap as H,isSeq as Nt,isScalar as De,parseDocument as Wt}from"yaml";function Me(n,e){let t=Wt(n);if(!t.contents||!H(t.contents)){let r=new xt(e);return t.commentBefore&&(r.commentBefore=t.commentBefore),String(r)}return te(t,t.contents,e),String(t)}function te(n,e,t){let r=Object.keys(t),o=new Set(r),s=new Map;for(let a of e.items){let d=jt(a);d!==null&&s.set(d,a)}let i=[];for(let a of r){let d=t[a],c=s.get(a);c?(Ot(n,c,d),i.push(c)):i.push(n.createPair(a,d))}e.items=i}function Ot(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)){Nt(r)?Et(n,r,t):e.value=n.createNode(t);return}H(r)?te(n,r,t):e.value=n.createNode(t)}function Et(n,e,t){if(!(t.length>0&&t.every(i=>i&&typeof i=="object"&&typeof i.id=="string"))){let i=n.createNode(t);e.items=i.items;return}let o=new Map;for(let i of e.items)if(H(i)){let a=i.get("id",!0);De(a)&&typeof a.value=="string"&&o.set(a.value,i)}let s=[];for(let i of t){let a=i.id,d=o.get(a);d&&H(d)?(te(n,d,i),s.push(d)):s.push(n.createNode(i))}e.items=s}function jt(n){let e=n.key;return De(e)&&typeof e.value=="string"?e.value:typeof e=="string"?e:null}var oe=class{baseDir;constructor(e={}){this.baseDir=e.baseDir??R(process.cwd(),".agentx/workflows"),Ct(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=K(t,"utf-8");return e.endsWith(".json")?JSON.parse(r):L(r,{filePath:e})}list(){if(!v(this.baseDir))return[];let e=new Map;for(let r of U(this.baseDir,{withFileTypes:!0})){if(!r.isFile()||!this.isWorkflowFile(r.name))continue;let o=this.idFromFilename(r.name),s=e.get(o)??[];s.push(r.name),e.set(o,s)}let t=[];for(let[,r]of e)if(!(r.length>1))try{let o=this.readAndParse(r[0]),s=$.safeParse(o);s.success&&t.push(s.data)}catch{}return t.sort((r,o)=>r.id.localeCompare(o.id))}validateAll(){let e=[];if(!v(this.baseDir))return e;let t=new Map;for(let r of U(this.baseDir,{withFileTypes:!0})){if(!r.isFile()||!this.isWorkflowFile(r.name))continue;let o=this.idFromFilename(r.name),s=t.get(o)??[];s.push(r.name),t.set(o,s)}for(let[r,o]of t){if(o.length>1){let u=[...o].sort();for(let p of u)e.push({id:r,path:re(this.baseDir,R(this.baseDir,p)),issues:[`duplicate workflow id "${r}" \u2014 found ${u.join(" and ")}; delete one to disambiguate`],isValid:!1});continue}let s=o[0],i=R(this.baseDir,s),a=re(this.baseDir,i),d;try{d=this.readAndParse(s)}catch(u){let p=u instanceof b?u.message:`parse error: ${u?.message??u}`;e.push({id:r,path:a,issues:[p],isValid:!1});continue}let c=$.safeParse(d);if(!c.success){let u=c.error.issues.map(p=>`${p.path.join(".")||"<root>"}: ${p.message}`);e.push({id:String(d?.id??r),path:a,issues:u,isValid:!1});continue}let g=ee(c.data);e.push({workflow:c.data,issues:g,isValid:g.length===0})}return e}get(e){let t=this.pathForJson(e),r=this.pathForYaml(e),o=R(this.baseDir,`${e}.yml`),s=v(t),i=v(r)||v(o);if(s&&i)return null;if(s)try{let d=JSON.parse(K(t,"utf-8")),c=$.safeParse(d);return c.success?c.data:null}catch{return null}let a=v(r)?r:v(o)?o:null;if(a)try{let d=K(a,"utf-8"),c=L(d,{filePath:re(this.baseDir,a)}),g=$.safeParse(c);return g.success?g.data:null}catch{return null}if(!v(this.baseDir))return null;for(let d of U(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name)||this.idFromFilename(d.name)===e))try{let g=this.readAndParse(d.name),u=$.safeParse(g);if(u.success&&u.data.id===e)return u.data}catch{}return null}save(e,t={}){let r=new Date().toISOString().slice(0,10),o=$.parse({...e,created:e.created||r,updated:r}),s=this.pathForYaml(o.id),i=R(this.baseDir,`${o.id}.yml`),a=v(s)?s:v(i)?i:null;if(!a&&v(this.baseDir)){for(let d of U(this.baseDir,{withFileTypes:!0}))if(!(!d.isFile()||!this.isWorkflowFile(d.name))&&!d.name.endsWith(".json"))try{let c=this.readAndParse(d.name),g=$.safeParse(c);if(g.success&&g.data.id===o.id){a=R(this.baseDir,d.name);break}}catch{}}if(a&&t.convertFromYaml)return B(a),ne(this.pathForJson(o.id),JSON.stringify(o,null,2)+`
|
|
2
2
|
`),o;if(a){let d=K(a,"utf-8");try{let c=Me(d,o);return ne(a,c),o}catch(c){let g=new Error(`yaml round-trip failed for "${o.id}" at ${a}: ${c?.message??c}`);throw g.yamlPath=a,g}}return ne(this.pathForJson(o.id),JSON.stringify(o,null,2)+`
|
|
3
3
|
`),o}delete(e){let t=this.pathForJson(e),r=this.pathForYaml(e),o=R(this.baseDir,`${e}.yml`),s=!1;return v(t)&&(B(t),s=!0),v(r)&&(B(r),s=!0),v(o)&&(B(o),s=!0),s}};import{createHash as Ft,randomUUID as Dt}from"crypto";import{appendFileSync as _e,existsSync as E,mkdirSync as Le,readdirSync as He,readFileSync as ie,statSync as Ue,unlinkSync as Ke,writeFileSync as Mt}from"fs";import{resolve as O}from"path";function _t(n){return n.replace(/[^a-zA-Z0-9._:#@-]/g,"_").slice(0,200)}function x(n,e,t){return Ft("sha1").update(`${n}|${e}|${t}`).digest("hex").slice(0,16)}var se=class{baseDir;runsDir;indexDir;nodeId;constructor(e){this.baseDir=e.baseDir??O(process.cwd(),".agentx/workflows"),this.runsDir=O(this.baseDir,"_runs"),this.indexDir=O(this.baseDir,"_index"),this.nodeId=e.nodeId,Le(this.runsDir,{recursive:!0}),Le(this.indexDir,{recursive:!0})}runPath(e){return O(this.runsDir,`${e}.jsonl`)}indexPath(e){return O(this.indexDir,`${e.backend}__${_t(e.id)}.json`)}create(e){let t=new Date().toISOString(),r=Dt(),o={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,joinCounters:{},createdAt:t,updatedAt:t};return this.appendSnapshot(o),this.writeIndex(e.entityRef,o.id),o}get(e){let t=this.runPath(e);if(!E(t))return null;let r=ie(t,"utf-8").trim();if(!r)return null;let o=null;for(let s of r.split(`
|
|
4
4
|
`)){let i;try{i=JSON.parse(s)}catch{continue}if(i.v===2){if(i.kind==="snapshot")o=i.run;else if(i.kind==="exec"&&o&&o.id===i.runId){let a=o;o={...a,history:[...a.history,i.entry],pending:i.pending,status:i.status??a.status,pausedAt:i.pausedAt===null?void 0:i.pausedAt??a.pausedAt,context:i.context??a.context,joinCounters:i.joinCounters??a.joinCounters,updatedAt:i.entry.at}}}}return o}getActiveByEntity(e){let t=this.indexPath(e);if(!E(t))return null;try{return JSON.parse(ie(t,"utf-8")).runId}catch{return null}}getHomeNodeByEntity(e){let t=this.indexPath(e);if(!E(t))return null;try{return JSON.parse(ie(t,"utf-8")).homeNode}catch{return null}}recordExecution(e){let t=this.get(e.runId);if(!t)return null;if(t.history.some(s=>s.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};_e(this.runPath(e.runId),JSON.stringify(r)+`
|
|
@@ -6,4 +6,4 @@ import{a as Se,b as Ae}from"./chunk-4BR7D2OU.js";import{a as X}from"./chunk-M4AM
|
|
|
6
6
|
`)}writeIndex(e,t){Mt(this.indexPath(e),JSON.stringify({runId:t,homeNode:this.nodeId,updatedAt:new Date().toISOString()},null,2)+`
|
|
7
7
|
`)}clearIndex(e){let t=this.indexPath(e);if(E(t))try{Ke(t)}catch{}}};import{existsSync as Be,mkdirSync as Lt,readFileSync as Ht,unlinkSync as Ut,writeFileSync as Kt}from"fs";import{resolve as ae}from"path";import{z as j}from"zod";var qe=j.object({version:j.literal(1),nodes:j.record(j.object({x:j.number(),y:j.number()}))}),de=class{baseDir;layoutsDir;constructor(e={}){this.baseDir=e.baseDir??ae(process.cwd(),".agentx/workflows"),this.layoutsDir=ae(this.baseDir,"_layouts"),Lt(this.layoutsDir,{recursive:!0})}pathFor(e){let t=e.replace(/[^a-zA-Z0-9._-]/g,"_");return ae(this.layoutsDir,`${t}.json`)}get(e){let t=this.pathFor(e);if(!Be(t))return null;try{let r=qe.safeParse(JSON.parse(Ht(t,"utf-8")));return r.success?r.data:null}catch{return null}}save(e,t){let r=qe.parse(t);return Kt(this.pathFor(e),JSON.stringify(r,null,2)+`
|
|
8
8
|
`),r}sync(e,t){let r=this.get(e);if(!r)return null;let o={};for(let i of t)r.nodes[i]&&(o[i]=r.nodes[i]);let s={version:1,nodes:o};return this.save(e,s)}delete(e){let t=this.pathFor(e);return Be(t)?(Ut(t),!0):!1}};function ze(n){return new Set(n.toLowerCase().replace(/[^a-z0-9\s]/g," ").split(/\s+/).filter(e=>e.length>3))}function Bt(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 qt(n,e){let t=ze(n.message),r=e.filter(s=>s.state==="active"&&(s.status??"active")==="active"),o=null;for(let s of r){let i=0,a=[];if(s.ownerAgent&&s.ownerAgent===n.agentId&&(i+=.25,a.push("owner-agent")),n.channel&&s.tags.includes(n.channel)&&(i+=.15,a.push("channel-tag")),n.intentPath?.length&&s.intentPath.length){let u=n.intentPath.filter((p,m)=>s.intentPath[m]===p).length;u>0&&(i+=Math.min(.3,u*.1),a.push("intent-path"))}let d=[s.id,s.title,s.description??"",...s.tags].join(" "),c=Bt(t,ze(d));c>0&&(i+=Math.min(.35,c),a.push("text-similarity")),(s.matchCount??0)>0&&(i+=Math.min(.1,s.matchCount*.01),a.push("prior-matches"));let g=Math.max(0,Math.min(1,i));(!o||g>o.confidence)&&(o={workflow:s,confidence:g,reasons:a})}return o&&o.confidence>0?o:null}function ce(n){let{workflow:e,fromNodeId:t,selectedPort:r}=n,o=e.nodes.find(a=>a.id===t);if(!o)return{nextPending:[]};let s=e.edges.filter(a=>a.from===t);return{nextPending:(o.type==="branch"?s.filter(a=>(a.fromPort??"")===(r??"")):s).map(a=>a.to)}}function le(n,e){let t=n.config.cases??[],r=n.config.default??"";for(let o of t)if(zt(o.when,e))return o.to;return r}function zt(n,e){let t=n.params??{},r=String(t.path??""),o=q(e,r);switch(n.kind){case"equals":return o===t.value;case"contains":return typeof o=="string"?o.includes(String(t.value??"")):Array.isArray(o)?o.some(s=>s===t.value):!1;case"matches":{if(typeof o!="string")return!1;try{return new RegExp(String(t.regex??"")).test(o)}catch{return!1}}case"exists":return o!=null&&o!=="";default:return!1}}function q(n,e){if(!e)return;let t=e.split("."),r=n;for(let o of t){if(r==null||typeof r!="object")return;r=r[o]}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 N(n,e){return n.nodes.find(t=>t.id===e)}ct();lt();function Yt(n,e,t){let r=n.split(".");if(r[0]==="env"){if(r.length!==2)return"";let s=r[1];if(!t.has(s))return"";let i=process.env[s];return typeof i=="string"?i:""}let o=e;for(let s of r){if(o==null||typeof o!="object")return"";o=o[s]}return o==null?"":typeof o=="object"?JSON.stringify(o):String(o)}function S(n,e,t={}){let r=new Set(t.envAllow||[]);return n.replace(/\{\{\s*([a-zA-Z_][a-zA-Z0-9_.-]*)\s*\}\}/g,(o,s)=>Yt(s,e,r))}function w(n,e,t={}){let r={};for(let[o,s]of Object.entries(n))typeof s=="string"?r[o]=S(s,e,t):Array.isArray(s)?r[o]=s.map(i=>typeof i=="string"?S(i,e,t):i):s&&typeof s=="object"?r[o]=w(s,e,t):r[o]=s;return r}var Ye="workflow-classify",Y="unsure",Je=async n=>{let e=n.node.config,t=n.run.context,r={envAllow:n.workflow.envAllow},o=S(String(e.input??""),t,r).trim();if(!o)return{error:`classify node "${n.node.id}" missing config.input`};let s=e.labels,i=Array.isArray(s)?Object.fromEntries(s.map(f=>[String(f),null])):typeof s=="object"&&s?Object.fromEntries(Object.entries(s).map(([f,y])=>[f,y==null?null:String(y)])):{},a=Object.keys(i);if(a.length<2)return{error:`classify node "${n.node.id}" needs at least two labels`};if(a.includes(Y))return{error:`classify node "${n.node.id}": "${Y}" is reserved for the low-confidence port`};let d=typeof e.minConfidence=="number"?e.minConfidence:.7,c=e.instructions?S(String(e.instructions),t,r):void 0,g={input:o};if(e.state&&typeof e.state=="object")for(let[f,y]of Object.entries(e.state)){let I=typeof y=="string"?S(y,t,r):y;(I===null||["string","number","boolean"].includes(typeof I))&&(g[f]=I)}let u=await we(Ye,g,{label:ye(i,c)},{features:{workflow:n.workflow.id,node:n.node.id}});if(!u)return{error:`classify node "${n.node.id}": decision seat unavailable (set decisions.seats.${Ye}.mode)`};let p=u.answers.label,m=p.confidence>=d,k=m?p.choice:Y;return n.log(`[node:${n.node.id}] classify \u2192 ${p.choice} (${p.confidence.toFixed(2)})${m?"":` \u2014 below ${d}, routing to ${Y}`}`),{output:{result:p.choice,label:p.choice,confidence:p.confidence,probabilities:p.probabilities,unsure:!m,port:k},port:k}};var ue=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(o=>{let s=this.waiters.get(e)??[];s.push({resolve:()=>{this.active.set(e,(this.active.get(e)??0)+1),o()}}),this.waiters.set(e,s)})}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}}},J=new ue;function Ge(n,e){return`${n}:${e}`}var C=async n=>({output:n.run.context[n.node.id]??{}}),Jt=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 o=S(r,n.run.context,{envAllow:n.workflow.envAllow}),s=typeof e.timeoutMinutes=="number"?e.timeoutMinutes:void 0,i=typeof e.maxConcurrent=="number"&&e.maxConcurrent>0?e.maxConcurrent:null,a=i?Ge(n.workflow.id,n.node.id):null;if(a&&i){let c=J.stats(a);c.active>=i&&n.log(`[node:${n.node.id}] gated: ${c.active} active (cap ${i}), ${c.waiting+1} waiting`),await J.acquire(a,i)}let d=Date.now();try{let c=await n.agents.execute({agentId:t,message:o,workflowRunId:n.run.id,timeoutMinutes:s}),g=Date.now()-d;if(c.error){let m=c.errorKind??"unknown";return n.log(`[node:${n.node.id}] agent "${t}" failed (${m}): ${c.error}`),{error:`[${m}] ${c.error}`}}let p=String(e.resultParser??"acme-result-token")==="json"?kn(c.content):Ze(c.content);return{output:{reply:c.content,result:p.result,json:p.json,taskId:c.taskId,durationMs:g}}}catch(c){return n.log(`[node:${n.node.id}] agent "${t}" threw: ${c.message}`),{error:c.message}}finally{a&&J.release(a)}},Gt=async n=>{let e=le(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}})},Vt=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),o=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 s=fe(n,e.accountId),i=n.channels[t];if(i?.send)try{return{output:{messageId:await i.send({channel:t,chatId:r,text:o,...s?{accountId:s}:{}})??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:o,accountId:s})).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)`}},Zt=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),o=String(e.title??""),s=String(e.description??""),i=Array.isArray(e.labels)?e.labels.map(String):[],a=Array.isArray(e.assignees)?e.assignees.map(String):[];if(!r||!o)return{error:`action.createIssue "${n.node.id}" needs project + title`};let d=ge(n),c=n.channels[t];if(!c?.createIssue)return{error:`channel "${t}" does not support createIssue`};try{let g=await c.createIssue({project:r,title:o,description:s,labels:i,assignees:a,agentId:d});return g?{output:{issue:{iid:g.iid,url:g.url,webUrl:g.url}}}:{error:"createIssue returned null (see adapter log)"}}catch(g){return{error:`action.createIssue failed: ${g.message}`}}},Qt=async()=>({output:{}}),Xt=async n=>{let e=n.node.config,t=String(e.name??n.node.id),r=e.waitFor??{},o=e.resumeMatch??{};return{paused:!0,pausedAt:{kind:"checkpoint",nodeId:n.node.id,checkpointName:t,resumeMatch:{...r,...o}}}},en=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),o=String(e.iid??""),s=Array.isArray(e.add)?e.add.map(String):[],i=Array.isArray(e.remove)?e.remove.map(String):[];if(!r||!o)return{error:`action.setLabel "${n.node.id}" needs project + iid (try {{trigger.project}} / {{trigger.issue.iid}})`};if(s.length===0&&i.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=ge(n),c=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await a.setLabels({project:r,kind:c,iid:o,add:s,remove:i,agentId:d})??[],add:s,remove:i}}},tn=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.project??""),o=String(e.iid??"");if(!r||!o)return{error:`action.readLabel "${n.node.id}" needs project + iid`};let s=n.channels[t];if(!s?.getLabels)return{error:`channel "${t}" does not support getLabels`};let i=e.kind==="merge_request"?"merge_request":"issue";return{output:{labels:await s.getLabels({project:r,kind:i,iid:o})??[]}}},nn=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),o=String(e.messageId??""),s=String(e.emoji??"\u{1F440}");if(!t||!r||!o)return{error:`action.react "${n.node.id}" needs channel + chatId + messageId`};let i=fe(n,e.accountId),a=n.channels[t];if(!a?.react)return{error:`channel "${t}" does not support react`};try{return await a.react(r,o,s,i),{output:{emoji:s}}}catch(d){return{error:`action.react failed: ${d.message}`}}},rn=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??""),r=String(e.chatId??""),o=String(e.messageId??""),s=String(e.text??""),i=e.parseMode?String(e.parseMode):void 0;if(!t||!r||!o||!s)return{error:`action.editMessage "${n.node.id}" needs channel + chatId + messageId + text`};let a=fe(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,o,s,i,a)}}}catch(c){return{error:`action.editMessage failed: ${c.message}`}}},on=async n=>{let e=w(n.node.config,n.run.context,{envAllow:n.workflow.envAllow}),t=String(e.channel??"gitlab"),r=String(e.chatId??""),o=Number(e.durationMs??0);if(!r||!o)return{error:`action.logTime "${n.node.id}" needs chatId + durationMs`};let s=n.channels[t];if(!s?.logTimeSpent)return{error:`channel "${t}" does not support logTimeSpent`};let i=ge(n);try{return await s.logTimeSpent(r,o,i),{output:{durationMs:o}}}catch(a){return{error:`action.logTime failed: ${a.message}`}}},sn=async n=>{let e=w(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(),o=e.headers&&typeof e.headers=="object"?e.headers:{"Content-Type":"application/json"},s;e.body!==void 0&&(s=typeof e.body=="string"?e.body:JSON.stringify(e.body));try{let i=await fetch(t,{method:r,headers:o,body:s}),a=await i.text(),d=a;try{d=JSON.parse(a)}catch{}return{output:{ok:i.ok,status:i.status,body:d}}}catch(i){return{error:`action.callHTTP failed: ${i.message}`}}},an=async n=>{let e=w(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:o}=await import("./store-MCOA6N4F.js"),{runAction:s}=await import("./runner-YRBVNYTY.js"),i=new o().get(t);if(!i)return{error:`action.run "${n.node.id}": no action "${t}" in registry`};try{let a=await s(i,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}`}}},dn=async n=>{let e=w(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:o,getBuiltin:s}=await import("./builtin-B67DMJ3M.js");if(!s(t))return{error:`action.builtin "${n.node.id}": unknown built-in "${t}"`};try{return{output:await o(t,r)}}catch(i){let a=i?.name==="ZodError"?`validation: ${i.message}`:i?.message||String(i);return{error:`action.builtin "${t}" failed: ${a}`}}},cn=async n=>{let e=n.node.config,t=n.run.context;return typeof e.path=="string"&&e.path?{output:{value:q(t,e.path)}}:e.template&&typeof e.template=="object"?{output:w(e.template,t,{envAllow:n.workflow.envAllow})}:{output:{}}};function ln(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),o=Number(e[3]??0),s=Number(e[4]??0),i=((t*24+r)*60+o)*6e4+s*1e3;if(i>0)return new Date(Date.now()+i).toISOString()}}}}var un=async n=>{let e=n.node.config,t=w(e,n.run.context,{envAllow:n.workflow.envAllow}),r=String(t.workflowId??"");if(!r)return{error:`subProcess "${n.node.id}" missing config.workflowId`};let o=n.run.depth??0,s=n.workflow.maxChildDepth??5;if(o+1>=s)return{error:`max child workflow depth ${s} exceeded at ${n.workflow.id} \u2192 ${r} (parent depth ${o})`};let i=e.inputMap,a={};if(i==="*")a={...n.run.context};else if(i&&typeof i=="object")for(let[d,c]of Object.entries(i))c&&typeof c=="object"&&!Array.isArray(c)?a[d]=w(c,n.run.context,{envAllow:n.workflow.envAllow}):typeof c=="string"&&(a[d]={value:S(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}}},pn=C,fn=async n=>{let e=n.node.config,t=w(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 o=t.scope==="global"?"global":"workflow",s=t.payload&&typeof t.payload=="object"?t.payload:{};return{output:{emittedAt:new Date().toISOString(),name:r,scope:o,payload:s},emitSignal:{name:r,scope:o,payload:s}}},gn=async n=>{let e=n.node.config,t=w(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 o=t.scope==="global"?"global":"workflow",s=e.match&&typeof e.match=="object"?e.match:{};return{paused:!0,pausedAt:{kind:"signalWait",nodeId:n.node.id,signalName:r,match:s,scope:o}}},mn=async n=>{let e=n.node.config,t=w(e,n.run.context,{envAllow:n.workflow.envAllow}),r=ln(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)`}},hn=async()=>({output:{}}),yn=async n=>{let e=n.node.config,r=(Array.isArray(e.inputs)?e.inputs:[]).map(i=>typeof i=="string"?S(i,n.run.context,{envAllow:n.workflow.envAllow}):i),o=Array.isArray(e.rules)?e.rules:[];for(let i of o){let a=Array.isArray(i.when)?i.when:[];if(a.length!==r.length)continue;let d=!0;for(let c=0;c<a.length;c++)if(!wn(a[c],r[c])){d=!1;break}if(d)return{output:{...i.output??{},matchedPort:i.to??""},port:i.to}}let s=e.default;return{output:{...s?.output??{},matchedPort:s?.to??""},port:s?.to}};function wn(n,e){if(n==null||n==="*")return!0;let t=String(n),r=typeof e=="number"?e:String(e??""),o=/^(>=|<=|>|<)\s*(-?\d+(?:\.\d+)?)$/.exec(t);if(o){let s=o[1],i=Number(o[2]),a=typeof r=="number"?r:Number(r);if(Number.isNaN(a))return!1;switch(s){case">":return a>i;case"<":return a<i;case">=":return a>=i;case"<=":return a<=i}}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 Ve={"trigger.channel":C,"trigger.manual":C,"trigger.cron":C,"trigger.hook":C,"trigger.form":pn,agent:Jt,classify:Je,branch:Gt,transform:cn,"gateway.parallel":hn,rule:yn,"action.send":Vt,"action.createIssue":Zt,"action.setLabel":en,"action.readLabel":tn,"action.react":nn,"action.editMessage":rn,"action.logTime":on,"action.callHTTP":sn,"action.run":an,"action.builtin":dn,subProcess:un,"signal.emit":fn,"signal.wait":gn,"timer.boundary":mn,checkpoint:Xt,end:Qt};function pe(n){return Ve[n]}function fe(n,e){if(typeof e=="string"&&e)return e;let t=n.workflow.nodes.find(s=>s.type.startsWith("trigger."));if(!t)return;let o=n.run.context[t.id]?.accountId;return typeof o=="string"&&o?o:void 0}function ge(n){for(let e=n.run.history.length-1;e>=0;e--){let t=n.run.history[e],r=n.workflow.nodes.find(o=>o.id===t.nodeId);if(r?.type==="agent")return r.config.agentId??void 0}}function Ze(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 kn(n){let{result:e}=Ze(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 F=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 G(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 bn(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 vn(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 In(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 Qe(n,e,t,r,o=Date.now){let s=bn(e,t,o),i=vn(r),a=In(i),d=ve(n,s,a,o);return Ie(n,"workflow",d,i,o),d}var Sn=4e3,An=8,me=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 Q({log:t=>this.log(t)}),this.signals=e.signals??new F,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})}catch{}}async commit(e,t){let o=(this.commitChains.get(e)??Promise.resolve()).then(()=>t(),()=>t());return this.commitChains.set(e,o.then(()=>{},()=>{})),o}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 o={name:r.pausedAt.signalName,scope:r.pausedAt.scope,workflowId:r.workflowId,match:r.pausedAt.match??{}};if(!G(o,e))continue;let s=this.store.list().find(i=>i.id===r.workflowId);s&&(await this.commit(r.id,()=>{let i=this.runs.get(r.id);if(!i||i.status!=="paused"||!i.pausedAt||i.pausedAt.kind!=="signalWait"||!G({name:i.pausedAt.signalName,scope:i.pausedAt.scope,workflowId:i.workflowId,match:i.pausedAt.match??{}},e))return;let a=N(s,i.pausedAt.nodeId),d=a?s.edges.filter(g=>g.from===a.id).map(g=>g.to):[],c={receivedAt:new Date().toISOString(),name:e.name,payload:e.payload};this.runs.recordExecution({runId:i.id,entry:{at:c.receivedAt,nodeId:i.pausedAt.nodeId,inputKeys:[],status:"resumed",output:c,idempotencyKey:x(i.id,i.pausedAt.nodeId,`signal:${e.name}:${e.emittedAt}`)},nextPending:d,status:"running",pausedAt:null,context:{...i.context,[i.pausedAt.nodeId]:c}}),this.log(`[workflow:${s.id}] run ${i.id} resumed from signal "${e.name}"`),this.emitRunEvent({runId:i.id,workflowId:s.id,nodeId:i.pausedAt.nodeId,phase:"resumed",status:"running",note:`signal:${e.name}`})}),this.walk(s,r.id,`signal:${e.name}`).catch(i=>this.log(`[workflow:${s.id}] walk-after-signal failed: ${i.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 o=N(t,e.nodeId),s=o?t.edges.filter(d=>d.from===o.id).map(d=>d.to):[],i=new Date().toISOString(),a={firedAt:i,scheduledFor:e.fireAt};this.runs.recordExecution({runId:r.id,entry:{at:i,nodeId:e.nodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:x(r.id,e.nodeId,`timer:${e.id}`)},nextPending:s,status:"running",pausedAt:null,context:{...r.context,[e.nodeId]:a}}),this.log(`[workflow:${t.id}] run ${r.id} resumed from timer "${e.nodeId}" (fired ${i})`),this.emitRunEvent({runId:r.id,workflowId:t.id,nodeId:e.nodeId,phase:"resumed",status:"running",note:`timer:${e.id}`})}),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(i=>i.id===e.workflowId);if(!t)return this.log(`[workflows] dispatchWorkflow: workflow "${e.workflowId}" not found`),{claimed:!1,run:null};let o=t.nodes.find(i=>i.type.startsWith("trigger."))?.config??{},s={source:e.trigger?.source??o.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,s)}startChannelAck(e,t){let r=String(t.channel??""),o=String(t.chatId??"");if(!r||!o)return;let s=this.channels[r];if(!s)return;let i=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&&s.react)try{Promise.resolve(s.react(o,d,"\u{1F440}",i)).catch(()=>{})}catch{}if(this.ackTypingTimers.has(e)||!s.sendTyping)return;let c=()=>{try{Promise.resolve(s.sendTyping(o,i)).catch(()=>{})}catch{}};c();let g=setInterval(c,Sn);this.ackTypingTimers.set(e,g)}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),o=t.some(a=>a.fanOut)?t:t.slice(0,1),s=[],i=[];for(let a of o){let d=await this.dispatchOne(a,e.entityRef,e.event,e.trigger);d.claimed&&s.push(a),d.run&&i.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:s,runs:i}}matchByTrigger(e,t){let r=this.store.list(),o=[];for(let s of r){if(s.state&&s.state!=="active")continue;if(t){if(!s.mesh?.allowRemote)continue;let c=s.mesh.peers;if(c&&c.length>0&&!c.includes(t.peer))continue}let i=s.nodes.find(c=>c.type.startsWith("trigger."));if(!i)continue;let a=i.config;if(a.source!==e.source||s.project&&e.project&&s.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!=="*"&&V(e.source,d.chat)!==V(e.source,e.chat))continue;if(d.labels?.length){let c=new Set(e.labels??[]);if(!d.labels.some(u=>c.has(u)))continue}}o.push(s)}return o.sort((s,i)=>i.priority-s.priority||s.id.localeCompare(i.id))}async dispatchOne(e,t,r,o){let s=await this.dispatchOneLegacy(e,t,r,o);if(be("workflow")!=="off")try{Qe(ke(),{workflowId:e.id,eventId:r.id,triggerSource:o.source,project:o.project??null,entityRef:t},JSON.stringify({event:r,trigger:o,entityRef:t}),{claimed:s.claimed,runId:s.run?.id??null})}catch(i){this.log(`[ledger] workflow ${e.id} run ${s.run?.id??"?"} record failed: ${i?.message??i}`)}return s}async dispatchOneLegacy(e,t,r,o){let s=this.runs.getActiveByEntity(t),i=s?this.runs.getHomeNodeByEntity(t):null;if(s&&i&&i!==this.nodeId){if(!this.forwarder)return this.log(`[workflow:${e.id}] run ${s} home'd on "${i}" but no forwarder \u2014 dropping`),{claimed:!1,run:null};try{await this.forwarder.forwardTransition(i,{workflowId:e.id,event:r,entityRef:t})}catch(d){this.log(`[workflow:${e.id}] forward to "${i}" failed: ${d.message}`)}return{claimed:!0,run:null}}let a=s?this.runs.get(s):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(!$n(a.pausedAt.resumeMatch,o,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=N(e,a.pausedAt.nodeId),c=d?e.edges.filter(k=>k.from===d.id).map(k=>k.to):[],g={at:new Date().toISOString(),nodeId:a.pausedAt.nodeId,inputKeys:[],status:"resumed",output:{event:r.payload},idempotencyKey:x(a.id,a.pausedAt.nodeId,`resume:${r.id}`)},u={...a.context,[a.pausedAt.nodeId]:{event:r.payload}},p=a.pausedAt.checkpointName,m=this.runs.recordExecution({runId:a.id,entry:g,nextPending:c,status:"running",pausedAt:null,context:u});m&&(a=m),this.log(`[workflow:${e.id}] run ${a.id} resumed from checkpoint "${p}"`),o.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}),o.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){try{await this.walkInner(e,t,r)}finally{this.stopChannelAck(t)}}async walkInner(e,t,r){let o=this.runs.get(t);if(o)for(;o.status==="running"&&o.pending.length>0;){let s=o.pending.slice(0,An);await Promise.allSettled(s.map(a=>this.executeNodeAndCommit(e,t,a,r)));let i=this.runs.get(t);if(!i||(o=i,o.status!=="running"))return}}async executeNodeAndCommit(e,t,r,o){let s=x(t,r,o),i=await this.commit(t,()=>{let f=this.runs.get(t);if(!f)return{kind:"done"};if(f.status!=="running")return{kind:"done"};let y=N(e,r);if(!y)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:s,note:"node definition missing from workflow"},nextPending:f.pending.filter(A=>A!==r),status:"failed"}),{kind:"done"};let I=pe(y.type);return I?f.history.some(A=>A.idempotencyKey===s)?(this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:r,inputKeys:[],status:"skipped",idempotencyKey:s+"_dedup",note:"duplicate execution dropped"},nextPending:f.pending.filter(A=>A!==r)}),{kind:"done"}):{kind:"go",run:f,node:y,handler:I}:(this.log(`[workflow:${e.id}] no handler for node type "${y.type}"`),this.runs.recordExecution({runId:t,entry:{at:new Date().toISOString(),nodeId:r,inputKeys:[],status:"failed",idempotencyKey:s,note:`no handler for node type "${y.type}"`},nextPending:f.pending.filter(A=>A!==r),status:"failed"}),{kind:"done"})});if(i.kind==="done")return;let{run:a,node:d,handler:c}=i,g=e.edges.filter(f=>f.to===r).map(f=>f.from),u;if(d.type!=="agent"){let f=X();if(f)try{u=Se(f,{agentId:`workflow:${d.type}`,channel:"workflow",chatId:`${e.id}:${r}`,workflowRunId:t,workflowId:e.id,workflowNodeId:r,messagePreview:`${d.type} ${r}`})}catch{}}let p=d.retry??{maxAttempts:1,backoffMs:1e3},m={error:"retry-loop did not run"},k=0;for(;k<p.maxAttempts;){k++;try{m=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(f){this.log(`[workflow:${e.id}] handler "${d.type}" threw: ${f.message}`),m={error:f.message}}if(!m.error||m.paused)break;if(k<p.maxAttempts){let f=p.backoffMs*Math.pow(2,k-1);this.log(`[workflow:${e.id}] node "${r}" failed (attempt ${k}/${p.maxAttempts}): ${m.error.slice(0,120)} \u2014 retrying in ${f}ms`),await new Promise(y=>setTimeout(y,f))}}if(u){let f=X();if(f)try{Ae(f,u,{status:m.error?"error":"ok",error:m.error??null})}catch{}}await this.commit(t,async()=>{let f=this.runs.get(t);if(!f)return;let y=new Date().toISOString(),I=f.pending.filter(h=>h!==r);if(m.error){let h=f.status==="running"?"failed":void 0;this.runs.recordExecution({runId:t,entry:{at:y,nodeId:r,inputKeys:g,status:"failed",idempotencyKey:s,note:m.error.slice(0,200)},nextPending:I,status:h}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:"failed",status:h??f.status,note:m.error.slice(0,200)});return}if(m.paused&&m.pausedAt){let h=m.pausedAt,T=null;if(m.spawnChild&&h.kind==="subProcess"){if(T=await this.spawnChild({parent:f,parentNodeId:r,childWorkflowId:m.spawnChild.workflowId,input:m.spawnChild.input}),!T){this.runs.recordExecution({runId:t,entry:{at:y,nodeId:r,inputKeys:g,status:"failed",idempotencyKey:s,note:`subProcess: child workflow "${m.spawnChild.workflowId}" not found`},nextPending:I,status:"failed"});return}h={...h,childRunId:T.id}}if(this.runs.recordExecution({runId:t,entry:{at:y,nodeId:r,inputKeys:g,status:"paused",idempotencyKey:s},nextPending:I,status:"paused",pausedAt:h}),this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:"paused",status:"paused",note:h.kind}),T&&this.kickChildWalk(T),h.kind==="timerWait")try{this.timers.schedule({runId:t,workflowId:e.id,nodeId:h.nodeId,fireAt:h.fireAt,cancelKey:`${t}:${h.nodeId}`})}catch(he){this.log(`[workflow:${e.id}] timer schedule failed: ${he.message}`)}return}let A=m.output??{},rt={...f.context,[r]:A},{nextPending:ot}=ce({workflow:e,fromNodeId:r,selectedPort:m.port}),Z=[],D={...f.joinCounters??{}};for(let h of ot){let T=N(e,h);if(!(T?.type==="gateway.parallel"&&String(T.config?.mode??"fanOut")==="join")){Z.push(h);continue}let _=D[h]??[];_.includes(r)||_.push(r),D[h]=_;let at=e.edges.filter(dt=>dt.to===h).length;_.length>=at&&(Z.push(h),delete D[h])}let it=[...I,...Z],M=d.type==="end",st=f.status==="running"?M?String(d.config.status??"completed"):"running":void 0,W=this.runs.recordExecution({runId:t,entry:{at:y,nodeId:r,inputKeys:g,status:"ok",output:A,idempotencyKey:s},nextPending:M?[]:it,status:st,context:rt,joinCounters:D});this.emitRunEvent({runId:t,workflowId:e.id,nodeId:r,phase:M?"completed":"ok",status:W?.status??f.status}),m.emitSignal&&this.emitSignal({name:m.emitSignal.name,scope:m.emitSignal.scope,workflowId:e.id,payload:m.emitSignal.payload}),M&&W&&W.parentRunId&&W.parentNodeId&&this.resumeParent({parentRunId:W.parentRunId,parentNodeId:W.parentNodeId,childRun:W}).catch(h=>this.log(`[workflow:${e.id}] resumeParent failed: ${h.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 o={...e.input};o[r.triggerId]={...o[r.triggerId]??{},parentRunId:e.parent.id,parentNodeId:e.parentNodeId};let s={backend:"agentx-internal",id:`subprocess:${e.parent.id}:${e.parentNodeId}`},i=this.runs.create({workflowId:t.id,initialPending:r.pending,entityRef:s,initialContext:o,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 ${i.id} spawned from ${e.parent.id}/${e.parentNodeId} (depth ${i.depth})`),i}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(o=>o.id===t.workflowId);r&&(await this.commit(e.parentRunId,()=>{let o=this.runs.get(e.parentRunId);if(!o||o.status!=="paused"||!o.pausedAt||o.pausedAt.kind!=="subProcess"||o.pausedAt.nodeId!==e.parentNodeId||o.pausedAt.childRunId!==e.childRun.id)return;let s=N(r,e.parentNodeId),i=s?r.edges.filter(d=>d.from===s.id).map(d=>d.to):[],a={childRunId:e.childRun.id,status:e.childRun.status,output:Rn(e.childRun)};this.runs.recordExecution({runId:o.id,entry:{at:new Date().toISOString(),nodeId:e.parentNodeId,inputKeys:[],status:"resumed",output:a,idempotencyKey:x(o.id,e.parentNodeId,`child:${e.childRun.id}`)},nextPending:i,status:"running",pausedAt:null,context:{...o.context,[e.parentNodeId]:a}}),this.log(`[workflow:${r.id}] parent run ${o.id} resumed from subProcess child ${e.childRun.id}`),this.emitRunEvent({runId:o.id,workflowId:r.id,nodeId:e.parentNodeId,phase:"resumed",status:"running",note:`child:${e.childRun.id}`})}),this.walk(r,e.parentRunId,`child:${e.childRun.id}`))}};function Rn(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 $n(n,e,t){let r=s=>{let i=n[s];if(i===void 0||i===""||i==="*")return!0;if(Array.isArray(i)){let a=new Set(e.labels??[]);return i.some(d=>a.has(String(d)))}return s==="chat"?V(e.source,String(i))===V(e.source,e.chat):e[s]===i};if(!r("source")||!r("project")||!r("repo")||!r("chat"))return!1;let o=n.eventIdLike;return!(typeof o=="string"&&o&&!t.id.includes(o))}function V(n,e){return e==null?"":n==="whatsapp-message"?e.replace(/@s\.whatsapp\.net$|@g\.us$/i,"").replace(/[\s+()]/g,""):e}function Pn(n){return{"pre:channel-message":async e=>{let t=e.msg;if(!t)return{};let r=Tn(t.channel);if(!r)return{};let o=t.group?.id??t.sender.id,s={backend:t.channel,id:`${t.channel}:${o}`},{claimed:i}=await n.dispatch({trigger:{source:r,chat:o},entityRef:s,event:{id:`${t.channel}:${t.accountId}:${t.id}`,payload:xn(t)}});return i.length===0?{}:i.every(d=>d.nodes.find(g=>g.type.startsWith("trigger."))?.config?.passthrough===!0)?{}:{blocked:!0,message:`handled by workflow${i.length>1?"s":""}: ${i.map(d=>d.id).join(", ")}`}},"on:gitlab-issue":async e=>{let t=e.project,r=e.iid,o=e.issueEvent;if(!t||r===void 0)return{};let s=Array.isArray(o?.object_attributes?.labels)?o.object_attributes.labels.map(d=>typeof d=="string"?d:d?.title).filter(Boolean):o?.labels?.map(d=>d?.title)??[],i=o?.assignees??o?.object_attributes?.assignee_ids??[],a={backend:"gitlab",id:`${t}#${r}`};return await n.dispatch({trigger:{source:"gitlab-issue",project:t,labels:s},entityRef:a,event:{id:`gitlab-issue:${t}:${r}:${o?.object_attributes?.updated_at||o?.object_attributes?.action||"evt"}`,payload:{issue:{iid:r,title:o?.object_attributes?.title,description:o?.object_attributes?.description,url:o?.object_attributes?.url,action:o?.object_attributes?.action,labels:s,assignees:i},project:t,channel:"gitlab",chatId:`${t}:issue:${r}`}}}),{}},"on:gitlab-mr":async e=>{let t=e.project,r=e.iid,o=e.mrEvent;if(!t||r===void 0)return{};let s=Array.isArray(e.labels)?e.labels:Array.isArray(o?.object_attributes?.labels)?o.object_attributes.labels.map(c=>typeof c=="string"?c:c?.title).filter(Boolean):[],i=o?.assignees??o?.object_attributes?.assignee_ids??[],a=o?.reviewers??[],d={backend:"gitlab",id:`${t}!${r}`};return await n.dispatch({trigger:{source:"gitlab-mr",project:t,labels:s},entityRef:d,event:{id:`gitlab-mr:${t}:${r}:${o?.object_attributes?.updated_at||o?.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:s,assignees:i,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:s}}}),{}},"on:gitlab-note":async e=>{let t=e.project,r=e.noteId,o=e.noteableType,s=e.noteableIid,i=e.text,a=e.authorUsername,d=e.mentions??[];if(!t||!r||!o||!s)return{};let c=o==="merge_request"?{backend:"gitlab",id:`${t}!${s}`}:{backend:"gitlab",id:`${t}#${s}`};return await n.dispatch({trigger:{source:"gitlab-note",project:t},entityRef:c,event:{id:`gitlab-note:${t}:${o}:${s}:${r}`,payload:{note:{id:r,text:i,author:a,mentions:d,noteableType:o,noteableIid:s,noteableTitle:e.noteableTitle},project:t,channel:"gitlab",chatId:`${t}:${o}:${s}`,noteId:r,noteableType:o,noteableIid:s,text:i,author:a,mentions:d}}}),{}},"on:gitlab-pipeline":async e=>{let t=e.project,r=e.pipelineId,o=e.status,s=e.ref;if(!t||!o)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}:${o}`,payload:{pipeline:{id:r,status:o,ref:s},project:t,channel:"gitlab",chatId:`${t}:merge_request:${a}`}}}),{}}}}function Tn(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 xn(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()}}}function Nn(n){let e=n.store.list(),t=0,r=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(i=>i.type.startsWith("trigger."));if(s){if(s.type==="trigger.cron"){let i=s.config;if(!i.spec){n.log(`[workflows] ${o.id} trigger.cron missing config.spec \u2014 skipping`);continue}On({workflowId:o.id,triggerNodeId:s.id,spec:i.spec,timezone:i.timezone??"UTC"},n.dispatcher,n.log),t++}else if(s.type==="trigger.hook"){let i=s.config;if(!i.event||!i.event.startsWith("on:")){n.log(`[workflows] ${o.id} trigger.hook config.event must start with "on:" \u2014 skipping`);continue}n.hooks.registerHandler(i.event,`workflows:${o.id}`,async a=>{try{let d=typeof a.project=="string"?a.project:void 0;if(o.project&&d&&o.project!==d)return{};if(i.filter){if(Array.isArray(i.filter.topic)&&i.filter.topic.length>0){let p=typeof a.topic=="string"?a.topic.toLowerCase():void 0;if(!p||!i.filter.topic.map(m=>m.toLowerCase()).includes(p))return{}}if(Array.isArray(i.filter.action)&&i.filter.action.length>0){let p=typeof a.action=="string"?a.action:void 0;if(!p||!i.filter.action.includes(p))return{}}if(Array.isArray(i.filter.mentions)&&i.filter.mentions.length>0){let p=Array.isArray(a.mentions)?a.mentions.map(f=>f.toLowerCase().replace(/^@/,"")):[];if(!i.filter.mentions.map(f=>f.toLowerCase().replace(/^@/,"")).some(f=>p.includes(f)))return{}}if(Array.isArray(i.filter.noteableType)&&i.filter.noteableType.length>0){let p=typeof a.noteableType=="string"?a.noteableType.toLowerCase():void 0,m=i.filter.noteableType.map(k=>k.toLowerCase());if(!p||!m.includes(p))return{}}if(Array.isArray(i.filter.assigneesAdded)&&i.filter.assigneesAdded.length>0){let p=Array.isArray(a.assigneesAdded)?a.assigneesAdded.map(f=>f.toLowerCase().replace(/^@/,"")):[];if(!i.filter.assigneesAdded.map(f=>f.toLowerCase().replace(/^@/,"")).some(f=>p.includes(f)))return{}}if(Array.isArray(i.filter.reviewersAdded)&&i.filter.reviewersAdded.length>0){let p=Array.isArray(a.reviewersAdded)?a.reviewersAdded.map(f=>f.toLowerCase().replace(/^@/,"")):[];if(!i.filter.reviewersAdded.map(f=>f.toLowerCase().replace(/^@/,"")).some(f=>p.includes(f)))return{}}if(Array.isArray(i.filter.labelsAdded)&&i.filter.labelsAdded.length>0){let p=Array.isArray(a.labelsAdded)?a.labelsAdded.map(f=>f.toLowerCase()):[];if(!i.filter.labelsAdded.map(f=>f.toLowerCase()).some(f=>p.includes(f)))return{}}}let c=Wn(o.id,i.event,a);if(await n.dispatcher.dispatchWorkflow({workflowId:o.id,entityRef:{backend:"hook",id:c},event:{id:`hook:${i.event}:${Date.now().toString(36)}`,payload:{hookEvent:i.event,...a}}}),i.passthrough)return{};let g=a.__workflowClaimed;return{modified:{__workflowClaimed:[...Array.isArray(g)?g:[],o.id]}}}catch(d){return n.log(`[workflows] ${o.id} hook dispatch failed: ${d.message}`),{}}},60),r++}}}return{cronTimers:t,hookSubscribers:r}}function Wn(n,e,t){let r=typeof t.project=="string"?t.project:"",o=t.iid!=null?String(t.iid):"";if(e==="on:gitlab-issue"&&r&&o)return`${n}:${e}:${r}#${o}`;if(e==="on:gitlab-mr"&&r&&o)return`${n}:${e}:${r}!${o}`;if(e==="on:gitlab-pipeline"&&r){let s=t.pipelineId!=null?String(t.pipelineId):"";if(s)return`${n}:${e}:${r}@pipeline:${s}`}return`${n}:${e}:${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function On(n,e,t){let r=()=>{let o;try{o=Re(n.spec,new Date,n.timezone)}catch(i){t(`[workflows] ${n.workflowId} cron spec invalid: ${i.message}`);return}let s=Math.max(1e3,o.getTime()-Date.now());setTimeout(()=>{(async()=>{let i=`cron:${n.workflowId}:${o.toISOString()}`;try{await e.dispatchWorkflow({workflowId:n.workflowId,trigger:{source:"cron"},entityRef:{backend:"cron",id:`${n.workflowId}@${o.toISOString()}`},event:{id:i,payload:{now:o.toISOString(),spec:n.spec,workflowId:n.workflowId}}})}catch(a){t(`[workflows] ${n.workflowId} cron dispatch failed: ${a.message}`)}finally{r()}})()},s)};r()}function Xe(n){return n.nodes.find(r=>r.type.startsWith("trigger."))?.config?.inputSchema??null}function et(n,e){if(!n||!e?.properties)return{};let t=n.match(/^([^:]+\/[^:]+):([^:]+):(.+)$/);if(!t)return{};let[,r,o,s]=t,i={};if(e.properties.project&&(i.project=r),o==="push"){let a=s.match(/^refs\/heads\/(.+)$/);a&&e.properties.ref&&(i.ref=a[1])}else{let a=Number(s);Number.isFinite(a)&&(e.properties.id&&(i.id=a),e.properties.iid&&(i.iid=a),e.properties.mrId&&(i.mrId=a),e.properties.issueId&&(i.issueId=a),e.properties.prId&&(i.prId=a))}return i}function tt(n,e){if(!n?.properties)return e;let t={...e};for(let[r,o]of Object.entries(n.properties))t[r]===void 0&&o&&"default"in o&&(t[r]=o.default);return t}function nt(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 jn(n,e){let t=Xe(n);if(!t?.properties){let d={};for(let[c,g]of Object.entries(e))g!==void 0&&(d[c]=g);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 o=et(e.chatId,t),s={...r,...o},i={...s};s=tt(t,s);let a=Object.keys(s).filter(d=>i[d]===void 0&&s[d]!==void 0);return{inputs:s,missing:nt(t,s),filledFrom:{passthrough:Object.keys(r),chatId:Object.keys(o),defaults:a}}}export{Te as a,$ as b,ee as c,b as d,L as e,Tt as f,oe as g,se as h,de as i,me as j,Pn as k,Nn as l,qt as m,jn as n};
|
|
9
|
-
//# sourceMappingURL=chunk-
|
|
9
|
+
//# sourceMappingURL=chunk-5FEQI22L.js.map
|