qlogicagent 2.19.13 → 2.20.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 (92) hide show
  1. package/README.md +0 -1
  2. package/dist/agent-contract.js +1 -1
  3. package/dist/agent.js +31 -31
  4. package/dist/cli.js +1 -1
  5. package/dist/host-contract.js +1 -1
  6. package/dist/index.js +457 -453
  7. package/dist/orchestration.js +13 -13
  8. package/dist/project-memory-host.js +19 -18
  9. package/dist/protocol.js +1 -1
  10. package/dist/tunables.js +1 -1
  11. package/dist/types/cli/acp-extended-handlers.d.ts +5 -10
  12. package/dist/types/cli/acp-extended-host-adapter.d.ts +1 -1
  13. package/dist/types/cli/community-workflow-installer.d.ts +2 -2
  14. package/dist/types/cli/handlers/dream-handler.d.ts +6 -0
  15. package/dist/types/cli/handlers/goal-handler.d.ts +1 -13
  16. package/dist/types/cli/handlers/product-handler.d.ts +6 -9
  17. package/dist/types/cli/handlers/solo-handler.d.ts +3 -6
  18. package/dist/types/cli/handlers/workflow-compute-handler.d.ts +1 -1
  19. package/dist/types/cli/memory-coordinator.d.ts +0 -2
  20. package/dist/types/cli/multi-agent-handler-host.d.ts +1 -1
  21. package/dist/types/cli/orchestration-memory-context.d.ts +1 -0
  22. package/dist/types/cli/product-coordinator.d.ts +2 -5
  23. package/dist/types/cli/rpc-registry.d.ts +0 -3
  24. package/dist/types/cli/runtime-hook-bootstrap.d.ts +0 -2
  25. package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +2 -1
  26. package/dist/types/cli/stdio-server.d.ts +2 -3
  27. package/dist/types/cli/task-distillation-coordinator.d.ts +0 -3
  28. package/dist/types/contracts/hooks.d.ts +2 -0
  29. package/dist/types/host-contract/index.d.ts +3 -13
  30. package/dist/types/index.d.ts +0 -1
  31. package/dist/types/orchestration/agent-instance.d.ts +30 -15
  32. package/dist/types/orchestration/agent-roster.d.ts +2 -2
  33. package/dist/types/orchestration/goal-loop-coordinator.d.ts +18 -8
  34. package/dist/types/orchestration/goal-mode-adapters.d.ts +6 -1
  35. package/dist/types/orchestration/goal-run-persistence.d.ts +12 -10
  36. package/dist/types/orchestration/goal-run-types.d.ts +3 -21
  37. package/dist/types/orchestration/index.d.ts +0 -1
  38. package/dist/types/orchestration/product-checkpoint.d.ts +10 -6
  39. package/dist/types/orchestration/product-persistence.d.ts +47 -20
  40. package/dist/types/orchestration/product-planner.d.ts +30 -10
  41. package/dist/types/orchestration/product-run-coordinator.d.ts +4 -3
  42. package/dist/types/orchestration/solo-evaluator.d.ts +10 -16
  43. package/dist/types/orchestration/solo-persistence.d.ts +10 -10
  44. package/dist/types/orchestration/workflow/budget-permission-gate.d.ts +1 -1
  45. package/dist/types/orchestration/workflow/capability-catalog.d.ts +11 -34
  46. package/dist/types/orchestration/workflow/host-executors.d.ts +3 -3
  47. package/dist/types/orchestration/workflow/n8n-import.d.ts +0 -1
  48. package/dist/types/orchestration/workflow/node-schema.d.ts +5 -18
  49. package/dist/types/orchestration/workflow/params-schema.d.ts +7 -16
  50. package/dist/types/orchestration/workflow/qla-executor-host.d.ts +4 -27
  51. package/dist/types/orchestration/workflow/workflow-bundle.d.ts +10 -28
  52. package/dist/types/orchestration/workflow/workflow-controller.d.ts +14 -8
  53. package/dist/types/orchestration/workflow/workflow-error.d.ts +1 -1
  54. package/dist/types/orchestration/workflow/workflow-render.d.ts +1 -1
  55. package/dist/types/orchestration/workflow/workflow-scheduler.d.ts +8 -8
  56. package/dist/types/orchestration/workflow/workflow-store.d.ts +7 -8
  57. package/dist/types/orchestration/workflow-chat-builder.d.ts +1 -1
  58. package/dist/types/protocol/agent-contract.d.ts +7 -7
  59. package/dist/types/protocol/methods.d.ts +1 -129
  60. package/dist/types/protocol/notifications.d.ts +1 -1
  61. package/dist/types/protocol/wire/acp-agent-management.d.ts +45 -24
  62. package/dist/types/protocol/wire/acp-protocol.d.ts +3 -8
  63. package/dist/types/protocol/wire/agent-methods.d.ts +2 -468
  64. package/dist/types/protocol/wire/index.d.ts +1 -1
  65. package/dist/types/protocol/wire/notification-payloads.d.ts +0 -6
  66. package/dist/types/protocol/wire/thread-protocol.d.ts +1 -1
  67. package/dist/types/runtime/config/tunable-defaults.d.ts +0 -9
  68. package/dist/types/runtime/hooks/memory-hooks.d.ts +11 -4
  69. package/dist/types/runtime/infra/acp-protocol-adapter.d.ts +1 -2
  70. package/dist/types/runtime/memory/implicit-extraction.d.ts +4 -1
  71. package/dist/types/runtime/memory/recall-category-filter.d.ts +0 -12
  72. package/dist/types/runtime/ports/memory-recall-source.d.ts +1 -0
  73. package/dist/types/runtime/ports/project-memory-store.d.ts +3 -0
  74. package/dist/types/skills/memory/host-memory-provider.d.ts +7 -0
  75. package/dist/types/skills/memory/memdir.d.ts +1 -2
  76. package/dist/types/skills/memory/task-distillation.d.ts +18 -4
  77. package/dist/types/skills/skill-system/skill-lifecycle.d.ts +0 -17
  78. package/dist/types/skills/skill-system/skill-validation.d.ts +1 -1
  79. package/dist/types/transport/acp-server.d.ts +1 -5
  80. package/dist/types/workflow-host.d.ts +2 -4
  81. package/dist/workflow-host.js +7 -9
  82. package/package.json +1 -1
  83. package/dist/types/cli/credential-vault.d.ts +0 -68
  84. package/dist/types/orchestration/skill-improvement.d.ts +0 -97
  85. package/dist/types/skills/memory/local-store-records.d.ts +0 -206
  86. package/dist/types/skills/memory/local-store.d.ts +0 -376
  87. package/dist/types/skills/memory/memory-attachment-store.d.ts +0 -62
  88. package/dist/types/skills/memory/memory-consolidation.d.ts +0 -64
  89. package/dist/types/skills/memory/memory-db-path.d.ts +0 -13
  90. package/dist/types/skills/memory/proposal-consumer.d.ts +0 -51
  91. package/dist/types/skills/memory/sqlite-memory-mappers.d.ts +0 -7
  92. package/dist/types/skills/memory/sqlite-memory-schema.d.ts +0 -11
@@ -1,13 +1,11 @@
1
- import{join as $}from"node:path";import{mkdir as st,readdir as at,rm as ut}from"node:fs/promises";import{readFile as Yt,writeFile as Qt,mkdir as Xt,rename as Zt,unlink as en}from"node:fs/promises";import{dirname as tn,join as nn}from"node:path";import{randomUUID as rn}from"node:crypto";async function on(r,e){let t=tn(r);await Xt(t,{recursive:!0});let n=nn(t,`.tmp-${rn()}`);try{await Qt(n,e,"utf-8");let o;for(let i=0;i<3;i++)try{await Zt(n,r);return}catch(s){if(o=s,s.code!=="EPERM")throw s;await new Promise(a=>setTimeout(a,50*(i+1)))}throw o}catch(o){throw await en(n).catch(()=>{}),o}}async function C(r){try{let e=await Yt(r,"utf-8");return JSON.parse(e)}catch(e){if(e.code==="ENOENT")return;throw e}}async function j(r,e){await on(r,JSON.stringify(e,null,2)+`
2
- `)}import{resolve as yn}from"node:path";import{join as mn}from"node:path";import{homedir as un}from"node:os";import{join as y}from"node:path";import{existsSync as Wo}from"node:fs";import{createHash as sn}from"node:crypto";import{resolve as an}from"node:path";function me(r){return sn("sha256").update(an(r).toLowerCase()).digest("hex").slice(0,16)}var Le=".qlogicagent";function I(){return process.env.QLOGICAGENT_HOME||y(un(),Le)}function ee(){let r=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(r)return r;let e=process.env.QLOGIC_IMPLICIT_OWNER_ID?.trim();if(e)return e;let t=process.env.QLOGIC_DEVICE_ID?.trim();return t?`oc_${t}`:"oc_local"}function dn(r){let e=r.trim();if(!e)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(e).replace(/\./g,"%2E")}function _(r=ee()){return y(I(),"profiles",dn(r))}function Ke(r=ee()){return y(_(r),"memory")}var cn="projectData";function Je(){return y(I(),cn)}function he(r){if(!r)throw new Error("getProjectDataDirById: projectId is required");return y(Je(),r)}function Ge(){return y(I(),"plugins")}function Ve(){return y(I(),"skills")}function ze(){return y(_(),"settings.json")}function Ye(){return y(I(),"plugin-cache")}function Qe(){return y(I(),"mcp.json")}function Xe(){return y(I(),"marketplace.json")}function H(r){if(!r)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return y(r,Le)}function Ze(r){return y(H(r),"plugins")}function et(r){return y(H(r),"settings.json")}function tt(r){return y(H(r),"INSTRUCTIONS.md")}function nt(r){return y(H(r),"rules")}import{resolve as qo}from"node:path";var ln=()=>{},we;function rt(){if(fn(),!we)throw new Error("host project authority negotiated but snapshot is not hydrated");return{activeProjectId:we.activeProjectId,projects:we.projects.map(r=>({...r}))}}function fn(){let r=ln();if(!r)throw new Error("gateway project authority is not available");return r}function gn(){let r=rt();return{activeProjectId:r.activeProjectId,projects:r.projects.map(e=>({...e}))}}function ot(r){return gn().projects.find(e=>e.id===r)??null}function hn(r){return ot(r)?r:me(r)}function wn(r){return he(hn(r))}function it(r){return mn(wn(r),"sessions")}var ye=class{constructor(e={}){this.options=e}options;lastActiveWorkdir=null;getActiveProjectRoot(){return this.options.getActiveProjectRoot?.()??process.cwd()}setActiveWorkdir(e){let t=yn(e);this.lastActiveWorkdir=t,this.options.setActiveWorkdir?.(t)}getActiveWorkdir(){return this.lastActiveWorkdir??this.getActiveProjectRoot()}resolveProjectDir(e){return this.options.resolveProjectDir?.(e)}resolveActiveOwnerUserId(){return ee()}getUserAgentHome(){return I()}getOwnerProfileDir(e){return _(e)}getProfileMemoryDir(e){return Ke(e)}getUserSettingsPath(){return ze()}getUserSkillsDir(){return Ve()}getUserPluginsDir(){return Ge()}getUserMcpConfigPath(){return Qe()}getUserPluginCacheDir(){return Ye()}getUserMarketplaceConfigPath(){return Xe()}getProjectAgentDir(e=this.getActiveProjectRoot()){return H(e)}getProjectSettingsPath(e=this.getActiveProjectRoot()){return et(e)}getProjectInstructionsPath(e=this.getActiveProjectRoot()){return tt(e)}getProjectPluginsDir(e=this.getActiveProjectRoot()){return Ze(e)}getProjectRulesDir(e=this.getActiveProjectRoot()){return nt(e)}getProjectSessionDataRoot(e=this.getActiveProjectRoot()){return it(e)}},kn=new ye;function te(){return kn}function A(r){return $(te().getProjectAgentDir(r),"workflows")}function dt(r,e){return $(A(e),r,"workflow.json")}function ke(r,e){return $(A(e),r,"revisions")}var bn=20,be=class{constructor(e){this.cwd=e;if(!e)throw new Error("WorkflowStore requires a project cwd")}cwd;async save(e){if(!e.id)throw new Error("WorkflowRecord.id is required");let t=$(A(this.cwd),e.id);await st(t,{recursive:!0}),await j(dt(e.id,this.cwd),e),await this.snapshotRevision(e)}async snapshotRevision(e){try{let t=ke(e.id,this.cwd);await st(t,{recursive:!0}),await j($(t,`${e.rev}.json`),e);let n=await this.revisionNumbers(e.id);for(let o of n.slice(bn))await ut($(t,`${o}.json`),{force:!0})}catch{}}async revisionNumbers(e){let t;try{t=await at(ke(e,this.cwd))}catch{return[]}return t.map(n=>Number(n.replace(/\.json$/,""))).filter(n=>Number.isInteger(n)&&n>0).sort((n,o)=>o-n)}async listRevisions(e){let t=[];for(let n of await this.revisionNumbers(e)){let o=await this.loadRevision(e,n);o&&t.push({rev:n,updatedAt:o.updatedAt,name:o.name,nodeCount:o.def.nodes.length})}return t}async loadRevision(e,t){return C($(ke(e,this.cwd),`${t}.json`))}async load(e){return C(dt(e,this.cwd))}async require(e){let t=await this.load(e);if(!t)throw new Error(`Workflow "${e}" not found`);return t}async list(){let e;try{e=await at(A(this.cwd))}catch{return[]}let t=[];for(let n of e){let o=await this.load(n);o&&t.push(o)}return t}async listActive(){return(await this.list()).filter(e=>e.active)}async delete(e){await ut($(A(this.cwd),e),{recursive:!0,force:!0})}};var q=class{nodes=new Map;edges=[];constructor(e){for(let t of e){if(this.nodes.has(t.id))throw new Error(`Duplicate node ID: ${t.id}`);this.nodes.set(t.id,{id:t.id,kind:t.kind??"agent",params:t.params??{},status:"pending",outPorts:t.outPorts??["default"],joinPolicy:t.joinPolicy??"all",runIndex:0,maxIterations:t.maxIterations})}for(let t of e)for(let n of t.dependsOn??[]){if(!this.nodes.has(n))throw new Error(`Node "${t.id}" depends on unknown node "${n}"`);this.edges.push({from:n,to:t.id,fromPort:"default"})}this.validateDag()}getNode(e){return this.nodes.get(e)}getAllNodes(){return[...this.nodes.values()]}getReadyNodes(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending"||this.isBlockedByFailed(t.id))continue;let n=this.incomingForwardEdges(t.id);if(n.length===0){e.push(t);continue}t.joinPolicy==="any"?n.some(o=>this.edgeSatisfied(o))&&e.push(t):n.every(o=>this.edgeSatisfied(o))&&e.push(t)}return e}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!this.isBlockedByFailed(e.id)&&!this.isSkippable(e.id))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed"||e.status==="skipped")}getBlockedNodes(){return[...this.nodes.values()].filter(e=>e.status==="pending"&&this.isBlockedByFailed(e.id))}getProgress(){let e=0,t=0,n=0,o=0,i=0,s=0;for(let a of this.nodes.values())switch(a.status){case"completed":e++;break;case"running":t++;break;case"failed":n++;break;case"pending":o++;break;case"paused":i++;break;case"skipped":s++;break}return{total:this.nodes.size,completed:e,running:t,failed:n,pending:o,paused:i,skipped:s}}markRunning(e){let t=this.requireNode(e);if(t.status!=="pending")throw new Error(`Node "${e}" is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let n=this.requireNode(e);if(n.status!=="running")throw new Error(`Node "${e}" is ${n.status}, cannot complete`);n.status="completed",n.output=t.output,n.completedAt=Date.now(),n.firedPorts=t.firedPorts??n.outPorts,t.inputTokens!==void 0&&(n.inputTokens=t.inputTokens),t.outputTokens!==void 0&&(n.outputTokens=t.outputTokens),t.changedFiles!==void 0&&(n.changedFiles=t.changedFiles),n.acceptanceUnverified=t.acceptanceUnverified,this.propagateSkips()}markFailed(e,t){let n=this.requireNode(e);n.status="failed",n.error=t,n.completedAt=Date.now(),this.propagateSkips()}markPaused(e){let t=this.requireNode(e);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.requireNode(e);t.status==="paused"&&(t.status="pending")}markSkipped(e){let t=this.requireNode(e);if(t.status!=="pending")throw new Error(`Node "${e}" is ${t.status}, cannot skip`);t.status="skipped",t.firedPorts=[],this.propagateSkips()}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}decideLoop(e,t){let n=this.requireNode(e);if(n.kind!=="loop")throw new Error(`Node "${e}" is not a loop controller`);if(!n.maxIterations||n.maxIterations<=0)throw new Error(`Loop "${e}" requires maxIterations > 0`);let o=n.iteration??0;t&&o<n.maxIterations?(n.iteration=o+1,n.firedPorts=["loop"],this.resetLoopScope(e)):(n.firedPorts=["done"],t&&(n.error=`loop_cap_reached:${n.maxIterations}`)),this.propagateSkips()}addNode(e){if(this.nodes.has(e.id))throw new Error(`Node "${e.id}" already exists`);for(let t of e.dependsOn??[])if(!this.nodes.has(t))throw new Error(`Node "${e.id}" depends on unknown node "${t}"`);this.nodes.set(e.id,{id:e.id,kind:e.kind??"agent",params:e.params??{},status:"pending",outPorts:e.outPorts??["default"],joinPolicy:e.joinPolicy??"all",runIndex:0,maxIterations:e.maxIterations});for(let t of e.dependsOn??[])this.edges.push({from:t,to:e.id,fromPort:"default"});try{this.validateDag()}catch(t){throw this.nodes.delete(e.id),this.edges=this.edges.filter(n=>n.to!==e.id||!e.dependsOn?.includes(n.from)),t}}addNodes(e){let t=[],n=[];try{for(let o of e){if(this.nodes.has(o.id))throw new Error(`Node "${o.id}" already exists`);for(let s of o.dependsOn??[])if(!this.nodes.has(s))throw new Error(`Unknown dep "${s}" for "${o.id}"`);this.nodes.set(o.id,{id:o.id,kind:o.kind??"agent",params:o.params??{},status:"pending",outPorts:o.outPorts??["default"],joinPolicy:o.joinPolicy??"all",runIndex:0,maxIterations:o.maxIterations}),t.push(o.id);let i=(o.dependsOn??[]).map(s=>({from:s,to:o.id,fromPort:"default"}));this.edges.push(...i),n.push(...i)}this.validateDag()}catch(o){for(let i of t)this.nodes.delete(i);throw this.edges=this.edges.filter(i=>!n.includes(i)),o}}removeNode(e){let t=this.requireNode(e);if(t.status==="running")throw new Error(`Cannot remove running node "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed node "${e}"`);this.edges=this.edges.filter(n=>n.from!==e&&n.to!==e),this.nodes.delete(e)}retryNode(e,t){let n=this.requireNode(e);if(n.status!=="failed")throw new Error(`Node "${e}" is ${n.status}, only failed nodes can be retried`);n.status="pending",n.error=void 0,n.output=void 0,n.firedPorts=void 0,n.startedAt=void 0,n.completedAt=void 0,n.inputTokens=void 0,n.outputTokens=void 0,n.changedFiles=void 0,t&&Object.assign(n.params,t)}resetForReplay(e){if(!this.nodes.has(e))throw new Error(`Node "${e}" not found`);let t=new Set([e]),n=!0;for(;n;){n=!1;for(let o of this.nodes.values()){if(t.has(o.id))continue;this.incomingForwardEdges(o.id).map(s=>s.from).some(s=>t.has(s))&&(t.add(o.id),n=!0)}}for(let o of t){let i=this.nodes.get(o);i.status="pending",i.output=void 0,i.firedPorts=void 0,i.error=void 0,i.startedAt=void 0,i.completedAt=void 0,i.inputTokens=void 0,i.outputTokens=void 0,i.changedFiles=void 0}return[...t]}updateNodeParams(e,t){let n=this.requireNode(e);if(n.status!=="pending")throw new Error(`Node "${e}" is ${n.status}, can only update pending nodes`);Object.assign(n.params,t)}addEdge(e){let{from:t,to:n,fromPort:o="default",loopBack:i=!1}=e;if(!this.nodes.has(t))throw new Error(`Unknown source node "${t}"`);if(!this.nodes.has(n))throw new Error(`Unknown target node "${n}"`);let s=this.nodes.get(t);if(!i&&!s.outPorts.includes(o))throw new Error(`Node "${t}" has no outPort "${o}"`);if(!this.edges.find(d=>d.from===t&&d.to===n&&(d.fromPort??"default")===o))if(this.edges.push({from:t,to:n,fromPort:o,loopBack:i}),i){let d=this.nodes.get(n);if(!d.maxIterations||d.maxIterations<=0)throw this.edges.pop(),new Error(`LoopBack controller "${n}" requires maxIterations > 0`)}else try{this.validateDag()}catch(d){throw this.edges=this.edges.filter(l=>!(l.from===t&&l.to===n&&(l.fromPort??"default")===o)),d}}removeEdge(e,t,n){let o=n??"default";this.edges=this.edges.filter(i=>!(i.from===e&&i.to===t&&(i.fromPort??"default")===o))}serialize(){return[...this.nodes.values()].map(e=>{let t=this.incomingForwardEdges(e.id).map(n=>n.from);return{id:e.id,kind:e.kind,params:e.params,dependsOn:t,outPorts:e.outPorts,joinPolicy:e.joinPolicy,status:e.status,firedPorts:e.firedPorts,output:e.output,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt,inputTokens:e.inputTokens,outputTokens:e.outputTokens,changedFiles:e.changedFiles,acceptanceUnverified:e.acceptanceUnverified,runIndex:e.runIndex,maxIterations:e.maxIterations,iteration:e.iteration}})}restore(e){for(let t of e){let n=this.nodes.get(t.id);n&&(n.status=t.status==="running"?"pending":t.status,n.output=t.output,n.error=t.error,n.firedPorts=t.firedPorts,n.startedAt=t.startedAt,n.completedAt=t.completedAt,n.inputTokens=t.inputTokens,n.outputTokens=t.outputTokens,n.changedFiles=t.changedFiles,n.acceptanceUnverified=t.acceptanceUnverified,n.runIndex=t.runIndex??0,n.iteration=t.iteration)}}getUpstreamOutputs(e){if(!this.nodes.get(e))return[];let n=this.incomingForwardEdges(e),o=new Set,i=[];for(let s of n){let a=s.from;if(o.has(a))continue;o.add(a);let d=this.nodes.get(a);if(d&&d.status==="completed"&&d.output!=null){let l=typeof d.output=="string"?d.output:JSON.stringify(d.output);l.trim()&&i.push({taskId:a,output:l})}}return i}edgeSatisfied(e){let t=this.nodes.get(e.from);if(!t||t.status!=="completed")return!1;let n=e.fromPort??"default";return(t.firedPorts??t.outPorts).includes(n)}edgeDead(e){let t=this.nodes.get(e.from);if(!t)return!1;if(t.status==="skipped")return!0;if(t.status==="completed"){if(t.kind==="loop"&&!(t.firedPorts??[]).includes("done"))return!1;let n=e.fromPort??"default";return!(t.firedPorts??t.outPorts).includes(n)}return!1}incomingForwardEdges(e){return this.edges.filter(t=>t.to===e&&!t.loopBack)}isBlockedByFailed(e){return this.incomingForwardEdges(e).some(t=>this.nodes.get(t.from)?.status==="failed")}isSkippable(e){let t=this.incomingForwardEdges(e);return t.length===0?!1:this.nodes.get(e).joinPolicy==="any"?t.every(o=>this.edgeDead(o)):t.some(o=>this.edgeDead(o))}propagateSkips(){let e=!0;for(;e;){e=!1;for(let t of this.nodes.values())t.status==="pending"&&this.isSkippable(t.id)&&(t.status="skipped",t.firedPorts=[],e=!0)}}resetLoopScope(e){let t=this.loopBodyNodes(e);for(let n of t){let o=this.nodes.get(n);o.status="pending",o.runIndex=(o.runIndex??0)+1,o.output=void 0,o.firedPorts=void 0,o.error=void 0,o.startedAt=void 0,o.completedAt=void 0,o.inputTokens=void 0,o.outputTokens=void 0,o.changedFiles=void 0}}loopBodyNodes(e){let t=new Set,n=(o,i)=>{for(let s of this.edges)s.from!==o||s.loopBack||i&&(s.fromPort??"default")!=="loop"||s.to!==e&&(t.has(s.to)||(t.add(s.to),n(s.to,!1)))};return n(e,!0),t}validateDag(){for(let i of this.edges){if(!this.nodes.has(i.from))throw new Error(`Edge references unknown source "${i.from}"`);if(!this.nodes.has(i.to))throw new Error(`Edge references unknown target "${i.to}"`)}let e=this.edges.filter(i=>!i.loopBack),t=new Set,n=new Set,o=i=>{if(n.has(i))throw new Error(`Cycle detected involving node "${i}"`);if(!t.has(i)){n.add(i);for(let s of e)s.from===i&&o(s.to);n.delete(i),t.add(i)}};for(let i of this.nodes.keys())o(i);for(let i of this.edges){if(!i.loopBack)continue;let s=this.nodes.get(i.to);if(!s?.maxIterations||s.maxIterations<=0)throw new Error(`LoopBack controller "${i.to}" must have maxIterations > 0`)}for(let i of this.nodes.values())if(i.maxIterations!==void 0&&i.maxIterations>1e3)throw new Error(`Loop "${i.id}" maxIterations ${i.maxIterations} exceeds the hard cap of 1000`)}requireNode(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown node: "${e}"`);return t}};function D(r,e){return e?{json:r,binary:e}:{json:r}}function ct(r){let e={};for(let t of Object.keys(r).sort())e[t]=r[t].map(n=>({json:n.json,binary:n.binary?Object.fromEntries(Object.keys(n.binary).sort().map(o=>[o,n.binary[o].ref])):void 0}));return xe(e)}function xe(r){return JSON.stringify(ve(r))}function ve(r){if(Array.isArray(r))return r.map(ve);if(r&&typeof r=="object"){let e={};for(let t of Object.keys(r).sort())e[t]=ve(r[t]);return e}return r}var pt=new Set(["__proto__","prototype","constructor"]);function lt(r,e){let t=ht(r),n=new oe(t,r),o=n.parseExpression();return n.expectEnd(),B(o,e)}function ie(r){try{let e=ht(r),t=new oe(e,r),n=t.parseExpression();return t.expectEnd(),G(n),null}catch(e){return e instanceof Error?e.message:String(e)}}var vn=new Set(["input","json","node","now","vars","trigger"]),ft=new Set(["len","upper","lower","default","jsonpath","date"]);function G(r){switch(r.type){case"root":if(!vn.has(r.name))throw new Error(`Unknown context root "$${r.name}" (allowed: $input $json $node $now $vars $trigger)`);return;case"lit":return;case"func":if(!ft.has(r.name))throw new Error(`Unknown function "${r.name}" (whitelist: ${[...ft].join(", ")})`);r.args.forEach(G);return;case"prop":G(r.target);return;case"index":if(G(r.target),typeof r.key!="number"&&typeof r.key!="string")throw new Error("index key must be a number or string literal");return;case"call":if(!(r.target.type==="root"&&r.target.name==="node"))throw new Error("Only $node(...) is callable in this position");r.args.forEach(G);return}}function P(r,e){let t=r.match(/^\s*\{\{([\s\S]*)\}\}\s*$/);return t?lt(t[1],e):r.includes("{{")?r.replace(/\{\{([\s\S]*?)\}\}/g,(n,o)=>{let i=lt(o,e);if(i==null)throw new Error(`Expression "{{${o.trim()}}}" resolved to ${i} in string interpolation`);return typeof i=="object"?JSON.stringify(i):String(i)}):r}function mt(r,e){return Re(r,e)}function Re(r,e){if(typeof r=="string")return P(r,e);if(Array.isArray(r))return r.map(t=>Re(t,e));if(r&&typeof r=="object"){let t={};for(let[n,o]of Object.entries(r))t[n]=Re(o,e);return t}return r}function ht(r){let e=[],t=0,n=i=>/[A-Za-z_]/.test(i),o=i=>/[A-Za-z0-9_]/.test(i);for(;t<r.length;){let i=r[t];if(/\s/.test(i)){t++;continue}if(i==="$"){t++;let s="";for(;t<r.length&&o(r[t]);)s+=r[t++];if(!s)throw new Error('Bare "$" is not a valid expression');e.push({t:"dollar",v:s});continue}if(n(i)){let s="";for(;t<r.length&&o(r[t]);)s+=r[t++];e.push({t:"id",v:s});continue}if(/[0-9]/.test(i)||i==="-"&&/[0-9]/.test(r[t+1]??"")){let s=r[t++];for(;t<r.length&&/[0-9.]/.test(r[t]);)s+=r[t++];e.push({t:"num",v:s});continue}if(i==='"'||i==="'"){let s=i;t++;let a="";for(;t<r.length&&r[t]!==s;)r[t]==="\\"&&t+1<r.length?(a+=r[t+1],t+=2):a+=r[t++];if(r[t]!==s)throw new Error("Unterminated string literal in expression");t++,e.push({t:"str",v:a});continue}if(".[](),".includes(i)){e.push({t:"punc",v:i}),t++;continue}throw new Error(`Unexpected character "${i}" in expression`)}return e}var oe=class{constructor(e,t){this.toks=e;this.src=t}toks;src;pos=0;parseExpression(){return this.parseAccessors(this.parseAtom())}peek(){return this.toks[this.pos]}next(){return this.toks[this.pos++]}expectEnd(){if(this.pos!==this.toks.length)throw new Error(`Unexpected trailing tokens in expression "${this.src.trim()}"`)}parseAtom(){let e=this.peek();if(!e)throw new Error("Empty expression");if(e.t==="dollar")return this.next(),{type:"root",name:e.v};if(e.t==="num")return this.next(),{type:"lit",value:Number(e.v)};if(e.t==="str")return this.next(),{type:"lit",value:e.v};if(e.t==="id"){if(e.v==="true")return this.next(),{type:"lit",value:!0};if(e.v==="false")return this.next(),{type:"lit",value:!1};if(e.v==="null")return this.next(),{type:"lit",value:null};if(this.next(),this.peek()?.t==="punc"&&this.peek().v==="("){let t=this.parseArgs();return{type:"func",name:e.v,args:t}}throw new Error(`Bare identifier "${e.v}" is not allowed (only whitelist function calls)`)}if(e.t==="punc"&&e.v==="("){this.next();let t=this.parseExpression();return this.expectPunc(")"),t}throw new Error(`Unexpected token "${e.v}" in expression`)}parseAccessors(e){let t=e;for(;;){let n=this.peek();if(!n||n.t!=="punc")break;if(n.v==="."){this.next();let o=this.next();if(!o||o.t!=="id"&&o.t!=="num")throw new Error('Expected property name after "."');t={type:"prop",target:t,key:o.v}}else if(n.v==="["){this.next();let o=this.next(),i;if(o.t==="num")i=Number(o.v);else if(o.t==="str")i=o.v;else throw new Error("Index must be a number or string literal");this.expectPunc("]"),t={type:"index",target:t,key:i}}else if(n.v==="("){let o=this.parseArgs();t={type:"call",target:t,args:o}}else break}return t}parseArgs(){this.expectPunc("(");let e=[];if(this.peek()?.t==="punc"&&this.peek().v===")")return this.next(),e;for(;;){e.push(this.parseExpression());let t=this.next();if(!t)throw new Error("Unterminated argument list");if(t.t==="punc"&&t.v===")")break;if(!(t.t==="punc"&&t.v===","))throw new Error('Expected "," or ")" in argument list')}return e}expectPunc(e){let t=this.next();if(!t||t.t!=="punc"||t.v!==e)throw new Error(`Expected "${e}" in expression`)}},wt=Symbol("nodeAccessor");function B(r,e){switch(r.type){case"lit":return r.value;case"root":return xn(r.name,e);case"func":return En(r.name,r.args.map(t=>B(t,e)));case"prop":return gt(B(r.target,e),r.key);case"index":return gt(B(r.target,e),r.key);case"call":{if(B(r.target,e)===wt){let n=r.args.map(i=>B(i,e));if(n.length!==1||typeof n[0]!="string")throw new Error("$node(...) takes exactly one string argument");let o=e.nodes?.[n[0]];if(!o)throw new Error(`$node("${n[0]}") not found (not completed or unknown)`);return o}throw new Error("Only $node(...) is callable in this position")}}}function xn(r,e){switch(r){case"input":return e.input??{};case"json":return e.json??{};case"vars":return e.vars??{};case"trigger":return e.trigger??{};case"now":return(e.now?e.now():new Date).toISOString();case"node":return wt;default:throw new Error(`Unknown context root "$${r}" (allowed: $input $json $node $now $vars $trigger)`)}}function gt(r,e){if(typeof e=="string"&&pt.has(e))throw new Error(`Access to "${e}" is forbidden`);if(r==null)throw new Error(`Cannot read "${e}" of ${r}`);if(typeof e=="number"){if(!Array.isArray(r))throw new Error(`Cannot index non-array with [${e}]`);return r[e]}return r[e]}function En(r,e){switch(r){case"len":{let t=e[0];if(typeof t=="string"||Array.isArray(t))return t.length;if(t&&typeof t=="object")return Object.keys(t).length;throw new Error(`len() expects string/array/object, got ${typeof t}`)}case"upper":return String(re(e,0,"upper")).toUpperCase();case"lower":return String(re(e,0,"lower")).toLowerCase();case"default":return e[0]===null||e[0]===void 0?e[1]:e[0];case"jsonpath":return Pn(e[0],String(re(e,1,"jsonpath")));case"date":return Sn(e);case"eq":return Pe(e[0],e[1]);case"ne":return!Pe(e[0],e[1]);case"gt":return ne(e[0],e[1])>0;case"gte":return ne(e[0],e[1])>=0;case"lt":return ne(e[0],e[1])<0;case"lte":return ne(e[0],e[1])<=0;case"not":return!Ee(re(e,0,"not"));case"and":return e.every(Ee);case"or":return e.some(Ee);case"contains":return Rn(e[0],e[1]);default:throw new Error(`Unknown function "${r}()" (whitelist: len upper lower default jsonpath date eq ne gt gte lt lte not and or contains)`)}}function Ee(r){return!!r}function Pe(r,e){return r===e?!0:typeof r!=typeof e?!1:r&&e&&typeof r=="object"?JSON.stringify(r)===JSON.stringify(e):!1}function ne(r,e){if(typeof r=="number"&&typeof e=="number")return r-e;if(typeof r=="string"&&typeof e=="string")return r<e?-1:r>e?1:0;throw new Error(`Cannot compare ${typeof r} with ${typeof e}`)}function Rn(r,e){if(typeof r=="string")return r.includes(String(e));if(Array.isArray(r))return r.some(t=>Pe(t,e));throw new Error("contains() expects string/array as first argument")}function re(r,e,t){if(r.length<=e||r[e]===void 0)throw new Error(`${t}() missing required argument #${e+1}`);return r[e]}function Pn(r,e){let t=e.match(/[^.[\]]+/g)??[],n=r;for(let o of t){if(pt.has(o))throw new Error(`jsonpath segment "${o}" is forbidden`);if(n==null)return;let i=/^\d+$/.test(o)?Number(o):o;n=n[i]}return n}function Sn(r){let e=r.length===0?new Date:new Date(r[0]);if(Number.isNaN(e.getTime()))throw new Error(`date() received an invalid date: ${String(r[0])}`);if(r.length<2)return e.toISOString();let t=String(r[1]),n=o=>String(o).padStart(2,"0");return t.replace(/YYYY/g,String(e.getUTCFullYear())).replace(/MM/g,n(e.getUTCMonth()+1)).replace(/DD/g,n(e.getUTCDate())).replace(/HH/g,n(e.getUTCHours())).replace(/mm/g,n(e.getUTCMinutes())).replace(/ss/g,n(e.getUTCSeconds()))}import{mkdirSync as In,writeFileSync as An}from"node:fs";import{dirname as Nn,resolve as $n}from"node:path";var yt={filter:["condition"],transform:["mapping"],script:["*"],n8nNode:["*"],agentBinding:["*"],modelBinding:["*"],toolBinding:["*"],integration:["*"],file:["*"],form:["*"],documentLoader:["*"],parser:["*"],retriever:["*"],textSplitter:["*"],vectorStore:["*"],extract:["*"],limit:["*"],split:["*"],respond:["*"]};function se(r,e){return{json:e.json,vars:r.vars,trigger:r.trigger,now:r.now}}var Dn=(r,e)=>{let t=e.assignments?.assignments;if(Array.isArray(t)){let o={};for(let i of t){if(!i||typeof i!="object")continue;let s=i;typeof s.name!="string"||!s.name||(o[s.name]=Fn(s.value,s.type))}return{outputs:{default:[{json:o}]}}}return{outputs:{default:[{json:e.json&&typeof e.json=="object"&&!Array.isArray(e.json)?e.json:{value:e.json??e.value??null}}]}}},Cn=r=>({outputs:{default:r.default??[]}}),jn=r=>{let e=[];for(let t of Object.keys(r))e.push(...r[t]);return{outputs:{default:e}}},Tn=(r,e)=>{let n=!!e.condition?"true":"false",o=r.default??[],i={true:[],false:[]};return i[n]=o,{outputs:i,firedPorts:[n]}},Wn=(r,e,t)=>({outputs:{default:[{json:t.trigger??(e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload:{})}]}}),On=(r,e,t)=>{let n=e.condition;if(typeof n!="string"||!n.trim())throw new Error('filter node requires string param "condition" (per-item {{ }} expression over $json)');return{outputs:{default:(r.default??[]).filter(s=>!!P(n,se(t,s)))}}},Mn=(r,e)=>{let t=Array.isArray(e.cases)?e.cases:[];if(t.length===0)throw new Error('switch node requires non-empty param "cases" ([{port, condition}])');let n=r.default??[],o=typeof e.defaultPort=="string"&&e.defaultPort?e.defaultPort:"default",i=o;for(let a of t){if(typeof a.port!="string"||!a.port)throw new Error('switch case requires string "port"');if(a.condition){i=a.port;break}}let s={};for(let a of t)typeof a.port=="string"&&(s[a.port]=[]);return s[o]=s[o]??[],s[i]=n,{outputs:s,firedPorts:[i]}},_n=r=>{let e=r.default??[];return{outputs:{default:[{json:{items:e.map(t=>t.json),count:e.length}}]}}},Hn=(r,e,t)=>{let n=e.mapping;if(typeof n!="object"||n===null||Array.isArray(n))throw new Error('transform node requires object param "mapping" ({outKey: "{{ expr }}"})');let o=Object.entries(n);if(o.length===0)throw new Error('transform node: "mapping" must have at least one key');return{outputs:{default:(r.default??[]).map(a=>{let d={};for(let[l,u]of o)d[l]=typeof u=="string"?P(u,se(t,a)):u;return{json:d}})}}},qn=async(r,e,t)=>{if(e.until==="webhook"){let o=t.host;if(!o?.waitWebhook)throw new Error("wait(until=webhook) requires an ExecutorHost with waitWebhook");let i=typeof e.path=="string"&&e.path.trim()?e.path.trim():"";if(!i)throw new Error('wait(until=webhook) requires param "path" (the webhook path to wait for)');let s=typeof e.timeoutMs=="number"&&e.timeoutMs>0?e.timeoutMs:void 0,a=await o.waitWebhook({path:i.startsWith("/")?i:`/${i}`,nodeId:t.nodeId,workflowId:t.workflowId,timeoutMs:s,signal:t.signal});return{outputs:{default:[...r.default??[],{json:{webhook:a}}]}}}let n=Number(e.ms);if(!Number.isFinite(n)||n<1||n>36e5)throw new Error('wait node requires param "ms" in 1..3600000');return await new Promise((o,i)=>{let s=setTimeout(()=>{t.signal?.removeEventListener("abort",a),o()},n),a=()=>{clearTimeout(s),i(new Error("wait node canceled"))};t.signal?.addEventListener("abort",a,{once:!0})}),{outputs:{default:r.default??[]}}},Bn=(r,e,t)=>{let n=typeof e._n8nType=="string"?`(\u6765\u81EA n8n \u8282\u70B9\u300C${e._n8nType}\u300D)`:"";throw new Error(`\u8282\u70B9\u300C${t.nodeId}\u300D${n}\u5BFC\u5165\u65F6\u672A\u80FD\u81EA\u52A8\u8F6C\u6362,\u8BF7\u6253\u5F00\u8282\u70B9\u5B8C\u6210\u4EBA\u5DE5\u8FC1\u79FB\u540E\u518D\u8FD0\u884C`)},k=(r,e,t)=>{let n=typeof e._n8nType=="string"?` (${e._n8nType})`:"",i=(Array.isArray(e._n8nOutPorts)?e._n8nOutPorts:["default"]).filter(l=>typeof l=="string"&&l.length>0),s=r.default??[],a=s.length>0?s:[{json:{imported:!0,nodeId:t.nodeId,kind:t.kind,n8nType:e._n8nType}}],d={};for(let l of i.length>0?i:["default"])d[l]=a;if(d.default||(d.default=a),e._importMode==="n8n-strict-template")throw new Error(`Imported n8n node "${t.nodeId}"${n} requires a native executor or binding before live runs.`);return{outputs:d}},Un=(r,e,t)=>{if((typeof e.operation=="string"?e.operation:"write")!=="write")throw new Error(`Imported file node "${t.nodeId}" supports operation "write" only for live runs`);let o=r.default?.[0];if(!o)throw new Error(`Imported file node "${t.nodeId}" requires an input item`);let i=Kn(e.fileName,o,t);if(!i)throw new Error(`Imported file node "${t.nodeId}" requires fileName`);let s=$n(i);return In(Nn(s),{recursive:!0}),An(s,Ln(o)),{outputs:{default:[{json:{...o.json,fileName:s,written:!0}}]}}},kt={set:Dn,passthrough:Cn,merge:jn,if:Tn,trigger:Wn,filter:On,switch:Mn,aggregate:_n,transform:Hn,wait:qn,manual:Bn,script:k,n8nNode:k,agentBinding:k,modelBinding:k,toolBinding:k,integration:k,file:Un,form:k,documentLoader:k,parser:k,retriever:k,textSplitter:k,vectorStore:k,extract:k,limit:k,split:k,respond:k};function Fn(r,e){if(e==="number"){let t=Number(r);return Number.isFinite(t)?t:r}if(e==="boolean"){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1}return r}function Ln(r){return typeof r.json.bodyBase64=="string"?Buffer.from(r.json.bodyBase64,"base64"):typeof r.json.body=="string"?r.json.body:r.json.body!==void 0?JSON.stringify(r.json.body,null,2):typeof r.json.data=="string"?r.json.data:JSON.stringify(r.json,null,2)}function Kn(r,e,t){if(typeof r!="string")return"";let n=r.startsWith("=")?r.slice(1):r,o=n.match(/^\{\{\s*([\s\S]*?)\s*\}\}$/);return o?String(Jn(o[1],e,t)??""):n.includes("{{")?String(P(n,se(t,e))):n}function Jn(r,e,t){let n=r.match(/^\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(n)return e.json[n[1]];let o=r.match(/^(["'])([\s\S]*)\1\s*\+\s*\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(o)return`${Gn(o[1],o[2])}${String(e.json[o[3]]??"")}`;if(r.startsWith("$json."))return P(`{{ ${r} }}`,se(t,e));throw new Error(`Imported n8n expression is unsupported at node "${t.nodeId}": ${r}`)}function Gn(r,e){if(r==='"')try{return JSON.parse(`"${e}"`)}catch{return e}return e.replace(/\\'/g,"'").replace(/\\\\/g,"\\")}var Vn=new Set(["agentBinding","modelBinding"]),V=class{executors=new Map;constructor(e=!0){if(e)for(let[t,n]of Object.entries(kt))this.executors.set(t,n)}register(e,t){if(this.executors.has(e))throw new Error(`NodeExecutor for kind "${e}" already registered`);this.executors.set(e,t)}override(e,t){if(!this.executors.has(e))throw new Error(`Cannot override unregistered kind "${e}"`);this.executors.set(e,t)}installHostExecutors(e){for(let[t,n]of Object.entries(e))this.executors.has(t)?Vn.has(t)&&this.override(t,n):this.register(t,n)}has(e){return this.executors.has(e)}get(e){let t=this.executors.get(e);if(!t)throw new Error(`No NodeExecutor registered for kind "${e}"`);return t}kinds(){return[...this.executors.keys()]}};function bt(r,e){let t=r??"any",n=e??"any";return t==="any"||n==="any"||t===n?!0:n==="binary"&&(t==="image"||t==="video"||t==="audio")}function ae(r){return r!=="manual"&&r!=="intent"&&r!=="form"}function z(r){let e=typeof r=="string"?r.trim():"";if(!e||e==="self")throw new Error('Workflow agent nodes require an explicit agentId; "self" is not a valid identity');return e}function R(r,e){if(!r)throw new Error(`Node kind "${e}" requires a host (ExecutorHost) but none was injected. Provide one via WorkflowRuntimeOptions.host.`);return r}function N(r,e,t){let n=r[e];if(typeof n!="string"||n.length===0)throw new Error(`Node kind "${t}" requires string param "${e}"`);return n}function xt(r,e){let t=r[e];if(t==null)return{};if(typeof t!="object"||Array.isArray(t))throw new Error(`Param "${e}" must be an object`);return t}var zn=async(r,e,t)=>({outputs:{default:await R(t.host,"agent").runAgent({agentId:z(e.agentId),prompt:N(e,"prompt","agent"),input:r.default??[],signal:t.signal})}}),Yn=async(r,e,t)=>{let n=R(t.host,"agentBinding"),o=Rt(e,r.default??[],t,"agentBinding");return{outputs:{default:await n.runAgent({agentId:z(e.agentId),prompt:o,input:r.default??[],signal:t.signal})}}},Qn=async(r,e,t)=>{let n=R(t.host,"modelBinding");if(!n.runModel)throw new Error('Node kind "modelBinding" requires an ExecutorHost with runModel');return{outputs:{default:await n.runModel({prompt:Rt(e,r.default??[],t,"modelBinding"),modelHint:lr(e),temperature:vt(e.temperature),maxTokens:vt(e.maxTokens),input:r.default??[],signal:t.signal})}}},Xn=async(r,e,t)=>({outputs:{default:await R(t.host,"tool").invokeTool({tool:N(e,"tool","tool"),args:xt(e,"args"),unattended:ae(t.triggerKind??"manual"),input:r.default??[],signal:t.signal})}}),Zn=async(r,e,t)=>{let n=R(t.host,"http"),o=typeof e.method=="string"?e.method:"GET",i=await n.httpRequest({method:o,url:N(e,"url","http"),headers:ur(e),body:ar(e),credentialId:typeof e.credentialId=="string"&&e.credentialId?e.credentialId:void 0,signal:t.signal}),s=r.default?.[0]?.json??{};return{outputs:{default:i.map(a=>({...a,json:{...s,...a.json}}))}}},er=async(r,e,t)=>({outputs:{default:await R(t.host,"mcp").invokeMcp({server:N(e,"server","mcp"),tool:N(e,"tool","mcp"),args:xt(e,"args"),signal:t.signal})}}),tr=async(r,e,t)=>({outputs:{default:await R(t.host,"channel").sendChannel({channel:N(e,"channel","channel"),target:typeof e.target=="string"?e.target:void 0,payload:e.payload??r.default?.[0]?.json??{},input:r.default??[],signal:t.signal})}}),nr=async(r,e,t)=>{let n=R(t.host,"skill"),o=e.args;return{outputs:{default:await n.invokeTool({tool:"skill_view",args:{name:N(e,"skill","skill"),...o!=null&&o!==""?{args:o}:{}},input:r.default??[],signal:t.signal})}}},rr=async(r,e,t)=>{let n=R(t.host,"memory");if(!n.memory)throw new Error('Node kind "memory" requires an ExecutorHost with a memory backend');let o=N(e,"op","memory");if(o!=="read"&&o!=="write"&&o!=="search")throw new Error(`memory node: op must be "read"|"write"|"search", got "${o}"`);if(e.scope==="global")throw new Error('memory node: scope "global" \u9700\u7ECF\u6743\u9650\u95F8\u95E8(\u672A\u5F00\u653E);\u9ED8\u8BA4\u9879\u76EE\u7EA7\u8BF7\u79FB\u9664 scope');return{outputs:{default:await n.memory({op:o,key:typeof e.key=="string"&&e.key?e.key:void 0,value:e.value!==void 0?e.value:r.default?.[0]?.json,query:typeof e.query=="string"?e.query:void 0,input:r.default??[],signal:t.signal})}}},or=async(r,e,t)=>{let n=R(t.host,"subworkflow");if(!n.runSubworkflow)throw new Error('Node kind "subworkflow" requires an ExecutorHost with runSubworkflow');let o=e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload:r.default?.[0]?.json;return{outputs:{default:await n.runSubworkflow({workflowId:N(e,"workflowId","subworkflow"),callerWorkflowId:t.workflowId,projectId:typeof e.projectId=="string"&&e.projectId?e.projectId:void 0,payload:o,input:r.default??[],signal:t.signal})}}},ir=async(r,e,t)=>{let n=R(t.host,"approval");if(!n.approval)throw new Error('Node kind "approval" requires an ExecutorHost with approval');let o=await n.approval({nodeId:t.nodeId,workflowId:t.workflowId,prompt:typeof e.prompt=="string"&&e.prompt?e.prompt:void 0,timeoutMs:typeof e.timeoutMs=="number"&&e.timeoutMs>0?e.timeoutMs:void 0,timeoutAction:e.timeoutAction==="approve"||e.timeoutAction==="reject"||e.timeoutAction==="keepPending"?e.timeoutAction:void 0,input:r.default??[],signal:t.signal});if(!o.approved)throw new Error(`approval node "${t.nodeId}" denied${o.note?`: ${o.note}`:""} (${o.decidedAt})`);return{outputs:{default:[...r.default??[],{json:{approved:!0,decidedAt:o.decidedAt,...o.note?{note:o.note}:{}}}]}}},ue={agent:zn,agentBinding:Yn,modelBinding:Qn,tool:Xn,http:Zn,mcp:er,channel:tr,skill:nr,memory:rr,subworkflow:or,approval:ir},sr=Object.keys(ue);function ar(r){if(r.body!==void 0)return r.body;if(r.sendBody!==!0)return;let e=Et(r.bodyParameters);if(e.length!==0)return Object.fromEntries(e)}function ur(r){let e={};if(r.headers&&typeof r.headers=="object"&&!Array.isArray(r.headers))for(let[t,n]of Object.entries(r.headers))typeof n=="string"&&(e[t]=n);for(let[t,n]of Et(r.headerParameters))e[t]=String(n);return Object.keys(e).length>0?e:void 0}function Et(r){let e=r&&typeof r=="object"&&!Array.isArray(r)?r.parameters:void 0;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let o=n;typeof o.name!="string"||!o.name||t.push([o.name,o.value??""])}return t}function Rt(r,e,t,n){let o=cr(r.prompt,r.text,r.message,r.input);if(!o)throw new Error(`Node kind "${n}" requires a prompt/text parameter`);return dr(o,{json:e[0]?.json??{},input:{default:e},vars:t.vars,trigger:t.trigger,now:t.now})}function dr(r,e){let t=r.startsWith("=")?r.slice(1):r;return t.includes("{{")?String(P(t,e)):t}function cr(...r){for(let e of r)if(typeof e=="string"&&e.trim())return e}function lr(r){let e=r.model??r.modelName;if(typeof e=="string"&&e)return e;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e.value??e.cachedResultName;if(typeof t=="string"&&t)return t}}function vt(r){let e=typeof r=="number"?r:typeof r=="string"?Number(r):NaN;return Number.isFinite(e)?e:void 0}var U=class extends Error{constructor(t){super(t?`Workflow paused at "${t}"`:"Workflow paused");this.atNodeId=t;this.name="WorkflowPauseSignal"}atNodeId},b=class extends Error{constructor(e="Workflow run canceled"){super(e),this.name="WorkflowRunCanceled"}},Y=class{constructor(e,t={}){this.def=e;this.registry=t.registry??new V,this.gate=t.gate,this.now=t.now??(()=>new Date),this.trigger=t.trigger,this.triggerKind=t.triggerKind,this.log=t.log,this.host=t.host,this.abortController=t.signal?void 0:new AbortController,this.signal=t.signal??this.abortController.signal,this.checkpoint=t.checkpoint,this.preserveCheckpoint=t.preserveCheckpoint===!0,this.onNodeStatus=t.onNodeStatus,this.host&&this.registry.installHostExecutors(ue);for(let n of e.nodes)this.nodeDefs.set(n.id,n);for(let n of e.edges)n.loopBack&&this.loopBackOf.set(n.from,n.to)}def;registry;gate;now;trigger;triggerKind;log;host;abortController;signal;checkpoint;preserveCheckpoint;onNodeStatus;dag;nodeDefs=new Map;nodeOutputs=new Map;cache=new Map;loopBackOf=new Map;pauseRequested=!1;nodeStats={};statsSeq=0;checkpointLoaded=!1;setNodeParams(e,t){let n=this.nodeDefs.get(e);if(!n)throw new Error(`Unknown node "${e}"`);n.params={...n.params??{},...t}}pause(){this.pauseRequested=!0}cancel(e="Workflow run canceled"){let t=new b(e);this.abortController&&!this.abortController.signal.aborted&&this.abortController.abort(t)}extendBudget(e){if(!this.gate?.extend)throw new Error("WorkflowRuntime has no extensible budget gate to raise");this.gate.extend(e)}async run(){await this.loadCheckpoint(),this.throwIfCanceled(),this.dag=this.buildDag(),this.nodeOutputs.clear(),this.pauseRequested=!1;let e=new Set,t;try{let i=0;for(;!this.dag.isFinished();){if(++i>1e5)throw new Error("WorkflowRuntime did not converge");let s=this.dag.getReadyNodes();if(s.length===0)break;for(let a of s)await this.executeNode(a,e)}}catch(i){if(i instanceof U)t=i.atNodeId;else throw i}let n={};for(let[i,s]of this.nodeOutputs)n[i]=s;let o=t?"paused":this.dag.isAllCompleted()?"completed":"failed";return o==="completed"&&this.checkpoint&&(this.preserveCheckpoint?await this.persistCheckpoint():await this.checkpoint.clear()),{status:o,outputs:n,executed:e,progress:this.dag.getProgress(),pausedAt:t,nodeStats:{...this.nodeStats}}}async loadCheckpoint(){if(!this.checkpoint||this.checkpointLoaded)return;this.checkpointLoaded=!0;let e=await this.checkpoint.load();if(e)for(let t of e.entries)this.cache.set(t.key,t.result)}async persistCheckpoint(){if(!this.checkpoint)return;let e=[...this.cache.entries()].map(([t,n])=>({key:t,result:n}));await this.checkpoint.persist(e)}async executeNode(e,t){if(this.throwIfCanceled(),this.pauseRequested)throw new U(e.id);if(e.kind==="loop"){this.enterLoop(e);return}let n=this.collectInputs(e.id),o=this.buildExprContext(n),i=this.nodeDefs.get(e.id)?.params??{},s=yt[e.kind]??[],a=s.includes("*"),d=a?{}:s.length>0?Object.fromEntries(Object.entries(i).filter(([m])=>!s.includes(m))):i,l={...mt(d,o),...a?i:Object.fromEntries(s.filter(m=>m in i).map(m=>[m,i[m]]))},u=this.cacheKey(e.kind,l,n,e.runIndex),f=Date.now(),c=0,g=(m,O)=>{let K=Date.now();this.nodeStats[e.id]={seq:++this.statsSeq,startedAt:new Date(f).toISOString(),finishedAt:new Date(K).toISOString(),durationMs:K-f,attempts:c,cacheHit:O,status:m}},p=this.cache.get(u),h=p!==void 0,w=!1;if(p)this.dag.markRunning(e.id);else{this.gate?.check(e.id,e.kind),this.dag.markRunning(e.id),this.onNodeStatus?.(e.id,"running");let m=this.nodeDefs.get(e.id),O=Math.max(1,m?.retry?.maxTries??1),K=Math.max(0,m?.retry?.backoffMs??1e3),pe=m?.timeoutMs,E;for(let S=0;S<O;S++){c++,this.throwIfCanceled();let M={nodeId:e.id,kind:e.kind,workflowId:this.def.id,triggerKind:this.triggerKind,runIndex:e.runIndex,vars:this.def.vars??{},trigger:this.trigger,now:this.now,log:this.log,host:this.host,signal:pe!==void 0&&pe>0?AbortSignal.any([this.signal,AbortSignal.timeout(pe)]):this.signal};try{p=await this.registry.get(e.kind)(n,l,M),E=void 0;break}catch(J){if(this.isCanceled())throw this.canceledError(J);E=J;let Fe=S+1<O;this.log?.warn(`node "${e.id}" attempt ${S+1}/${O} failed: ${J instanceof Error?J.message:String(J)}`+(Fe?` \u2014 retrying in ${K*2**S}ms`:"")),Fe&&await this.cancellableDelay(K*2**S)}}if(E!==void 0){let S=m?.onError??"stop",M=E instanceof Error?E.message:String(E);if(S==="errorPort")this.onNodeStatus?.(e.id,"failed",M),p={outputs:{error:[{json:{error:M,nodeId:e.id,kind:e.kind,attempts:O}}]},firedPorts:["error"]},w=!0;else if(S==="continue")this.onNodeStatus?.(e.id,"failed",M),p={outputs:{},firedPorts:[]},w=!0;else throw this.onNodeStatus?.(e.id,"failed",M),g("failed",!1),E&&typeof E=="object"&&!E.nodeId&&(E.nodeId=e.id),E}this.throwIfCanceled(),w?t.add(e.id):(this.cache.set(u,p),t.add(e.id),await this.persistCheckpoint())}this.nodeOutputs.set(e.id,p.outputs),this.dag.markCompleted(e.id,{output:p.outputs,firedPorts:p.firedPorts}),w||this.onNodeStatus?.(e.id,"completed"),g(w?"failed":"completed",h);let x=this.loopBackOf.get(e.id);x&&this.decideLoopBack(x)}enterLoop(e){this.dag.markRunning(e.id);let t={loop:[{json:{iteration:e.iteration??0}}],done:[]};this.nodeOutputs.set(e.id,t),this.dag.markCompleted(e.id,{output:t,firedPorts:["loop"]}),this.onNodeStatus?.(e.id,"completed")}decideLoopBack(e){let t=this.evalLoopCondition(e);this.dag.decideLoop(e,t);let n=this.dag.getNode(e);this.surfaceLoopCap(n);let o=n.firedPorts??[];this.nodeOutputs.set(e,{loop:o.includes("loop")?[{json:{iteration:n.iteration??0}}]:[],done:o.includes("done")?[{json:{iteration:n.iteration??0}}]:[]})}surfaceLoopCap(e){if(!e.error?.startsWith("loop_cap_reached:")||this.nodeStats[e.id]?.warning)return;let t=`loop "${e.id}" hit its maxIterations cap (${e.maxIterations}) \u2014 forced exit via "done" while the loop condition still asked to continue`;this.log?.warn(t);let n=this.nodeStats[e.id],o=new Date().toISOString();this.nodeStats[e.id]=n?{...n,warning:t}:{seq:++this.statsSeq,startedAt:o,finishedAt:o,durationMs:0,attempts:0,cacheHit:!1,status:"completed",warning:t}}evalLoopCondition(e){let n=this.nodeDefs.get(e)?.params?.condition;if(n==null||n==="")return!0;let o=this.buildExprContext({});return!!(typeof n=="string"?P(n,o):n)}collectInputs(e){let t={};for(let n of this.def.edges){if(n.to!==e||n.loopBack)continue;let o=n.fromPort??"default",i=n.toPort??"default",s=this.nodeOutputs.get(n.from);if(!s)continue;let a=s[o];a&&(t[i]??=[]).push(...a)}return t}buildExprContext(e){let t={};for(let[n,o]of this.nodeOutputs)t[n]={output:o};return{input:e,json:e.default?.[0]?.json??{},nodes:t,vars:this.def.vars??{},trigger:this.trigger,now:this.now}}cacheKey(e,t,n,o){return xe([e,t,ct(n),o])}isCanceled(){return this.signal.aborted}canceledError(e){let t=this.signal.reason;return t instanceof b?t:t instanceof Error?new b(t.message):e instanceof b?e:e instanceof Error&&this.signal.aborted?new b(e.message):new b(t===void 0?"Workflow run canceled":String(t))}throwIfCanceled(){if(this.isCanceled())throw this.canceledError()}cancellableDelay(e){return e<=0?Promise.resolve():new Promise((t,n)=>{let o=setTimeout(()=>{this.signal.removeEventListener("abort",i),t()},e),i=()=>{clearTimeout(o),n(this.canceledError())};this.signal.addEventListener("abort",i,{once:!0})})}buildDag(){let e=this.def.nodes.map(n=>{let o=n.outPorts??fr(n.kind);return n.onError==="errorPort"&&!o.includes("error")&&(o=[...o,"error"]),{id:n.id,kind:n.kind,params:n.params??{},outPorts:o,joinPolicy:n.joinPolicy??"all",maxIterations:n.maxIterations}}),t=new q(e);for(let n of this.def.edges)n.loopBack||t.addEdge({from:n.from,to:n.to,fromPort:n.fromPort??"default"});for(let n of this.def.edges)n.loopBack&&t.addEdge({from:n.from,to:n.to,loopBack:!0});return t}};function fr(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}var gr=new Set(["agent","tool","http","mcp","channel","im"]);var Se=class extends Error{constructor(t,n,o){super(`Permission denied: node "${t}" (kind "${n}") may not run under unattended trigger "${o}". Authorize it by adding "${n}" to allowUnattendedKinds.`);this.nodeId=t;this.kind=n;this.trigger=o;this.name="WorkflowPermissionDenied"}nodeId;kind;trigger},de=class extends U{constructor(t,n,o){super(t);this.reason=n;this.limit=o;this.name="WorkflowBudgetExceeded",this.message=`Budget exceeded (${n} limit ${o}) before node "${t}"`}reason;limit},ce=class{trigger;maxNodeExecutions;maxDurationMs;allow;now;executions=0;startedAt=-1;constructor(e){if(!Number.isInteger(e.maxNodeExecutions)||e.maxNodeExecutions<=0)throw new Error(`BudgetPermissionGate: maxNodeExecutions must be a positive integer, got ${e.maxNodeExecutions}`);if(e.maxDurationMs!==void 0&&!(e.maxDurationMs>0))throw new Error(`BudgetPermissionGate: maxDurationMs must be greater than 0 when provided, got ${e.maxDurationMs}`);this.trigger=e.trigger,this.maxNodeExecutions=e.maxNodeExecutions,this.maxDurationMs=e.maxDurationMs,this.allow=new Set(e.allowUnattendedKinds??[]),this.now=e.now??(()=>Date.now())}get unattended(){return ae(this.trigger)}check(e,t){if(this.unattended&&gr.has(t)&&!this.allow.has(t))throw new Se(e,t,this.trigger);if(this.startedAt<0&&(this.startedAt=this.now()),this.maxDurationMs!==void 0&&this.now()-this.startedAt>=this.maxDurationMs)throw new de(e,"duration",this.maxDurationMs);if(this.executions>=this.maxNodeExecutions)throw new de(e,"executions",this.maxNodeExecutions);this.executions++}extend(e){if(e.executions!==void 0){if(!Number.isInteger(e.executions)||e.executions<=0)throw new Error(`BudgetPermissionGate.extend: executions delta must be a positive integer, got ${e.executions}`);this.maxNodeExecutions+=e.executions}if(e.durationMs!==void 0){if(!(e.durationMs>0))throw new Error(`BudgetPermissionGate.extend: durationMs delta must be greater than 0, got ${e.durationMs}`);if(this.maxDurationMs===void 0)throw new Error("BudgetPermissionGate.extend: cannot extend duration on a gate with no duration cap");this.maxDurationMs+=e.durationMs}}};function It(r){switch(r.type){case"manual":return[];case"schedule":return yr(r.cron);case"im-message":return vr(r.channel,r.match);case"webhook":return xr(r.path);case"intent":return mr(r.phrases,r.aliases,r.surfaces);case"form":return wr(r.fields);default:return[`unknown trigger type: ${JSON.stringify(r)}`]}}var pr=new Set(["welcome","chat"]);function mr(r,e,t){let n=[];if(!Array.isArray(r)||r.length===0)n.push("intent.phrases must be a non-empty array of trigger phrases");else for(let o of r)(typeof o!="string"||o.trim()==="")&&n.push(`intent.phrases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(e!==void 0)if(!Array.isArray(e))n.push("intent.aliases must be an array when present");else for(let o of e)(typeof o!="string"||o.trim()==="")&&n.push(`intent.aliases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(t!==void 0)if(!Array.isArray(t)||t.length===0)n.push("intent.surfaces must be a non-empty array when present");else for(let o of t)(typeof o!="string"||!pr.has(o))&&n.push(`intent.surfaces entries must be "welcome"|"chat", got ${JSON.stringify(o)}`);return n}var hr=new Set(["text","number","select"]);function wr(r){let e=[];if(!Array.isArray(r)||r.length===0)return["form.fields must be a non-empty array"];let t=new Set;for(let n of r){if(typeof n?.key!="string"||!/^[\w-]+$/.test(n.key)){e.push(`form field key must be a [\\w-]+ string, got ${JSON.stringify(n?.key)}`);continue}t.has(n.key)&&e.push(`duplicate form field key "${n.key}"`),t.add(n.key),n.type!==void 0&&(typeof n.type!="string"||!hr.has(n.type))&&e.push(`form field "${n.key}": type must be text|number|select`),n.type==="select"&&(!Array.isArray(n.options)||n.options.length===0)&&e.push(`form field "${n.key}": select requires non-empty options`)}return e}var Pt=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],St=["SUN","MON","TUE","WED","THU","FRI","SAT"];function yr(r){if(typeof r!="string"||r.trim()==="")return["schedule.cron must be a non-empty string"];let e=r.trim().split(/\s+/);if(e.length!==5&&e.length!==6)return[`schedule.cron must have 5 or 6 fields, got ${e.length}: "${r}"`];let n=e.length===6?[{label:"second",min:0,max:59},{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Pt},{label:"day-of-week",min:0,max:7,names:St}]:[{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Pt},{label:"day-of-week",min:0,max:7,names:St}],o=[];for(let i=0;i<n.length;i++){let s=kr(e[i],n[i]);s&&o.push(`schedule.cron ${s}`)}return o}function kr(r,e){for(let t of r.split(",")){let n=br(t,e);if(n)return n}}function br(r,e){if(r==="")return`${e.label} has an empty list element`;let t=r,n,o=r.indexOf("/");if(o!==-1&&(t=r.slice(0,o),n=r.slice(o+1),!/^\d+$/.test(n)||Number(n)<=0))return`${e.label} has an invalid step "/${n}"`;if(t==="*")return;let i=t.indexOf("-");if(i!==-1){let a=Ie(t.slice(0,i),e),d=Ie(t.slice(i+1),e);return a===void 0||d===void 0?`${e.label} has an invalid range "${t}"`:a>d?`${e.label} range "${t}" is descending`:void 0}if(t===""&&n!==void 0)return`${e.label} step "${r}" needs a base ("*" or a range)`;if(Ie(t,e)===void 0)return`${e.label} value "${t}" is out of range ${e.min}-${e.max}`}function Ie(r,e){let t;if(/^\d+$/.test(r))t=Number(r);else if(e.names){let n=e.names.indexOf(r.toUpperCase());if(n===-1)return;t=e.label==="month"?n+1:n}else return;if(!(t<e.min||t>e.max))return t}function vr(r,e){let t=[];if((typeof r!="string"||r.trim()==="")&&t.push("im-message.channel must be a non-empty string"),e!==void 0)if(typeof e!="string")t.push("im-message.match must be a string regex");else try{new RegExp(e)}catch(n){t.push(`im-message.match is not a valid regex: ${n.message}`)}return t}function xr(r){return typeof r!="string"||r===""?["webhook.path must be a non-empty string"]:r.startsWith("/")?/\s/.test(r)?[`webhook.path must not contain whitespace: "${r}"`]:r.includes("..")?[`webhook.path must not contain "..": "${r}"`]:/^\/[A-Za-z0-9\-._~/]*$/.test(r)?[]:[`webhook.path contains illegal characters: "${r}"`]:[`webhook.path must start with "/": "${r}"`]}var v=class extends Error{constructor(t){super(`Patch rejected: ${t.join("; ")}`);this.errors=t;this.name="PatchError"}errors};function Ae(r,e){let t=[],n=Pr(r),o=new Map(n.def.nodes.map(l=>[l.id,l])),i=e.scope?new Set(e.scope):void 0,s=new Set,a=l=>!i||i.has(l)||s.has(l),d=[];for(let[l,u]of e.patch.entries()){let f=`op[${l}] ${u.op}`;switch(u.op){case"add_node":{u.node?.id?o.has(u.node.id)?t.push(`${f}: node "${u.node.id}" already exists`):(n.def.nodes.push(u.node),o.set(u.node.id,u.node),i&&s.add(u.node.id)):t.push(`${f}: node.id is required`);break}case"remove_node":{o.has(u.nodeId)?a(u.nodeId)?(n.def.nodes=n.def.nodes.filter(c=>c.id!==u.nodeId),o.delete(u.nodeId),n.def.edges=n.def.edges.filter(c=>c.from!==u.nodeId&&c.to!==u.nodeId)):t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"update_params":{let c=o.get(u.nodeId);c?a(u.nodeId)?c.params=Er(c.params,u.params):t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"rename_node":{let c=o.get(u.nodeId);c?a(u.nodeId)?c.name=u.name:t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"set_node_options":{let c=o.get(u.nodeId);if(!c){t.push(`${f}: node "${u.nodeId}" not found`);break}if(!a(u.nodeId)){t.push(`${f}: node "${u.nodeId}" is outside the edit scope`);break}u.retry!==void 0&&(u.retry===null?delete c.retry:!Number.isInteger(u.retry.maxTries)||u.retry.maxTries<1||u.retry.maxTries>10?t.push(`${f}: retry.maxTries must be an integer 1..10`):u.retry.backoffMs!==void 0&&(!Number.isFinite(u.retry.backoffMs)||u.retry.backoffMs<0)?t.push(`${f}: retry.backoffMs must be a non-negative number`):c.retry={maxTries:u.retry.maxTries,...u.retry.backoffMs!==void 0?{backoffMs:u.retry.backoffMs}:{}}),u.timeoutMs!==void 0&&(u.timeoutMs===null?delete c.timeoutMs:!Number.isFinite(u.timeoutMs)||u.timeoutMs<=0?t.push(`${f}: timeoutMs must be a positive number`):c.timeoutMs=u.timeoutMs),u.onError!==void 0&&(u.onError===null?delete c.onError:u.onError!=="stop"&&u.onError!=="continue"&&u.onError!=="errorPort"?t.push(`${f}: onError must be "stop"|"continue"|"errorPort"`):c.onError=u.onError);break}case"set_node_ui":{if(!u.positions||typeof u.positions!="object"){t.push(`${f}: positions is required`);break}for(let[c,g]of Object.entries(u.positions)){let p=o.get(c);if(!p){t.push(`${f}: node "${c}" not found`);continue}if(!a(c)){t.push(`${f}: node "${c}" is outside the edit scope`);continue}if(g===null){delete p.ui;continue}if(!Number.isFinite(g?.x)||!Number.isFinite(g?.y)){t.push(`${f}: position for "${c}" must be finite {x,y}`);continue}p.ui={x:g.x,y:g.y}}break}case"add_edge":{let c=u.edge;if(!c?.from||!c?.to){t.push(`${f}: edge.from and edge.to are required`);break}if(i&&!a(c.from)&&!a(c.to)){t.push(`${f}: edge ${c.from}\u2192${c.to} has no endpoint in the edit scope`);break}let g=c.fromPort??"default";if(n.def.edges.some(m=>m.from===c.from&&m.to===c.to&&(m.fromPort??"default")===g)){t.push(`${f}: \u8FDE\u7EBF\u5DF2\u5B58\u5728(${c.from} \u2192 ${c.to})`);break}let p=o.get(c.from),h=o.get(c.to),w=p?.outPortTypes?.[g],x=h?.inPorts?.find(m=>m.name===(c.toPort??"default"))?.type;if(!bt(w,x)){t.push(`${f}: \u7AEF\u53E3\u7C7B\u578B\u4E0D\u5339\u914D:\u300C${p?.name??c.from}\u300D\u8F93\u51FA ${w??"any"},\u300C${h?.name??c.to}\u300D\u9700\u8981 ${x??"any"} \u2014\u2014 \u63A5\u4E0D\u4E0A,\u8BF7\u6362\u4E2A\u76EE\u6807\u7AEF\u53E3`);break}n.def.edges.push(c);break}case"remove_edge":{let{from:c,to:g,fromPort:p}=u.edge;if(i&&!a(c)&&!a(g))t.push(`${f}: edge ${c}\u2192${g} has no endpoint in the edit scope`);else{let h=n.def.edges.length;n.def.edges=n.def.edges.filter(w=>!(w.from===c&&w.to===g&&(w.fromPort??"default")===(p??"default"))),n.def.edges.length===h&&t.push(`${f}: edge ${c}\u2192${g} not found`)}break}case"set_trigger":{if(i)t.push(`${f}: trigger is workflow-global and cannot be changed in a scoped edit`);else if(u.trigger){let c=It(u.trigger);if(c.length>0)for(let g of c)t.push(`${f}: ${g}`);else n.meta.trigger=u.trigger}else n.meta.trigger=u.trigger;break}case"set_meta":{i?t.push(`${f}: meta is workflow-global and cannot be changed in a scoped edit`):(u.meta.name!==void 0&&(n.meta.name=u.meta.name),u.meta.active!==void 0&&(n.meta.active=u.meta.active));break}default:t.push(`${f}: unknown op`)}t.length===0&&d.push(u)}if(t.length>0)throw new v(t);if(Nt(n.def,t),At(n.def,t),t.length>0)throw new v(t);return{target:n,applied:d}}function Er(r,e){let t={...r??{}};for(let[n,o]of Object.entries(e))o===null?delete t[n]:t[n]=o;return t}function Q(r){let e=[];return Nt(r,e),At(r,e),e}function At(r,e){let t=(n,o,i)=>{if(typeof n=="string"){if(n.startsWith("="))return;for(let s of n.matchAll(/\{\{([\s\S]*?)\}\}/g)){let a=ie(s[1].trim());a&&e.push(`\u8282\u70B9\u300C${o}\u300D\u53C2\u6570 ${i} \u7684\u8868\u8FBE\u5F0F\u300C{{ ${s[1].trim()} }}\u300D\u8D85\u51FA\u53D7\u9650\u8BED\u8A00:${a}`)}return}if(Array.isArray(n)){n.forEach((s,a)=>t(s,o,`${i}[${a}]`));return}if(n&&typeof n=="object")for(let[s,a]of Object.entries(n))t(a,o,i?`${i}.${s}`:s)};for(let n of r.nodes)n.params?._importMode!=="n8n-strict-template"&&n.params&&t(n.params,n.id,"")}function Nt(r,e){try{let t=r.nodes.map(o=>{let i=o.outPorts??Rr(o.kind);return o.onError==="errorPort"&&!i.includes("error")&&(i=[...i,"error"]),{id:o.id,kind:o.kind,params:o.params??{},outPorts:i,joinPolicy:o.joinPolicy??"all",maxIterations:o.maxIterations}}),n=new q(t);for(let o of r.edges)o.loopBack||n.addEdge({from:o.from,to:o.to,fromPort:o.fromPort??"default"});for(let o of r.edges)o.loopBack&&n.addEdge({from:o.from,to:o.to,loopBack:!0})}catch(t){e.push(`graph invalid: ${t.message}`)}}function Rr(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}function Pr(r){return{def:{...r.def,nodes:r.def.nodes.map(e=>({...e,params:e.params?{...e.params}:void 0})),edges:r.def.edges.map(e=>({...e})),vars:r.def.vars?{...r.def.vars}:void 0},meta:{...r.meta}}}function Ne(r,e={}){let t=e.maxNodes??50,n=e.maxValueLen??60,o=`Workflow ${JSON.stringify(r.name)} (rev ${r.rev}, trigger: ${Sr(r.trigger)}, ${r.active?"active":"inactive"})`,i=r.def.nodes,a=i.slice(0,t).map(f=>" "+Ir(f,n)),d=i.length===0?"nodes: (none)":["nodes:",...a].join(`
1
+ import{join as A}from"node:path";import{mkdir as et,readdir as tt,rm as nt}from"node:fs/promises";import{readFile as Bt,writeFile as Ut,mkdir as Ft,rename as Lt,unlink as Kt}from"node:fs/promises";import{dirname as Jt,join as Gt}from"node:path";import{randomUUID as Vt}from"node:crypto";async function zt(r,e){let t=Jt(r);await Ft(t,{recursive:!0});let n=Gt(t,`.tmp-${Vt()}`);try{await Ut(n,e,"utf-8");let o;for(let i=0;i<3;i++)try{await Lt(n,r);return}catch(s){if(o=s,s.code!=="EPERM")throw s;await new Promise(a=>setTimeout(a,50*(i+1)))}throw o}catch(o){throw await Kt(n).catch(()=>{}),o}}async function j(r){try{let e=await Bt(r,"utf-8");return JSON.parse(e)}catch(e){if(e.code==="ENOENT")return;throw e}}async function D(r,e){await zt(r,JSON.stringify(e,null,2)+`
2
+ `)}import{resolve as dn}from"node:path";import{join as sn}from"node:path";import{homedir as Xt}from"node:os";import{join as y}from"node:path";import{existsSync as go}from"node:fs";import{createHash as Yt}from"node:crypto";import{resolve as Qt}from"node:path";function le(r){return Yt("sha256").update(Qt(r).toLowerCase()).digest("hex").slice(0,16)}var He=".qlogicagent";function S(){return process.env.QLOGICAGENT_HOME||y(Xt(),He)}function Q(){let r=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(r)return r;let e=process.env.QLOGIC_IMPLICIT_OWNER_ID?.trim();if(e)return e;let t=process.env.QLOGIC_DEVICE_ID?.trim();return t?`oc_${t}`:"oc_local"}function Zt(r){let e=r.trim();if(!e)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(e).replace(/\./g,"%2E")}function X(r=Q()){return y(S(),"profiles",Zt(r))}function _e(r=Q()){return y(X(r),"memory")}var en="projectData";function qe(){return y(S(),en)}function fe(r){if(!r)throw new Error("getProjectDataDirById: projectId is required");return y(qe(),r)}function Be(){return y(S(),"plugins")}function Ue(){return y(S(),"skills")}function Fe(){return y(X(),"settings.json")}function Le(){return y(S(),"plugin-cache")}function Ke(){return y(S(),"mcp.json")}function Je(){return y(S(),"marketplace.json")}function O(r){if(!r)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return y(r,He)}function Ge(r){return y(O(r),"plugins")}function Ve(r){return y(O(r),"settings.json")}function ze(r){return y(O(r),"INSTRUCTIONS.md")}function Ye(r){return y(O(r),"rules")}import{resolve as yo}from"node:path";var tn=()=>{},ge;function Qe(){if(nn(),!ge)throw new Error("host project authority negotiated but snapshot is not hydrated");return{activeProjectId:ge.activeProjectId,projects:ge.projects.map(r=>({...r}))}}function nn(){let r=tn();if(!r)throw new Error("gateway project authority is not available");return r}function rn(){let r=Qe();return{activeProjectId:r.activeProjectId,projects:r.projects.map(e=>({...e}))}}function Xe(r){return rn().projects.find(e=>e.id===r)??null}function an(r){return Xe(r)?r:le(r)}function un(r){return fe(an(r))}function Ze(r){return sn(un(r),"sessions")}var pe=class{constructor(e={}){this.options=e}options;lastActiveWorkdir=null;getActiveProjectRoot(){return this.options.getActiveProjectRoot?.()??process.cwd()}setActiveWorkdir(e){let t=dn(e);this.lastActiveWorkdir=t,this.options.setActiveWorkdir?.(t)}getActiveWorkdir(){return this.lastActiveWorkdir??this.getActiveProjectRoot()}resolveProjectDir(e){return this.options.resolveProjectDir?.(e)}resolveActiveOwnerUserId(){return Q()}getUserAgentHome(){return S()}getOwnerProfileDir(e){return X(e)}getProfileMemoryDir(e){return _e(e)}getUserSettingsPath(){return Fe()}getUserSkillsDir(){return Ue()}getUserPluginsDir(){return Be()}getUserMcpConfigPath(){return Ke()}getUserPluginCacheDir(){return Le()}getUserMarketplaceConfigPath(){return Je()}getProjectAgentDir(e=this.getActiveProjectRoot()){return O(e)}getProjectSettingsPath(e=this.getActiveProjectRoot()){return Ve(e)}getProjectInstructionsPath(e=this.getActiveProjectRoot()){return ze(e)}getProjectPluginsDir(e=this.getActiveProjectRoot()){return Ge(e)}getProjectRulesDir(e=this.getActiveProjectRoot()){return Ye(e)}getProjectSessionDataRoot(e=this.getActiveProjectRoot()){return Ze(e)}},cn=new pe;function Z(){return cn}function N(r){return A(Z().getProjectAgentDir(r),"workflows")}function rt(r,e){return A(N(e),r,"workflow.json")}function me(r,e){return A(N(e),r,"revisions")}var ln=20,he=class{constructor(e){this.cwd=e;if(!e)throw new Error("WorkflowStore requires a project cwd")}cwd;async save(e){if(!e.id)throw new Error("WorkflowRecord.id is required");let t=A(N(this.cwd),e.id);await et(t,{recursive:!0}),await D(rt(e.id,this.cwd),e),await this.snapshotRevision(e)}async snapshotRevision(e){try{let t=me(e.id,this.cwd);await et(t,{recursive:!0}),await D(A(t,`${e.rev}.json`),e);let n=await this.revisionNumbers(e.id);for(let o of n.slice(ln))await nt(A(t,`${o}.json`),{force:!0})}catch{}}async revisionNumbers(e){let t;try{t=await tt(me(e,this.cwd))}catch{return[]}return t.map(n=>Number(n.replace(/\.json$/,""))).filter(n=>Number.isInteger(n)&&n>0).sort((n,o)=>o-n)}async listRevisions(e){let t=[];for(let n of await this.revisionNumbers(e)){let o=await this.loadRevision(e,n);o&&t.push({rev:n,updatedAt:o.updatedAt,name:o.name,nodeCount:o.def.nodes.length})}return t}async loadRevision(e,t){return j(A(me(e,this.cwd),`${t}.json`))}async load(e){return j(rt(e,this.cwd))}async require(e){let t=await this.load(e);if(!t)throw new Error(`Workflow "${e}" not found`);return t}async list(){let e;try{e=await tt(N(this.cwd))}catch{return[]}let t=[];for(let n of e){let o=await this.load(n);o&&t.push(o)}return t}async listActive(){return(await this.list()).filter(e=>e.active)}async delete(e){await nt(A(N(this.cwd),e),{recursive:!0,force:!0})}};var H=class{nodes=new Map;edges=[];constructor(e){for(let t of e){if(this.nodes.has(t.id))throw new Error(`Duplicate node ID: ${t.id}`);this.nodes.set(t.id,{id:t.id,kind:t.kind??"agent",params:t.params??{},status:"pending",outPorts:t.outPorts??["default"],joinPolicy:t.joinPolicy??"all",runIndex:0,maxIterations:t.maxIterations})}for(let t of e)for(let n of t.dependsOn??[]){if(!this.nodes.has(n))throw new Error(`Node "${t.id}" depends on unknown node "${n}"`);this.edges.push({from:n,to:t.id,fromPort:"default"})}this.validateDag()}getNode(e){return this.nodes.get(e)}getAllNodes(){return[...this.nodes.values()]}getReadyNodes(){let e=[];for(let t of this.nodes.values()){if(t.status!=="pending"||this.isBlockedByFailed(t.id))continue;let n=this.incomingForwardEdges(t.id);if(n.length===0){e.push(t);continue}t.joinPolicy==="any"?n.some(o=>this.edgeSatisfied(o))&&e.push(t):n.every(o=>this.edgeSatisfied(o))&&e.push(t)}return e}isFinished(){for(let e of this.nodes.values())if(e.status==="running"||e.status==="paused"||e.status==="pending"&&!this.isBlockedByFailed(e.id)&&!this.isSkippable(e.id))return!1;return!0}isAllCompleted(){return[...this.nodes.values()].every(e=>e.status==="completed"||e.status==="skipped")}getBlockedNodes(){return[...this.nodes.values()].filter(e=>e.status==="pending"&&this.isBlockedByFailed(e.id))}getProgress(){let e=0,t=0,n=0,o=0,i=0,s=0;for(let a of this.nodes.values())switch(a.status){case"completed":e++;break;case"running":t++;break;case"failed":n++;break;case"pending":o++;break;case"paused":i++;break;case"skipped":s++;break}return{total:this.nodes.size,completed:e,running:t,failed:n,pending:o,paused:i,skipped:s}}markRunning(e){let t=this.requireNode(e);if(t.status!=="pending")throw new Error(`Node "${e}" is ${t.status}, cannot start`);t.status="running",t.startedAt=Date.now()}markCompleted(e,t){let n=this.requireNode(e);if(n.status!=="running")throw new Error(`Node "${e}" is ${n.status}, cannot complete`);n.status="completed",n.output=t.output,n.completedAt=Date.now(),n.firedPorts=t.firedPorts??n.outPorts,t.inputTokens!==void 0&&(n.inputTokens=t.inputTokens),t.outputTokens!==void 0&&(n.outputTokens=t.outputTokens),t.changedFiles!==void 0&&(n.changedFiles=t.changedFiles),n.acceptanceUnverified=t.acceptanceUnverified,this.propagateSkips()}markFailed(e,t){let n=this.requireNode(e);n.status="failed",n.error=t,n.completedAt=Date.now(),this.propagateSkips()}markPaused(e){let t=this.requireNode(e);t.status==="running"&&(t.status="paused")}resumePaused(e){let t=this.requireNode(e);t.status==="paused"&&(t.status="pending")}markSkipped(e){let t=this.requireNode(e);if(t.status!=="pending")throw new Error(`Node "${e}" is ${t.status}, cannot skip`);t.status="skipped",t.firedPorts=[],this.propagateSkips()}pauseAll(){for(let e of this.nodes.values())e.status==="running"&&(e.status="paused")}resumeAll(){for(let e of this.nodes.values())e.status==="paused"&&(e.status="pending")}decideLoop(e,t){let n=this.requireNode(e);if(n.kind!=="loop")throw new Error(`Node "${e}" is not a loop controller`);if(!n.maxIterations||n.maxIterations<=0)throw new Error(`Loop "${e}" requires maxIterations > 0`);let o=n.iteration??0;t&&o<n.maxIterations?(n.iteration=o+1,n.firedPorts=["loop"],this.resetLoopScope(e)):(n.firedPorts=["done"],t&&(n.error=`loop_cap_reached:${n.maxIterations}`)),this.propagateSkips()}addNode(e){if(this.nodes.has(e.id))throw new Error(`Node "${e.id}" already exists`);for(let t of e.dependsOn??[])if(!this.nodes.has(t))throw new Error(`Node "${e.id}" depends on unknown node "${t}"`);this.nodes.set(e.id,{id:e.id,kind:e.kind??"agent",params:e.params??{},status:"pending",outPorts:e.outPorts??["default"],joinPolicy:e.joinPolicy??"all",runIndex:0,maxIterations:e.maxIterations});for(let t of e.dependsOn??[])this.edges.push({from:t,to:e.id,fromPort:"default"});try{this.validateDag()}catch(t){throw this.nodes.delete(e.id),this.edges=this.edges.filter(n=>n.to!==e.id||!e.dependsOn?.includes(n.from)),t}}addNodes(e){let t=[],n=[];try{for(let o of e){if(this.nodes.has(o.id))throw new Error(`Node "${o.id}" already exists`);for(let s of o.dependsOn??[])if(!this.nodes.has(s))throw new Error(`Unknown dep "${s}" for "${o.id}"`);this.nodes.set(o.id,{id:o.id,kind:o.kind??"agent",params:o.params??{},status:"pending",outPorts:o.outPorts??["default"],joinPolicy:o.joinPolicy??"all",runIndex:0,maxIterations:o.maxIterations}),t.push(o.id);let i=(o.dependsOn??[]).map(s=>({from:s,to:o.id,fromPort:"default"}));this.edges.push(...i),n.push(...i)}this.validateDag()}catch(o){for(let i of t)this.nodes.delete(i);throw this.edges=this.edges.filter(i=>!n.includes(i)),o}}removeNode(e){let t=this.requireNode(e);if(t.status==="running")throw new Error(`Cannot remove running node "${e}"`);if(t.status==="completed")throw new Error(`Cannot remove completed node "${e}"`);this.edges=this.edges.filter(n=>n.from!==e&&n.to!==e),this.nodes.delete(e)}retryNode(e,t){let n=this.requireNode(e);if(n.status!=="failed")throw new Error(`Node "${e}" is ${n.status}, only failed nodes can be retried`);n.status="pending",n.error=void 0,n.output=void 0,n.firedPorts=void 0,n.startedAt=void 0,n.completedAt=void 0,n.inputTokens=void 0,n.outputTokens=void 0,n.changedFiles=void 0,t&&Object.assign(n.params,t)}resetForReplay(e){if(!this.nodes.has(e))throw new Error(`Node "${e}" not found`);let t=new Set([e]),n=!0;for(;n;){n=!1;for(let o of this.nodes.values()){if(t.has(o.id))continue;this.incomingForwardEdges(o.id).map(s=>s.from).some(s=>t.has(s))&&(t.add(o.id),n=!0)}}for(let o of t){let i=this.nodes.get(o);i.status="pending",i.output=void 0,i.firedPorts=void 0,i.error=void 0,i.startedAt=void 0,i.completedAt=void 0,i.inputTokens=void 0,i.outputTokens=void 0,i.changedFiles=void 0}return[...t]}updateNodeParams(e,t){let n=this.requireNode(e);if(n.status!=="pending")throw new Error(`Node "${e}" is ${n.status}, can only update pending nodes`);Object.assign(n.params,t)}addEdge(e){let{from:t,to:n,fromPort:o="default",loopBack:i=!1}=e;if(!this.nodes.has(t))throw new Error(`Unknown source node "${t}"`);if(!this.nodes.has(n))throw new Error(`Unknown target node "${n}"`);let s=this.nodes.get(t);if(!i&&!s.outPorts.includes(o))throw new Error(`Node "${t}" has no outPort "${o}"`);if(!this.edges.find(d=>d.from===t&&d.to===n&&(d.fromPort??"default")===o))if(this.edges.push({from:t,to:n,fromPort:o,loopBack:i}),i){let d=this.nodes.get(n);if(!d.maxIterations||d.maxIterations<=0)throw this.edges.pop(),new Error(`LoopBack controller "${n}" requires maxIterations > 0`)}else try{this.validateDag()}catch(d){throw this.edges=this.edges.filter(l=>!(l.from===t&&l.to===n&&(l.fromPort??"default")===o)),d}}removeEdge(e,t,n){let o=n??"default";this.edges=this.edges.filter(i=>!(i.from===e&&i.to===t&&(i.fromPort??"default")===o))}serialize(){return[...this.nodes.values()].map(e=>{let t=this.incomingForwardEdges(e.id).map(n=>n.from);return{id:e.id,kind:e.kind,params:e.params,dependsOn:t,outPorts:e.outPorts,joinPolicy:e.joinPolicy,status:e.status,firedPorts:e.firedPorts,output:e.output,error:e.error,startedAt:e.startedAt,completedAt:e.completedAt,inputTokens:e.inputTokens,outputTokens:e.outputTokens,changedFiles:e.changedFiles,acceptanceUnverified:e.acceptanceUnverified,runIndex:e.runIndex,maxIterations:e.maxIterations,iteration:e.iteration}})}restore(e){for(let t of e){let n=this.nodes.get(t.id);n&&(n.status=t.status==="running"?"pending":t.status,n.output=t.output,n.error=t.error,n.firedPorts=t.firedPorts,n.startedAt=t.startedAt,n.completedAt=t.completedAt,n.inputTokens=t.inputTokens,n.outputTokens=t.outputTokens,n.changedFiles=t.changedFiles,n.acceptanceUnverified=t.acceptanceUnverified,n.runIndex=t.runIndex??0,n.iteration=t.iteration)}}getUpstreamOutputs(e){if(!this.nodes.get(e))return[];let n=this.incomingForwardEdges(e),o=new Set,i=[];for(let s of n){let a=s.from;if(o.has(a))continue;o.add(a);let d=this.nodes.get(a);if(d&&d.status==="completed"&&d.output!=null){let l=typeof d.output=="string"?d.output:JSON.stringify(d.output);l.trim()&&i.push({taskId:a,output:l})}}return i}edgeSatisfied(e){let t=this.nodes.get(e.from);if(!t||t.status!=="completed")return!1;let n=e.fromPort??"default";return(t.firedPorts??t.outPorts).includes(n)}edgeDead(e){let t=this.nodes.get(e.from);if(!t)return!1;if(t.status==="skipped")return!0;if(t.status==="completed"){if(t.kind==="loop"&&!(t.firedPorts??[]).includes("done"))return!1;let n=e.fromPort??"default";return!(t.firedPorts??t.outPorts).includes(n)}return!1}incomingForwardEdges(e){return this.edges.filter(t=>t.to===e&&!t.loopBack)}isBlockedByFailed(e){return this.incomingForwardEdges(e).some(t=>this.nodes.get(t.from)?.status==="failed")}isSkippable(e){let t=this.incomingForwardEdges(e);return t.length===0?!1:this.nodes.get(e).joinPolicy==="any"?t.every(o=>this.edgeDead(o)):t.some(o=>this.edgeDead(o))}propagateSkips(){let e=!0;for(;e;){e=!1;for(let t of this.nodes.values())t.status==="pending"&&this.isSkippable(t.id)&&(t.status="skipped",t.firedPorts=[],e=!0)}}resetLoopScope(e){let t=this.loopBodyNodes(e);for(let n of t){let o=this.nodes.get(n);o.status="pending",o.runIndex=(o.runIndex??0)+1,o.output=void 0,o.firedPorts=void 0,o.error=void 0,o.startedAt=void 0,o.completedAt=void 0,o.inputTokens=void 0,o.outputTokens=void 0,o.changedFiles=void 0}}loopBodyNodes(e){let t=new Set,n=(o,i)=>{for(let s of this.edges)s.from!==o||s.loopBack||i&&(s.fromPort??"default")!=="loop"||s.to!==e&&(t.has(s.to)||(t.add(s.to),n(s.to,!1)))};return n(e,!0),t}validateDag(){for(let i of this.edges){if(!this.nodes.has(i.from))throw new Error(`Edge references unknown source "${i.from}"`);if(!this.nodes.has(i.to))throw new Error(`Edge references unknown target "${i.to}"`)}let e=this.edges.filter(i=>!i.loopBack),t=new Set,n=new Set,o=i=>{if(n.has(i))throw new Error(`Cycle detected involving node "${i}"`);if(!t.has(i)){n.add(i);for(let s of e)s.from===i&&o(s.to);n.delete(i),t.add(i)}};for(let i of this.nodes.keys())o(i);for(let i of this.edges){if(!i.loopBack)continue;let s=this.nodes.get(i.to);if(!s?.maxIterations||s.maxIterations<=0)throw new Error(`LoopBack controller "${i.to}" must have maxIterations > 0`)}for(let i of this.nodes.values())if(i.maxIterations!==void 0&&i.maxIterations>1e3)throw new Error(`Loop "${i.id}" maxIterations ${i.maxIterations} exceeds the hard cap of 1000`)}requireNode(e){let t=this.nodes.get(e);if(!t)throw new Error(`Unknown node: "${e}"`);return t}};function C(r,e){return e?{json:r,binary:e}:{json:r}}function ot(r){let e={};for(let t of Object.keys(r).sort())e[t]=r[t].map(n=>({json:n.json,binary:n.binary?Object.fromEntries(Object.keys(n.binary).sort().map(o=>[o,n.binary[o].ref])):void 0}));return ye(e)}function ye(r){return JSON.stringify(we(r))}function we(r){if(Array.isArray(r))return r.map(we);if(r&&typeof r=="object"){let e={};for(let t of Object.keys(r).sort())e[t]=we(r[t]);return e}return r}var ut=new Set(["__proto__","prototype","constructor"]);function it(r,e){let t=ct(r),n=new ne(t,r),o=n.parseExpression();return n.expectEnd(),_(o,e)}function re(r){try{let e=ct(r),t=new ne(e,r),n=t.parseExpression();return t.expectEnd(),L(n),null}catch(e){return e instanceof Error?e.message:String(e)}}var fn=new Set(["input","json","node","now","vars","trigger"]),st=new Set(["len","upper","lower","default","jsonpath","date"]);function L(r){switch(r.type){case"root":if(!fn.has(r.name))throw new Error(`Unknown context root "$${r.name}" (allowed: $input $json $node $now $vars $trigger)`);return;case"lit":return;case"func":if(!st.has(r.name))throw new Error(`Unknown function "${r.name}" (whitelist: ${[...st].join(", ")})`);r.args.forEach(L);return;case"prop":L(r.target);return;case"index":if(L(r.target),typeof r.key!="number"&&typeof r.key!="string")throw new Error("index key must be a number or string literal");return;case"call":if(!(r.target.type==="root"&&r.target.name==="node"))throw new Error("Only $node(...) is callable in this position");r.args.forEach(L);return}}function E(r,e){let t=r.match(/^\s*\{\{([\s\S]*)\}\}\s*$/);return t?it(t[1],e):r.includes("{{")?r.replace(/\{\{([\s\S]*?)\}\}/g,(n,o)=>{let i=it(o,e);if(i==null)throw new Error(`Expression "{{${o.trim()}}}" resolved to ${i} in string interpolation`);return typeof i=="object"?JSON.stringify(i):String(i)}):r}function dt(r,e){return be(r,e)}function be(r,e){if(typeof r=="string")return E(r,e);if(Array.isArray(r))return r.map(t=>be(t,e));if(r&&typeof r=="object"){let t={};for(let[n,o]of Object.entries(r))t[n]=be(o,e);return t}return r}function ct(r){let e=[],t=0,n=i=>/[A-Za-z_]/.test(i),o=i=>/[A-Za-z0-9_]/.test(i);for(;t<r.length;){let i=r[t];if(/\s/.test(i)){t++;continue}if(i==="$"){t++;let s="";for(;t<r.length&&o(r[t]);)s+=r[t++];if(!s)throw new Error('Bare "$" is not a valid expression');e.push({t:"dollar",v:s});continue}if(n(i)){let s="";for(;t<r.length&&o(r[t]);)s+=r[t++];e.push({t:"id",v:s});continue}if(/[0-9]/.test(i)||i==="-"&&/[0-9]/.test(r[t+1]??"")){let s=r[t++];for(;t<r.length&&/[0-9.]/.test(r[t]);)s+=r[t++];e.push({t:"num",v:s});continue}if(i==='"'||i==="'"){let s=i;t++;let a="";for(;t<r.length&&r[t]!==s;)r[t]==="\\"&&t+1<r.length?(a+=r[t+1],t+=2):a+=r[t++];if(r[t]!==s)throw new Error("Unterminated string literal in expression");t++,e.push({t:"str",v:a});continue}if(".[](),".includes(i)){e.push({t:"punc",v:i}),t++;continue}throw new Error(`Unexpected character "${i}" in expression`)}return e}var ne=class{constructor(e,t){this.toks=e;this.src=t}toks;src;pos=0;parseExpression(){return this.parseAccessors(this.parseAtom())}peek(){return this.toks[this.pos]}next(){return this.toks[this.pos++]}expectEnd(){if(this.pos!==this.toks.length)throw new Error(`Unexpected trailing tokens in expression "${this.src.trim()}"`)}parseAtom(){let e=this.peek();if(!e)throw new Error("Empty expression");if(e.t==="dollar")return this.next(),{type:"root",name:e.v};if(e.t==="num")return this.next(),{type:"lit",value:Number(e.v)};if(e.t==="str")return this.next(),{type:"lit",value:e.v};if(e.t==="id"){if(e.v==="true")return this.next(),{type:"lit",value:!0};if(e.v==="false")return this.next(),{type:"lit",value:!1};if(e.v==="null")return this.next(),{type:"lit",value:null};if(this.next(),this.peek()?.t==="punc"&&this.peek().v==="("){let t=this.parseArgs();return{type:"func",name:e.v,args:t}}throw new Error(`Bare identifier "${e.v}" is not allowed (only whitelist function calls)`)}if(e.t==="punc"&&e.v==="("){this.next();let t=this.parseExpression();return this.expectPunc(")"),t}throw new Error(`Unexpected token "${e.v}" in expression`)}parseAccessors(e){let t=e;for(;;){let n=this.peek();if(!n||n.t!=="punc")break;if(n.v==="."){this.next();let o=this.next();if(!o||o.t!=="id"&&o.t!=="num")throw new Error('Expected property name after "."');t={type:"prop",target:t,key:o.v}}else if(n.v==="["){this.next();let o=this.next(),i;if(o.t==="num")i=Number(o.v);else if(o.t==="str")i=o.v;else throw new Error("Index must be a number or string literal");this.expectPunc("]"),t={type:"index",target:t,key:i}}else if(n.v==="("){let o=this.parseArgs();t={type:"call",target:t,args:o}}else break}return t}parseArgs(){this.expectPunc("(");let e=[];if(this.peek()?.t==="punc"&&this.peek().v===")")return this.next(),e;for(;;){e.push(this.parseExpression());let t=this.next();if(!t)throw new Error("Unterminated argument list");if(t.t==="punc"&&t.v===")")break;if(!(t.t==="punc"&&t.v===","))throw new Error('Expected "," or ")" in argument list')}return e}expectPunc(e){let t=this.next();if(!t||t.t!=="punc"||t.v!==e)throw new Error(`Expected "${e}" in expression`)}},lt=Symbol("nodeAccessor");function _(r,e){switch(r.type){case"lit":return r.value;case"root":return gn(r.name,e);case"func":return pn(r.name,r.args.map(t=>_(t,e)));case"prop":return at(_(r.target,e),r.key);case"index":return at(_(r.target,e),r.key);case"call":{if(_(r.target,e)===lt){let n=r.args.map(i=>_(i,e));if(n.length!==1||typeof n[0]!="string")throw new Error("$node(...) takes exactly one string argument");let o=e.nodes?.[n[0]];if(!o)throw new Error(`$node("${n[0]}") not found (not completed or unknown)`);return o}throw new Error("Only $node(...) is callable in this position")}}}function gn(r,e){switch(r){case"input":return e.input??{};case"json":return e.json??{};case"vars":return e.vars??{};case"trigger":return e.trigger??{};case"now":return(e.now?e.now():new Date).toISOString();case"node":return lt;default:throw new Error(`Unknown context root "$${r}" (allowed: $input $json $node $now $vars $trigger)`)}}function at(r,e){if(typeof e=="string"&&ut.has(e))throw new Error(`Access to "${e}" is forbidden`);if(r==null)throw new Error(`Cannot read "${e}" of ${r}`);if(typeof e=="number"){if(!Array.isArray(r))throw new Error(`Cannot index non-array with [${e}]`);return r[e]}return r[e]}function pn(r,e){switch(r){case"len":{let t=e[0];if(typeof t=="string"||Array.isArray(t))return t.length;if(t&&typeof t=="object")return Object.keys(t).length;throw new Error(`len() expects string/array/object, got ${typeof t}`)}case"upper":return String(te(e,0,"upper")).toUpperCase();case"lower":return String(te(e,0,"lower")).toLowerCase();case"default":return e[0]===null||e[0]===void 0?e[1]:e[0];case"jsonpath":return hn(e[0],String(te(e,1,"jsonpath")));case"date":return wn(e);case"eq":return ve(e[0],e[1]);case"ne":return!ve(e[0],e[1]);case"gt":return ee(e[0],e[1])>0;case"gte":return ee(e[0],e[1])>=0;case"lt":return ee(e[0],e[1])<0;case"lte":return ee(e[0],e[1])<=0;case"not":return!ke(te(e,0,"not"));case"and":return e.every(ke);case"or":return e.some(ke);case"contains":return mn(e[0],e[1]);default:throw new Error(`Unknown function "${r}()" (whitelist: len upper lower default jsonpath date eq ne gt gte lt lte not and or contains)`)}}function ke(r){return!!r}function ve(r,e){return r===e?!0:typeof r!=typeof e?!1:r&&e&&typeof r=="object"?JSON.stringify(r)===JSON.stringify(e):!1}function ee(r,e){if(typeof r=="number"&&typeof e=="number")return r-e;if(typeof r=="string"&&typeof e=="string")return r<e?-1:r>e?1:0;throw new Error(`Cannot compare ${typeof r} with ${typeof e}`)}function mn(r,e){if(typeof r=="string")return r.includes(String(e));if(Array.isArray(r))return r.some(t=>ve(t,e));throw new Error("contains() expects string/array as first argument")}function te(r,e,t){if(r.length<=e||r[e]===void 0)throw new Error(`${t}() missing required argument #${e+1}`);return r[e]}function hn(r,e){let t=e.match(/[^.[\]]+/g)??[],n=r;for(let o of t){if(ut.has(o))throw new Error(`jsonpath segment "${o}" is forbidden`);if(n==null)return;let i=/^\d+$/.test(o)?Number(o):o;n=n[i]}return n}function wn(r){let e=r.length===0?new Date:new Date(r[0]);if(Number.isNaN(e.getTime()))throw new Error(`date() received an invalid date: ${String(r[0])}`);if(r.length<2)return e.toISOString();let t=String(r[1]),n=o=>String(o).padStart(2,"0");return t.replace(/YYYY/g,String(e.getUTCFullYear())).replace(/MM/g,n(e.getUTCMonth()+1)).replace(/DD/g,n(e.getUTCDate())).replace(/HH/g,n(e.getUTCHours())).replace(/mm/g,n(e.getUTCMinutes())).replace(/ss/g,n(e.getUTCSeconds()))}import{mkdirSync as yn,writeFileSync as kn}from"node:fs";import{dirname as bn,resolve as vn}from"node:path";var ft={filter:["condition"],transform:["mapping"],script:["*"],n8nNode:["*"],agentBinding:["*"],modelBinding:["*"],toolBinding:["*"],integration:["*"],file:["*"],form:["*"],documentLoader:["*"],parser:["*"],retriever:["*"],textSplitter:["*"],vectorStore:["*"],extract:["*"],limit:["*"],split:["*"],respond:["*"]};function oe(r,e){return{json:e.json,vars:r.vars,trigger:r.trigger,now:r.now}}var xn=(r,e)=>{let t=e.assignments?.assignments;if(Array.isArray(t)){let o={};for(let i of t){if(!i||typeof i!="object")continue;let s=i;typeof s.name!="string"||!s.name||(o[s.name]=Tn(s.value,s.type))}return{outputs:{default:[{json:o}]}}}return{outputs:{default:[{json:e.json&&typeof e.json=="object"&&!Array.isArray(e.json)?e.json:{value:e.json??e.value??null}}]}}},Pn=r=>({outputs:{default:r.default??[]}}),En=r=>{let e=[];for(let t of Object.keys(r))e.push(...r[t]);return{outputs:{default:e}}},Rn=(r,e)=>{let n=!!e.condition?"true":"false",o=r.default??[],i={true:[],false:[]};return i[n]=o,{outputs:i,firedPorts:[n]}},In=(r,e,t)=>({outputs:{default:[{json:t.trigger??(e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload:{})}]}}),Sn=(r,e,t)=>{let n=e.condition;if(typeof n!="string"||!n.trim())throw new Error('filter node requires string param "condition" (per-item {{ }} expression over $json)');return{outputs:{default:(r.default??[]).filter(s=>!!E(n,oe(t,s)))}}},Nn=(r,e)=>{let t=Array.isArray(e.cases)?e.cases:[];if(t.length===0)throw new Error('switch node requires non-empty param "cases" ([{port, condition}])');let n=r.default??[],o=typeof e.defaultPort=="string"&&e.defaultPort?e.defaultPort:"default",i=o;for(let a of t){if(typeof a.port!="string"||!a.port)throw new Error('switch case requires string "port"');if(a.condition){i=a.port;break}}let s={};for(let a of t)typeof a.port=="string"&&(s[a.port]=[]);return s[o]=s[o]??[],s[i]=n,{outputs:s,firedPorts:[i]}},An=r=>{let e=r.default??[];return{outputs:{default:[{json:{items:e.map(t=>t.json),count:e.length}}]}}},$n=(r,e,t)=>{let n=e.mapping;if(typeof n!="object"||n===null||Array.isArray(n))throw new Error('transform node requires object param "mapping" ({outKey: "{{ expr }}"})');let o=Object.entries(n);if(o.length===0)throw new Error('transform node: "mapping" must have at least one key');return{outputs:{default:(r.default??[]).map(a=>{let d={};for(let[l,u]of o)d[l]=typeof u=="string"?E(u,oe(t,a)):u;return{json:d}})}}},jn=async(r,e,t)=>{if(e.until==="webhook"){let o=t.host;if(!o?.waitWebhook)throw new Error("wait(until=webhook) requires an ExecutorHost with waitWebhook");let i=typeof e.path=="string"&&e.path.trim()?e.path.trim():"";if(!i)throw new Error('wait(until=webhook) requires param "path" (the webhook path to wait for)');let s=typeof e.timeoutMs=="number"&&e.timeoutMs>0?e.timeoutMs:void 0,a=await o.waitWebhook({path:i.startsWith("/")?i:`/${i}`,nodeId:t.nodeId,workflowId:t.workflowId,timeoutMs:s,signal:t.signal});return{outputs:{default:[...r.default??[],{json:{webhook:a}}]}}}let n=Number(e.ms);if(!Number.isFinite(n)||n<1||n>36e5)throw new Error('wait node requires param "ms" in 1..3600000');return await new Promise((o,i)=>{let s=setTimeout(()=>{t.signal?.removeEventListener("abort",a),o()},n),a=()=>{clearTimeout(s),i(new Error("wait node canceled"))};t.signal?.addEventListener("abort",a,{once:!0})}),{outputs:{default:r.default??[]}}},Dn=(r,e,t)=>{let n=typeof e._n8nType=="string"?`(\u6765\u81EA n8n \u8282\u70B9\u300C${e._n8nType}\u300D)`:"";throw new Error(`\u8282\u70B9\u300C${t.nodeId}\u300D${n}\u5BFC\u5165\u65F6\u672A\u80FD\u81EA\u52A8\u8F6C\u6362,\u8BF7\u6253\u5F00\u8282\u70B9\u5B8C\u6210\u4EBA\u5DE5\u8FC1\u79FB\u540E\u518D\u8FD0\u884C`)},k=(r,e,t)=>{let n=typeof e._n8nType=="string"?` (${e._n8nType})`:"",i=(Array.isArray(e._n8nOutPorts)?e._n8nOutPorts:["default"]).filter(l=>typeof l=="string"&&l.length>0),s=r.default??[],a=s.length>0?s:[{json:{imported:!0,nodeId:t.nodeId,kind:t.kind,n8nType:e._n8nType}}],d={};for(let l of i.length>0?i:["default"])d[l]=a;if(d.default||(d.default=a),e._importMode==="n8n-strict-template")throw new Error(`Imported n8n node "${t.nodeId}"${n} requires a native executor or binding before live runs.`);return{outputs:d}},Cn=(r,e,t)=>{if((typeof e.operation=="string"?e.operation:"write")!=="write")throw new Error(`Imported file node "${t.nodeId}" supports operation "write" only for live runs`);let o=r.default?.[0];if(!o)throw new Error(`Imported file node "${t.nodeId}" requires an input item`);let i=Mn(e.fileName,o,t);if(!i)throw new Error(`Imported file node "${t.nodeId}" requires fileName`);let s=vn(i);return yn(bn(s),{recursive:!0}),kn(s,Wn(o)),{outputs:{default:[{json:{...o.json,fileName:s,written:!0}}]}}},gt={set:xn,passthrough:Pn,merge:En,if:Rn,trigger:In,filter:Sn,switch:Nn,aggregate:An,transform:$n,wait:jn,manual:Dn,script:k,n8nNode:k,agentBinding:k,modelBinding:k,toolBinding:k,integration:k,file:Cn,form:k,documentLoader:k,parser:k,retriever:k,textSplitter:k,vectorStore:k,extract:k,limit:k,split:k,respond:k};function Tn(r,e){if(e==="number"){let t=Number(r);return Number.isFinite(t)?t:r}if(e==="boolean"){if(typeof r=="boolean")return r;if(r==="true")return!0;if(r==="false")return!1}return r}function Wn(r){return typeof r.json.bodyBase64=="string"?Buffer.from(r.json.bodyBase64,"base64"):typeof r.json.body=="string"?r.json.body:r.json.body!==void 0?JSON.stringify(r.json.body,null,2):typeof r.json.data=="string"?r.json.data:JSON.stringify(r.json,null,2)}function Mn(r,e,t){if(typeof r!="string")return"";let n=r.startsWith("=")?r.slice(1):r,o=n.match(/^\{\{\s*([\s\S]*?)\s*\}\}$/);return o?String(On(o[1],e,t)??""):n.includes("{{")?String(E(n,oe(t,e))):n}function On(r,e,t){let n=r.match(/^\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(n)return e.json[n[1]];let o=r.match(/^(["'])([\s\S]*)\1\s*\+\s*\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(o)return`${Hn(o[1],o[2])}${String(e.json[o[3]]??"")}`;if(r.startsWith("$json."))return E(`{{ ${r} }}`,oe(t,e));throw new Error(`Imported n8n expression is unsupported at node "${t.nodeId}": ${r}`)}function Hn(r,e){if(r==='"')try{return JSON.parse(`"${e}"`)}catch{return e}return e.replace(/\\'/g,"'").replace(/\\\\/g,"\\")}var _n=new Set(["agentBinding","modelBinding"]),K=class{executors=new Map;constructor(e=!0){if(e)for(let[t,n]of Object.entries(gt))this.executors.set(t,n)}register(e,t){if(this.executors.has(e))throw new Error(`NodeExecutor for kind "${e}" already registered`);this.executors.set(e,t)}override(e,t){if(!this.executors.has(e))throw new Error(`Cannot override unregistered kind "${e}"`);this.executors.set(e,t)}installHostExecutors(e){for(let[t,n]of Object.entries(e))this.executors.has(t)?_n.has(t)&&this.override(t,n):this.register(t,n)}has(e){return this.executors.has(e)}get(e){let t=this.executors.get(e);if(!t)throw new Error(`No NodeExecutor registered for kind "${e}"`);return t}kinds(){return[...this.executors.keys()]}};function pt(r,e){let t=r??"any",n=e??"any";return t==="any"||n==="any"||t===n?!0:n==="binary"&&(t==="image"||t==="video"||t==="audio")}function mt(r){return r!=="manual"&&r!=="intent"&&r!=="form"}function J(r){let e=typeof r=="string"?r.trim():"";if(!e||e==="self")throw new Error('Workflow agent nodes require an explicit agentId; "self" is not a valid identity');return e}function $(r,e){if(!r)throw new Error(`Node kind "${e}" requires a host (ExecutorHost) but none was injected. Provide one via WorkflowRuntimeOptions.host.`);return r}function G(r,e,t){let n=r[e];if(typeof n!="string"||n.length===0)throw new Error(`Node kind "${t}" requires string param "${e}"`);return n}var qn=async(r,e,t)=>({outputs:{default:await $(t.host,"agent").runAgent({agentId:J(e.agentId),prompt:G(e,"prompt","agent"),input:r.default??[],signal:t.signal})}}),Bn=async(r,e,t)=>{let n=$(t.host,"agentBinding"),o=yt(e,r.default??[],t,"agentBinding");return{outputs:{default:await n.runAgent({agentId:J(e.agentId),prompt:o,input:r.default??[],signal:t.signal})}}},Un=async(r,e,t)=>{let n=$(t.host,"modelBinding");if(!n.runModel)throw new Error('Node kind "modelBinding" requires an ExecutorHost with runModel');return{outputs:{default:await n.runModel({prompt:yt(e,r.default??[],t,"modelBinding"),modelHint:Zn(e),temperature:ht(e.temperature),maxTokens:ht(e.maxTokens),input:r.default??[],signal:t.signal})}}},Fn=async(r,e,t)=>{let n=$(t.host,"http"),o=typeof e.method=="string"?e.method:"GET",i=await n.httpRequest({method:o,url:G(e,"url","http"),headers:Yn(e),body:zn(e),signal:t.signal}),s=r.default?.[0]?.json??{};return{outputs:{default:i.map(a=>({...a,json:{...s,...a.json}}))}}},Ln=async(r,e,t)=>({outputs:{default:await $(t.host,"channel").sendChannel({channel:G(e,"channel","channel"),target:typeof e.target=="string"?e.target:void 0,payload:e.payload??r.default?.[0]?.json??{},input:r.default??[],signal:t.signal})}}),Kn=async(r,e,t)=>{let n=$(t.host,"memory");if(!n.memory)throw new Error('Node kind "memory" requires an ExecutorHost with a memory backend');let o=G(e,"op","memory");if(o!=="read"&&o!=="write"&&o!=="search")throw new Error(`memory node: op must be "read"|"write"|"search", got "${o}"`);if(e.scope==="global")throw new Error('memory node: scope "global" \u9700\u7ECF\u6743\u9650\u95F8\u95E8(\u672A\u5F00\u653E);\u9ED8\u8BA4\u9879\u76EE\u7EA7\u8BF7\u79FB\u9664 scope');return{outputs:{default:await n.memory({op:o,key:typeof e.key=="string"&&e.key?e.key:void 0,value:e.value!==void 0?e.value:r.default?.[0]?.json,query:typeof e.query=="string"?e.query:void 0,input:r.default??[],signal:t.signal})}}},Jn=async(r,e,t)=>{let n=$(t.host,"subworkflow");if(!n.runSubworkflow)throw new Error('Node kind "subworkflow" requires an ExecutorHost with runSubworkflow');let o=e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload:r.default?.[0]?.json;return{outputs:{default:await n.runSubworkflow({workflowId:G(e,"workflowId","subworkflow"),callerWorkflowId:t.workflowId,projectId:typeof e.projectId=="string"&&e.projectId?e.projectId:void 0,payload:o,input:r.default??[],signal:t.signal})}}},Gn=async(r,e,t)=>{let n=$(t.host,"approval");if(!n.approval)throw new Error('Node kind "approval" requires an ExecutorHost with approval');let o=await n.approval({nodeId:t.nodeId,workflowId:t.workflowId,prompt:typeof e.prompt=="string"&&e.prompt?e.prompt:void 0,timeoutMs:typeof e.timeoutMs=="number"&&e.timeoutMs>0?e.timeoutMs:void 0,timeoutAction:e.timeoutAction==="approve"||e.timeoutAction==="reject"||e.timeoutAction==="keepPending"?e.timeoutAction:void 0,input:r.default??[],signal:t.signal});if(!o.approved)throw new Error(`approval node "${t.nodeId}" denied${o.note?`: ${o.note}`:""} (${o.decidedAt})`);return{outputs:{default:[...r.default??[],{json:{approved:!0,decidedAt:o.decidedAt,...o.note?{note:o.note}:{}}}]}}},ie={agent:qn,agentBinding:Bn,modelBinding:Un,http:Fn,channel:Ln,memory:Kn,subworkflow:Jn,approval:Gn},Vn=Object.keys(ie);function zn(r){if(r.body!==void 0)return r.body;if(r.sendBody!==!0)return;let e=wt(r.bodyParameters);if(e.length!==0)return Object.fromEntries(e)}function Yn(r){let e={};if(r.headers&&typeof r.headers=="object"&&!Array.isArray(r.headers))for(let[t,n]of Object.entries(r.headers))typeof n=="string"&&(e[t]=n);for(let[t,n]of wt(r.headerParameters))e[t]=String(n);return Object.keys(e).length>0?e:void 0}function wt(r){let e=r&&typeof r=="object"&&!Array.isArray(r)?r.parameters:void 0;if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!n||typeof n!="object")continue;let o=n;typeof o.name!="string"||!o.name||t.push([o.name,o.value??""])}return t}function yt(r,e,t,n){let o=Xn(r.prompt,r.text,r.message,r.input);if(!o)throw new Error(`Node kind "${n}" requires a prompt/text parameter`);return Qn(o,{json:e[0]?.json??{},input:{default:e},vars:t.vars,trigger:t.trigger,now:t.now})}function Qn(r,e){let t=r.startsWith("=")?r.slice(1):r;return t.includes("{{")?String(E(t,e)):t}function Xn(...r){for(let e of r)if(typeof e=="string"&&e.trim())return e}function Zn(r){let e=r.model??r.modelName;if(typeof e=="string"&&e)return e;if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e.value??e.cachedResultName;if(typeof t=="string"&&t)return t}}function ht(r){let e=typeof r=="number"?r:typeof r=="string"?Number(r):NaN;return Number.isFinite(e)?e:void 0}var q=class extends Error{constructor(t){super(t?`Workflow paused at "${t}"`:"Workflow paused");this.atNodeId=t;this.name="WorkflowPauseSignal"}atNodeId},b=class extends Error{constructor(e="Workflow run canceled"){super(e),this.name="WorkflowRunCanceled"}},V=class{constructor(e,t={}){this.def=e;this.registry=t.registry??new K,this.gate=t.gate,this.now=t.now??(()=>new Date),this.trigger=t.trigger,this.triggerKind=t.triggerKind,this.log=t.log,this.host=t.host,this.abortController=t.signal?void 0:new AbortController,this.signal=t.signal??this.abortController.signal,this.checkpoint=t.checkpoint,this.preserveCheckpoint=t.preserveCheckpoint===!0,this.onNodeStatus=t.onNodeStatus,this.host&&!t.registry&&this.registry.installHostExecutors(ie);for(let n of e.nodes)this.nodeDefs.set(n.id,n);for(let n of e.edges)n.loopBack&&this.loopBackOf.set(n.from,n.to)}def;registry;gate;now;trigger;triggerKind;log;host;abortController;signal;checkpoint;preserveCheckpoint;onNodeStatus;dag;nodeDefs=new Map;nodeOutputs=new Map;cache=new Map;loopBackOf=new Map;pauseRequested=!1;nodeStats={};statsSeq=0;checkpointLoaded=!1;setNodeParams(e,t){let n=this.nodeDefs.get(e);if(!n)throw new Error(`Unknown node "${e}"`);n.params={...n.params??{},...t}}pause(){this.pauseRequested=!0}cancel(e="Workflow run canceled"){let t=new b(e);this.abortController&&!this.abortController.signal.aborted&&this.abortController.abort(t)}extendBudget(e){if(!this.gate?.extend)throw new Error("WorkflowRuntime has no extensible budget gate to raise");this.gate.extend(e)}async run(){await this.loadCheckpoint(),this.throwIfCanceled(),this.dag=this.buildDag(),this.nodeOutputs.clear(),this.pauseRequested=!1;let e=new Set,t;try{let i=0;for(;!this.dag.isFinished();){if(++i>1e5)throw new Error("WorkflowRuntime did not converge");let s=this.dag.getReadyNodes();if(s.length===0)break;for(let a of s)await this.executeNode(a,e)}}catch(i){if(i instanceof q)t=i.atNodeId;else throw i}let n={};for(let[i,s]of this.nodeOutputs)n[i]=s;let o=t?"paused":this.dag.isAllCompleted()?"completed":"failed";return o==="completed"&&this.checkpoint&&(this.preserveCheckpoint?await this.persistCheckpoint():await this.checkpoint.clear()),{status:o,outputs:n,executed:e,progress:this.dag.getProgress(),pausedAt:t,nodeStats:{...this.nodeStats}}}async loadCheckpoint(){if(!this.checkpoint||this.checkpointLoaded)return;this.checkpointLoaded=!0;let e=await this.checkpoint.load();if(e)for(let t of e.entries)this.cache.set(t.key,t.result)}async persistCheckpoint(){if(!this.checkpoint)return;let e=[...this.cache.entries()].map(([t,n])=>({key:t,result:n}));await this.checkpoint.persist(e)}async executeNode(e,t){if(this.throwIfCanceled(),this.pauseRequested)throw new q(e.id);if(e.kind==="loop"){this.enterLoop(e);return}let n=this.collectInputs(e.id),o=this.buildExprContext(n),i=this.nodeDefs.get(e.id)?.params??{},s=ft[e.kind]??[],a=s.includes("*"),d=a?{}:s.length>0?Object.fromEntries(Object.entries(i).filter(([m])=>!s.includes(m))):i,l={...dt(d,o),...a?i:Object.fromEntries(s.filter(m=>m in i).map(m=>[m,i[m]]))},u=this.cacheKey(e.kind,l,n,e.runIndex),f=Date.now(),c=0,g=(m,M)=>{let U=Date.now();this.nodeStats[e.id]={seq:++this.statsSeq,startedAt:new Date(f).toISOString(),finishedAt:new Date(U).toISOString(),durationMs:U-f,attempts:c,cacheHit:M,status:m}},p=this.cache.get(u),h=p!==void 0,w=!1;if(p)this.dag.markRunning(e.id);else{this.gate?.check(e.id,e.kind),this.dag.markRunning(e.id),this.onNodeStatus?.(e.id,"running");let m=this.nodeDefs.get(e.id),M=Math.max(1,m?.retry?.maxTries??1),U=Math.max(0,m?.retry?.backoffMs??1e3),ce=m?.timeoutMs,P;for(let R=0;R<M;R++){c++,this.throwIfCanceled();let I={nodeId:e.id,kind:e.kind,workflowId:this.def.id,triggerKind:this.triggerKind,runIndex:e.runIndex,vars:this.def.vars??{},trigger:this.trigger,now:this.now,log:this.log,host:this.host,signal:ce!==void 0&&ce>0?AbortSignal.any([this.signal,AbortSignal.timeout(ce)]):this.signal};try{if(p=await this.registry.get(e.kind)(n,l,I),I.signal?.aborted)throw I.signal.reason instanceof Error?I.signal.reason:new Error(`node "${e.id}" execution was aborted`);P=void 0;break}catch(F){if(this.isCanceled())throw this.canceledError(F);P=F;let Oe=R+1<M;this.log?.warn(`node "${e.id}" attempt ${R+1}/${M} failed: ${F instanceof Error?F.message:String(F)}`+(Oe?` \u2014 retrying in ${U*2**R}ms`:"")),Oe&&await this.cancellableDelay(U*2**R)}}if(P!==void 0){let R=m?.onError??"stop",I=P instanceof Error?P.message:String(P);if(R==="errorPort")this.onNodeStatus?.(e.id,"failed",I),p={outputs:{error:[{json:{error:I,nodeId:e.id,kind:e.kind,attempts:M}}]},firedPorts:["error"]},w=!0;else if(R==="continue")this.onNodeStatus?.(e.id,"failed",I),p={outputs:{},firedPorts:[]},w=!0;else throw this.onNodeStatus?.(e.id,"failed",I),g("failed",!1),P&&typeof P=="object"&&!P.nodeId&&(P.nodeId=e.id),P}this.throwIfCanceled(),w?t.add(e.id):(this.cache.set(u,p),t.add(e.id),await this.persistCheckpoint())}this.nodeOutputs.set(e.id,p.outputs),this.dag.markCompleted(e.id,{output:p.outputs,firedPorts:p.firedPorts}),w||this.onNodeStatus?.(e.id,"completed"),g(w?"failed":"completed",h);let x=this.loopBackOf.get(e.id);x&&this.decideLoopBack(x)}enterLoop(e){this.dag.markRunning(e.id);let t={loop:[{json:{iteration:e.iteration??0}}],done:[]};this.nodeOutputs.set(e.id,t),this.dag.markCompleted(e.id,{output:t,firedPorts:["loop"]}),this.onNodeStatus?.(e.id,"completed")}decideLoopBack(e){let t=this.evalLoopCondition(e);this.dag.decideLoop(e,t);let n=this.dag.getNode(e);this.surfaceLoopCap(n);let o=n.firedPorts??[];this.nodeOutputs.set(e,{loop:o.includes("loop")?[{json:{iteration:n.iteration??0}}]:[],done:o.includes("done")?[{json:{iteration:n.iteration??0}}]:[]})}surfaceLoopCap(e){if(!e.error?.startsWith("loop_cap_reached:")||this.nodeStats[e.id]?.warning)return;let t=`loop "${e.id}" hit its maxIterations cap (${e.maxIterations}) \u2014 forced exit via "done" while the loop condition still asked to continue`;this.log?.warn(t);let n=this.nodeStats[e.id],o=new Date().toISOString();this.nodeStats[e.id]=n?{...n,warning:t}:{seq:++this.statsSeq,startedAt:o,finishedAt:o,durationMs:0,attempts:0,cacheHit:!1,status:"completed",warning:t}}evalLoopCondition(e){let n=this.nodeDefs.get(e)?.params?.condition;if(n==null||n==="")return!0;let o=this.buildExprContext({});return!!(typeof n=="string"?E(n,o):n)}collectInputs(e){let t={};for(let n of this.def.edges){if(n.to!==e||n.loopBack)continue;let o=n.fromPort??"default",i=n.toPort??"default",s=this.nodeOutputs.get(n.from);if(!s)continue;let a=s[o];a&&(t[i]??=[]).push(...a)}return t}buildExprContext(e){let t={};for(let[n,o]of this.nodeOutputs)t[n]={output:o};return{input:e,json:e.default?.[0]?.json??{},nodes:t,vars:this.def.vars??{},trigger:this.trigger,now:this.now}}cacheKey(e,t,n,o){return ye([e,t,ot(n),o])}isCanceled(){return this.signal.aborted}canceledError(e){let t=this.signal.reason;return t instanceof b?t:t instanceof Error?new b(t.message):e instanceof b?e:e instanceof Error&&this.signal.aborted?new b(e.message):new b(t===void 0?"Workflow run canceled":String(t))}throwIfCanceled(){if(this.isCanceled())throw this.canceledError()}cancellableDelay(e){return e<=0?Promise.resolve():new Promise((t,n)=>{let o=setTimeout(()=>{this.signal.removeEventListener("abort",i),t()},e),i=()=>{clearTimeout(o),n(this.canceledError())};this.signal.addEventListener("abort",i,{once:!0})})}buildDag(){let e=this.def.nodes.map(n=>{let o=n.outPorts??er(n.kind);return n.onError==="errorPort"&&!o.includes("error")&&(o=[...o,"error"]),{id:n.id,kind:n.kind,params:n.params??{},outPorts:o,joinPolicy:n.joinPolicy??"all",maxIterations:n.maxIterations}}),t=new H(e);for(let n of this.def.edges)n.loopBack||t.addEdge({from:n.from,to:n.to,fromPort:n.fromPort??"default"});for(let n of this.def.edges)n.loopBack&&t.addEdge({from:n.from,to:n.to,loopBack:!0});return t}};function er(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}var tr=new Set(["agent","action","http","channel","im"]);var xe=class extends Error{constructor(t,n,o){super(`Permission denied: node "${t}" (kind "${n}") may not run under unattended trigger "${o}". Authorize it by adding "${n}" to allowUnattendedKinds.`);this.nodeId=t;this.kind=n;this.trigger=o;this.name="WorkflowPermissionDenied"}nodeId;kind;trigger},se=class extends q{constructor(t,n,o){super(t);this.reason=n;this.limit=o;this.name="WorkflowBudgetExceeded",this.message=`Budget exceeded (${n} limit ${o}) before node "${t}"`}reason;limit},ae=class{trigger;maxNodeExecutions;maxDurationMs;allow;now;executions=0;startedAt=-1;constructor(e){if(!Number.isInteger(e.maxNodeExecutions)||e.maxNodeExecutions<=0)throw new Error(`BudgetPermissionGate: maxNodeExecutions must be a positive integer, got ${e.maxNodeExecutions}`);if(e.maxDurationMs!==void 0&&!(e.maxDurationMs>0))throw new Error(`BudgetPermissionGate: maxDurationMs must be greater than 0 when provided, got ${e.maxDurationMs}`);this.trigger=e.trigger,this.maxNodeExecutions=e.maxNodeExecutions,this.maxDurationMs=e.maxDurationMs,this.allow=new Set(e.allowUnattendedKinds??[]),this.now=e.now??(()=>Date.now())}get unattended(){return mt(this.trigger)}check(e,t){if(this.unattended&&tr.has(t)&&!this.allow.has(t))throw new xe(e,t,this.trigger);if(this.startedAt<0&&(this.startedAt=this.now()),this.maxDurationMs!==void 0&&this.now()-this.startedAt>=this.maxDurationMs)throw new se(e,"duration",this.maxDurationMs);if(this.executions>=this.maxNodeExecutions)throw new se(e,"executions",this.maxNodeExecutions);this.executions++}extend(e){if(e.executions!==void 0){if(!Number.isInteger(e.executions)||e.executions<=0)throw new Error(`BudgetPermissionGate.extend: executions delta must be a positive integer, got ${e.executions}`);this.maxNodeExecutions+=e.executions}if(e.durationMs!==void 0){if(!(e.durationMs>0))throw new Error(`BudgetPermissionGate.extend: durationMs delta must be greater than 0, got ${e.durationMs}`);if(this.maxDurationMs===void 0)throw new Error("BudgetPermissionGate.extend: cannot extend duration on a gate with no duration cap");this.maxDurationMs+=e.durationMs}}};function vt(r){switch(r.type){case"manual":return[];case"schedule":return sr(r.cron);case"im-message":return dr(r.channel,r.match);case"webhook":return cr(r.path);case"intent":return rr(r.phrases,r.aliases,r.surfaces);case"form":return ir(r.fields);default:return[`unknown trigger type: ${JSON.stringify(r)}`]}}var nr=new Set(["welcome","chat"]);function rr(r,e,t){let n=[];if(!Array.isArray(r)||r.length===0)n.push("intent.phrases must be a non-empty array of trigger phrases");else for(let o of r)(typeof o!="string"||o.trim()==="")&&n.push(`intent.phrases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(e!==void 0)if(!Array.isArray(e))n.push("intent.aliases must be an array when present");else for(let o of e)(typeof o!="string"||o.trim()==="")&&n.push(`intent.aliases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(t!==void 0)if(!Array.isArray(t)||t.length===0)n.push("intent.surfaces must be a non-empty array when present");else for(let o of t)(typeof o!="string"||!nr.has(o))&&n.push(`intent.surfaces entries must be "welcome"|"chat", got ${JSON.stringify(o)}`);return n}var or=new Set(["text","number","select"]);function ir(r){let e=[];if(!Array.isArray(r)||r.length===0)return["form.fields must be a non-empty array"];let t=new Set;for(let n of r){if(typeof n?.key!="string"||!/^[\w-]+$/.test(n.key)){e.push(`form field key must be a [\\w-]+ string, got ${JSON.stringify(n?.key)}`);continue}t.has(n.key)&&e.push(`duplicate form field key "${n.key}"`),t.add(n.key),n.type!==void 0&&(typeof n.type!="string"||!or.has(n.type))&&e.push(`form field "${n.key}": type must be text|number|select`),n.type==="select"&&(!Array.isArray(n.options)||n.options.length===0)&&e.push(`form field "${n.key}": select requires non-empty options`)}return e}var kt=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],bt=["SUN","MON","TUE","WED","THU","FRI","SAT"];function sr(r){if(typeof r!="string"||r.trim()==="")return["schedule.cron must be a non-empty string"];let e=r.trim().split(/\s+/);if(e.length!==5&&e.length!==6)return[`schedule.cron must have 5 or 6 fields, got ${e.length}: "${r}"`];let n=e.length===6?[{label:"second",min:0,max:59},{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:kt},{label:"day-of-week",min:0,max:7,names:bt}]:[{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:kt},{label:"day-of-week",min:0,max:7,names:bt}],o=[];for(let i=0;i<n.length;i++){let s=ar(e[i],n[i]);s&&o.push(`schedule.cron ${s}`)}return o}function ar(r,e){for(let t of r.split(",")){let n=ur(t,e);if(n)return n}}function ur(r,e){if(r==="")return`${e.label} has an empty list element`;let t=r,n,o=r.indexOf("/");if(o!==-1&&(t=r.slice(0,o),n=r.slice(o+1),!/^\d+$/.test(n)||Number(n)<=0))return`${e.label} has an invalid step "/${n}"`;if(t==="*")return;let i=t.indexOf("-");if(i!==-1){let a=Pe(t.slice(0,i),e),d=Pe(t.slice(i+1),e);return a===void 0||d===void 0?`${e.label} has an invalid range "${t}"`:a>d?`${e.label} range "${t}" is descending`:void 0}if(t===""&&n!==void 0)return`${e.label} step "${r}" needs a base ("*" or a range)`;if(Pe(t,e)===void 0)return`${e.label} value "${t}" is out of range ${e.min}-${e.max}`}function Pe(r,e){let t;if(/^\d+$/.test(r))t=Number(r);else if(e.names){let n=e.names.indexOf(r.toUpperCase());if(n===-1)return;t=e.label==="month"?n+1:n}else return;if(!(t<e.min||t>e.max))return t}function dr(r,e){let t=[];if((typeof r!="string"||r.trim()==="")&&t.push("im-message.channel must be a non-empty string"),e!==void 0)if(typeof e!="string")t.push("im-message.match must be a string regex");else try{new RegExp(e)}catch(n){t.push(`im-message.match is not a valid regex: ${n.message}`)}return t}function cr(r){return typeof r!="string"||r===""?["webhook.path must be a non-empty string"]:r.startsWith("/")?/\s/.test(r)?[`webhook.path must not contain whitespace: "${r}"`]:r.includes("..")?[`webhook.path must not contain "..": "${r}"`]:/^\/[A-Za-z0-9\-._~/]*$/.test(r)?[]:[`webhook.path contains illegal characters: "${r}"`]:[`webhook.path must start with "/": "${r}"`]}var v=class extends Error{constructor(t){super(`Patch rejected: ${t.join("; ")}`);this.errors=t;this.name="PatchError"}errors};function Ee(r,e){let t=[],n=gr(r),o=new Map(n.def.nodes.map(l=>[l.id,l])),i=e.scope?new Set(e.scope):void 0,s=new Set,a=l=>!i||i.has(l)||s.has(l),d=[];for(let[l,u]of e.patch.entries()){let f=`op[${l}] ${u.op}`;switch(u.op){case"add_node":{u.node?.id?o.has(u.node.id)?t.push(`${f}: node "${u.node.id}" already exists`):(n.def.nodes.push(u.node),o.set(u.node.id,u.node),i&&s.add(u.node.id)):t.push(`${f}: node.id is required`);break}case"remove_node":{o.has(u.nodeId)?a(u.nodeId)?(n.def.nodes=n.def.nodes.filter(c=>c.id!==u.nodeId),o.delete(u.nodeId),n.def.edges=n.def.edges.filter(c=>c.from!==u.nodeId&&c.to!==u.nodeId)):t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"update_params":{let c=o.get(u.nodeId);c?a(u.nodeId)?c.params=lr(c.params,u.params):t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"rename_node":{let c=o.get(u.nodeId);c?a(u.nodeId)?c.name=u.name:t.push(`${f}: node "${u.nodeId}" is outside the edit scope`):t.push(`${f}: node "${u.nodeId}" not found`);break}case"set_node_options":{let c=o.get(u.nodeId);if(!c){t.push(`${f}: node "${u.nodeId}" not found`);break}if(!a(u.nodeId)){t.push(`${f}: node "${u.nodeId}" is outside the edit scope`);break}u.retry!==void 0&&(u.retry===null?delete c.retry:!Number.isInteger(u.retry.maxTries)||u.retry.maxTries<1||u.retry.maxTries>10?t.push(`${f}: retry.maxTries must be an integer 1..10`):u.retry.backoffMs!==void 0&&(!Number.isFinite(u.retry.backoffMs)||u.retry.backoffMs<0)?t.push(`${f}: retry.backoffMs must be a non-negative number`):c.retry={maxTries:u.retry.maxTries,...u.retry.backoffMs!==void 0?{backoffMs:u.retry.backoffMs}:{}}),u.timeoutMs!==void 0&&(u.timeoutMs===null?delete c.timeoutMs:!Number.isFinite(u.timeoutMs)||u.timeoutMs<=0?t.push(`${f}: timeoutMs must be a positive number`):c.timeoutMs=u.timeoutMs),u.onError!==void 0&&(u.onError===null?delete c.onError:u.onError!=="stop"&&u.onError!=="continue"&&u.onError!=="errorPort"?t.push(`${f}: onError must be "stop"|"continue"|"errorPort"`):c.onError=u.onError);break}case"set_node_ui":{if(!u.positions||typeof u.positions!="object"){t.push(`${f}: positions is required`);break}for(let[c,g]of Object.entries(u.positions)){let p=o.get(c);if(!p){t.push(`${f}: node "${c}" not found`);continue}if(!a(c)){t.push(`${f}: node "${c}" is outside the edit scope`);continue}if(g===null){delete p.ui;continue}if(!Number.isFinite(g?.x)||!Number.isFinite(g?.y)){t.push(`${f}: position for "${c}" must be finite {x,y}`);continue}p.ui={x:g.x,y:g.y}}break}case"add_edge":{let c=u.edge;if(!c?.from||!c?.to){t.push(`${f}: edge.from and edge.to are required`);break}if(i&&!a(c.from)&&!a(c.to)){t.push(`${f}: edge ${c.from}\u2192${c.to} has no endpoint in the edit scope`);break}let g=c.fromPort??"default";if(n.def.edges.some(m=>m.from===c.from&&m.to===c.to&&(m.fromPort??"default")===g)){t.push(`${f}: \u8FDE\u7EBF\u5DF2\u5B58\u5728(${c.from} \u2192 ${c.to})`);break}let p=o.get(c.from),h=o.get(c.to),w=p?.outPortTypes?.[g],x=h?.inPorts?.find(m=>m.name===(c.toPort??"default"))?.type;if(!pt(w,x)){t.push(`${f}: \u7AEF\u53E3\u7C7B\u578B\u4E0D\u5339\u914D:\u300C${p?.name??c.from}\u300D\u8F93\u51FA ${w??"any"},\u300C${h?.name??c.to}\u300D\u9700\u8981 ${x??"any"} \u2014\u2014 \u63A5\u4E0D\u4E0A,\u8BF7\u6362\u4E2A\u76EE\u6807\u7AEF\u53E3`);break}n.def.edges.push(c);break}case"remove_edge":{let{from:c,to:g,fromPort:p}=u.edge;if(i&&!a(c)&&!a(g))t.push(`${f}: edge ${c}\u2192${g} has no endpoint in the edit scope`);else{let h=n.def.edges.length;n.def.edges=n.def.edges.filter(w=>!(w.from===c&&w.to===g&&(w.fromPort??"default")===(p??"default"))),n.def.edges.length===h&&t.push(`${f}: edge ${c}\u2192${g} not found`)}break}case"set_trigger":{if(i)t.push(`${f}: trigger is workflow-global and cannot be changed in a scoped edit`);else if(u.trigger){let c=vt(u.trigger);if(c.length>0)for(let g of c)t.push(`${f}: ${g}`);else n.meta.trigger=u.trigger}else n.meta.trigger=u.trigger;break}case"set_meta":{i?t.push(`${f}: meta is workflow-global and cannot be changed in a scoped edit`):(u.meta.name!==void 0&&(n.meta.name=u.meta.name),u.meta.active!==void 0&&(n.meta.active=u.meta.active));break}default:t.push(`${f}: unknown op`)}t.length===0&&d.push(u)}if(t.length>0)throw new v(t);if(Pt(n.def,t),xt(n.def,t),t.length>0)throw new v(t);return{target:n,applied:d}}function lr(r,e){let t={...r??{}};for(let[n,o]of Object.entries(e))o===null?delete t[n]:t[n]=o;return t}function z(r){let e=[];for(let t of r.nodes)(t.kind==="tool"||t.kind==="skill"||t.kind==="mcp")&&e.push(`\u8282\u70B9\u300C${t.id}\u300D\u4F7F\u7528\u4E86 legacy kind "${t.kind}";\u8BF7\u6539\u7528 Agent \u63D2\u4EF6\u6216 canonical Action \u8282\u70B9`);return Pt(r,e),xt(r,e),e}function xt(r,e){let t=(n,o,i)=>{if(typeof n=="string"){if(n.startsWith("="))return;for(let s of n.matchAll(/\{\{([\s\S]*?)\}\}/g)){let a=re(s[1].trim());a&&e.push(`\u8282\u70B9\u300C${o}\u300D\u53C2\u6570 ${i} \u7684\u8868\u8FBE\u5F0F\u300C{{ ${s[1].trim()} }}\u300D\u8D85\u51FA\u53D7\u9650\u8BED\u8A00:${a}`)}return}if(Array.isArray(n)){n.forEach((s,a)=>t(s,o,`${i}[${a}]`));return}if(n&&typeof n=="object")for(let[s,a]of Object.entries(n))t(a,o,i?`${i}.${s}`:s)};for(let n of r.nodes)n.params?._importMode!=="n8n-strict-template"&&n.params&&t(n.params,n.id,"")}function Pt(r,e){try{let t=r.nodes.map(o=>{let i=o.outPorts??fr(o.kind);return o.onError==="errorPort"&&!i.includes("error")&&(i=[...i,"error"]),{id:o.id,kind:o.kind,params:o.params??{},outPorts:i,joinPolicy:o.joinPolicy??"all",maxIterations:o.maxIterations}}),n=new H(t);for(let o of r.edges)o.loopBack||n.addEdge({from:o.from,to:o.to,fromPort:o.fromPort??"default"});for(let o of r.edges)o.loopBack&&n.addEdge({from:o.from,to:o.to,loopBack:!0})}catch(t){e.push(`graph invalid: ${t.message}`)}}function fr(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}function gr(r){return{def:{...r.def,nodes:r.def.nodes.map(e=>({...e,params:e.params?{...e.params}:void 0})),edges:r.def.edges.map(e=>({...e})),vars:r.def.vars?{...r.def.vars}:void 0},meta:{...r.meta}}}function Re(r,e={}){let t=e.maxNodes??50,n=e.maxValueLen??60,o=`Workflow ${JSON.stringify(r.name)} (rev ${r.rev}, trigger: ${pr(r.trigger)}, ${r.active?"active":"inactive"})`,i=r.def.nodes,a=i.slice(0,t).map(f=>" "+mr(f,n)),d=i.length===0?"nodes: (none)":["nodes:",...a].join(`
3
3
  `),l=i.length>t?`
4
- \u2026 ${i.length-t} more node(s); call workflow.get for the full definition`:"",u=$r(r.def.edges);return`${o}
4
+ \u2026 ${i.length-t} more node(s); fetch the full definition from the Gateway Host`:"",u=yr(r.def.edges);return`${o}
5
5
  ${d}${l}
6
- ${u}`}function Sr(r){if(!r)return"none";switch(r.type){case"manual":return"manual";case"schedule":return`schedule ${JSON.stringify(r.cron)}`;case"im-message":return r.match?`im-message ${r.channel} match=${JSON.stringify(r.match)}`:`im-message ${r.channel}`;case"webhook":return`webhook ${r.path}`;case"intent":return`intent ${r.phrases.map(e=>JSON.stringify(e)).join(" / ")}${r.semantic?" +semantic":""}`;case"form":return`form [${r.fields.map(e=>e.key).join(", ")}]`}}function Ir(r,e){let t=r.name?` "${r.name}"`:"",n=Ar(r.params,e),o=(r.outPorts??Dr(r.kind)).join(","),i=[`${r.id} [${r.kind}]${t}`];return n&&i.push(n),i.push(`out: ${o}`),i.join(" ")}function Ar(r,e){if(!r)return"";let t=Object.keys(r).sort();return t.length===0?"":t.map(n=>`${n}=${Nr(r[n],e)}`).join(" ")}function Nr(r,e){let t;return typeof r=="string"?t=r.includes("{{")?r:JSON.stringify(r):t=JSON.stringify(r),t.length>e&&(t=t.slice(0,e-1)+"\u2026"),t}function $r(r){return r.length===0?"edges: (none)":`edges:
7
- ${r.map(t=>{let n=t.fromPort??"default",o=t.toPort??"default",i=t.loopBack?" (loopBack)":"";return`${t.from}.${n}\u2192${t.to}.${o}${i}`}).join(" ; ")}`}function Dr(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}function Cr(r){let e=[],t=r;return t=t.replace(/\$node\[\s*(['"])([^'"\]]+)\1\s*\]\.json/g,'$node("$2").output.default[0].json'),t=t.replace(/\$\(\s*(['"])([^'")]+)\1\s*\)(?:\.item|\.first\(\))?\.json/g,'$node("$2").output.default[0].json'),t=t.replace(/\$items\(\s*(['"])([^'")]+)\1\s*\)\[(\d+)\]\.json/g,'$node("$2").output.default[$3].json'),t=t.replace(/\$input(?:\.item|\.first\(\))\.json/g,"$json"),/\$now\b/.test(t)&&e.push("$now:n8n \u4E3A Luxon DateTime,\u6B64\u5904\u4E3A Date(\u683C\u5F0F\u5316\u51FD\u6570\u7528 date(...))"),{body:t,notes:e}}function jr(r){if(!r.startsWith("="))return null;let e=r.slice(1);if(!e.includes("{{"))return{ok:!0,converted:e,notes:[]};let t=[],n=null,o=e.replace(/\{\{([\s\S]*?)\}\}/g,(i,s)=>{if(n)return i;let{body:a,notes:d}=Cr(s.trim()),l=ie(a);return l?(n=`\u8868\u8FBE\u5F0F\u300C{{ ${s.trim()} }}\u300D\u8D85\u51FA\u53D7\u9650\u8BED\u8A00(${l})`,i):(t.push(...d),`{{ ${a} }}`)});return n?{ok:!1,reason:n}:{ok:!0,converted:o,notes:t}}function $t(r,e,t=""){let n=(o,i)=>{if(typeof o=="string"){let s=jr(o);return s===null?o:s.ok?(e.converted++,e.notes.push(...s.notes),s.converted):(e.manual.push({path:i,raw:o,reason:s.reason}),o)}return Array.isArray(o)?o.map((s,a)=>n(s,`${i}[${a}]`)):o&&typeof o=="object"?Object.fromEntries(Object.entries(o).map(([s,a])=>[s,n(a,i?`${i}.${s}`:s)])):o};return n(r,t)}var Dt={"@n8n/n8n-nodes-langchain.agent":"agentBinding","@n8n/n8n-nodes-langchain.chainLlm":"agentBinding","@n8n/n8n-nodes-langchain.chainRetrievalQa":"agentBinding","@n8n/n8n-nodes-langchain.chainSummarization":"agentBinding","@n8n/n8n-nodes-langchain.chatTrigger":"trigger","@n8n/n8n-nodes-langchain.documentDefaultDataLoader":"documentLoader","@n8n/n8n-nodes-langchain.embeddingsOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.informationExtractor":"agentBinding","@n8n/n8n-nodes-langchain.lmChatGoogleGemini":"modelBinding","@n8n/n8n-nodes-langchain.lmChatOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.lmChatOpenRouter":"modelBinding","@n8n/n8n-nodes-langchain.lmOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.memoryBufferWindow":"memory","@n8n/n8n-nodes-langchain.openAi":"modelBinding","@n8n/n8n-nodes-langchain.outputParserStructured":"parser","@n8n/n8n-nodes-langchain.retrieverVectorStore":"retriever","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter":"textSplitter","@n8n/n8n-nodes-langchain.textSplitterTokenSplitter":"textSplitter","@n8n/n8n-nodes-langchain.toolCode":"script","@n8n/n8n-nodes-langchain.toolSerpApi":"toolBinding","@n8n/n8n-nodes-langchain.toolVectorStore":"toolBinding","@n8n/n8n-nodes-langchain.toolWorkflow":"subworkflow","@n8n/n8n-nodes-langchain.vectorStoreInMemory":"vectorStore","@n8n/n8n-nodes-langchain.vectorStoreQdrant":"vectorStore","n8n-nodes-base.aggregate":"aggregate","n8n-nodes-base.code":"script","n8n-nodes-base.convertToFile":"file","n8n-nodes-base.discord":"channel","n8n-nodes-base.executeWorkflow":"subworkflow","n8n-nodes-base.executeWorkflowTrigger":"trigger","n8n-nodes-base.extractFromFile":"file","n8n-nodes-base.facebookGraphApi":"channel","n8n-nodes-base.filter":"filter","n8n-nodes-base.form":"form","n8n-nodes-base.formTrigger":"trigger","n8n-nodes-base.gmail":"integration","n8n-nodes-base.gmailTool":"toolBinding","n8n-nodes-base.gmailTrigger":"trigger","n8n-nodes-base.googleDocs":"integration","n8n-nodes-base.googleDocsTool":"toolBinding","n8n-nodes-base.googleDrive":"integration","n8n-nodes-base.googleSheets":"integration","n8n-nodes-base.googleSheetsTrigger":"trigger","n8n-nodes-base.html":"transform","n8n-nodes-base.htmlExtract":"extract","n8n-nodes-base.httpRequest":"http","n8n-nodes-base.if":"if","n8n-nodes-base.limit":"limit","n8n-nodes-base.linkedIn":"channel","n8n-nodes-base.localFileTrigger":"trigger","n8n-nodes-base.manualTrigger":"trigger","n8n-nodes-base.merge":"merge","n8n-nodes-base.noOp":"passthrough","n8n-nodes-base.openAi":"modelBinding","n8n-nodes-base.postgres":"integration","n8n-nodes-base.postgresTool":"toolBinding","n8n-nodes-base.readBinaryFile":"file","n8n-nodes-base.readWriteFile":"file","n8n-nodes-base.respondToWebhook":"respond","n8n-nodes-base.s3":"integration","n8n-nodes-base.scheduleTrigger":"trigger","n8n-nodes-base.set":"set","n8n-nodes-base.splitInBatches":"split","n8n-nodes-base.splitOut":"split","n8n-nodes-base.spreadsheetFile":"file","n8n-nodes-base.supabaseTool":"toolBinding","n8n-nodes-base.switch":"switch","n8n-nodes-base.telegram":"channel","n8n-nodes-base.telegramTrigger":"trigger","n8n-nodes-base.twitter":"channel","n8n-nodes-base.wait":"wait","n8n-nodes-base.whatsApp":"channel","n8n-nodes-base.whatsAppTrigger":"trigger","n8n-nodes-base.writeBinaryFile":"file","n8n-nodes-base.writeFile":"file","n8n-nodes-base.youTube":"integration"},Tr=new Set(["openAiApi","googlePalmApi","openRouterApi","mistralCloudApi","anthropicApi"]),Wr=new Set(["agentBinding"]);function Ct(r){return Tr.has(r)}function jt(r){return Wr.has(r)}function Tt(r){return"workflow"}function Wt(r,e){let t=`${r} ${e}`.toLowerCase();return t.includes("gmail")?"gmail":t.includes("googlesheets")?"google-sheets":t.includes("googledrive")?"google-drive":t.includes("googledocs")?"google-docs":t.includes("telegram")?"telegram":t.includes("whatsapp")?"whatsapp":t.includes("youtube")?"youtube":t.includes("postgres")?"postgres":t.includes("supabase")?"supabase":t.includes("qdrant")?"qdrant":t.includes("s3")?"s3":t.includes("twitter")||t.includes("xapi")?"x":t.includes("facebook")?"facebook":t.includes("linkedin")?"linkedin":t.includes("discord")?"discord":t.includes("serp")?"serpapi":t.includes("firecrawl")?"firecrawl":t.includes("elevenlabs")?"elevenlabs":"custom"}var Ot={"n8n-nodes-base.set":"set","n8n-nodes-base.if":"if","n8n-nodes-base.merge":"merge","n8n-nodes-base.noOp":"passthrough","n8n-nodes-base.httpRequest":"http","n8n-nodes-base.manualTrigger":"trigger","n8n-nodes-base.scheduleTrigger":"trigger","n8n-nodes-base.cron":"trigger","n8n-nodes-base.webhook":"trigger","n8n-nodes-base.formTrigger":"trigger","n8n-nodes-base.switch":"switch","n8n-nodes-base.filter":"filter","n8n-nodes-base.wait":"wait","n8n-nodes-base.aggregate":"aggregate","n8n-nodes-base.executeWorkflow":"subworkflow"},Or={httpBasicAuth:"basic",httpBearerAuth:"bearer",httpHeaderAuth:"custom",httpQueryAuth:"custom",oAuth2Api:"oauth2",httpCustomAuth:"custom"},Mr=new Set(["n8n-nodes-base.stickyNote"]),_r=new Set(["n8n-nodes-base.code","n8n-nodes-base.function","n8n-nodes-base.functionItem","@n8n/n8n-nodes-langchain.toolCode"]),W=class extends Error{constructor(t){super(`n8n import rejected: ${t.join("; ")}`);this.errors=t;this.name="N8nImportError"}errors};function Mt(r,e,t={}){let n=Ur(r),o=t.strictTemplates===!0,i=[],s={status:"full",nodes:[],expressions:{converted:0,manual:[]},credentials:[],bindings:{models:[],agents:[],connections:[]},notes:[]},a=new Set,d=new Set,l=[];for(let[f,c]of n.nodes.entries()){if(typeof c?.name!="string"||c.name===""){i.push(`nodes[${f}] has a missing/empty name`);continue}if(a.has(c.name)){i.push(`duplicate node name "${c.name}"`);continue}if(a.add(c.name),typeof c.type!="string"||c.type===""){i.push(`node "${c.name}" has a missing/empty type`);continue}if(Mr.has(c.type)){d.add(c.name),s.nodes.push({id:c.name,n8nType:c.type,outcome:"skipped",notes:["annotation node skipped"]});continue}let g={id:c.name,n8nType:c.type,outcome:"converted",notes:[]};s.nodes.push(g);let p=Hr(c.type,o);_r.has(c.type)&&!o?(p="manual",g.outcome="manual",g.notes.push("Code node contains imported script; default import keeps it as a fail-loud manual placeholder.")):p||(o?(p="n8nNode",g.outcome="unsupported",g.notes.push(`unsupported n8n node type "${c.type}" preserved as raw n8nNode`)):(p="manual",g.outcome="manual",g.notes.push(`unmapped n8n node type "${c.type}", please replace it manually`)));let h={converted:0,manual:[],notes:[]},w=$t({...c.parameters??{}},h);s.expressions.converted+=h.converted;for(let m of h.manual)s.expressions.manual.push({nodeId:c.name,...m}),g.notes.push(`parameter ${m.path}: ${m.reason}`),g.outcome==="converted"&&(g.outcome="partial");for(let m of h.notes)s.notes.includes(m)||s.notes.push(m);Br(c,p,s,o),o&&jt(p)&&(s.bindings.agents.push({nodeId:c.name,fallback:!0,label:c.name}),g.outcome=g.outcome==="converted"?"partial":g.outcome,g.notes.push("agent capability will be resolved from the configured Agent panel, not from n8n credentials"));let x={id:c.name,kind:p,name:c.name,params:{...w,_n8nType:c.type}};o&&(x.params={...x.params,_importMode:"n8n-strict-template",_bindingKind:p}),Array.isArray(c.position)&&Number.isFinite(c.position[0])&&Number.isFinite(c.position[1])&&(x.ui={x:c.position[0],y:c.position[1]}),qr(x,p,g,o),l.push(x)}let u=n.connections?Fr(n.connections,a,d,l,i,o):[];if(o&&Jr(u,l),Kr(l),l.length===0&&i.length===0&&i.push("workflow has no nodes"),i.length>0)throw new W(i);return s.status=s.nodes.some(f=>f.outcome==="manual"||f.outcome==="unsupported")?"manual":s.nodes.some(f=>f.outcome==="partial")||s.expressions.manual.length>0?"partial":"full",{name:typeof n.name=="string"&&n.name!==""?n.name:e,def:{id:e,nodes:l,edges:u},report:s}}function Hr(r,e){return e?Dt[r]??Ot[r]??"n8nNode":Ot[r]}function qr(r,e,t,n){let o=r.params;if(e==="if"){r.outPorts=["true","false"];return}if(e==="wait"){let i=typeof o.amount=="number"?o.amount:Number(o.amount),s=typeof o.unit=="string"?o.unit:"seconds",a=s==="hours"?36e5:s==="minutes"?6e4:1e3;Number.isFinite(i)&&i>0?o.ms=Math.min(36e5,Math.round(i*a)):n||(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push("wait duration could not be parsed"));return}if(e==="subworkflow"){let i=typeof o.workflowId=="object"&&o.workflowId!==null?o.workflowId.value:o.workflowId;typeof i=="string"&&i?(o.workflowId=i,t.outcome=t.outcome==="converted"?"partial":t.outcome,t.notes.push("subworkflow target keeps the n8n workflow id and must be rebound to a local workflow")):n||(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push("subworkflow target is missing"));return}(e==="switch"||e==="filter")&&!n&&(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push(`${e} conditions preserve n8n params and may need review`))}function Br(r,e,t,n){if(!(!r.credentials||typeof r.credentials!="object")){for(let[o,i]of Object.entries(r.credentials)){if(n&&Ct(o)){t.bindings.models.push({nodeId:r.name,n8nCredentialType:o,modelPurpose:Tt(o),label:i?.name});continue}let s=Wt(r.type,o);n&&t.bindings.connections.push({nodeId:r.name,n8nCredentialType:o,connectionType:s,label:i?.name}),t.credentials.push({nodeId:r.name,n8nCredentialType:o,label:i?.name,suggestedVaultType:Or[o]??s??"custom"})}n&&e==="modelBinding"&&t.bindings.models.push({nodeId:r.name,n8nCredentialType:"model-registry",modelPurpose:"workflow"})}}function Ur(r){let e;if(typeof r=="string")try{e=JSON.parse(r)}catch(n){throw new W([`invalid JSON: ${n.message}`])}else e=r;if(!e||typeof e!="object")throw new W(["workflow must be a JSON object"]);let t=e;if(!Array.isArray(t.nodes))throw new W(["workflow.nodes must be an array"]);if(t.connections!==void 0&&(typeof t.connections!="object"||t.connections===null))throw new W(["workflow.connections must be an object"]);return{name:t.name,nodes:t.nodes,connections:t.connections??{}}}function Fr(r,e,t,n,o,i){let s=new Map(n.map(d=>[d.id,d.kind])),a=[];for(let d of Object.keys(r).sort()){if(t.has(d))continue;if(!e.has(d)){o.push(`connection source "${d}" is not a declared node`);continue}let l=r[d]??{};for(let u of Object.keys(l).sort()){let f=l[u];if(Array.isArray(f))for(let c=0;c<f.length;c++){let g=Lr(d,s.get(d),u,c,n,o,i),p=f[c];if(Array.isArray(p))for(let h of p){if(!h||typeof h.node!="string"){o.push(`connection from "${d}" has a malformed target`);continue}if(t.has(h.node))continue;if(!e.has(h.node)){o.push(`connection from "${d}" targets missing node "${h.node}"`);continue}let w={from:d,to:h.node};g!=="default"&&(w.fromPort=g),i&&typeof h.type=="string"&&h.type&&h.type!=="main"&&(w.toPort=h.type),a.push(w)}}}}return a}function Lr(r,e,t,n,o,i,s){return t!=="main"?T(o,r,n===0?t:`${t}_${n}`):e==="if"?n===0?"true":n===1?"false":(s||i.push(`if node "${r}" has an unsupported output index ${n}`),T(o,r,`out_${n}`)):e==="switch"?T(o,r,`case_${n}`):e==="filter"?n===0?T(o,r,"default"):(s||i.push(`filter node "${r}" has an unsupported discarded output`),T(o,r,n===1?"discarded":`out_${n}`)):n===0?T(o,r,"default"):(s||i.push(`node "${r}" has an unmodeled multi-output index ${n} (only single-output supported)`),T(o,r,`out_${n}`))}function T(r,e,t){let n=r.find(o=>o.id===e);return n&&(n.outPorts=n.outPorts??[],n.outPorts.includes(t)||n.outPorts.push(t)),t}function Kr(r){for(let e of r)e.outPorts&&e.outPorts.length>0&&(e.params={...e.params??{},_n8nOutPorts:e.outPorts})}function Jr(r,e){let t=[];for(let n of r)if(Gr(t,n.to,n.from)){n.loopBack=!0;let o=e.find(i=>i.id===n.to);o&&(!o.maxIterations||o.maxIterations<=0)&&(o.maxIterations=100)}else t.push(n)}function Gr(r,e,t){let n=[e],o=new Set;for(;n.length>0;){let i=n.pop();if(i===t)return!0;if(!o.has(i)){o.add(i);for(let s of r)s.from===i&&n.push(s.to)}}return!1}import{join as Bt}from"node:path";import{mkdir as Vr}from"node:fs/promises";function le(r,...e){let t=r.toLowerCase();return e.some(n=>t.includes(n.toLowerCase()))}function _t(r,e){let t=(r??"").trim(),n=t.length>300?`${t.slice(0,300)}\u2026`:t||void 0;return le(t,"credential","\u51ED\u8BC1","unauthorized","forbidden","401","403","auth")?{class:"user",message:"\u9274\u6743\u6CA1\u901A\u8FC7 \u2014\u2014 \u51ED\u8BC1\u7F3A\u5931\u6216\u5DF2\u5931\u6548\u3002",hint:"\u53BB\u51ED\u8BC1\u4FDD\u9669\u5E93\u914D\u7F6E\u540E\u91CD\u8DD1\u8FD9\u6B65\u3002",actions:["open_credentials","rerun_node","ai_fix"],detail:n}:le(t,"\u4E0D\u5B58\u5728\u7684","\u5F15\u7528\u4E86\u4E0D\u5B58\u5728","no nodeexecutor","\u76EE\u5F55\u5916","not registered","unknown kind","\u672A\u80FD\u81EA\u52A8\u8F6C\u6362","\u4EBA\u5DE5\u8FC1\u79FB")?{class:"capability",message:"\u8FD9\u4E00\u6B65\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u80FD\u529B / \u5DE5\u5177\u3002",hint:"\u6362\u4E00\u4E2A\u771F\u5B9E\u5B58\u5728\u7684\u5DE5\u5177,\u6216\u8BA9 AI \u6539\u8FD9\u4E00\u6B65\u3002",actions:["ai_fix","swap_capability","rerun_node"],detail:n}:le(t,"econnrefused","enotfound","etimedout","fetch failed","network","timeout","timed out","socket","getaddrinfo","invalid url","request failed","5xx","502","503","504")?{class:"network",message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25 \u2014\u2014 \u5730\u5740\u4E0D\u901A\u3001\u8D85\u65F6\u6216\u5BF9\u65B9\u62A5\u9519\u3002",hint:"\u786E\u8BA4\u5730\u5740/\u7F51\u7EDC\u540E\u91CD\u8DD1;\u5730\u5740\u4E0D\u5BF9\u5C31\u8BA9 AI \u6539\u3002",actions:["rerun_node","ai_fix"],detail:n}:le(t,"requires string param","requires param","requires object param","requires non-empty","\u7F3A\u5C11\u5FC5\u586B","required","must be","\u5FC5\u586B","in 1..","must have at least")?{class:"user",message:"\u8FD9\u4E00\u6B65\u7F3A\u5C11\u5FC5\u8981\u4FE1\u606F(\u5FC5\u586B\u53C2\u6570\u6CA1\u586B\u5168\u6216\u683C\u5F0F\u4E0D\u5BF9)\u3002",hint:"\u8BA9 AI \u8865\u5168,\u6216\u5728\u300C\u9AD8\u7EA7\u300D\u91CC\u624B\u52A8\u586B\u3002",actions:["ai_fix","rerun_node"],detail:n}:{class:"system",message:"\u8FD9\u4E00\u6B65\u6267\u884C\u51FA\u9519\u4E86\u3002",hint:"\u53EF\u4EE5\u91CD\u8DD1;\u82E5\u53CD\u590D\u5931\u8D25,\u8BA9 AI \u770B\u770B\u8FD9\u4E00\u6B65\u3002",actions:["rerun_node","ai_fix","rerun_all"],detail:n}}var zr=20,Ht=2e3;function qt(r,e){return Bt(A(r),e,"runs","history.json")}function De(r){let e={};for(let[t,n]of Object.entries(r.outputs)){let o={};for(let[a,d]of Object.entries(n))o[a]=d.map(l=>l.json);let i=JSON.stringify(o);i.length>Ht&&(i=`${i.slice(0,Ht)}\u2026(truncated)`);let s=r.nodeStats?.[t];e[t]={executed:r.executed.has(t),preview:i,...s?{seq:s.seq,startedAt:s.startedAt,durationMs:s.durationMs,attempts:s.attempts,cacheHit:s.cacheHit,nodeStatus:s.status,...s.warning!==void 0?{warning:s.warning}:{}}:{}}}return e}var $e=class{constructor(e){this.cwd=e;if(!e)throw new Error("WorkflowRunHistoryStore requires a project cwd")}cwd;async begin(e,t){let n=await this.read(e);n.unshift({...t,status:"running"}),await this.write(e,n.slice(0,zr))}async finish(e,t,n){let o=await this.read(e),i=o.find(s=>s.runId===t);i&&(Object.assign(i,n),i.errorInfo=i.status==="failed"&&i.error?_t(i.error):void 0,await this.write(e,o))}async list(e){return(await this.read(e)).map(({nodes:t,...n})=>n)}async get(e,t){return(await this.read(e)).find(n=>n.runId===t)}async read(e){try{let t=await C(qt(this.cwd,e));return Array.isArray(t)?t:[]}catch{return[]}}async write(e,t){let n=qt(this.cwd,e);await Vr(Bt(A(this.cwd),e,"runs"),{recursive:!0}),await j(n,t)}};import{randomUUID as Yr}from"node:crypto";var Ce=class{constructor(e,t,n){this.store=e;this.runtimeFactory=t;this.runHistory=n}store;runtimeFactory;runHistory;slots=new Map;activeRuns=new Map;activeRunIdsByWorkflow=new Map;suppressedHistoryRunIds=new Set;async create(e){let t=Q(e.def);if(t.length>0)throw new v(t);let n=new Date().toISOString(),o={id:e.id,name:e.name,...e.owner?{owner:e.owner}:{},def:e.def,active:e.active??!1,concurrency:e.concurrency??"queue",rev:1,createdAt:n,updatedAt:n};return await this.store.save(o),o}async update(e,t){let o={...await this.store.require(e),...t,updatedAt:new Date().toISOString()};if(t.def!==void 0){let i=Q(o.def);if(i.length>0)throw new v(i)}return await this.store.save(o),o}async setActive(e,t){if(t){let n=await this.store.require(e);if(!n.publishedDef)throw new Error(`Workflow "${e}" has no published version \u2014 publish the draft before activating`);if(n.archived)throw new Error(`Workflow "${e}" is archived \u2014 restore it before activating`)}return this.update(e,{active:t})}async publish(e){let t=await this.store.require(e);if(t.archived)throw new Error(`Workflow "${e}" is archived \u2014 restore it before publishing`);let n=Q(t.def);if(n.length>0)throw new v(n);let o={...t,publishedDef:structuredClone(t.def),publishedRev:t.rev,updatedAt:new Date().toISOString()};return await this.store.save(o),o}async archive(e,t){let o={...await this.store.require(e),archived:t,...t?{active:!1}:{},updatedAt:new Date().toISOString()};return await this.store.save(o),o}async revertTo(e,t){let n=await this.store.require(e),o=await this.store.loadRevision(e,t);if(!o)throw new Error(`Workflow "${e}" has no stored revision ${t}`);let i=Q(o.def);if(i.length>0)throw new v(i);let s={...n,def:o.def,name:o.name,trigger:o.trigger??null,rev:n.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(s),s}async importN8n(e,t,n={}){let{name:o,def:i,report:s}=Mt(t,e,{strictTemplates:!0});return{record:await this.create({id:e,name:o,def:i,concurrency:n.concurrency,owner:n.owner}),report:s}}async get(e){return this.store.require(e)}async describe(e,t){let n=await this.store.require(e);return Ne(n,t)}async patch(e,t){let n=await this.store.require(e),o=t.baseRev!==void 0&&t.baseRev<n.rev,i={def:n.def,meta:{name:n.name,active:n.active,trigger:n.trigger??null}},s,a;try{let u=Ae(i,t);s=u.applied,a=u.target}catch(u){if(o&&u instanceof v)return{ok:!1,conflict:{latestRev:n.rev}};throw u}if(a.meta.active===!0&&!n.active&&!n.publishedDef)throw new v([`workflow "${e}" has no published version \u2014 publish the draft before activating (set_meta.active)`]);let l={...n,def:a.def,name:a.meta.name??n.name,active:a.meta.active??n.active,trigger:a.meta.trigger??null,rev:n.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(l),{ok:!0,rev:l.rev,applied:s}}async run(e,t,n={}){let o=await this.store.require(e);if(o.archived)throw new Error(`Workflow "${e}" is archived and cannot run`);let i=t?.type??"manual",s=i==="manual"||i==="intent"||i==="form",a;if(s)a=o.def;else{if(!o.publishedDef)throw new Error(`Workflow "${e}" has no published version \u2014 unattended trigger "${i}" refused`);a=o.publishedDef}let d={workflowId:e,runId:Yr(),type:i,payload:t?.payload,permissionScope:o.permissionScope,reuseCache:n.reuseCache===!0},l=this.slotFor(e),u=()=>{if(l.pending>0)switch(o.concurrency){case"skip":return Promise.resolve({workflowId:e,status:"skipped"});case"parallel":return this.startParallel(e,a,d);case"queue":return this.track(e,l,a,d,!0)}return this.track(e,l,a,d,!1)};return this.recordRun(e,d,u,n.recordHistory===!1)}async recordRun(e,t,n,o=!1){let i=Date.now();if(!this.runHistory||o)try{let a=await n();return{...a,runId:a.runId??t.runId}}catch(a){if(a instanceof b)return{workflowId:e,status:"canceled",runId:t.runId};throw a}await this.runHistory.begin(e,{runId:t.runId,triggerType:t.type,startedAt:new Date(i).toISOString()}).catch(()=>{});let s=a=>this.finishRunHistory(e,t.runId,i,a);try{let a=await n();return await s({status:a.status,...a.result?{nodes:De(a.result)}:{}}),{...a,runId:t.runId}}catch(a){if(a instanceof b)return await s({status:"canceled",error:a.message}),{workflowId:e,status:"canceled",runId:t.runId};throw await s({status:"failed",error:a instanceof Error?a.message:String(a),failedNodeId:a?.nodeId}),a}}pause(e,t={}){this.requireActiveRun(e,t.runId).runtime.pause()}async resume(e,t={}){let n=this.requireActiveRun(e,t.runId);if(n.status!=="paused")throw new Error(`Workflow "${e}" run "${n.runId}" is not paused`);t.extraBudget&&n.runtime.extendBudget(t.extraBudget),n.status="running";let o=this.slotFor(e);o.pending++;let i=n.runtime.run().then(async s=>{let a={workflowId:e,runId:n.runId,status:s.status,result:s};return s.status==="paused"?n.status="paused":this.unregisterActiveRun(n.runId),await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:a.status,nodes:De(s)}),a}).catch(async s=>{if(this.unregisterActiveRun(n.runId),s instanceof b)return await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"canceled",error:s.message}),{workflowId:e,runId:n.runId,status:"canceled"};throw await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"failed",error:s instanceof Error?s.message:String(s),failedNodeId:s?.nodeId}),s}).finally(()=>{o.pending--});return o.tail=i.catch(()=>{}),i}async cancelRun(e,t={}){let n=this.requireActiveRun(e,t.runId),o=t.reason??`Workflow "${e}" run "${n.runId}" canceled`,i=new b(o);return n.runtime.cancel(o),n.abortController.signal.aborted||n.abortController.abort(i),this.unregisterActiveRun(n.runId),n.status==="paused"&&await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"canceled",error:o}),{workflowId:e,runId:n.runId,status:"canceled"}}async delete(e){let t=[...this.activeRunIdsByWorkflow.get(e)??[]];for(let n of t)this.suppressedHistoryRunIds.add(n),await this.cancelRun(e,{runId:n,reason:`Workflow "${e}" deleted`}).catch(()=>{});this.slots.delete(e),await this.store.delete(e)}async listActive(){return this.store.listActive()}slotFor(e){let t=this.slots.get(e);return t||(t={tail:Promise.resolve(),pending:0},this.slots.set(e,t)),t}registerActiveRun(e){this.activeRuns.set(e.runId,e);let t=this.activeRunIdsByWorkflow.get(e.workflowId);t||(t=new Set,this.activeRunIdsByWorkflow.set(e.workflowId,t)),t.add(e.runId)}unregisterActiveRun(e){let t=this.activeRuns.get(e);if(!t)return;this.activeRuns.delete(e);let n=this.activeRunIdsByWorkflow.get(t.workflowId);n&&(n.delete(e),n.size===0&&this.activeRunIdsByWorkflow.delete(t.workflowId))}requireActiveRun(e,t){if(t){let s=this.activeRuns.get(t);if(!s||s.workflowId!==e)throw new Error(`Workflow "${e}" has no active run "${t}"`);return s}let n=[...this.activeRunIdsByWorkflow.get(e)??[]],o=this.slots.get(e)?.latestRunId;if(o&&n.includes(o))return this.activeRuns.get(o);let i=n.at(-1);if(!i)throw new Error(`Workflow "${e}" has no active run`);return this.activeRuns.get(i)}async finishRunHistory(e,t,n,o){!this.runHistory||this.suppressedHistoryRunIds.has(t)||await this.runHistory.finish(e,t,{finishedAt:new Date().toISOString(),durationMs:Date.now()-n,...o}).catch(()=>{})}track(e,t,n,o,i){t.pending++;let s=()=>this.startTrackedRuntime(e,t,n,o),d=(i?t.tail.then(s):s()).finally(()=>{t.pending--});return t.tail=d.catch(()=>{}),d}async startParallel(e,t,n){return this.startTrackedRuntime(e,void 0,t,n)}async startTrackedRuntime(e,t,n,o){let i=new AbortController,s=this.runtimeFactory(n,{...o,signal:i.signal}),a={workflowId:e,runId:o.runId,startedAtMs:Date.now(),runtime:s,abortController:i,status:"running"};this.registerActiveRun(a),t&&(t.runtime=s,t.latestRunId=o.runId);try{let d=await s.run(),l={workflowId:e,runId:o.runId,status:d.status,result:d};return d.status==="paused"?a.status="paused":this.unregisterActiveRun(o.runId),l}catch(d){throw this.unregisterActiveRun(o.runId),d}}};function Qr(r){return(e,t)=>new Y(e,{registry:r.registry,host:r.host,signal:t.signal,checkpoint:r.checkpoint?.(t.workflowId,t.reuseCache?"shared-cache":t.runId),preserveCheckpoint:t.reuseCache===!0,trigger:t.payload,triggerKind:t.type,now:r.now,onNodeStatus:r.emitNodeStatus?(n,o,i)=>r.emitNodeStatus(t.workflowId,n,o,i):void 0,gate:new ce({trigger:t.type,maxNodeExecutions:r.budget.maxNodeExecutions,maxDurationMs:r.budget.maxDurationMs,allowUnattendedKinds:t.permissionScope?.allowUnattendedKinds??r.allowUnattendedKinds,now:r.now?()=>r.now().getTime():void 0})})}function Xr(r){let e=r.content??[],t=a=>a.type==="text"&&typeof a.text=="string",n=e.filter(t).map(a=>a.text).join(`
8
- `),o=e.filter(a=>!t(a));if(o.length===0)return n;let i=[...new Set(o.map(a=>a.type??"unknown"))].join(", "),s=`[${o.length} non-text block${o.length===1?"":"s"} omitted (${i})]`;return n?`${n}
9
- ${s}`:s}function Zr(r){let e=r.findTool,t=r.fetchImpl??fetch;return{async runAgent(n){let o=await r.runAgent({agentId:n.agentId,prompt:n.prompt,signal:n.signal});return[D({text:o,output:o})]},async runModel(n){if(!r.resolveClientForPurpose)throw new Error("workflow model node: no configured model resolver is wired");let o=r.resolveClientForPurpose("textGeneration");if(!o)throw new Error("workflow model node: no textGeneration model is configured");let i="";for await(let s of o.transport.stream({model:o.model,messages:[{role:"user",content:n.prompt}],temperature:n.temperature,maxTokens:n.maxTokens,tools:[]},o.apiKey,n.signal))if(s.type==="delta"&&(i+=s.text),s.type==="error")throw new Error(s.message);return[D({text:i,output:i,model:o.model,...n.modelHint?{importedModel:n.modelHint}:{},choices:[{text:i}]})]},async invokeTool(n){let o=e(n.tool);if(!o)throw new Error(`workflow tool node: no qlogicagent tool named "${n.tool}"`);if(!o.execute)throw new Error(`workflow tool node: qlogicagent tool "${n.tool}" is not executable`);let i=n.args;if(r.workspaceCwd&&n.tool==="exec"){let d=i.workdir;(d==null||d==="")&&(i={...i,workdir:r.workspaceCwd})}n.unattended&&r.auditUnattendedTool&&r.auditUnattendedTool({...n,args:i});let s=`wf_${n.tool}_${Date.now().toString(36)}`,a=await o.execute(s,i,n.signal);return[D({result:Xr(a),details:a.details??null})]},async httpRequest(n){let o=n.headers;if(n.credentialId){if(!r.resolveCredentialHeaders)throw new Error(`workflow http node: credentialId "${n.credentialId}" set but no credential vault is wired`);o={...o,...r.resolveCredentialHeaders(n.credentialId)}}let i=await t(n.url,{method:n.method||"GET",headers:o,body:n.body===void 0?void 0:typeof n.body=="string"?n.body:JSON.stringify(n.body),signal:n.signal}),s=i.headers.get("content-type")??"";if(s.includes("application/json")){let l=await i.text(),u=l;try{l.length>0&&(u=JSON.parse(l))}catch{u={__unparsedJson:l}}return[D({status:i.status,ok:i.ok,body:u})]}let a=Buffer.from(await i.arrayBuffer()),d=eo(i.headers.get("content-disposition"));return[D({status:i.status,ok:i.ok,bodyBase64:a.toString("base64"),mimeType:s||"application/octet-stream",size:a.byteLength,...d?{filename:d}:{}})]},async invokeMcp(n){let o=await r.invokeMcp({server:n.server,tool:n.tool,args:n.args,signal:n.signal});return[D({result:o})]},async sendChannel(n){if(!r.sendChannel)throw new Error("workflow channel node: sendChannel requires the xiaozhiclaw gateway host, none injected (channel/IM nodes are unavailable in standalone qlogicagent \u2014 D12/D13).");let o=await r.sendChannel({channel:n.channel,target:n.target,payload:n.payload,signal:n.signal});return[D({sent:!0,result:o})]},async memory(n){if(!r.memory)throw new Error("workflow memory node: no memory backend injected (handler host wires the project memdir)");return r.memory(n)},async runSubworkflow(n){if(!r.runSubworkflow)throw new Error("workflow subworkflow node: no sub-run backend injected (handler host wires the controller)");return r.runSubworkflow(n)},async approval(n){if(!r.approval)throw new Error("workflow approval node: no approval backend injected (handler host wires the notify/await loop)");return r.approval(n)},async waitWebhook(n){if(!r.waitWebhook)throw new Error("workflow wait(until=webhook): no webhook-wait backend injected (handler host wires the wake registry)");return r.waitWebhook(n)}}}function eo(r){if(!r)return;let e=r.match(/filename\*=UTF-8''([^;]+)/i);if(e)return decodeURIComponent(e[1].trim().replace(/^"|"$/g,""));let t=r.match(/filename=([^;]+)/i);return t?t[1].trim().replace(/^"|"$/g,""):void 0}var Ut=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],Ft=["SUN","MON","TUE","WED","THU","FRI","SAT"];function to(r){if(typeof r!="string"||r.trim()==="")throw new Error("cron must be a non-empty string");let e=r.trim().split(/\s+/);if(e.length!==5&&e.length!==6)throw new Error(`cron must have 5 or 6 fields, got ${e.length}: "${r}"`);let t=e.length===6,n=t?[{label:"second",min:0,max:59},{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Ut},{label:"day-of-week",min:0,max:7,names:Ft}]:[{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Ut},{label:"day-of-week",min:0,max:7,names:Ft}],o=n.map((d,l)=>({spec:d,raw:e[l],set:no(e[l],n[l])})),i=d=>{let l=o.find(u=>u.spec.label===d);if(!l)throw new Error(`internal: missing cron field ${d}`);return l},s=i("day-of-week"),a=new Set;for(let d of s.set)a.add(d===7?0:d);return{hasSeconds:t,seconds:t?i("second").set:new Set([0]),minutes:i("minute").set,hours:i("hour").set,doms:i("day-of-month").set,months:i("month").set,dows:a,domRestricted:i("day-of-month").raw.trim()!=="*",dowRestricted:s.raw.trim()!=="*"}}function no(r,e){let t=new Set;for(let n of r.split(","))ro(n,e,t);if(t.size===0)throw new Error(`cron ${e.label} expanded to an empty set: "${r}"`);return t}function ro(r,e,t){if(r==="")throw new Error(`cron ${e.label} has an empty list element`);let n=r,o=1,i=r.indexOf("/");if(i!==-1){n=r.slice(0,i);let d=r.slice(i+1);if(!/^\d+$/.test(d)||Number(d)<=0)throw new Error(`cron ${e.label} has an invalid step "/${d}"`);o=Number(d)}let s,a;if(n==="*")s=e.min,a=e.max;else{let d=n.indexOf("-");if(d!==-1){let l=je(n.slice(0,d),e),u=je(n.slice(d+1),e);if(l===void 0||u===void 0)throw new Error(`cron ${e.label} has an invalid range "${n}"`);if(l>u)throw new Error(`cron ${e.label} range "${n}" is descending`);s=l,a=u}else{let l=je(n,e);if(l===void 0)throw new Error(`cron ${e.label} value "${n}" is out of range ${e.min}-${e.max}`);s=l,a=o===1?l:e.max}}for(let d=s;d<=a;d+=o)t.add(d)}function je(r,e){let t;if(/^\d+$/.test(r))t=Number(r);else if(e.names){let n=e.names.indexOf(r.toUpperCase());if(n===-1)return;t=e.label==="month"?n+1:n}else return;if(!(t<e.min||t>e.max))return t}var oo=5*366+32;function Te(r,e){let t=to(r),n=new Date(e);t.hasSeconds?(n.setUTCMilliseconds(0),n.setUTCSeconds(n.getUTCSeconds()+1)):(n.setUTCSeconds(0,0),n.setUTCMinutes(n.getUTCMinutes()+1));for(let o=0;o<oo;o++){if(!t.months.has(n.getUTCMonth()+1)){n.setUTCMonth(n.getUTCMonth()+1,1),n.setUTCHours(0,0,0,0);continue}if(!io(t,n)){n.setUTCDate(n.getUTCDate()+1),n.setUTCHours(0,0,0,0);continue}if(!t.hours.has(n.getUTCHours())){n.setUTCHours(n.getUTCHours()+1,0,0,0);continue}if(!t.minutes.has(n.getUTCMinutes())){n.setUTCMinutes(n.getUTCMinutes()+1,0,0);continue}if(t.hasSeconds&&!t.seconds.has(n.getUTCSeconds())){n.setUTCSeconds(n.getUTCSeconds()+1,0);continue}return n.getTime()}throw new Error(`cron "${r}" has no matching time within ~5 years of ${new Date(e).toISOString()}`)}function io(r,e){let t=r.doms.has(e.getUTCDate()),n=r.dows.has(e.getUTCDay());return r.domRestricted&&r.dowRestricted?t||n:r.domRestricted?t:r.dowRestricted?n:!0}var so={now:()=>Date.now(),setTimer:(r,e)=>setTimeout(r,e),clearTimer:r=>clearTimeout(r)},Lt=2e9,We=class{controller;clock;onError;onRunStarted;onRunCompleted;onRunFailed;triggers=new Map;cronArms=new Map;lastFireAt=new Map;minTriggerIntervalMs;onTriggerDropped;started=!1;constructor(e){if(!e.controller)throw new Error("WorkflowScheduler requires a controller");if(typeof e.onError!="function")throw new Error("WorkflowScheduler requires an onError handler");if(this.controller=e.controller,this.clock=e.clock??so,this.onError=e.onError,this.onRunStarted=e.onRunStarted,this.onRunCompleted=e.onRunCompleted,this.onRunFailed=e.onRunFailed,this.minTriggerIntervalMs=e.minTriggerIntervalMs??0,this.onTriggerDropped=e.onTriggerDropped,this.minTriggerIntervalMs>0&&!this.onTriggerDropped)throw new Error("WorkflowScheduler: minTriggerIntervalMs > 0 requires onTriggerDropped (drops must never be silent, \xA71.5)")}async start(){if(this.started)throw new Error("WorkflowScheduler already started");this.started=!0;let e=await this.controller.listActive();for(let t of e)this.registerTrigger(t.id,t.trigger??{type:"manual"})}stop(){for(let e of this.cronArms.values())this.clock.clearTimer(e.handle);this.cronArms.clear(),this.triggers.clear(),this.started=!1}async refresh(e){let t;try{t=await this.controller.get(e)}catch{this.unregister(e);return}if(!t.active){this.unregister(e);return}this.registerTrigger(e,t.trigger??{type:"manual"})}unregister(e){let t=this.cronArms.get(e);t&&(this.clock.clearTimer(t.handle),this.cronArms.delete(e)),this.triggers.delete(e)}registeredIds(){return[...this.triggers.keys()]}nextFireAt(e){return this.cronArms.get(e)?.fireAt}async onWebhook(e,t){let n=this.matchingIds(o=>o.type==="webhook"&&o.path===e).filter(o=>this.passesRateLimit(o,"webhook"));return Promise.all(n.map(o=>this.runWithLifecycle(o,{type:"webhook",payload:t})))}async onImMessage(e,t,n){let o=this.matchingIds(s=>s.type==="im-message"&&s.channel===e&&ao(s.match,t)).filter(s=>this.passesRateLimit(s,"im-message")),i={...n,channel:e,text:t};return Promise.all(o.map(s=>this.runWithLifecycle(s,{type:"im-message",payload:i})))}async triggerManual(e,t){return this.runWithLifecycle(e,{type:"manual",payload:t})}matchingIds(e){let t=[];for(let[n,o]of this.triggers)e(o)&&t.push(n);return t}registerTrigger(e,t){if(this.unregister(e),this.triggers.set(e,t),t.type==="schedule"){let n=Te(t.cron,this.clock.now());this.armCron(e,t.cron,n)}}armCron(e,t,n){let o=Math.max(0,n-this.clock.now()),i={cron:t,fireAt:n,handle:void 0};o>Lt?i.handle=this.clock.setTimer(()=>{this.cronArms.get(e)===i&&this.armCron(e,t,n)},Lt):i.handle=this.clock.setTimer(()=>this.fireCron(e,i),o),this.cronArms.set(e,i)}fireCron(e,t){if(this.cronArms.get(e)!==t)return;let n;try{n=Te(t.cron,t.fireAt)}catch(o){this.cronArms.delete(e),this.onError(o,e);return}this.armCron(e,t.cron,n),this.passesRateLimit(e,"schedule")&&this.runWithLifecycle(e,{type:"schedule"}).catch(o=>this.onError(o,e))}passesRateLimit(e,t){if(this.minTriggerIntervalMs<=0)return!0;let n=this.clock.now(),o=this.lastFireAt.get(e);return o!==void 0&&n-o<this.minTriggerIntervalMs?(this.onTriggerDropped?.(e,t,{sinceLastMs:n-o,minIntervalMs:this.minTriggerIntervalMs}),!1):(this.lastFireAt.set(e,n),!0)}async runWithLifecycle(e,t){this.onRunStarted?.(e,t.type);try{let n=await this.controller.run(e,t);return this.onRunCompleted?.(n,t.type),n}catch(n){throw this.onRunFailed?.(e,t.type,n),n}}};function ao(r,e){return r===void 0?!0:new RegExp(r).test(e)}import{createCipheriv as uo,createDecipheriv as co,randomBytes as Kt,randomUUID as lo}from"node:crypto";import{existsSync as F,mkdirSync as Jt,readFileSync as Oe,writeFileSync as Me,readdirSync as fo,rmSync as go}from"node:fs";import{join as X}from"node:path";var Gt="aes-256-gcm",_e=class{dir;constructor(e=_()){this.dir=X(e,"credentials")}keyPath(){return X(this.dir,".vault-key")}ensureKey(){F(this.dir)||Jt(this.dir,{recursive:!0});let e=this.keyPath();if(!F(e)){let t=Kt(32);return Me(e,t.toString("base64"),{mode:384}),t}return Buffer.from(Oe(e,"utf-8").trim(),"base64")}encrypt(e){let t=this.ensureKey(),n=Kt(12),o=uo(Gt,t,n),i=Buffer.concat([o.update(JSON.stringify(e),"utf-8"),o.final()]);return`${n.toString("base64")}.${o.getAuthTag().toString("base64")}.${i.toString("base64")}`}decrypt(e){let t=this.ensureKey(),[n,o,i]=e.split(".");if(!n||!o||!i)throw new Error("credential vault: malformed ciphertext envelope");let s=co(Gt,t,Buffer.from(n,"base64"));s.setAuthTag(Buffer.from(o,"base64"));let a=Buffer.concat([s.update(Buffer.from(i,"base64")),s.final()]);return JSON.parse(a.toString("utf-8"))}filePath(e){if(!/^[\w-]+$/.test(e))throw new Error(`credential vault: illegal id "${e}"`);return X(this.dir,`${e}.json`)}list(){if(!F(this.dir))return[];let e=[];for(let t of fo(this.dir))if(t.endsWith(".json"))try{let n=JSON.parse(Oe(X(this.dir,t),"utf-8"));if(!n||typeof n!="object"||typeof n.id!="string"||typeof n.updatedAt!="string")throw new Error("malformed credential envelope");e.push({id:n.id,type:n.type,label:n.label,createdAt:n.createdAt,updatedAt:n.updatedAt,meta:n.meta})}catch(n){let o=t.replace(/\.json$/,"");console.error(`[credential-vault] credential file ${X(this.dir,t)} is unreadable or corrupted - shown as corrupt in the list: ${n instanceof Error?n.message:String(n)}`),e.push({id:o,type:"custom",label:`${o} (corrupted credential file - delete and re-create it)`,createdAt:"",updatedAt:"",corrupt:!0})}return e.sort((t,n)=>n.updatedAt.localeCompare(t.updatedAt))}create(e){Vt(e.type,e.data);let t=e.id??`cred_${lo().slice(0,8)}`,n=new Date().toISOString(),o={id:t,type:e.type,label:e.label||t,createdAt:n,updatedAt:n,...e.meta?{meta:e.meta}:{},enc:this.encrypt(e.data)};return F(this.dir)||Jt(this.dir,{recursive:!0}),Me(this.filePath(t),JSON.stringify(o,null,2),{mode:384}),{id:t,type:o.type,label:o.label,createdAt:n,updatedAt:n,meta:o.meta}}get(e){let t=this.filePath(e);if(!F(t))throw new Error(`credential "${e}" not found`);let n=JSON.parse(Oe(t,"utf-8"));return{summary:{id:n.id,type:n.type,label:n.label,createdAt:n.createdAt,updatedAt:n.updatedAt,meta:n.meta},data:this.decrypt(n.enc)}}delete(e){let t=this.filePath(e);return F(t)?(go(t,{force:!0}),!0):!1}updateData(e,t,n){let{summary:o}=this.get(e);Vt(o.type,t);let i=new Date().toISOString(),s=o.meta;if(n){s={...o.meta??{},...n};for(let l of Object.keys(s))s[l]===void 0&&delete s[l]}let a={...o,...s!==void 0?{meta:s}:{},updatedAt:i},d={...a,enc:this.encrypt(t)};return Me(this.filePath(e),JSON.stringify(d,null,2),{mode:384}),a}};function Z(r,e,t){if(typeof r[e]!="string"||!r[e])throw new Error(`credential(${t}): "${e}" is required`)}function Vt(r,e){switch(r){case"apiKey":Z(e,"headerName",r),Z(e,"value",r);return;case"bearer":Z(e,"token",r);return;case"basic":Z(e,"username",r),Z(e,"password",r);return;case"oauth2":return;case"custom":if(typeof e.headers!="object"||e.headers===null||Array.isArray(e.headers))throw new Error('credential(custom): "headers" object is required');return;default:{let t=r;throw new Error(`credential: unknown type ${JSON.stringify(t)}`)}}}function po(r,e){switch(r){case"apiKey":return{[String(e.headerName)]:String(e.value)};case"bearer":return{Authorization:`Bearer ${String(e.token)}`};case"basic":return{Authorization:`Basic ${Buffer.from(`${String(e.username)}:${String(e.password)}`).toString("base64")}`};case"oauth2":{if(typeof e.accessToken!="string"||!e.accessToken)throw new Error("credential(oauth2): no accessToken yet \u2014 complete the OAuth authorization first");return{Authorization:`Bearer ${e.accessToken}`}}case"custom":return{...e.headers};default:{let t=r;throw new Error(`credential: unknown type ${JSON.stringify(t)}`)}}}import{join as zt}from"node:path";import{mkdir as mo,rm as ho}from"node:fs/promises";function wo(r,e,t){return zt(te().getProjectAgentDir(r),"workflows",e,"runs",t)}var He=class{constructor(e,t,n){this.workflowId=t;this.runId=n;if(!e)throw new Error("FileRunCheckpoint requires a project cwd");if(!t)throw new Error("FileRunCheckpoint requires a workflowId");if(!n)throw new Error("FileRunCheckpoint requires a runId");this.dir=wo(e,t,n),this.file=zt(this.dir,"cache.json")}workflowId;runId;dir;file;async load(){return C(this.file)}async persist(e){await mo(this.dir,{recursive:!0});let t={workflowId:this.workflowId,runId:this.runId,entries:e,updatedAt:new Date().toISOString()};await j(this.file,t)}async clear(){await ho(this.dir,{recursive:!0,force:!0})}};import*as L from"node:fs";import*as fe from"node:path";var qe=class{file;constructor(e){this.file=fe.join(e,"audit.jsonl")}append(e){try{L.mkdirSync(fe.dirname(this.file),{recursive:!0}),L.appendFileSync(this.file,`${JSON.stringify(e)}
6
+ ${u}`}function pr(r){if(!r)return"none";switch(r.type){case"manual":return"manual";case"schedule":return`schedule ${JSON.stringify(r.cron)}`;case"im-message":return r.match?`im-message ${r.channel} match=${JSON.stringify(r.match)}`:`im-message ${r.channel}`;case"webhook":return`webhook ${r.path}`;case"intent":return`intent ${r.phrases.map(e=>JSON.stringify(e)).join(" / ")}${r.semantic?" +semantic":""}`;case"form":return`form [${r.fields.map(e=>e.key).join(", ")}]`}}function mr(r,e){let t=r.name?` "${r.name}"`:"",n=hr(r.params,e),o=(r.outPorts??kr(r.kind)).join(","),i=[`${r.id} [${r.kind}]${t}`];return n&&i.push(n),i.push(`out: ${o}`),i.join(" ")}function hr(r,e){if(!r)return"";let t=Object.keys(r).sort();return t.length===0?"":t.map(n=>`${n}=${wr(r[n],e)}`).join(" ")}function wr(r,e){let t;return typeof r=="string"?t=r.includes("{{")?r:JSON.stringify(r):t=JSON.stringify(r),t.length>e&&(t=t.slice(0,e-1)+"\u2026"),t}function yr(r){return r.length===0?"edges: (none)":`edges:
7
+ ${r.map(t=>{let n=t.fromPort??"default",o=t.toPort??"default",i=t.loopBack?" (loopBack)":"";return`${t.from}.${n}\u2192${t.to}.${o}${i}`}).join(" ; ")}`}function kr(r){return r==="if"?["true","false"]:r==="loop"?["loop","done"]:["default"]}function br(r){let e=[],t=r;return t=t.replace(/\$node\[\s*(['"])([^'"\]]+)\1\s*\]\.json/g,'$node("$2").output.default[0].json'),t=t.replace(/\$\(\s*(['"])([^'")]+)\1\s*\)(?:\.item|\.first\(\))?\.json/g,'$node("$2").output.default[0].json'),t=t.replace(/\$items\(\s*(['"])([^'")]+)\1\s*\)\[(\d+)\]\.json/g,'$node("$2").output.default[$3].json'),t=t.replace(/\$input(?:\.item|\.first\(\))\.json/g,"$json"),/\$now\b/.test(t)&&e.push("$now:n8n \u4E3A Luxon DateTime,\u6B64\u5904\u4E3A Date(\u683C\u5F0F\u5316\u51FD\u6570\u7528 date(...))"),{body:t,notes:e}}function vr(r){if(!r.startsWith("="))return null;let e=r.slice(1);if(!e.includes("{{"))return{ok:!0,converted:e,notes:[]};let t=[],n=null,o=e.replace(/\{\{([\s\S]*?)\}\}/g,(i,s)=>{if(n)return i;let{body:a,notes:d}=br(s.trim()),l=re(a);return l?(n=`\u8868\u8FBE\u5F0F\u300C{{ ${s.trim()} }}\u300D\u8D85\u51FA\u53D7\u9650\u8BED\u8A00(${l})`,i):(t.push(...d),`{{ ${a} }}`)});return n?{ok:!1,reason:n}:{ok:!0,converted:o,notes:t}}function Et(r,e,t=""){let n=(o,i)=>{if(typeof o=="string"){let s=vr(o);return s===null?o:s.ok?(e.converted++,e.notes.push(...s.notes),s.converted):(e.manual.push({path:i,raw:o,reason:s.reason}),o)}return Array.isArray(o)?o.map((s,a)=>n(s,`${i}[${a}]`)):o&&typeof o=="object"?Object.fromEntries(Object.entries(o).map(([s,a])=>[s,n(a,i?`${i}.${s}`:s)])):o};return n(r,t)}var Rt={"@n8n/n8n-nodes-langchain.agent":"agentBinding","@n8n/n8n-nodes-langchain.chainLlm":"agentBinding","@n8n/n8n-nodes-langchain.chainRetrievalQa":"agentBinding","@n8n/n8n-nodes-langchain.chainSummarization":"agentBinding","@n8n/n8n-nodes-langchain.chatTrigger":"trigger","@n8n/n8n-nodes-langchain.documentDefaultDataLoader":"documentLoader","@n8n/n8n-nodes-langchain.embeddingsOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.informationExtractor":"agentBinding","@n8n/n8n-nodes-langchain.lmChatGoogleGemini":"modelBinding","@n8n/n8n-nodes-langchain.lmChatOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.lmChatOpenRouter":"modelBinding","@n8n/n8n-nodes-langchain.lmOpenAi":"modelBinding","@n8n/n8n-nodes-langchain.memoryBufferWindow":"memory","@n8n/n8n-nodes-langchain.openAi":"modelBinding","@n8n/n8n-nodes-langchain.outputParserStructured":"parser","@n8n/n8n-nodes-langchain.retrieverVectorStore":"retriever","@n8n/n8n-nodes-langchain.textSplitterRecursiveCharacterTextSplitter":"textSplitter","@n8n/n8n-nodes-langchain.textSplitterTokenSplitter":"textSplitter","@n8n/n8n-nodes-langchain.toolCode":"script","@n8n/n8n-nodes-langchain.toolSerpApi":"toolBinding","@n8n/n8n-nodes-langchain.toolVectorStore":"toolBinding","@n8n/n8n-nodes-langchain.toolWorkflow":"subworkflow","@n8n/n8n-nodes-langchain.vectorStoreInMemory":"vectorStore","@n8n/n8n-nodes-langchain.vectorStoreQdrant":"vectorStore","n8n-nodes-base.aggregate":"aggregate","n8n-nodes-base.code":"script","n8n-nodes-base.convertToFile":"file","n8n-nodes-base.discord":"channel","n8n-nodes-base.executeWorkflow":"subworkflow","n8n-nodes-base.executeWorkflowTrigger":"trigger","n8n-nodes-base.extractFromFile":"file","n8n-nodes-base.facebookGraphApi":"channel","n8n-nodes-base.filter":"filter","n8n-nodes-base.form":"form","n8n-nodes-base.formTrigger":"trigger","n8n-nodes-base.gmail":"integration","n8n-nodes-base.gmailTool":"toolBinding","n8n-nodes-base.gmailTrigger":"trigger","n8n-nodes-base.googleDocs":"integration","n8n-nodes-base.googleDocsTool":"toolBinding","n8n-nodes-base.googleDrive":"integration","n8n-nodes-base.googleSheets":"integration","n8n-nodes-base.googleSheetsTrigger":"trigger","n8n-nodes-base.html":"transform","n8n-nodes-base.htmlExtract":"extract","n8n-nodes-base.httpRequest":"http","n8n-nodes-base.if":"if","n8n-nodes-base.limit":"limit","n8n-nodes-base.linkedIn":"channel","n8n-nodes-base.localFileTrigger":"trigger","n8n-nodes-base.manualTrigger":"trigger","n8n-nodes-base.merge":"merge","n8n-nodes-base.noOp":"passthrough","n8n-nodes-base.openAi":"modelBinding","n8n-nodes-base.postgres":"integration","n8n-nodes-base.postgresTool":"toolBinding","n8n-nodes-base.readBinaryFile":"file","n8n-nodes-base.readWriteFile":"file","n8n-nodes-base.respondToWebhook":"respond","n8n-nodes-base.s3":"integration","n8n-nodes-base.scheduleTrigger":"trigger","n8n-nodes-base.set":"set","n8n-nodes-base.splitInBatches":"split","n8n-nodes-base.splitOut":"split","n8n-nodes-base.spreadsheetFile":"file","n8n-nodes-base.supabaseTool":"toolBinding","n8n-nodes-base.switch":"switch","n8n-nodes-base.telegram":"channel","n8n-nodes-base.telegramTrigger":"trigger","n8n-nodes-base.twitter":"channel","n8n-nodes-base.wait":"wait","n8n-nodes-base.whatsApp":"channel","n8n-nodes-base.whatsAppTrigger":"trigger","n8n-nodes-base.writeBinaryFile":"file","n8n-nodes-base.writeFile":"file","n8n-nodes-base.youTube":"integration"},xr=new Set(["openAiApi","googlePalmApi","openRouterApi","mistralCloudApi","anthropicApi"]),Pr=new Set(["agentBinding"]);function It(r){return xr.has(r)}function St(r){return Pr.has(r)}function Nt(r){return"workflow"}function At(r,e){let t=`${r} ${e}`.toLowerCase();return t.includes("gmail")?"gmail":t.includes("googlesheets")?"google-sheets":t.includes("googledrive")?"google-drive":t.includes("googledocs")?"google-docs":t.includes("telegram")?"telegram":t.includes("whatsapp")?"whatsapp":t.includes("youtube")?"youtube":t.includes("postgres")?"postgres":t.includes("supabase")?"supabase":t.includes("qdrant")?"qdrant":t.includes("s3")?"s3":t.includes("twitter")||t.includes("xapi")?"x":t.includes("facebook")?"facebook":t.includes("linkedin")?"linkedin":t.includes("discord")?"discord":t.includes("serp")?"serpapi":t.includes("firecrawl")?"firecrawl":t.includes("elevenlabs")?"elevenlabs":"custom"}var $t={"n8n-nodes-base.set":"set","n8n-nodes-base.if":"if","n8n-nodes-base.merge":"merge","n8n-nodes-base.noOp":"passthrough","n8n-nodes-base.httpRequest":"http","n8n-nodes-base.manualTrigger":"trigger","n8n-nodes-base.scheduleTrigger":"trigger","n8n-nodes-base.cron":"trigger","n8n-nodes-base.webhook":"trigger","n8n-nodes-base.formTrigger":"trigger","n8n-nodes-base.switch":"switch","n8n-nodes-base.filter":"filter","n8n-nodes-base.wait":"wait","n8n-nodes-base.aggregate":"aggregate","n8n-nodes-base.executeWorkflow":"subworkflow"},Er=new Set(["n8n-nodes-base.stickyNote"]),Rr=new Set(["n8n-nodes-base.code","n8n-nodes-base.function","n8n-nodes-base.functionItem","@n8n/n8n-nodes-langchain.toolCode"]),W=class extends Error{constructor(t){super(`n8n import rejected: ${t.join("; ")}`);this.errors=t;this.name="N8nImportError"}errors};function jt(r,e,t={}){let n=Ar(r),o=t.strictTemplates===!0,i=[],s={status:"full",nodes:[],expressions:{converted:0,manual:[]},credentials:[],bindings:{models:[],agents:[],connections:[]},notes:[]},a=new Set,d=new Set,l=[];for(let[f,c]of n.nodes.entries()){if(typeof c?.name!="string"||c.name===""){i.push(`nodes[${f}] has a missing/empty name`);continue}if(a.has(c.name)){i.push(`duplicate node name "${c.name}"`);continue}if(a.add(c.name),typeof c.type!="string"||c.type===""){i.push(`node "${c.name}" has a missing/empty type`);continue}if(Er.has(c.type)){d.add(c.name),s.nodes.push({id:c.name,n8nType:c.type,outcome:"skipped",notes:["annotation node skipped"]});continue}let g={id:c.name,n8nType:c.type,outcome:"converted",notes:[]};s.nodes.push(g);let p=Ir(c.type,o);Rr.has(c.type)&&!o?(p="manual",g.outcome="manual",g.notes.push("Code node contains imported script; default import keeps it as a fail-loud manual placeholder.")):p||(o?(p="n8nNode",g.outcome="unsupported",g.notes.push(`unsupported n8n node type "${c.type}" preserved as raw n8nNode`)):(p="manual",g.outcome="manual",g.notes.push(`unmapped n8n node type "${c.type}", please replace it manually`)));let h={converted:0,manual:[],notes:[]},w=Et({...c.parameters??{}},h);s.expressions.converted+=h.converted;for(let m of h.manual)s.expressions.manual.push({nodeId:c.name,...m}),g.notes.push(`parameter ${m.path}: ${m.reason}`),g.outcome==="converted"&&(g.outcome="partial");for(let m of h.notes)s.notes.includes(m)||s.notes.push(m);Nr(c,p,s,o),o&&St(p)&&(s.bindings.agents.push({nodeId:c.name,fallback:!0,label:c.name}),g.outcome=g.outcome==="converted"?"partial":g.outcome,g.notes.push("agent capability will be resolved from the configured Agent panel, not from n8n credentials"));let x={id:c.name,kind:p,name:c.name,params:{...w,_n8nType:c.type}};o&&(x.params={...x.params,_importMode:"n8n-strict-template",_bindingKind:p}),Array.isArray(c.position)&&Number.isFinite(c.position[0])&&Number.isFinite(c.position[1])&&(x.ui={x:c.position[0],y:c.position[1]}),Sr(x,p,g,o),l.push(x)}let u=n.connections?$r(n.connections,a,d,l,i,o):[];if(o&&Cr(u,l),Dr(l),l.length===0&&i.length===0&&i.push("workflow has no nodes"),i.length>0)throw new W(i);return s.status=s.nodes.some(f=>f.outcome==="manual"||f.outcome==="unsupported")?"manual":s.nodes.some(f=>f.outcome==="partial")||s.expressions.manual.length>0?"partial":"full",{name:typeof n.name=="string"&&n.name!==""?n.name:e,def:{id:e,nodes:l,edges:u},report:s}}function Ir(r,e){return e?Rt[r]??$t[r]??"n8nNode":$t[r]}function Sr(r,e,t,n){let o=r.params;if(e==="if"){r.outPorts=["true","false"];return}if(e==="wait"){let i=typeof o.amount=="number"?o.amount:Number(o.amount),s=typeof o.unit=="string"?o.unit:"seconds",a=s==="hours"?36e5:s==="minutes"?6e4:1e3;Number.isFinite(i)&&i>0?o.ms=Math.min(36e5,Math.round(i*a)):n||(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push("wait duration could not be parsed"));return}if(e==="subworkflow"){let i=typeof o.workflowId=="object"&&o.workflowId!==null?o.workflowId.value:o.workflowId;typeof i=="string"&&i?(o.workflowId=i,t.outcome=t.outcome==="converted"?"partial":t.outcome,t.notes.push("subworkflow target keeps the n8n workflow id and must be rebound to a local workflow")):n||(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push("subworkflow target is missing"));return}(e==="switch"||e==="filter")&&!n&&(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push(`${e} conditions preserve n8n params and may need review`))}function Nr(r,e,t,n){if(!(!r.credentials||typeof r.credentials!="object")){for(let[o,i]of Object.entries(r.credentials)){if(n&&It(o)){t.bindings.models.push({nodeId:r.name,n8nCredentialType:o,modelPurpose:Nt(o),label:i?.name});continue}let s=At(r.type,o);n&&t.bindings.connections.push({nodeId:r.name,n8nCredentialType:o,connectionType:s,label:i?.name}),t.credentials.push({nodeId:r.name,n8nCredentialType:o,label:i?.name})}n&&e==="modelBinding"&&t.bindings.models.push({nodeId:r.name,n8nCredentialType:"model-registry",modelPurpose:"workflow"})}}function Ar(r){let e;if(typeof r=="string")try{e=JSON.parse(r)}catch(n){throw new W([`invalid JSON: ${n.message}`])}else e=r;if(!e||typeof e!="object")throw new W(["workflow must be a JSON object"]);let t=e;if(!Array.isArray(t.nodes))throw new W(["workflow.nodes must be an array"]);if(t.connections!==void 0&&(typeof t.connections!="object"||t.connections===null))throw new W(["workflow.connections must be an object"]);return{name:t.name,nodes:t.nodes,connections:t.connections??{}}}function $r(r,e,t,n,o,i){let s=new Map(n.map(d=>[d.id,d.kind])),a=[];for(let d of Object.keys(r).sort()){if(t.has(d))continue;if(!e.has(d)){o.push(`connection source "${d}" is not a declared node`);continue}let l=r[d]??{};for(let u of Object.keys(l).sort()){let f=l[u];if(Array.isArray(f))for(let c=0;c<f.length;c++){let g=jr(d,s.get(d),u,c,n,o,i),p=f[c];if(Array.isArray(p))for(let h of p){if(!h||typeof h.node!="string"){o.push(`connection from "${d}" has a malformed target`);continue}if(t.has(h.node))continue;if(!e.has(h.node)){o.push(`connection from "${d}" targets missing node "${h.node}"`);continue}let w={from:d,to:h.node};g!=="default"&&(w.fromPort=g),i&&typeof h.type=="string"&&h.type&&h.type!=="main"&&(w.toPort=h.type),a.push(w)}}}}return a}function jr(r,e,t,n,o,i,s){return t!=="main"?T(o,r,n===0?t:`${t}_${n}`):e==="if"?n===0?"true":n===1?"false":(s||i.push(`if node "${r}" has an unsupported output index ${n}`),T(o,r,`out_${n}`)):e==="switch"?T(o,r,`case_${n}`):e==="filter"?n===0?T(o,r,"default"):(s||i.push(`filter node "${r}" has an unsupported discarded output`),T(o,r,n===1?"discarded":`out_${n}`)):n===0?T(o,r,"default"):(s||i.push(`node "${r}" has an unmodeled multi-output index ${n} (only single-output supported)`),T(o,r,`out_${n}`))}function T(r,e,t){let n=r.find(o=>o.id===e);return n&&(n.outPorts=n.outPorts??[],n.outPorts.includes(t)||n.outPorts.push(t)),t}function Dr(r){for(let e of r)e.outPorts&&e.outPorts.length>0&&(e.params={...e.params??{},_n8nOutPorts:e.outPorts})}function Cr(r,e){let t=[];for(let n of r)if(Tr(t,n.to,n.from)){n.loopBack=!0;let o=e.find(i=>i.id===n.to);o&&(!o.maxIterations||o.maxIterations<=0)&&(o.maxIterations=100)}else t.push(n)}function Tr(r,e,t){let n=[e],o=new Set;for(;n.length>0;){let i=n.pop();if(i===t)return!0;if(!o.has(i)){o.add(i);for(let s of r)s.from===i&&n.push(s.to)}}return!1}import{join as Wt}from"node:path";import{mkdir as Wr}from"node:fs/promises";function ue(r,...e){let t=r.toLowerCase();return e.some(n=>t.includes(n.toLowerCase()))}function Dt(r,e){let t=(r??"").trim(),n=t.length>300?`${t.slice(0,300)}\u2026`:t||void 0;return ue(t,"credential","\u51ED\u8BC1","unauthorized","forbidden","401","403","auth")?{class:"user",message:"\u9274\u6743\u6CA1\u901A\u8FC7 \u2014\u2014 \u51ED\u8BC1\u7F3A\u5931\u6216\u5DF2\u5931\u6548\u3002",hint:"\u68C0\u67E5\u5BF9\u5E94\u8282\u70B9\u6216 MCP \u63D2\u4EF6\u7684\u8FDE\u63A5\u914D\u7F6E\u540E\u91CD\u8DD1\u3002",actions:["ai_fix","rerun_node"],detail:n}:ue(t,"\u4E0D\u5B58\u5728\u7684","\u5F15\u7528\u4E86\u4E0D\u5B58\u5728","no nodeexecutor","\u76EE\u5F55\u5916","not registered","unknown kind","\u672A\u80FD\u81EA\u52A8\u8F6C\u6362","\u4EBA\u5DE5\u8FC1\u79FB")?{class:"capability",message:"\u8FD9\u4E00\u6B65\u5F15\u7528\u4E86\u4E0D\u5B58\u5728\u7684\u80FD\u529B / \u5DE5\u5177\u3002",hint:"\u6362\u4E00\u4E2A\u771F\u5B9E\u5B58\u5728\u7684\u5DE5\u5177,\u6216\u8BA9 AI \u6539\u8FD9\u4E00\u6B65\u3002",actions:["ai_fix","swap_capability","rerun_node"],detail:n}:ue(t,"econnrefused","enotfound","etimedout","fetch failed","network","timeout","timed out","socket","getaddrinfo","invalid url","request failed","5xx","502","503","504")?{class:"network",message:"\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25 \u2014\u2014 \u5730\u5740\u4E0D\u901A\u3001\u8D85\u65F6\u6216\u5BF9\u65B9\u62A5\u9519\u3002",hint:"\u786E\u8BA4\u5730\u5740/\u7F51\u7EDC\u540E\u91CD\u8DD1;\u5730\u5740\u4E0D\u5BF9\u5C31\u8BA9 AI \u6539\u3002",actions:["rerun_node","ai_fix"],detail:n}:ue(t,"requires string param","requires param","requires object param","requires non-empty","\u7F3A\u5C11\u5FC5\u586B","required","must be","\u5FC5\u586B","in 1..","must have at least")?{class:"user",message:"\u8FD9\u4E00\u6B65\u7F3A\u5C11\u5FC5\u8981\u4FE1\u606F(\u5FC5\u586B\u53C2\u6570\u6CA1\u586B\u5168\u6216\u683C\u5F0F\u4E0D\u5BF9)\u3002",hint:"\u8BA9 AI \u8865\u5168,\u6216\u5728\u300C\u9AD8\u7EA7\u300D\u91CC\u624B\u52A8\u586B\u3002",actions:["ai_fix","rerun_node"],detail:n}:{class:"system",message:"\u8FD9\u4E00\u6B65\u6267\u884C\u51FA\u9519\u4E86\u3002",hint:"\u53EF\u4EE5\u91CD\u8DD1;\u82E5\u53CD\u590D\u5931\u8D25,\u8BA9 AI \u770B\u770B\u8FD9\u4E00\u6B65\u3002",actions:["rerun_node","ai_fix","rerun_all"],detail:n}}var Mr=20,Ct=2e3;function Tt(r,e){return Wt(N(r),e,"runs","history.json")}function Se(r){let e={};for(let[t,n]of Object.entries(r.outputs)){let o={};for(let[a,d]of Object.entries(n))o[a]=d.map(l=>l.json);let i=JSON.stringify(o);i.length>Ct&&(i=`${i.slice(0,Ct)}\u2026(truncated)`);let s=r.nodeStats?.[t];e[t]={executed:r.executed.has(t),preview:i,...s?{seq:s.seq,startedAt:s.startedAt,durationMs:s.durationMs,attempts:s.attempts,cacheHit:s.cacheHit,nodeStatus:s.status,...s.warning!==void 0?{warning:s.warning}:{}}:{}}}return e}var Ie=class{constructor(e){this.cwd=e;if(!e)throw new Error("WorkflowRunHistoryStore requires a project cwd")}cwd;async begin(e,t){let n=await this.read(e);n.unshift({...t,status:"running"}),await this.write(e,n.slice(0,Mr))}async finish(e,t,n){let o=await this.read(e),i=o.find(s=>s.runId===t);i&&(Object.assign(i,n),i.errorInfo=i.status==="failed"&&i.error?Dt(i.error):void 0,await this.write(e,o))}async list(e){return(await this.read(e)).map(({nodes:t,...n})=>n)}async get(e,t){return(await this.read(e)).find(n=>n.runId===t)}async read(e){try{let t=await j(Tt(this.cwd,e));return Array.isArray(t)?t:[]}catch{return[]}}async write(e,t){let n=Tt(this.cwd,e);await Wr(Wt(N(this.cwd),e,"runs"),{recursive:!0}),await D(n,t)}};import{randomUUID as Or}from"node:crypto";var Ne=class{constructor(e,t,n){this.store=e;this.runtimeFactory=t;this.runHistory=n}store;runtimeFactory;runHistory;slots=new Map;activeRuns=new Map;activeRunIdsByWorkflow=new Map;suppressedHistoryRunIds=new Set;async create(e){let t=z(e.def);if(t.length>0)throw new v(t);let n=new Date().toISOString(),o={id:e.id,name:e.name,...e.owner?{owner:e.owner}:{},def:e.def,active:e.active??!1,concurrency:e.concurrency??"queue",rev:1,createdAt:n,updatedAt:n};return await this.store.save(o),o}async update(e,t){let o={...await this.store.require(e),...t,updatedAt:new Date().toISOString()};if(t.def!==void 0){let i=z(o.def);if(i.length>0)throw new v(i)}return await this.store.save(o),o}async setActive(e,t){if(t){let n=await this.store.require(e);if(!n.publishedDef)throw new Error(`Workflow "${e}" has no published version \u2014 publish the draft before activating`);if(n.archived)throw new Error(`Workflow "${e}" is archived \u2014 restore it before activating`)}return this.update(e,{active:t})}async publish(e){let t=await this.store.require(e);if(t.archived)throw new Error(`Workflow "${e}" is archived \u2014 restore it before publishing`);let n=z(t.def);if(n.length>0)throw new v(n);let o={...t,publishedDef:structuredClone(t.def),publishedRev:t.rev,updatedAt:new Date().toISOString()};return await this.store.save(o),o}async archive(e,t){let o={...await this.store.require(e),archived:t,...t?{active:!1}:{},updatedAt:new Date().toISOString()};return await this.store.save(o),o}async revertTo(e,t){let n=await this.store.require(e),o=await this.store.loadRevision(e,t);if(!o)throw new Error(`Workflow "${e}" has no stored revision ${t}`);let i=z(o.def);if(i.length>0)throw new v(i);let s={...n,def:o.def,name:o.name,trigger:o.trigger??null,rev:n.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(s),s}async importN8n(e,t,n={}){let{name:o,def:i,report:s}=jt(t,e,{strictTemplates:!0});return{record:await this.create({id:e,name:o,def:i,concurrency:n.concurrency,owner:n.owner}),report:s}}async get(e){return this.store.require(e)}async describe(e,t){let n=await this.store.require(e);return Re(n,t)}async patch(e,t){let n=await this.store.require(e),o=t.baseRev!==void 0&&t.baseRev<n.rev,i={def:n.def,meta:{name:n.name,active:n.active,trigger:n.trigger??null}},s,a;try{let u=Ee(i,t);s=u.applied,a=u.target}catch(u){if(o&&u instanceof v)return{ok:!1,conflict:{latestRev:n.rev}};throw u}if(a.meta.active===!0&&!n.active&&!n.publishedDef)throw new v([`workflow "${e}" has no published version \u2014 publish the draft before activating (set_meta.active)`]);let l={...n,def:a.def,name:a.meta.name??n.name,active:a.meta.active??n.active,trigger:a.meta.trigger??null,rev:n.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(l),{ok:!0,rev:l.rev,applied:s}}async run(e,t,n={}){let o=await this.store.require(e);if(o.archived)throw new Error(`Workflow "${e}" is archived and cannot run`);let i=t?.type??"manual",s=i==="manual"||i==="intent"||i==="form",a;if(s)a=o.def;else{if(!o.publishedDef)throw new Error(`Workflow "${e}" has no published version \u2014 unattended trigger "${i}" refused`);a=o.publishedDef}let d={workflowId:e,runId:Or(),type:i,payload:t?.payload,permissionScope:o.permissionScope,reuseCache:n.reuseCache===!0},l=this.slotFor(e),u=()=>{if(l.pending>0)switch(o.concurrency){case"skip":return Promise.resolve({workflowId:e,status:"skipped"});case"parallel":return this.startParallel(e,a,d);case"queue":return this.track(e,l,a,d,!0)}return this.track(e,l,a,d,!1)};return this.recordRun(e,d,u,n.recordHistory===!1,n.onStarted)}async recordRun(e,t,n,o=!1,i){let s=Date.now(),a={workflowId:e,runId:t.runId,triggerType:t.type};if(!this.runHistory||o)try{await i?.(a);let u=await n();return{...u,runId:u.runId??t.runId}}catch(u){if(u instanceof b)return{workflowId:e,status:"canceled",runId:t.runId};throw u}await this.runHistory.begin(e,{runId:t.runId,triggerType:t.type,startedAt:new Date(s).toISOString()});let d=u=>this.finishRunHistory(e,t.runId,s,u),l;try{await i?.(a),l=await n()}catch(u){if(u instanceof b)return await d({status:"canceled",error:u.message}),{workflowId:e,status:"canceled",runId:t.runId};throw await d({status:"failed",error:u instanceof Error?u.message:String(u),failedNodeId:u?.nodeId}),u}return await d({status:l.status,...l.result?{nodes:Se(l.result)}:{}}),{...l,runId:t.runId}}pause(e,t={}){this.requireActiveRun(e,t.runId).runtime.pause()}async resume(e,t={}){let n=this.requireActiveRun(e,t.runId);if(n.status!=="paused")throw new Error(`Workflow "${e}" run "${n.runId}" is not paused`);t.extraBudget&&n.runtime.extendBudget(t.extraBudget),n.status="running";let o=this.slotFor(e);o.pending++;let i=n.runtime.run().then(async s=>{let a={workflowId:e,runId:n.runId,status:s.status,result:s};return s.status==="paused"?n.status="paused":this.unregisterActiveRun(n.runId),await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:a.status,nodes:Se(s)}),a}).catch(async s=>{if(this.unregisterActiveRun(n.runId),s instanceof b)return await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"canceled",error:s.message}),{workflowId:e,runId:n.runId,status:"canceled"};throw await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"failed",error:s instanceof Error?s.message:String(s),failedNodeId:s?.nodeId}),s}).finally(()=>{o.pending--});return o.tail=i.catch(()=>{}),i}async cancelRun(e,t={}){let n=this.requireActiveRun(e,t.runId),o=t.reason??`Workflow "${e}" run "${n.runId}" canceled`,i=new b(o);return n.runtime.cancel(o),n.abortController.signal.aborted||n.abortController.abort(i),this.unregisterActiveRun(n.runId),n.status==="paused"&&await this.finishRunHistory(e,n.runId,n.startedAtMs,{status:"canceled",error:o}),{workflowId:e,runId:n.runId,status:"canceled"}}async delete(e){let t=[...this.activeRunIdsByWorkflow.get(e)??[]];for(let n of t)this.suppressedHistoryRunIds.add(n),await this.cancelRun(e,{runId:n,reason:`Workflow "${e}" deleted`}).catch(()=>{});this.slots.delete(e),await this.store.delete(e)}async listActive(){return this.store.listActive()}slotFor(e){let t=this.slots.get(e);return t||(t={tail:Promise.resolve(),pending:0},this.slots.set(e,t)),t}registerActiveRun(e){this.activeRuns.set(e.runId,e);let t=this.activeRunIdsByWorkflow.get(e.workflowId);t||(t=new Set,this.activeRunIdsByWorkflow.set(e.workflowId,t)),t.add(e.runId)}unregisterActiveRun(e){let t=this.activeRuns.get(e);if(!t)return;this.activeRuns.delete(e);let n=this.activeRunIdsByWorkflow.get(t.workflowId);n&&(n.delete(e),n.size===0&&this.activeRunIdsByWorkflow.delete(t.workflowId))}requireActiveRun(e,t){if(t){let s=this.activeRuns.get(t);if(!s||s.workflowId!==e)throw new Error(`Workflow "${e}" has no active run "${t}"`);return s}let n=[...this.activeRunIdsByWorkflow.get(e)??[]],o=this.slots.get(e)?.latestRunId;if(o&&n.includes(o))return this.activeRuns.get(o);let i=n.at(-1);if(!i)throw new Error(`Workflow "${e}" has no active run`);return this.activeRuns.get(i)}async finishRunHistory(e,t,n,o){!this.runHistory||this.suppressedHistoryRunIds.has(t)||await this.runHistory.finish(e,t,{finishedAt:new Date().toISOString(),durationMs:Date.now()-n,...o})}track(e,t,n,o,i){t.pending++;let s=()=>this.startTrackedRuntime(e,t,n,o),d=(i?t.tail.then(s):s()).finally(()=>{t.pending--});return t.tail=d.catch(()=>{}),d}async startParallel(e,t,n){return this.startTrackedRuntime(e,void 0,t,n)}async startTrackedRuntime(e,t,n,o){let i=new AbortController,s=this.runtimeFactory(n,{...o,signal:i.signal}),a={workflowId:e,runId:o.runId,startedAtMs:Date.now(),runtime:s,abortController:i,status:"running"};this.registerActiveRun(a),t&&(t.runtime=s,t.latestRunId=o.runId);try{let d=await s.run(),l={workflowId:e,runId:o.runId,status:d.status,result:d};return d.status==="paused"?a.status="paused":this.unregisterActiveRun(o.runId),l}catch(d){throw this.unregisterActiveRun(o.runId),d}}};function Hr(r){return(e,t)=>new V(e,{registry:r.registry,host:r.host,signal:t.signal,checkpoint:r.checkpoint?.(t.workflowId,t.reuseCache?"shared-cache":t.runId),preserveCheckpoint:t.reuseCache===!0,trigger:t.payload,triggerKind:t.type,now:r.now,onNodeStatus:r.emitNodeStatus?(n,o,i)=>r.emitNodeStatus(t.workflowId,n,o,i):void 0,gate:new ae({trigger:t.type,maxNodeExecutions:r.budget.maxNodeExecutions,maxDurationMs:r.budget.maxDurationMs,allowUnattendedKinds:t.permissionScope?.allowUnattendedKinds??r.allowUnattendedKinds,now:r.now?()=>r.now().getTime():void 0})})}function _r(r){let e=r.fetchImpl??fetch;return{async runAgent(t){let n=await r.runAgent({agentId:t.agentId,prompt:t.prompt,signal:t.signal});return[C({text:n,output:n})]},async runModel(t){if(!r.resolveClientForPurpose)throw new Error("workflow model node: no configured model resolver is wired");let n=r.resolveClientForPurpose("textGeneration");if(!n)throw new Error("workflow model node: no textGeneration model is configured");let o="";for await(let i of n.transport.stream({model:n.model,messages:[{role:"user",content:t.prompt}],temperature:t.temperature,maxTokens:t.maxTokens,tools:[]},n.apiKey,t.signal))if(i.type==="delta"&&(o+=i.text),i.type==="error")throw new Error(i.message);return[C({text:o,output:o,model:n.model,...t.modelHint?{importedModel:t.modelHint}:{},choices:[{text:o}]})]},async httpRequest(t){let n=await e(t.url,{method:t.method||"GET",headers:t.headers,body:t.body===void 0?void 0:typeof t.body=="string"?t.body:JSON.stringify(t.body),signal:t.signal}),o=n.headers.get("content-type")??"";if(o.includes("application/json")){let a=await n.text(),d=a;try{a.length>0&&(d=JSON.parse(a))}catch{d={__unparsedJson:a}}return[C({status:n.status,ok:n.ok,body:d})]}let i=Buffer.from(await n.arrayBuffer()),s=qr(n.headers.get("content-disposition"));return[C({status:n.status,ok:n.ok,bodyBase64:i.toString("base64"),mimeType:o||"application/octet-stream",size:i.byteLength,...s?{filename:s}:{}})]},async invokeMcp(t){let n=await r.invokeMcp({server:t.server,tool:t.tool,args:t.args,signal:t.signal});return[C({result:n})]},async sendChannel(t){if(!r.sendChannel)throw new Error("workflow channel node: sendChannel requires the xiaozhiclaw gateway host, none injected (channel/IM nodes are unavailable in standalone qlogicagent \u2014 D12/D13).");let n=await r.sendChannel({channel:t.channel,target:t.target,payload:t.payload,signal:t.signal});return[C({sent:!0,result:n})]},async memory(t){if(!r.memory)throw new Error("workflow memory node: no memory backend injected (handler host wires the project memdir)");return r.memory(t)},async runSubworkflow(t){if(!r.runSubworkflow)throw new Error("workflow subworkflow node: no sub-run backend injected (handler host wires the controller)");return r.runSubworkflow(t)},async approval(t){if(!r.approval)throw new Error("workflow approval node: no approval backend injected (handler host wires the notify/await loop)");return r.approval(t)},async waitWebhook(t){if(!r.waitWebhook)throw new Error("workflow wait(until=webhook): no webhook-wait backend injected (handler host wires the wake registry)");return r.waitWebhook(t)}}}function qr(r){if(!r)return;let e=r.match(/filename\*=UTF-8''([^;]+)/i);if(e)return decodeURIComponent(e[1].trim().replace(/^"|"$/g,""));let t=r.match(/filename=([^;]+)/i);return t?t[1].trim().replace(/^"|"$/g,""):void 0}var Mt=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],Ot=["SUN","MON","TUE","WED","THU","FRI","SAT"];function Br(r){if(typeof r!="string"||r.trim()==="")throw new Error("cron must be a non-empty string");let e=r.trim().split(/\s+/);if(e.length!==5&&e.length!==6)throw new Error(`cron must have 5 or 6 fields, got ${e.length}: "${r}"`);let t=e.length===6,n=t?[{label:"second",min:0,max:59},{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Mt},{label:"day-of-week",min:0,max:7,names:Ot}]:[{label:"minute",min:0,max:59},{label:"hour",min:0,max:23},{label:"day-of-month",min:1,max:31},{label:"month",min:1,max:12,names:Mt},{label:"day-of-week",min:0,max:7,names:Ot}],o=n.map((d,l)=>({spec:d,raw:e[l],set:Ur(e[l],n[l])})),i=d=>{let l=o.find(u=>u.spec.label===d);if(!l)throw new Error(`internal: missing cron field ${d}`);return l},s=i("day-of-week"),a=new Set;for(let d of s.set)a.add(d===7?0:d);return{hasSeconds:t,seconds:t?i("second").set:new Set([0]),minutes:i("minute").set,hours:i("hour").set,doms:i("day-of-month").set,months:i("month").set,dows:a,domRestricted:i("day-of-month").raw.trim()!=="*",dowRestricted:s.raw.trim()!=="*"}}function Ur(r,e){let t=new Set;for(let n of r.split(","))Fr(n,e,t);if(t.size===0)throw new Error(`cron ${e.label} expanded to an empty set: "${r}"`);return t}function Fr(r,e,t){if(r==="")throw new Error(`cron ${e.label} has an empty list element`);let n=r,o=1,i=r.indexOf("/");if(i!==-1){n=r.slice(0,i);let d=r.slice(i+1);if(!/^\d+$/.test(d)||Number(d)<=0)throw new Error(`cron ${e.label} has an invalid step "/${d}"`);o=Number(d)}let s,a;if(n==="*")s=e.min,a=e.max;else{let d=n.indexOf("-");if(d!==-1){let l=Ae(n.slice(0,d),e),u=Ae(n.slice(d+1),e);if(l===void 0||u===void 0)throw new Error(`cron ${e.label} has an invalid range "${n}"`);if(l>u)throw new Error(`cron ${e.label} range "${n}" is descending`);s=l,a=u}else{let l=Ae(n,e);if(l===void 0)throw new Error(`cron ${e.label} value "${n}" is out of range ${e.min}-${e.max}`);s=l,a=o===1?l:e.max}}for(let d=s;d<=a;d+=o)t.add(d)}function Ae(r,e){let t;if(/^\d+$/.test(r))t=Number(r);else if(e.names){let n=e.names.indexOf(r.toUpperCase());if(n===-1)return;t=e.label==="month"?n+1:n}else return;if(!(t<e.min||t>e.max))return t}var Lr=5*366+32;function $e(r,e){let t=Br(r),n=new Date(e);t.hasSeconds?(n.setUTCMilliseconds(0),n.setUTCSeconds(n.getUTCSeconds()+1)):(n.setUTCSeconds(0,0),n.setUTCMinutes(n.getUTCMinutes()+1));for(let o=0;o<Lr;o++){if(!t.months.has(n.getUTCMonth()+1)){n.setUTCMonth(n.getUTCMonth()+1,1),n.setUTCHours(0,0,0,0);continue}if(!Kr(t,n)){n.setUTCDate(n.getUTCDate()+1),n.setUTCHours(0,0,0,0);continue}if(!t.hours.has(n.getUTCHours())){n.setUTCHours(n.getUTCHours()+1,0,0,0);continue}if(!t.minutes.has(n.getUTCMinutes())){n.setUTCMinutes(n.getUTCMinutes()+1,0,0);continue}if(t.hasSeconds&&!t.seconds.has(n.getUTCSeconds())){n.setUTCSeconds(n.getUTCSeconds()+1,0);continue}return n.getTime()}throw new Error(`cron "${r}" has no matching time within ~5 years of ${new Date(e).toISOString()}`)}function Kr(r,e){let t=r.doms.has(e.getUTCDate()),n=r.dows.has(e.getUTCDay());return r.domRestricted&&r.dowRestricted?t||n:r.domRestricted?t:r.dowRestricted?n:!0}var Jr={now:()=>Date.now(),setTimer:(r,e)=>setTimeout(r,e),clearTimer:r=>clearTimeout(r)},Ht=2e9,je=class{controller;clock;onError;onRunStarted;onRunCompleted;onRunFailed;triggers=new Map;cronArms=new Map;lastFireAt=new Map;minTriggerIntervalMs;onTriggerDropped;started=!1;constructor(e){if(!e.controller)throw new Error("WorkflowScheduler requires a controller");if(typeof e.onError!="function")throw new Error("WorkflowScheduler requires an onError handler");if(this.controller=e.controller,this.clock=e.clock??Jr,this.onError=e.onError,this.onRunStarted=e.onRunStarted,this.onRunCompleted=e.onRunCompleted,this.onRunFailed=e.onRunFailed,this.minTriggerIntervalMs=e.minTriggerIntervalMs??0,this.onTriggerDropped=e.onTriggerDropped,this.minTriggerIntervalMs>0&&!this.onTriggerDropped)throw new Error("WorkflowScheduler: minTriggerIntervalMs > 0 requires onTriggerDropped (drops must never be silent, \xA71.5)")}async start(){if(this.started)throw new Error("WorkflowScheduler already started");this.started=!0;let e=await this.controller.listActive();for(let t of e)this.registerTrigger(t.id,t.trigger??{type:"manual"})}stop(){for(let e of this.cronArms.values())this.clock.clearTimer(e.handle);this.cronArms.clear(),this.triggers.clear(),this.started=!1}async refresh(e){let t;try{t=await this.controller.get(e)}catch{this.unregister(e);return}if(!t.active){this.unregister(e);return}this.registerTrigger(e,t.trigger??{type:"manual"})}unregister(e){let t=this.cronArms.get(e);t&&(this.clock.clearTimer(t.handle),this.cronArms.delete(e)),this.triggers.delete(e)}registeredIds(){return[...this.triggers.keys()]}nextFireAt(e){return this.cronArms.get(e)?.fireAt}async onWebhook(e,t){let n=this.matchingIds(o=>o.type==="webhook"&&o.path===e).filter(o=>this.passesRateLimit(o,"webhook"));return Promise.all(n.map(o=>this.runWithLifecycle(o,{type:"webhook",payload:t})))}async onImMessage(e,t,n){let o=this.matchingIds(s=>s.type==="im-message"&&s.channel===e&&Gr(s.match,t)).filter(s=>this.passesRateLimit(s,"im-message")),i={...n,channel:e,text:t};return Promise.all(o.map(s=>this.runWithLifecycle(s,{type:"im-message",payload:i})))}async triggerManual(e,t){return this.runWithLifecycle(e,{type:"manual",payload:t})}matchingIds(e){let t=[];for(let[n,o]of this.triggers)e(o)&&t.push(n);return t}registerTrigger(e,t){if(this.unregister(e),this.triggers.set(e,t),t.type==="schedule"){let n=$e(t.cron,this.clock.now());this.armCron(e,t.cron,n)}}armCron(e,t,n){let o=Math.max(0,n-this.clock.now()),i={cron:t,fireAt:n,handle:void 0};o>Ht?i.handle=this.clock.setTimer(()=>{this.cronArms.get(e)===i&&this.armCron(e,t,n)},Ht):i.handle=this.clock.setTimer(()=>this.fireCron(e,i),o),this.cronArms.set(e,i)}fireCron(e,t){if(this.cronArms.get(e)!==t)return;let n;try{n=$e(t.cron,t.fireAt)}catch(o){this.cronArms.delete(e),this.onError(o,e);return}this.armCron(e,t.cron,n),this.passesRateLimit(e,"schedule")&&this.runWithLifecycle(e,{type:"schedule"}).catch(o=>this.onError(o,e))}passesRateLimit(e,t){if(this.minTriggerIntervalMs<=0)return!0;let n=this.clock.now(),o=this.lastFireAt.get(e);return o!==void 0&&n-o<this.minTriggerIntervalMs?(this.onTriggerDropped?.(e,t,{sinceLastMs:n-o,minIntervalMs:this.minTriggerIntervalMs}),!1):(this.lastFireAt.set(e,n),!0)}async runWithLifecycle(e,t){let n;try{n=await this.controller.run(e,t,{onStarted:({runId:o})=>this.onRunStarted?.(e,t.type,o)})}catch(o){try{this.onRunFailed?.(e,t.type,o)}catch(i){this.reportLifecycleCallbackError(e,"failure",i)}throw o}try{this.onRunCompleted?.(n,t.type)}catch(o){this.reportLifecycleCallbackError(e,"completion",o)}return n}reportLifecycleCallbackError(e,t,n){let o=n instanceof Error?n.message:String(n);try{this.onError(new Error(`Workflow ${e} ${t} notification failed: ${o}`),e)}catch{}}};function Gr(r,e){return r===void 0?!0:new RegExp(r).test(e)}import{join as _t}from"node:path";import{mkdir as Vr,rm as zr}from"node:fs/promises";function Yr(r,e,t){return _t(Z().getProjectAgentDir(r),"workflows",e,"runs",t)}var De=class{constructor(e,t,n){this.workflowId=t;this.runId=n;if(!e)throw new Error("FileRunCheckpoint requires a project cwd");if(!t)throw new Error("FileRunCheckpoint requires a workflowId");if(!n)throw new Error("FileRunCheckpoint requires a runId");this.dir=Yr(e,t,n),this.file=_t(this.dir,"cache.json")}workflowId;runId;dir;file;async load(){return j(this.file)}async persist(e){await Vr(this.dir,{recursive:!0});let t={workflowId:this.workflowId,runId:this.runId,entries:e,updatedAt:new Date().toISOString()};await D(this.file,t)}async clear(){await zr(this.dir,{recursive:!0,force:!0})}};import*as B from"node:fs";import*as de from"node:path";var Ce=class{file;constructor(e){this.file=de.join(e,"audit.jsonl")}append(e){try{B.mkdirSync(de.dirname(this.file),{recursive:!0}),B.appendFileSync(this.file,`${JSON.stringify(e)}
10
8
  `,"utf8")}catch(t){process.stderr.write(`[workflow:audit] WRITE FAILED (${t instanceof Error?t.message:String(t)}) \u2014 entry: ${JSON.stringify(e)}
11
- `)}}list(e,t=100){let n;try{n=L.readFileSync(this.file,"utf8")}catch{return[]}let o=[];for(let i of n.split(`
9
+ `)}}list(e,t=100){let n;try{n=B.readFileSync(this.file,"utf8")}catch{return[]}let o=[];for(let i of n.split(`
12
10
  `))if(i.trim())try{let s=JSON.parse(i);(!e||s.workflowId===e)&&o.push(s)}catch{process.stderr.write(`[workflow:audit] skipping malformed line: ${i.slice(0,120)}
13
- `)}return o.reverse().slice(0,t)}};var Be=2,yo=/token|secret|authorization|api[-_]?key|apikey|password|credential|cookie|passphrase|private[-_]?key/i,ko="__CREDENTIAL_REQUIRED__";function ge(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function Ue(r,e,t,n,o){if(Array.isArray(r))return r.map((s,a)=>Ue(s,`${e}[${a}]`,t,n,o));if(!ge(r))return r;let i={};for(let[s,a]of Object.entries(r)){if(yo.test(s)&&a!==void 0&&a!==null&&a!==""){o.push({type:"custom",label:`${n} ${e}.${s}`,nodeIds:[t]}),i[s]=ko;continue}i[s]=Ue(a,`${e}.${s}`,t,n,o)}return i}function bo(r){let e=new Map;for(let t of r){let n=e.get(t.label);if(n)for(let o of t.nodeIds)n.nodeIds.includes(o)||n.nodeIds.push(o);else e.set(t.label,{...t,nodeIds:[...t.nodeIds]})}return[...e.values()]}function vo(r){return`\u8282\u70B9\u300C${r.name??r.id}\u300D`}function xo(r){let e=new Map,t=(n,o)=>{let i=`${n.category}:${n.ref}`,s=e.get(i);s?s.nodeIds.includes(o)||s.nodeIds.push(o):e.set(i,{...n,nodeIds:[o]})};for(let n of r.nodes){let o=n.params??{};switch(n.kind){case"agent":{let i=z(o.agentId);t({category:"agent",kind:"agent",ref:i,label:`Agent: ${i}`},n.id);break}case"tool":{let i=typeof o.tool=="string"?o.tool:"";i&&t({category:"tool",kind:"tool",ref:i,label:`\u5DE5\u5177: ${i}`},n.id);break}case"skill":{let i=typeof o.skill=="string"?o.skill:"";i&&t({category:"skill",kind:"skill",ref:i,label:`\u6280\u80FD: ${i}`},n.id);break}case"mcp":{let i=typeof o.server=="string"?o.server:"",s=typeof o.tool=="string"?o.tool:"";i&&t({category:"mcp",kind:"mcp",ref:s?`${i}.${s}`:i,label:`MCP: ${i}${s?` / ${s}`:""}`},n.id);break}case"channel":{let i=typeof o.channel=="string"?o.channel:"";i&&t({category:"channel",kind:"channel",ref:i,label:`\u6E20\u9053: ${i}`},n.id);break}case"memory":{t({category:"memory",kind:"memory",ref:"memory",label:"\u8BB0\u5FC6\u8BFB\u5199"},n.id);break}default:break}}return[...e.values()]}function Eo(r){let e=[],t=r.def.nodes.map(o=>({...o,...o.params!==void 0?{params:Ue(o.params,"params",o.id,vo(o),e)}:{}})),n={...r.def,nodes:t};return{schemaVersion:Be,name:r.name,def:n,...r.trigger?{trigger:r.trigger}:{},concurrency:r.concurrency,requires:xo(n),credentialsRequired:bo(e),meta:{source:"native"}}}function Ro(r){let e=typeof r=="string"?JSON.parse(r):r;if(!ge(e))throw new Error("workflow bundle: payload must be an object");if(e.schemaVersion!==Be)throw new Error(`workflow bundle: unsupported schemaVersion ${String(e.schemaVersion)} (expected ${Be})`);if(typeof e.name!="string"||!e.name)throw new Error("workflow bundle: `name` is required");let t=e.def;if(!ge(t)||!Array.isArray(t.nodes)||!Array.isArray(t.edges))throw new Error("workflow bundle: `def.nodes` and `def.edges` are required arrays");let n=e.concurrency;if(n!==void 0&&n!=="queue"&&n!=="skip"&&n!=="parallel")throw new Error(`workflow bundle: invalid concurrency "${String(n)}"`);return{name:e.name,def:t,trigger:ge(e.trigger)?e.trigger:void 0,concurrency:n,requires:Array.isArray(e.requires)?e.requires:[],credentialsRequired:Array.isArray(e.credentialsRequired)?e.credentialsRequired:[]}}export{_e as CredentialVault,He as FileRunCheckpoint,sr as HOST_BACKED_KINDS,V as NodeRegistry,v as PatchError,qe as WorkflowAuditStore,Ce as WorkflowController,$e as WorkflowRunHistoryStore,Y as WorkflowRuntime,We as WorkflowScheduler,be as WorkflowStore,Ae as applyPatch,Zr as createQlaExecutorHost,po as credentialToHeaders,Qr as defaultRuntimeFactory,Ro as fromWorkflowBundle,ue as hostExecutors,Ne as renderWorkflow,Eo as toWorkflowBundle,A as workflowsDir};
11
+ `)}return o.reverse().slice(0,t)}};var Te=3,Qr=/token|secret|authorization|api[-_]?key|apikey|password|credential|cookie|passphrase|private[-_]?key/i,Xr=new Set(["tool","skill","mcp"]);function Y(r){return typeof r=="object"&&r!==null&&!Array.isArray(r)}function Zr(r){if(Xr.has(r.kind))throw new Error(`workflow bundle: node "${r.name??r.id}" uses legacy kind "${r.kind}"; use an Agent plugin or canonical Action node`)}function We(r,e,t){if(Array.isArray(r)){for(let n=0;n<r.length;n+=1)We(r[n],`${e}[${n}]`,t);return}if(Y(r))for(let[n,o]of Object.entries(r)){if(Qr.test(n)&&o!==void 0&&o!==null&&o!=="")throw new Error(`workflow bundle: node "${t.name??t.id}" contains embedded authentication or secret field "${e}.${n}"; configure it in the owning MCP or Provider module`);We(o,`${e}.${n}`,t)}}function Me(r){for(let e of r.nodes)Zr(e),e.params!==void 0&&We(e.params,"params",e)}function qt(r){Me(r);let e=new Map,t=(n,o)=>{let i=`${n.category}:${n.ref}`,s=e.get(i);s?s.nodeIds.includes(o)||s.nodeIds.push(o):e.set(i,{...n,nodeIds:[o]})};for(let n of r.nodes){let o=n.params??{};switch(n.kind){case"agent":{let i=J(o.agentId);if(t({category:"agent",kind:"agent",ref:i,label:`Agent: ${i}`},n.id),Array.isArray(o.mcpPlugins))for(let s of o.mcpPlugins)!Y(s)||typeof s.id!="string"||!s.id||t({category:"mcp",kind:"plugin",ref:s.id,label:`MCP plugin: ${s.id}`},n.id);break}case"action":{let i=typeof o.toolName=="string"?o.toolName:"";i&&t({category:"mcp",kind:"action",ref:i,label:`MCP action: ${i}`},n.id);break}case"channel":{let i=typeof o.channel=="string"?o.channel:"";i&&t({category:"channel",kind:"channel",ref:i,label:`Channel: ${i}`},n.id);break}case"memory":t({category:"memory",kind:"memory",ref:"memory",label:"Memory"},n.id);break;default:break}}return[...e.values()]}function eo(r){Me(r.def);let e=structuredClone(r.def);return{schemaVersion:Te,name:r.name,def:e,...r.trigger?{trigger:structuredClone(r.trigger)}:{},concurrency:r.concurrency,requires:qt(e),meta:{source:"native"}}}function to(r){let e=typeof r=="string"?JSON.parse(r):r;if(!Y(e))throw new Error("workflow bundle: payload must be an object");if(e.schemaVersion!==Te)throw new Error(`workflow bundle: unsupported schemaVersion ${String(e.schemaVersion)} (expected ${Te})`);if(typeof e.name!="string"||!e.name)throw new Error("workflow bundle: `name` is required");let t=e.def;if(!Y(t)||!Array.isArray(t.nodes)||!Array.isArray(t.edges))throw new Error("workflow bundle: `def.nodes` and `def.edges` are required arrays");let n=e.concurrency;if(n!==void 0&&n!=="queue"&&n!=="skip"&&n!=="parallel")throw new Error(`workflow bundle: invalid concurrency "${String(n)}"`);let o=t;return Me(o),{name:e.name,def:o,trigger:Y(e.trigger)?e.trigger:void 0,concurrency:n,requires:qt(o)}}export{De as FileRunCheckpoint,Vn as HOST_BACKED_KINDS,K as NodeRegistry,v as PatchError,Ce as WorkflowAuditStore,Ne as WorkflowController,Ie as WorkflowRunHistoryStore,V as WorkflowRuntime,je as WorkflowScheduler,he as WorkflowStore,Ee as applyPatch,_r as createQlaExecutorHost,Hr as defaultRuntimeFactory,to as fromWorkflowBundle,ie as hostExecutors,Re as renderWorkflow,eo as toWorkflowBundle,N as workflowsDir};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qlogicagent",
3
- "version": "2.19.13",
3
+ "version": "2.20.1",
4
4
  "description": "XiaozhiClaw Agent CLI — subprocess architecture (JSON-RPC over stdio)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",