qlogicagent 2.18.12 → 2.19.2

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 (95) hide show
  1. package/README.md +382 -382
  2. package/dist/agent-contract.js +1 -0
  3. package/dist/cli.js +1 -1
  4. package/dist/default-project-knowledge/INSTRUCTIONS.md +7 -7
  5. package/dist/default-project-knowledge/rules/project-workflow.md +6 -6
  6. package/dist/host-contract.js +1 -1
  7. package/dist/host-session-collection-contract.js +1 -0
  8. package/dist/index.js +478 -505
  9. package/dist/pet-host.js +8 -8
  10. package/dist/project-memory-host.js +23 -23
  11. package/dist/protocol.js +1 -1
  12. package/dist/skills/builtin/desktop-screenshot/SKILL.md +62 -62
  13. package/dist/skills/builtin/office-doc-reading/SKILL.md +19 -19
  14. package/dist/types/cli/acp-commands.d.ts +1 -1
  15. package/dist/types/cli/acp-extended-handlers.d.ts +8 -8
  16. package/dist/types/cli/acp-extended-host-adapter.d.ts +0 -11
  17. package/dist/types/cli/acp-session-host.d.ts +2 -0
  18. package/dist/types/cli/core-tool-coordinator.d.ts +0 -9
  19. package/dist/types/cli/default-project-bootstrap.d.ts +2 -32
  20. package/dist/types/cli/handlers/session-handler.d.ts +0 -43
  21. package/dist/types/cli/handlers/solo-handler.d.ts +3 -14
  22. package/dist/types/cli/multi-agent-handler-host.d.ts +3 -16
  23. package/dist/types/cli/product-coordinator.d.ts +3 -14
  24. package/dist/types/cli/rpc-registry.d.ts +0 -2
  25. package/dist/types/cli/stdio-rpc-handler-hosts.d.ts +4 -1
  26. package/dist/types/cli/stdio-server.d.ts +1 -2
  27. package/dist/types/host-contract/index.d.ts +112 -19
  28. package/dist/types/host-session-collection-contract.d.ts +61 -0
  29. package/dist/types/orchestration/agent-instance.d.ts +11 -14
  30. package/dist/types/orchestration/agent-roster.d.ts +8 -4
  31. package/dist/types/orchestration/delegate-bridge.d.ts +8 -0
  32. package/dist/types/orchestration/goal-mode-adapters.d.ts +3 -3
  33. package/dist/types/orchestration/product-persistence.d.ts +0 -4
  34. package/dist/types/orchestration/product-planner.d.ts +4 -6
  35. package/dist/types/orchestration/solo-evaluator.d.ts +2 -5
  36. package/dist/types/orchestration/testing/delegate-test-bridge.d.ts +2 -1
  37. package/dist/types/orchestration/testing/host-agent-provider-directory-fixture.d.ts +7 -0
  38. package/dist/types/orchestration/workflow/qla-executor-host.d.ts +1 -1
  39. package/dist/types/protocol/agent-contract.d.ts +50 -0
  40. package/dist/types/protocol/methods.d.ts +20 -38
  41. package/dist/types/protocol/notifications.d.ts +1 -1
  42. package/dist/types/protocol/wire/acp-agent-management.d.ts +2 -190
  43. package/dist/types/protocol/wire/acp-protocol.d.ts +3 -4
  44. package/dist/types/protocol/wire/agent-events.d.ts +1 -32
  45. package/dist/types/protocol/wire/agent-methods.d.ts +1 -243
  46. package/dist/types/protocol/wire/gateway-rpc.d.ts +343 -15
  47. package/dist/types/protocol/wire/index.d.ts +3 -3
  48. package/dist/types/protocol/wire/notification-payloads.d.ts +103 -126
  49. package/dist/types/runtime/infra/host-agent-provider-directory.d.ts +17 -0
  50. package/dist/types/runtime/infra/project-authority-facade.d.ts +1 -1
  51. package/dist/types/runtime/infra/project-data-paths.d.ts +2 -1
  52. package/dist/types/runtime/infra/project-host-authority.d.ts +3 -2
  53. package/dist/types/runtime/infra/project-store.d.ts +4 -39
  54. package/dist/types/runtime/session/session-catalog.d.ts +0 -12
  55. package/dist/types/runtime/session/session-persistence.d.ts +1 -1
  56. package/dist/types/runtime/session/session-resource-key.d.ts +1 -1
  57. package/dist/types/runtime/session/session-types.d.ts +0 -23
  58. package/dist/types/transport/acp-server.d.ts +2 -10
  59. package/dist/vendor/hatch-pet/LICENSE.txt +201 -201
  60. package/dist/vendor/hatch-pet/NOTICE.md +25 -25
  61. package/dist/vendor/hatch-pet/references/animation-rows.md +29 -29
  62. package/dist/vendor/hatch-pet/references/codex-pet-contract.md +35 -35
  63. package/dist/vendor/hatch-pet/references/qa-rubric.md +66 -66
  64. package/dist/vendor/hatch-pet/scripts/compose_atlas.py +169 -169
  65. package/dist/vendor/hatch-pet/scripts/derive_running_left_from_running_right.py +150 -150
  66. package/dist/vendor/hatch-pet/scripts/extract_strip_frames.py +408 -408
  67. package/dist/vendor/hatch-pet/scripts/inspect_frames.py +256 -256
  68. package/dist/vendor/hatch-pet/scripts/make_contact_sheet.py +96 -96
  69. package/dist/vendor/hatch-pet/scripts/prepare_pet_run.py +834 -834
  70. package/dist/vendor/hatch-pet/scripts/render_animation_previews.py +78 -78
  71. package/dist/vendor/hatch-pet/scripts/validate_atlas.py +157 -157
  72. package/dist/workflow-host.js +10 -10
  73. package/package.json +16 -1
  74. package/dist/types/cli/agent-config-coordinator.d.ts +0 -27
  75. package/dist/types/cli/agent-config-runtime.d.ts +0 -11
  76. package/dist/types/cli/agent-status-notifier.d.ts +0 -11
  77. package/dist/types/cli/handlers/agents-handler.d.ts +0 -121
  78. package/dist/types/cli/handlers/project-handler.d.ts +0 -36
  79. package/dist/types/cli/project-command-service.d.ts +0 -28
  80. package/dist/types/orchestration/delegation-coordinator.d.ts +0 -100
  81. package/dist/types/runtime/infra/acp-detector.d.ts +0 -271
  82. package/dist/types/runtime/infra/agent-config-store.d.ts +0 -30
  83. package/dist/types/runtime/infra/agent-install-runner.d.ts +0 -80
  84. package/dist/types/runtime/infra/external-agent-approvals.d.ts +0 -59
  85. package/dist/types/runtime/infra/migrate-device-scope.d.ts +0 -49
  86. package/dist/types/runtime/infra/project-data-gc.d.ts +0 -15
  87. package/dist/types/runtime/session/native/claude-session-source.d.ts +0 -23
  88. package/dist/types/runtime/session/native/codex-index.d.ts +0 -21
  89. package/dist/types/runtime/session/native/codex-session-source.d.ts +0 -31
  90. package/dist/types/runtime/session/native/cwd-normalize.d.ts +0 -53
  91. package/dist/types/runtime/session/native/ephemeral-rollout-sweep.d.ts +0 -13
  92. package/dist/types/runtime/session/native/native-cwd-agents.d.ts +0 -17
  93. package/dist/types/runtime/session/native/native-session-source.d.ts +0 -89
  94. package/dist/types/runtime/session/native/native-title.d.ts +0 -1
  95. package/dist/types/runtime/session/native/register-builtin-sources.d.ts +0 -1
@@ -1,13 +1,13 @@
1
- import{join as N}from"node:path";import{mkdir as at,readdir as dt,rm as ut}from"node:fs/promises";import{readFile as Qt,writeFile as Xt,mkdir as Zt,rename as er,unlink as tr}from"node:fs/promises";import{dirname as rr,join as nr}from"node:path";import{randomUUID as or}from"node:crypto";async function ir(n,e){let t=rr(n);await Zt(t,{recursive:!0});let r=nr(t,`.tmp-${or()}`);try{await Xt(r,e,"utf-8");let o;for(let i=0;i<3;i++)try{await er(r,n);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 tr(r).catch(()=>{}),o}}async function D(n){try{let e=await Qt(n,"utf-8");return JSON.parse(e)}catch(e){if(e.code==="ENOENT")return;throw e}}async function C(n,e){await ir(n,JSON.stringify(e,null,2)+`
2
- `)}import{resolve as vr}from"node:path";import{join as yr}from"node:path";import{homedir as dr}from"node:os";import{join as y}from"node:path";import{existsSync as Ho}from"node:fs";import{createHash as sr}from"node:crypto";import{resolve as ar}from"node:path";function ee(n){return sr("sha256").update(ar(n).toLowerCase()).digest("hex").slice(0,16)}var Je=".qlogicagent";function E(){return process.env.QLOGICAGENT_HOME||y(dr(),Je)}function te(){let n=process.env.QLOGIC_LLMROUTER_USER_ID?.trim();if(n)return n;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 ur(n){let e=n.trim();if(!e)throw new Error("ownerUserId is required for profile-scoped storage");return encodeURIComponent(e).replace(/\./g,"%2E")}function _(n=te()){return y(E(),"profiles",ur(n))}function Ke(n=te()){return y(_(n),"memory")}var cr="projectData";function we(){return y(E(),cr)}function re(n){if(!n)throw new Error("getProjectDataDirById: projectId is required");return y(we(),n)}function Ge(){return y(E(),"plugins")}function Ve(){return y(E(),"skills")}function ze(){return y(_(),"settings.json")}function Ye(){return y(E(),"plugin-cache")}function Qe(){return y(E(),"mcp.json")}function Xe(){return y(E(),"marketplace.json")}function H(n){if(!n)throw new Error("getProjectAgentDir: cwd is required (must not fall back to process.cwd())");return y(n,Je)}function Ze(n){return y(H(n),"plugins")}function et(n){return y(H(n),"settings.json")}function tt(n){return y(H(n),"INSTRUCTIONS.md")}function rt(n){return y(H(n),"rules")}import{existsSync as fr,mkdirSync as Lo,readFileSync as gr,writeFileSync as Jo,readdirSync as Ko,renameSync as Go}from"node:fs";import{dirname as zo,join as pr,resolve as Yo}from"node:path";var lr=()=>{},ye;function nt(){return lr()!==void 0}function ot(){if(nt()){if(!ye)throw new Error("host project authority negotiated but snapshot is not hydrated");return{activeProjectId:ye.activeProjectId,projects:ye.projects.map(n=>({...n}))}}}function mr(){return pr(E(),"projects.json")}function hr(){let n=ot();if(n)return{activeProjectId:n.activeProjectId,projects:n.projects};let e=mr();if(!fr(e))return{activeProjectId:null,projects:[]};try{let t=gr(e,"utf-8");return JSON.parse(t)}catch{return{activeProjectId:null,projects:[]}}}function it(n){return hr().projects.find(t=>t.id===n)??null}function kr(n){return it(n)?n:ee(n)}function br(n){return re(kr(n))}function st(n){return yr(br(n),"sessions")}var ke=class{constructor(e={}){this.options=e}options;lastActiveWorkdir=null;getActiveProjectRoot(){return this.options.getActiveProjectRoot?.()??process.cwd()}setActiveWorkdir(e){let t=vr(e);this.lastActiveWorkdir=t,this.options.setActiveWorkdir?.(t)}getActiveWorkdir(){return this.lastActiveWorkdir??this.getActiveProjectRoot()}resolveProjectDir(e){return this.options.resolveProjectDir?.(e)}resolveActiveOwnerUserId(){return te()}getUserAgentHome(){return E()}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 rt(e)}getProjectSessionDataRoot(e=this.getActiveProjectRoot()){return st(e)}},xr=new ke;function ne(){return xr}function j(n){return N(ne().getProjectAgentDir(n),"workflows")}function ct(n,e){return N(j(e),n,"workflow.json")}function be(n,e){return N(j(e),n,"revisions")}var Pr=20,ve=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=N(j(this.cwd),e.id);await at(t,{recursive:!0}),await C(ct(e.id,this.cwd),e),await this.snapshotRevision(e)}async snapshotRevision(e){try{let t=be(e.id,this.cwd);await at(t,{recursive:!0}),await C(N(t,`${e.rev}.json`),e);let r=await this.revisionNumbers(e.id);for(let o of r.slice(Pr))await ut(N(t,`${o}.json`),{force:!0})}catch{}}async revisionNumbers(e){let t;try{t=await dt(be(e,this.cwd))}catch{return[]}return t.map(r=>Number(r.replace(/\.json$/,""))).filter(r=>Number.isInteger(r)&&r>0).sort((r,o)=>o-r)}async listRevisions(e){let t=[];for(let r of await this.revisionNumbers(e)){let o=await this.loadRevision(e,r);o&&t.push({rev:r,updatedAt:o.updatedAt,name:o.name,nodeCount:o.def.nodes.length})}return t}async loadRevision(e,t){return D(N(be(e,this.cwd),`${t}.json`))}async load(e){return D(ct(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 dt(j(this.cwd))}catch{return[]}let t=[];for(let r of e){let o=await this.load(r);o&&t.push(o)}return t}async listActive(){return(await this.list()).filter(e=>e.active)}async delete(e){await ut(N(j(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 r of t.dependsOn??[]){if(!this.nodes.has(r))throw new Error(`Node "${t.id}" depends on unknown node "${r}"`);this.edges.push({from:r,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 r=this.incomingForwardEdges(t.id);if(r.length===0){e.push(t);continue}t.joinPolicy==="any"?r.some(o=>this.edgeSatisfied(o))&&e.push(t):r.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,r=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":r++;break;case"pending":o++;break;case"paused":i++;break;case"skipped":s++;break}return{total:this.nodes.size,completed:e,running:t,failed:r,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 r=this.requireNode(e);if(r.status!=="running")throw new Error(`Node "${e}" is ${r.status}, cannot complete`);r.status="completed",r.output=t.output,r.completedAt=Date.now(),r.firedPorts=t.firedPorts??r.outPorts,t.inputTokens!==void 0&&(r.inputTokens=t.inputTokens),t.outputTokens!==void 0&&(r.outputTokens=t.outputTokens),t.changedFiles!==void 0&&(r.changedFiles=t.changedFiles),r.acceptanceUnverified=t.acceptanceUnverified,this.propagateSkips()}markFailed(e,t){let r=this.requireNode(e);r.status="failed",r.error=t,r.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 r=this.requireNode(e);if(r.kind!=="loop")throw new Error(`Node "${e}" is not a loop controller`);if(!r.maxIterations||r.maxIterations<=0)throw new Error(`Loop "${e}" requires maxIterations > 0`);let o=r.iteration??0;t&&o<r.maxIterations?(r.iteration=o+1,r.firedPorts=["loop"],this.resetLoopScope(e)):(r.firedPorts=["done"],t&&(r.error=`loop_cap_reached:${r.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(r=>r.to!==e.id||!e.dependsOn?.includes(r.from)),t}}addNodes(e){let t=[],r=[];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),r.push(...i)}this.validateDag()}catch(o){for(let i of t)this.nodes.delete(i);throw this.edges=this.edges.filter(i=>!r.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(r=>r.from!==e&&r.to!==e),this.nodes.delete(e)}retryNode(e,t){let r=this.requireNode(e);if(r.status!=="failed")throw new Error(`Node "${e}" is ${r.status}, only failed nodes can be retried`);r.status="pending",r.error=void 0,r.output=void 0,r.firedPorts=void 0,r.startedAt=void 0,r.completedAt=void 0,r.inputTokens=void 0,r.outputTokens=void 0,r.changedFiles=void 0,t&&Object.assign(r.params,t)}resetForReplay(e){if(!this.nodes.has(e))throw new Error(`Node "${e}" not found`);let t=new Set([e]),r=!0;for(;r;){r=!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),r=!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 r=this.requireNode(e);if(r.status!=="pending")throw new Error(`Node "${e}" is ${r.status}, can only update pending nodes`);Object.assign(r.params,t)}addEdge(e){let{from:t,to:r,fromPort:o="default",loopBack:i=!1}=e;if(!this.nodes.has(t))throw new Error(`Unknown source node "${t}"`);if(!this.nodes.has(r))throw new Error(`Unknown target node "${r}"`);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(u=>u.from===t&&u.to===r&&(u.fromPort??"default")===o))if(this.edges.push({from:t,to:r,fromPort:o,loopBack:i}),i){let u=this.nodes.get(r);if(!u.maxIterations||u.maxIterations<=0)throw this.edges.pop(),new Error(`LoopBack controller "${r}" requires maxIterations > 0`)}else try{this.validateDag()}catch(u){throw this.edges=this.edges.filter(l=>!(l.from===t&&l.to===r&&(l.fromPort??"default")===o)),u}}removeEdge(e,t,r){let o=r??"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(r=>r.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 r=this.nodes.get(t.id);r&&(r.status=t.status==="running"?"pending":t.status,r.output=t.output,r.error=t.error,r.firedPorts=t.firedPorts,r.startedAt=t.startedAt,r.completedAt=t.completedAt,r.inputTokens=t.inputTokens,r.outputTokens=t.outputTokens,r.changedFiles=t.changedFiles,r.acceptanceUnverified=t.acceptanceUnverified,r.runIndex=t.runIndex??0,r.iteration=t.iteration)}}getUpstreamOutputs(e){if(!this.nodes.get(e))return[];let r=this.incomingForwardEdges(e),o=new Set,i=[];for(let s of r){let a=s.from;if(o.has(a))continue;o.add(a);let u=this.nodes.get(a);if(u&&u.status==="completed"&&u.output!=null){let l=typeof u.output=="string"?u.output:JSON.stringify(u.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 r=e.fromPort??"default";return(t.firedPorts??t.outPorts).includes(r)}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 r=e.fromPort??"default";return!(t.firedPorts??t.outPorts).includes(r)}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 r of t){let o=this.nodes.get(r);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,r=(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),r(s.to,!1)))};return r(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,r=new Set,o=i=>{if(r.has(i))throw new Error(`Cycle detected involving node "${i}"`);if(!t.has(i)){r.add(i);for(let s of e)s.from===i&&o(s.to);r.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 $(n,e){return e?{json:n,binary:e}:{json:n}}function lt(n){let e={};for(let t of Object.keys(n).sort())e[t]=n[t].map(r=>({json:r.json,binary:r.binary?Object.fromEntries(Object.keys(r.binary).sort().map(o=>[o,r.binary[o].ref])):void 0}));return Pe(e)}function Pe(n){return JSON.stringify(xe(n))}function xe(n){if(Array.isArray(n))return n.map(xe);if(n&&typeof n=="object"){let e={};for(let t of Object.keys(n).sort())e[t]=xe(n[t]);return e}return n}var mt=new Set(["__proto__","prototype","constructor"]);function ft(n,e){let t=wt(n),r=new se(t,n),o=r.parseExpression();return r.expectEnd(),B(o,e)}function ae(n){try{let e=wt(n),t=new se(e,n),r=t.parseExpression();return t.expectEnd(),G(r),null}catch(e){return e instanceof Error?e.message:String(e)}}var Er=new Set(["input","json","node","now","vars","trigger"]),gt=new Set(["len","upper","lower","default","jsonpath","date"]);function G(n){switch(n.type){case"root":if(!Er.has(n.name))throw new Error(`Unknown context root "$${n.name}" (allowed: $input $json $node $now $vars $trigger)`);return;case"lit":return;case"func":if(!gt.has(n.name))throw new Error(`Unknown function "${n.name}" (whitelist: ${[...gt].join(", ")})`);n.args.forEach(G);return;case"prop":G(n.target);return;case"index":if(G(n.target),typeof n.key!="number"&&typeof n.key!="string")throw new Error("index key must be a number or string literal");return;case"call":if(!(n.target.type==="root"&&n.target.name==="node"))throw new Error("Only $node(...) is callable in this position");n.args.forEach(G);return}}function I(n,e){let t=n.match(/^\s*\{\{([\s\S]*)\}\}\s*$/);return t?ft(t[1],e):n.includes("{{")?n.replace(/\{\{([\s\S]*?)\}\}/g,(r,o)=>{let i=ft(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)}):n}function ht(n,e){return Re(n,e)}function Re(n,e){if(typeof n=="string")return I(n,e);if(Array.isArray(n))return n.map(t=>Re(t,e));if(n&&typeof n=="object"){let t={};for(let[r,o]of Object.entries(n))t[r]=Re(o,e);return t}return n}function wt(n){let e=[],t=0,r=i=>/[A-Za-z_]/.test(i),o=i=>/[A-Za-z0-9_]/.test(i);for(;t<n.length;){let i=n[t];if(/\s/.test(i)){t++;continue}if(i==="$"){t++;let s="";for(;t<n.length&&o(n[t]);)s+=n[t++];if(!s)throw new Error('Bare "$" is not a valid expression');e.push({t:"dollar",v:s});continue}if(r(i)){let s="";for(;t<n.length&&o(n[t]);)s+=n[t++];e.push({t:"id",v:s});continue}if(/[0-9]/.test(i)||i==="-"&&/[0-9]/.test(n[t+1]??"")){let s=n[t++];for(;t<n.length&&/[0-9.]/.test(n[t]);)s+=n[t++];e.push({t:"num",v:s});continue}if(i==='"'||i==="'"){let s=i;t++;let a="";for(;t<n.length&&n[t]!==s;)n[t]==="\\"&&t+1<n.length?(a+=n[t+1],t+=2):a+=n[t++];if(n[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 se=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 r=this.peek();if(!r||r.t!=="punc")break;if(r.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(r.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(r.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`)}},yt=Symbol("nodeAccessor");function B(n,e){switch(n.type){case"lit":return n.value;case"root":return Rr(n.name,e);case"func":return Ir(n.name,n.args.map(t=>B(t,e)));case"prop":return pt(B(n.target,e),n.key);case"index":return pt(B(n.target,e),n.key);case"call":{if(B(n.target,e)===yt){let r=n.args.map(i=>B(i,e));if(r.length!==1||typeof r[0]!="string")throw new Error("$node(...) takes exactly one string argument");let o=e.nodes?.[r[0]];if(!o)throw new Error(`$node("${r[0]}") not found (not completed or unknown)`);return o}throw new Error("Only $node(...) is callable in this position")}}}function Rr(n,e){switch(n){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 yt;default:throw new Error(`Unknown context root "$${n}" (allowed: $input $json $node $now $vars $trigger)`)}}function pt(n,e){if(typeof e=="string"&&mt.has(e))throw new Error(`Access to "${e}" is forbidden`);if(n==null)throw new Error(`Cannot read "${e}" of ${n}`);if(typeof e=="number"){if(!Array.isArray(n))throw new Error(`Cannot index non-array with [${e}]`);return n[e]}return n[e]}function Ir(n,e){switch(n){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(ie(e,0,"upper")).toUpperCase();case"lower":return String(ie(e,0,"lower")).toLowerCase();case"default":return e[0]===null||e[0]===void 0?e[1]:e[0];case"jsonpath":return jr(e[0],String(ie(e,1,"jsonpath")));case"date":return Ar(e);case"eq":return Ie(e[0],e[1]);case"ne":return!Ie(e[0],e[1]);case"gt":return oe(e[0],e[1])>0;case"gte":return oe(e[0],e[1])>=0;case"lt":return oe(e[0],e[1])<0;case"lte":return oe(e[0],e[1])<=0;case"not":return!Ee(ie(e,0,"not"));case"and":return e.every(Ee);case"or":return e.some(Ee);case"contains":return Sr(e[0],e[1]);default:throw new Error(`Unknown function "${n}()" (whitelist: len upper lower default jsonpath date eq ne gt gte lt lte not and or contains)`)}}function Ee(n){return!!n}function Ie(n,e){return n===e?!0:typeof n!=typeof e?!1:n&&e&&typeof n=="object"?JSON.stringify(n)===JSON.stringify(e):!1}function oe(n,e){if(typeof n=="number"&&typeof e=="number")return n-e;if(typeof n=="string"&&typeof e=="string")return n<e?-1:n>e?1:0;throw new Error(`Cannot compare ${typeof n} with ${typeof e}`)}function Sr(n,e){if(typeof n=="string")return n.includes(String(e));if(Array.isArray(n))return n.some(t=>Ie(t,e));throw new Error("contains() expects string/array as first argument")}function ie(n,e,t){if(n.length<=e||n[e]===void 0)throw new Error(`${t}() missing required argument #${e+1}`);return n[e]}function jr(n,e){let t=e.match(/[^.[\]]+/g)??[],r=n;for(let o of t){if(mt.has(o))throw new Error(`jsonpath segment "${o}" is forbidden`);if(r==null)return;let i=/^\d+$/.test(o)?Number(o):o;r=r[i]}return r}function Ar(n){let e=n.length===0?new Date:new Date(n[0]);if(Number.isNaN(e.getTime()))throw new Error(`date() received an invalid date: ${String(n[0])}`);if(n.length<2)return e.toISOString();let t=String(n[1]),r=o=>String(o).padStart(2,"0");return t.replace(/YYYY/g,String(e.getUTCFullYear())).replace(/MM/g,r(e.getUTCMonth()+1)).replace(/DD/g,r(e.getUTCDate())).replace(/HH/g,r(e.getUTCHours())).replace(/mm/g,r(e.getUTCMinutes())).replace(/ss/g,r(e.getUTCSeconds()))}import{mkdirSync as Nr,writeFileSync as $r}from"node:fs";import{dirname as Dr,resolve as Cr}from"node:path";var kt={filter:["condition"],transform:["mapping"],script:["*"],n8nNode:["*"],agentBinding:["*"],modelBinding:["*"],toolBinding:["*"],integration:["*"],file:["*"],form:["*"],documentLoader:["*"],parser:["*"],retriever:["*"],textSplitter:["*"],vectorStore:["*"],extract:["*"],limit:["*"],split:["*"],respond:["*"]};function de(n,e){return{json:e.json,vars:n.vars,trigger:n.trigger,now:n.now}}var Tr=(n,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]=Kr(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}}]}}},Wr=n=>({outputs:{default:n.default??[]}}),Or=n=>{let e=[];for(let t of Object.keys(n))e.push(...n[t]);return{outputs:{default:e}}},Mr=(n,e)=>{let r=!!e.condition?"true":"false",o=n.default??[],i={true:[],false:[]};return i[r]=o,{outputs:i,firedPorts:[r]}},_r=(n,e,t)=>({outputs:{default:[{json:t.trigger??(e.payload&&typeof e.payload=="object"&&!Array.isArray(e.payload)?e.payload:{})}]}}),Hr=(n,e,t)=>{let r=e.condition;if(typeof r!="string"||!r.trim())throw new Error('filter node requires string param "condition" (per-item {{ }} expression over $json)');return{outputs:{default:(n.default??[]).filter(s=>!!I(r,de(t,s)))}}},qr=(n,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 r=n.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]=r,{outputs:s,firedPorts:[i]}},Br=n=>{let e=n.default??[];return{outputs:{default:[{json:{items:e.map(t=>t.json),count:e.length}}]}}},Ur=(n,e,t)=>{let r=e.mapping;if(typeof r!="object"||r===null||Array.isArray(r))throw new Error('transform node requires object param "mapping" ({outKey: "{{ expr }}"})');let o=Object.entries(r);if(o.length===0)throw new Error('transform node: "mapping" must have at least one key');return{outputs:{default:(n.default??[]).map(a=>{let u={};for(let[l,d]of o)u[l]=typeof d=="string"?I(d,de(t,a)):d;return{json:u}})}}},Fr=async(n,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:[...n.default??[],{json:{webhook:a}}]}}}let r=Number(e.ms);if(!Number.isFinite(r)||r<1||r>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()},r),a=()=>{clearTimeout(s),i(new Error("wait node canceled"))};t.signal?.addEventListener("abort",a,{once:!0})}),{outputs:{default:n.default??[]}}},Lr=(n,e,t)=>{let r=typeof e._n8nType=="string"?`(\u6765\u81EA n8n \u8282\u70B9\u300C${e._n8nType}\u300D)`:"";throw new Error(`\u8282\u70B9\u300C${t.nodeId}\u300D${r}\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=(n,e,t)=>{let r=typeof e._n8nType=="string"?` (${e._n8nType})`:"",i=(Array.isArray(e._n8nOutPorts)?e._n8nOutPorts:["default"]).filter(l=>typeof l=="string"&&l.length>0),s=n.default??[],a=s.length>0?s:[{json:{imported:!0,nodeId:t.nodeId,kind:t.kind,n8nType:e._n8nType}}],u={};for(let l of i.length>0?i:["default"])u[l]=a;if(u.default||(u.default=a),e._importMode==="n8n-strict-template")throw new Error(`Imported n8n node "${t.nodeId}"${r} requires a native executor or binding before live runs.`);return{outputs:u}},Jr=(n,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=n.default?.[0];if(!o)throw new Error(`Imported file node "${t.nodeId}" requires an input item`);let i=Vr(e.fileName,o,t);if(!i)throw new Error(`Imported file node "${t.nodeId}" requires fileName`);let s=Cr(i);return Nr(Dr(s),{recursive:!0}),$r(s,Gr(o)),{outputs:{default:[{json:{...o.json,fileName:s,written:!0}}]}}},bt={set:Tr,passthrough:Wr,merge:Or,if:Mr,trigger:_r,filter:Hr,switch:qr,aggregate:Br,transform:Ur,wait:Fr,manual:Lr,script:k,n8nNode:k,agentBinding:k,modelBinding:k,toolBinding:k,integration:k,file:Jr,form:k,documentLoader:k,parser:k,retriever:k,textSplitter:k,vectorStore:k,extract:k,limit:k,split:k,respond:k};function Kr(n,e){if(e==="number"){let t=Number(n);return Number.isFinite(t)?t:n}if(e==="boolean"){if(typeof n=="boolean")return n;if(n==="true")return!0;if(n==="false")return!1}return n}function Gr(n){return typeof n.json.bodyBase64=="string"?Buffer.from(n.json.bodyBase64,"base64"):typeof n.json.body=="string"?n.json.body:n.json.body!==void 0?JSON.stringify(n.json.body,null,2):typeof n.json.data=="string"?n.json.data:JSON.stringify(n.json,null,2)}function Vr(n,e,t){if(typeof n!="string")return"";let r=n.startsWith("=")?n.slice(1):n,o=r.match(/^\{\{\s*([\s\S]*?)\s*\}\}$/);return o?String(zr(o[1],e,t)??""):r.includes("{{")?String(I(r,de(t,e))):r}function zr(n,e,t){let r=n.match(/^\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(r)return e.json[r[1]];let o=n.match(/^(["'])([\s\S]*)\1\s*\+\s*\$json\.([A-Za-z_][A-Za-z0-9_]*)$/);if(o)return`${Yr(o[1],o[2])}${String(e.json[o[3]]??"")}`;if(n.startsWith("$json."))return I(`{{ ${n} }}`,de(t,e));throw new Error(`Imported n8n expression is unsupported at node "${t.nodeId}": ${n}`)}function Yr(n,e){if(n==='"')try{return JSON.parse(`"${e}"`)}catch{return e}return e.replace(/\\'/g,"'").replace(/\\\\/g,"\\")}var Qr=new Set(["agentBinding","modelBinding"]),V=class{executors=new Map;constructor(e=!0){if(e)for(let[t,r]of Object.entries(bt))this.executors.set(t,r)}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,r]of Object.entries(e))this.executors.has(t)?Qr.has(t)&&this.override(t,r):this.register(t,r)}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 vt(n,e){let t=n??"any",r=e??"any";return t==="any"||r==="any"||t===r?!0:r==="binary"&&(t==="image"||t==="video"||t==="audio")}function ue(n){return n!=="manual"&&n!=="intent"&&n!=="form"}function z(n){let e=typeof n=="string"?n.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(n,e){if(!n)throw new Error(`Node kind "${e}" requires a host (ExecutorHost) but none was injected. Provide one via WorkflowRuntimeOptions.host.`);return n}function A(n,e,t){let r=n[e];if(typeof r!="string"||r.length===0)throw new Error(`Node kind "${t}" requires string param "${e}"`);return r}function Pt(n,e){let t=n[e];if(t==null)return{};if(typeof t!="object"||Array.isArray(t))throw new Error(`Param "${e}" must be an object`);return t}var Xr=async(n,e,t)=>({outputs:{default:await R(t.host,"agent").runAgent({agentId:z(e.agentId),prompt:A(e,"prompt","agent"),input:n.default??[],signal:t.signal})}}),Zr=async(n,e,t)=>{let r=R(t.host,"agentBinding"),o=Rt(e,n.default??[],t,"agentBinding");return{outputs:{default:await r.runAgent({agentId:z(e.agentId),prompt:o,input:n.default??[],signal:t.signal})}}},en=async(n,e,t)=>{let r=R(t.host,"modelBinding");if(!r.runModel)throw new Error('Node kind "modelBinding" requires an ExecutorHost with runModel');return{outputs:{default:await r.runModel({prompt:Rt(e,n.default??[],t,"modelBinding"),modelHint:mn(e),temperature:xt(e.temperature),maxTokens:xt(e.maxTokens),input:n.default??[],signal:t.signal})}}},tn=async(n,e,t)=>({outputs:{default:await R(t.host,"tool").invokeTool({tool:A(e,"tool","tool"),args:Pt(e,"args"),unattended:ue(t.triggerKind??"manual"),input:n.default??[],signal:t.signal})}}),rn=async(n,e,t)=>{let r=R(t.host,"http"),o=typeof e.method=="string"?e.method:"GET",i=await r.httpRequest({method:o,url:A(e,"url","http"),headers:fn(e),body:ln(e),credentialId:typeof e.credentialId=="string"&&e.credentialId?e.credentialId:void 0,signal:t.signal}),s=n.default?.[0]?.json??{};return{outputs:{default:i.map(a=>({...a,json:{...s,...a.json}}))}}},nn=async(n,e,t)=>({outputs:{default:await R(t.host,"mcp").invokeMcp({server:A(e,"server","mcp"),tool:A(e,"tool","mcp"),args:Pt(e,"args"),signal:t.signal})}}),on=async(n,e,t)=>({outputs:{default:await R(t.host,"channel").sendChannel({channel:A(e,"channel","channel"),target:typeof e.target=="string"?e.target:void 0,payload:e.payload??n.default?.[0]?.json??{},input:n.default??[],signal:t.signal})}}),sn=async(n,e,t)=>{let r=R(t.host,"skill"),o=e.args;return{outputs:{default:await r.invokeTool({tool:"skill_view",args:{name:A(e,"skill","skill"),...o!=null&&o!==""?{args:o}:{}},input:n.default??[],signal:t.signal})}}},an=async(n,e,t)=>{let r=R(t.host,"memory");if(!r.memory)throw new Error('Node kind "memory" requires an ExecutorHost with a memory backend');let o=A(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 r.memory({op:o,key:typeof e.key=="string"&&e.key?e.key:void 0,value:e.value!==void 0?e.value:n.default?.[0]?.json,query:typeof e.query=="string"?e.query:void 0,input:n.default??[],signal:t.signal})}}},dn=async(n,e,t)=>{let r=R(t.host,"subworkflow");if(!r.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:n.default?.[0]?.json;return{outputs:{default:await r.runSubworkflow({workflowId:A(e,"workflowId","subworkflow"),callerWorkflowId:t.workflowId,projectId:typeof e.projectId=="string"&&e.projectId?e.projectId:void 0,payload:o,input:n.default??[],signal:t.signal})}}},un=async(n,e,t)=>{let r=R(t.host,"approval");if(!r.approval)throw new Error('Node kind "approval" requires an ExecutorHost with approval');let o=await r.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:n.default??[],signal:t.signal});if(!o.approved)throw new Error(`approval node "${t.nodeId}" denied${o.note?`: ${o.note}`:""} (${o.decidedAt})`);return{outputs:{default:[...n.default??[],{json:{approved:!0,decidedAt:o.decidedAt,...o.note?{note:o.note}:{}}}]}}},ce={agent:Xr,agentBinding:Zr,modelBinding:en,tool:tn,http:rn,mcp:nn,channel:on,skill:sn,memory:an,subworkflow:dn,approval:un},cn=Object.keys(ce);function ln(n){if(n.body!==void 0)return n.body;if(n.sendBody!==!0)return;let e=Et(n.bodyParameters);if(e.length!==0)return Object.fromEntries(e)}function fn(n){let e={};if(n.headers&&typeof n.headers=="object"&&!Array.isArray(n.headers))for(let[t,r]of Object.entries(n.headers))typeof r=="string"&&(e[t]=r);for(let[t,r]of Et(n.headerParameters))e[t]=String(r);return Object.keys(e).length>0?e:void 0}function Et(n){let e=n&&typeof n=="object"&&!Array.isArray(n)?n.parameters:void 0;if(!Array.isArray(e))return[];let t=[];for(let r of e){if(!r||typeof r!="object")continue;let o=r;typeof o.name!="string"||!o.name||t.push([o.name,o.value??""])}return t}function Rt(n,e,t,r){let o=pn(n.prompt,n.text,n.message,n.input);if(!o)throw new Error(`Node kind "${r}" requires a prompt/text parameter`);return gn(o,{json:e[0]?.json??{},input:{default:e},vars:t.vars,trigger:t.trigger,now:t.now})}function gn(n,e){let t=n.startsWith("=")?n.slice(1):n;return t.includes("{{")?String(I(t,e)):t}function pn(...n){for(let e of n)if(typeof e=="string"&&e.trim())return e}function mn(n){let e=n.model??n.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 xt(n){let e=typeof n=="number"?n:typeof n=="string"?Number(n):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(ce);for(let r of e.nodes)this.nodeDefs.set(r.id,r);for(let r of e.edges)r.loopBack&&this.loopBackOf.set(r.from,r.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 r=this.nodeDefs.get(e);if(!r)throw new Error(`Unknown node "${e}"`);r.params={...r.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 r={};for(let[i,s]of this.nodeOutputs)r[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:r,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,r])=>({key:t,result:r}));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 r=this.collectInputs(e.id),o=this.buildExprContext(r),i=this.nodeDefs.get(e.id)?.params??{},s=kt[e.kind]??[],a=s.includes("*"),u=a?{}:s.length>0?Object.fromEntries(Object.entries(i).filter(([m])=>!s.includes(m))):i,l={...ht(u,o),...a?i:Object.fromEntries(s.filter(m=>m in i).map(m=>[m,i[m]]))},d=this.cacheKey(e.kind,l,r,e.runIndex),f=Date.now(),c=0,g=(m,O)=>{let J=Date.now();this.nodeStats[e.id]={seq:++this.statsSeq,startedAt:new Date(f).toISOString(),finishedAt:new Date(J).toISOString(),durationMs:J-f,attempts:c,cacheHit:O,status:m}},p=this.cache.get(d),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),J=Math.max(0,m?.retry?.backoffMs??1e3),he=m?.timeoutMs,P;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:he!==void 0&&he>0?AbortSignal.any([this.signal,AbortSignal.timeout(he)]):this.signal};try{p=await this.registry.get(e.kind)(r,l,M),P=void 0;break}catch(K){if(this.isCanceled())throw this.canceledError(K);P=K;let Le=S+1<O;this.log?.warn(`node "${e.id}" attempt ${S+1}/${O} failed: ${K instanceof Error?K.message:String(K)}`+(Le?` \u2014 retrying in ${J*2**S}ms`:"")),Le&&await this.cancellableDelay(J*2**S)}}if(P!==void 0){let S=m?.onError??"stop",M=P instanceof Error?P.message:String(P);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),P&&typeof P=="object"&&!P.nodeId&&(P.nodeId=e.id),P}this.throwIfCanceled(),w?t.add(e.id):(this.cache.set(d,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 r=this.dag.getNode(e);this.surfaceLoopCap(r);let o=r.firedPorts??[];this.nodeOutputs.set(e,{loop:o.includes("loop")?[{json:{iteration:r.iteration??0}}]:[],done:o.includes("done")?[{json:{iteration:r.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 r=this.nodeStats[e.id],o=new Date().toISOString();this.nodeStats[e.id]=r?{...r,warning:t}:{seq:++this.statsSeq,startedAt:o,finishedAt:o,durationMs:0,attempts:0,cacheHit:!1,status:"completed",warning:t}}evalLoopCondition(e){let r=this.nodeDefs.get(e)?.params?.condition;if(r==null||r==="")return!0;let o=this.buildExprContext({});return!!(typeof r=="string"?I(r,o):r)}collectInputs(e){let t={};for(let r of this.def.edges){if(r.to!==e||r.loopBack)continue;let o=r.fromPort??"default",i=r.toPort??"default",s=this.nodeOutputs.get(r.from);if(!s)continue;let a=s[o];a&&(t[i]??=[]).push(...a)}return t}buildExprContext(e){let t={};for(let[r,o]of this.nodeOutputs)t[r]={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,r,o){return Pe([e,t,lt(r),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,r)=>{let o=setTimeout(()=>{this.signal.removeEventListener("abort",i),t()},e),i=()=>{clearTimeout(o),r(this.canceledError())};this.signal.addEventListener("abort",i,{once:!0})})}buildDag(){let e=this.def.nodes.map(r=>{let o=r.outPorts??hn(r.kind);return r.onError==="errorPort"&&!o.includes("error")&&(o=[...o,"error"]),{id:r.id,kind:r.kind,params:r.params??{},outPorts:o,joinPolicy:r.joinPolicy??"all",maxIterations:r.maxIterations}}),t=new q(e);for(let r of this.def.edges)r.loopBack||t.addEdge({from:r.from,to:r.to,fromPort:r.fromPort??"default"});for(let r of this.def.edges)r.loopBack&&t.addEdge({from:r.from,to:r.to,loopBack:!0});return t}};function hn(n){return n==="if"?["true","false"]:n==="loop"?["loop","done"]:["default"]}var wn=new Set(["agent","tool","http","mcp","channel","im"]);var Se=class extends Error{constructor(t,r,o){super(`Permission denied: node "${t}" (kind "${r}") may not run under unattended trigger "${o}". Authorize it by adding "${r}" to allowUnattendedKinds.`);this.nodeId=t;this.kind=r;this.trigger=o;this.name="WorkflowPermissionDenied"}nodeId;kind;trigger},le=class extends U{constructor(t,r,o){super(t);this.reason=r;this.limit=o;this.name="WorkflowBudgetExceeded",this.message=`Budget exceeded (${r} limit ${o}) before node "${t}"`}reason;limit},fe=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 ue(this.trigger)}check(e,t){if(this.unattended&&wn.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 le(e,"duration",this.maxDurationMs);if(this.executions>=this.maxNodeExecutions)throw new le(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 jt(n){switch(n.type){case"manual":return[];case"schedule":return xn(n.cron);case"im-message":return Rn(n.channel,n.match);case"webhook":return In(n.path);case"intent":return kn(n.phrases,n.aliases,n.surfaces);case"form":return vn(n.fields);default:return[`unknown trigger type: ${JSON.stringify(n)}`]}}var yn=new Set(["welcome","chat"]);function kn(n,e,t){let r=[];if(!Array.isArray(n)||n.length===0)r.push("intent.phrases must be a non-empty array of trigger phrases");else for(let o of n)(typeof o!="string"||o.trim()==="")&&r.push(`intent.phrases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(e!==void 0)if(!Array.isArray(e))r.push("intent.aliases must be an array when present");else for(let o of e)(typeof o!="string"||o.trim()==="")&&r.push(`intent.aliases entries must be non-empty strings, got ${JSON.stringify(o)}`);if(t!==void 0)if(!Array.isArray(t)||t.length===0)r.push("intent.surfaces must be a non-empty array when present");else for(let o of t)(typeof o!="string"||!yn.has(o))&&r.push(`intent.surfaces entries must be "welcome"|"chat", got ${JSON.stringify(o)}`);return r}var bn=new Set(["text","number","select"]);function vn(n){let e=[];if(!Array.isArray(n)||n.length===0)return["form.fields must be a non-empty array"];let t=new Set;for(let r of n){if(typeof r?.key!="string"||!/^[\w-]+$/.test(r.key)){e.push(`form field key must be a [\\w-]+ string, got ${JSON.stringify(r?.key)}`);continue}t.has(r.key)&&e.push(`duplicate form field key "${r.key}"`),t.add(r.key),r.type!==void 0&&(typeof r.type!="string"||!bn.has(r.type))&&e.push(`form field "${r.key}": type must be text|number|select`),r.type==="select"&&(!Array.isArray(r.options)||r.options.length===0)&&e.push(`form field "${r.key}": select requires non-empty options`)}return e}var It=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],St=["SUN","MON","TUE","WED","THU","FRI","SAT"];function xn(n){if(typeof n!="string"||n.trim()==="")return["schedule.cron must be a non-empty string"];let e=n.trim().split(/\s+/);if(e.length!==5&&e.length!==6)return[`schedule.cron must have 5 or 6 fields, got ${e.length}: "${n}"`];let r=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:It},{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:It},{label:"day-of-week",min:0,max:7,names:St}],o=[];for(let i=0;i<r.length;i++){let s=Pn(e[i],r[i]);s&&o.push(`schedule.cron ${s}`)}return o}function Pn(n,e){for(let t of n.split(",")){let r=En(t,e);if(r)return r}}function En(n,e){if(n==="")return`${e.label} has an empty list element`;let t=n,r,o=n.indexOf("/");if(o!==-1&&(t=n.slice(0,o),r=n.slice(o+1),!/^\d+$/.test(r)||Number(r)<=0))return`${e.label} has an invalid step "/${r}"`;if(t==="*")return;let i=t.indexOf("-");if(i!==-1){let a=je(t.slice(0,i),e),u=je(t.slice(i+1),e);return a===void 0||u===void 0?`${e.label} has an invalid range "${t}"`:a>u?`${e.label} range "${t}" is descending`:void 0}if(t===""&&r!==void 0)return`${e.label} step "${n}" needs a base ("*" or a range)`;if(je(t,e)===void 0)return`${e.label} value "${t}" is out of range ${e.min}-${e.max}`}function je(n,e){let t;if(/^\d+$/.test(n))t=Number(n);else if(e.names){let r=e.names.indexOf(n.toUpperCase());if(r===-1)return;t=e.label==="month"?r+1:r}else return;if(!(t<e.min||t>e.max))return t}function Rn(n,e){let t=[];if((typeof n!="string"||n.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(r){t.push(`im-message.match is not a valid regex: ${r.message}`)}return t}function In(n){return typeof n!="string"||n===""?["webhook.path must be a non-empty string"]:n.startsWith("/")?/\s/.test(n)?[`webhook.path must not contain whitespace: "${n}"`]:n.includes("..")?[`webhook.path must not contain "..": "${n}"`]:/^\/[A-Za-z0-9\-._~/]*$/.test(n)?[]:[`webhook.path contains illegal characters: "${n}"`]:[`webhook.path must start with "/": "${n}"`]}var v=class extends Error{constructor(t){super(`Patch rejected: ${t.join("; ")}`);this.errors=t;this.name="PatchError"}errors};function Ae(n,e){let t=[],r=An(n),o=new Map(r.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),u=[];for(let[l,d]of e.patch.entries()){let f=`op[${l}] ${d.op}`;switch(d.op){case"add_node":{d.node?.id?o.has(d.node.id)?t.push(`${f}: node "${d.node.id}" already exists`):(r.def.nodes.push(d.node),o.set(d.node.id,d.node),i&&s.add(d.node.id)):t.push(`${f}: node.id is required`);break}case"remove_node":{o.has(d.nodeId)?a(d.nodeId)?(r.def.nodes=r.def.nodes.filter(c=>c.id!==d.nodeId),o.delete(d.nodeId),r.def.edges=r.def.edges.filter(c=>c.from!==d.nodeId&&c.to!==d.nodeId)):t.push(`${f}: node "${d.nodeId}" is outside the edit scope`):t.push(`${f}: node "${d.nodeId}" not found`);break}case"update_params":{let c=o.get(d.nodeId);c?a(d.nodeId)?c.params=Sn(c.params,d.params):t.push(`${f}: node "${d.nodeId}" is outside the edit scope`):t.push(`${f}: node "${d.nodeId}" not found`);break}case"rename_node":{let c=o.get(d.nodeId);c?a(d.nodeId)?c.name=d.name:t.push(`${f}: node "${d.nodeId}" is outside the edit scope`):t.push(`${f}: node "${d.nodeId}" not found`);break}case"set_node_options":{let c=o.get(d.nodeId);if(!c){t.push(`${f}: node "${d.nodeId}" not found`);break}if(!a(d.nodeId)){t.push(`${f}: node "${d.nodeId}" is outside the edit scope`);break}d.retry!==void 0&&(d.retry===null?delete c.retry:!Number.isInteger(d.retry.maxTries)||d.retry.maxTries<1||d.retry.maxTries>10?t.push(`${f}: retry.maxTries must be an integer 1..10`):d.retry.backoffMs!==void 0&&(!Number.isFinite(d.retry.backoffMs)||d.retry.backoffMs<0)?t.push(`${f}: retry.backoffMs must be a non-negative number`):c.retry={maxTries:d.retry.maxTries,...d.retry.backoffMs!==void 0?{backoffMs:d.retry.backoffMs}:{}}),d.timeoutMs!==void 0&&(d.timeoutMs===null?delete c.timeoutMs:!Number.isFinite(d.timeoutMs)||d.timeoutMs<=0?t.push(`${f}: timeoutMs must be a positive number`):c.timeoutMs=d.timeoutMs),d.onError!==void 0&&(d.onError===null?delete c.onError:d.onError!=="stop"&&d.onError!=="continue"&&d.onError!=="errorPort"?t.push(`${f}: onError must be "stop"|"continue"|"errorPort"`):c.onError=d.onError);break}case"set_node_ui":{if(!d.positions||typeof d.positions!="object"){t.push(`${f}: positions is required`);break}for(let[c,g]of Object.entries(d.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=d.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(r.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(!vt(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}r.def.edges.push(c);break}case"remove_edge":{let{from:c,to:g,fromPort:p}=d.edge;if(i&&!a(c)&&!a(g))t.push(`${f}: edge ${c}\u2192${g} has no endpoint in the edit scope`);else{let h=r.def.edges.length;r.def.edges=r.def.edges.filter(w=>!(w.from===c&&w.to===g&&(w.fromPort??"default")===(p??"default"))),r.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(d.trigger){let c=jt(d.trigger);if(c.length>0)for(let g of c)t.push(`${f}: ${g}`);else r.meta.trigger=d.trigger}else r.meta.trigger=d.trigger;break}case"set_meta":{i?t.push(`${f}: meta is workflow-global and cannot be changed in a scoped edit`):(d.meta.name!==void 0&&(r.meta.name=d.meta.name),d.meta.active!==void 0&&(r.meta.active=d.meta.active));break}default:t.push(`${f}: unknown op`)}t.length===0&&u.push(d)}if(t.length>0)throw new v(t);if(Nt(r.def,t),At(r.def,t),t.length>0)throw new v(t);return{target:r,applied:u}}function Sn(n,e){let t={...n??{}};for(let[r,o]of Object.entries(e))o===null?delete t[r]:t[r]=o;return t}function Q(n){let e=[];return Nt(n,e),At(n,e),e}function At(n,e){let t=(r,o,i)=>{if(typeof r=="string"){if(r.startsWith("="))return;for(let s of r.matchAll(/\{\{([\s\S]*?)\}\}/g)){let a=ae(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(r)){r.forEach((s,a)=>t(s,o,`${i}[${a}]`));return}if(r&&typeof r=="object")for(let[s,a]of Object.entries(r))t(a,o,i?`${i}.${s}`:s)};for(let r of n.nodes)r.params?._importMode!=="n8n-strict-template"&&r.params&&t(r.params,r.id,"")}function Nt(n,e){try{let t=n.nodes.map(o=>{let i=o.outPorts??jn(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}}),r=new q(t);for(let o of n.edges)o.loopBack||r.addEdge({from:o.from,to:o.to,fromPort:o.fromPort??"default"});for(let o of n.edges)o.loopBack&&r.addEdge({from:o.from,to:o.to,loopBack:!0})}catch(t){e.push(`graph invalid: ${t.message}`)}}function jn(n){return n==="if"?["true","false"]:n==="loop"?["loop","done"]:["default"]}function An(n){return{def:{...n.def,nodes:n.def.nodes.map(e=>({...e,params:e.params?{...e.params}:void 0})),edges:n.def.edges.map(e=>({...e})),vars:n.def.vars?{...n.def.vars}:void 0},meta:{...n.meta}}}function Ne(n,e={}){let t=e.maxNodes??50,r=e.maxValueLen??60,o=`Workflow ${JSON.stringify(n.name)} (rev ${n.rev}, trigger: ${Nn(n.trigger)}, ${n.active?"active":"inactive"})`,i=n.def.nodes,a=i.slice(0,t).map(f=>" "+$n(f,r)),u=i.length===0?"nodes: (none)":["nodes:",...a].join(`
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(`
3
3
  `),l=i.length>t?`
4
- \u2026 ${i.length-t} more node(s); call workflow.get for the full definition`:"",d=Tn(n.def.edges);return`${o}
5
- ${u}${l}
6
- ${d}`}function Nn(n){if(!n)return"none";switch(n.type){case"manual":return"manual";case"schedule":return`schedule ${JSON.stringify(n.cron)}`;case"im-message":return n.match?`im-message ${n.channel} match=${JSON.stringify(n.match)}`:`im-message ${n.channel}`;case"webhook":return`webhook ${n.path}`;case"intent":return`intent ${n.phrases.map(e=>JSON.stringify(e)).join(" / ")}${n.semantic?" +semantic":""}`;case"form":return`form [${n.fields.map(e=>e.key).join(", ")}]`}}function $n(n,e){let t=n.name?` "${n.name}"`:"",r=Dn(n.params,e),o=(n.outPorts??Wn(n.kind)).join(","),i=[`${n.id} [${n.kind}]${t}`];return r&&i.push(r),i.push(`out: ${o}`),i.join(" ")}function Dn(n,e){if(!n)return"";let t=Object.keys(n).sort();return t.length===0?"":t.map(r=>`${r}=${Cn(n[r],e)}`).join(" ")}function Cn(n,e){let t;return typeof n=="string"?t=n.includes("{{")?n:JSON.stringify(n):t=JSON.stringify(n),t.length>e&&(t=t.slice(0,e-1)+"\u2026"),t}function Tn(n){return n.length===0?"edges: (none)":`edges:
7
- ${n.map(t=>{let r=t.fromPort??"default",o=t.toPort??"default",i=t.loopBack?" (loopBack)":"";return`${t.from}.${r}\u2192${t.to}.${o}${i}`}).join(" ; ")}`}function Wn(n){return n==="if"?["true","false"]:n==="loop"?["loop","done"]:["default"]}function On(n){let e=[],t=n;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 Mn(n){if(!n.startsWith("="))return null;let e=n.slice(1);if(!e.includes("{{"))return{ok:!0,converted:e,notes:[]};let t=[],r=null,o=e.replace(/\{\{([\s\S]*?)\}\}/g,(i,s)=>{if(r)return i;let{body:a,notes:u}=On(s.trim()),l=ae(a);return l?(r=`\u8868\u8FBE\u5F0F\u300C{{ ${s.trim()} }}\u300D\u8D85\u51FA\u53D7\u9650\u8BED\u8A00(${l})`,i):(t.push(...u),`{{ ${a} }}`)});return r?{ok:!1,reason:r}:{ok:!0,converted:o,notes:t}}function $t(n,e,t=""){let r=(o,i)=>{if(typeof o=="string"){let s=Mn(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)=>r(s,`${i}[${a}]`)):o&&typeof o=="object"?Object.fromEntries(Object.entries(o).map(([s,a])=>[s,r(a,i?`${i}.${s}`:s)])):o};return r(n,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"},_n=new Set(["openAiApi","googlePalmApi","openRouterApi","mistralCloudApi","anthropicApi"]),Hn=new Set(["agentBinding"]);function Ct(n){return _n.has(n)}function Tt(n){return Hn.has(n)}function Wt(n){return"workflow"}function Ot(n,e){let t=`${n} ${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 Mt={"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"},qn={httpBasicAuth:"basic",httpBearerAuth:"bearer",httpHeaderAuth:"custom",httpQueryAuth:"custom",oAuth2Api:"oauth2",httpCustomAuth:"custom"},Bn=new Set(["n8n-nodes-base.stickyNote"]),Un=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 _t(n,e,t={}){let r=Kn(n),o=t.strictTemplates===!0,i=[],s={status:"full",nodes:[],expressions:{converted:0,manual:[]},credentials:[],bindings:{models:[],agents:[],connections:[]},notes:[]},a=new Set,u=new Set,l=[];for(let[f,c]of r.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(Bn.has(c.type)){u.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=Fn(c.type,o);Un.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);Jn(c,p,s,o),o&&Tt(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]}),Ln(x,p,g,o),l.push(x)}let d=r.connections?Gn(r.connections,a,u,l,i,o):[];if(o&&Yn(d,l),zn(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 r.name=="string"&&r.name!==""?r.name:e,def:{id:e,nodes:l,edges:d},report:s}}function Fn(n,e){return e?Dt[n]??Mt[n]??"n8nNode":Mt[n]}function Ln(n,e,t,r){let o=n.params;if(e==="if"){n.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)):r||(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")):r||(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push("subworkflow target is missing"));return}(e==="switch"||e==="filter")&&!r&&(t.outcome=t.outcome==="manual"?"manual":"partial",t.notes.push(`${e} conditions preserve n8n params and may need review`))}function Jn(n,e,t,r){if(!(!n.credentials||typeof n.credentials!="object")){for(let[o,i]of Object.entries(n.credentials)){if(r&&Ct(o)){t.bindings.models.push({nodeId:n.name,n8nCredentialType:o,modelPurpose:Wt(o),label:i?.name});continue}let s=Ot(n.type,o);r&&t.bindings.connections.push({nodeId:n.name,n8nCredentialType:o,connectionType:s,label:i?.name}),t.credentials.push({nodeId:n.name,n8nCredentialType:o,label:i?.name,suggestedVaultType:qn[o]??s??"custom"})}r&&e==="modelBinding"&&t.bindings.models.push({nodeId:n.name,n8nCredentialType:"model-registry",modelPurpose:"workflow"})}}function Kn(n){let e;if(typeof n=="string")try{e=JSON.parse(n)}catch(r){throw new W([`invalid JSON: ${r.message}`])}else e=n;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 Gn(n,e,t,r,o,i){let s=new Map(r.map(u=>[u.id,u.kind])),a=[];for(let u of Object.keys(n).sort()){if(t.has(u))continue;if(!e.has(u)){o.push(`connection source "${u}" is not a declared node`);continue}let l=n[u]??{};for(let d of Object.keys(l).sort()){let f=l[d];if(Array.isArray(f))for(let c=0;c<f.length;c++){let g=Vn(u,s.get(u),d,c,r,o,i),p=f[c];if(Array.isArray(p))for(let h of p){if(!h||typeof h.node!="string"){o.push(`connection from "${u}" has a malformed target`);continue}if(t.has(h.node))continue;if(!e.has(h.node)){o.push(`connection from "${u}" targets missing node "${h.node}"`);continue}let w={from:u,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 Vn(n,e,t,r,o,i,s){return t!=="main"?T(o,n,r===0?t:`${t}_${r}`):e==="if"?r===0?"true":r===1?"false":(s||i.push(`if node "${n}" has an unsupported output index ${r}`),T(o,n,`out_${r}`)):e==="switch"?T(o,n,`case_${r}`):e==="filter"?r===0?T(o,n,"default"):(s||i.push(`filter node "${n}" has an unsupported discarded output`),T(o,n,r===1?"discarded":`out_${r}`)):r===0?T(o,n,"default"):(s||i.push(`node "${n}" has an unmodeled multi-output index ${r} (only single-output supported)`),T(o,n,`out_${r}`))}function T(n,e,t){let r=n.find(o=>o.id===e);return r&&(r.outPorts=r.outPorts??[],r.outPorts.includes(t)||r.outPorts.push(t)),t}function zn(n){for(let e of n)e.outPorts&&e.outPorts.length>0&&(e.params={...e.params??{},_n8nOutPorts:e.outPorts})}function Yn(n,e){let t=[];for(let r of n)if(Qn(t,r.to,r.from)){r.loopBack=!0;let o=e.find(i=>i.id===r.to);o&&(!o.maxIterations||o.maxIterations<=0)&&(o.maxIterations=100)}else t.push(r)}function Qn(n,e,t){let r=[e],o=new Set;for(;r.length>0;){let i=r.pop();if(i===t)return!0;if(!o.has(i)){o.add(i);for(let s of n)s.from===i&&r.push(s.to)}}return!1}import{join as Ut}from"node:path";import{mkdir as Xn}from"node:fs/promises";function ge(n,...e){let t=n.toLowerCase();return e.some(r=>t.includes(r.toLowerCase()))}function Ht(n,e){let t=(n??"").trim(),r=t.length>300?`${t.slice(0,300)}\u2026`:t||void 0;return ge(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:r}:ge(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:r}:ge(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:r}:ge(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:r}:{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:r}}var Zn=20,qt=2e3;function Bt(n,e){return Ut(j(n),e,"runs","history.json")}function De(n){let e={};for(let[t,r]of Object.entries(n.outputs)){let o={};for(let[a,u]of Object.entries(r))o[a]=u.map(l=>l.json);let i=JSON.stringify(o);i.length>qt&&(i=`${i.slice(0,qt)}\u2026(truncated)`);let s=n.nodeStats?.[t];e[t]={executed:n.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 r=await this.read(e);r.unshift({...t,status:"running"}),await this.write(e,r.slice(0,Zn))}async finish(e,t,r){let o=await this.read(e),i=o.find(s=>s.runId===t);i&&(Object.assign(i,r),i.errorInfo=i.status==="failed"&&i.error?Ht(i.error):void 0,await this.write(e,o))}async list(e){return(await this.read(e)).map(({nodes:t,...r})=>r)}async get(e,t){return(await this.read(e)).find(r=>r.runId===t)}async read(e){try{let t=await D(Bt(this.cwd,e));return Array.isArray(t)?t:[]}catch{return[]}}async write(e,t){let r=Bt(this.cwd,e);await Xn(Ut(j(this.cwd),e,"runs"),{recursive:!0}),await C(r,t)}};import{randomUUID as eo}from"node:crypto";var Ce=class{constructor(e,t,r){this.store=e;this.runtimeFactory=t;this.runHistory=r}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 r=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:r,updatedAt:r};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 r=await this.store.require(e);if(!r.publishedDef)throw new Error(`Workflow "${e}" has no published version \u2014 publish the draft before activating`);if(r.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 r=Q(t.def);if(r.length>0)throw new v(r);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 r=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={...r,def:o.def,name:o.name,trigger:o.trigger??null,rev:r.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(s),s}async importN8n(e,t,r={}){let{name:o,def:i,report:s}=_t(t,e,{strictTemplates:!0});return{record:await this.create({id:e,name:o,def:i,concurrency:r.concurrency,owner:r.owner}),report:s}}async get(e){return this.store.require(e)}async describe(e,t){let r=await this.store.require(e);return Ne(r,t)}async patch(e,t){let r=await this.store.require(e),o=t.baseRev!==void 0&&t.baseRev<r.rev,i={def:r.def,meta:{name:r.name,active:r.active,trigger:r.trigger??null}},s,a;try{let d=Ae(i,t);s=d.applied,a=d.target}catch(d){if(o&&d instanceof v)return{ok:!1,conflict:{latestRev:r.rev}};throw d}if(a.meta.active===!0&&!r.active&&!r.publishedDef)throw new v([`workflow "${e}" has no published version \u2014 publish the draft before activating (set_meta.active)`]);let l={...r,def:a.def,name:a.meta.name??r.name,active:a.meta.active??r.active,trigger:a.meta.trigger??null,rev:r.rev+1,updatedAt:new Date().toISOString()};return await this.store.save(l),{ok:!0,rev:l.rev,applied:s}}async run(e,t,r={}){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 u={workflowId:e,runId:eo(),type:i,payload:t?.payload,permissionScope:o.permissionScope,reuseCache:r.reuseCache===!0},l=this.slotFor(e),d=()=>{if(l.pending>0)switch(o.concurrency){case"skip":return Promise.resolve({workflowId:e,status:"skipped"});case"parallel":return this.startParallel(e,a,u);case"queue":return this.track(e,l,a,u,!0)}return this.track(e,l,a,u,!1)};return this.recordRun(e,u,d,r.recordHistory===!1)}async recordRun(e,t,r,o=!1){let i=Date.now();if(!this.runHistory||o)try{let a=await r();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 r();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 r=this.requireActiveRun(e,t.runId);if(r.status!=="paused")throw new Error(`Workflow "${e}" run "${r.runId}" is not paused`);t.extraBudget&&r.runtime.extendBudget(t.extraBudget),r.status="running";let o=this.slotFor(e);o.pending++;let i=r.runtime.run().then(async s=>{let a={workflowId:e,runId:r.runId,status:s.status,result:s};return s.status==="paused"?r.status="paused":this.unregisterActiveRun(r.runId),await this.finishRunHistory(e,r.runId,r.startedAtMs,{status:a.status,nodes:De(s)}),a}).catch(async s=>{if(this.unregisterActiveRun(r.runId),s instanceof b)return await this.finishRunHistory(e,r.runId,r.startedAtMs,{status:"canceled",error:s.message}),{workflowId:e,runId:r.runId,status:"canceled"};throw await this.finishRunHistory(e,r.runId,r.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 r=this.requireActiveRun(e,t.runId),o=t.reason??`Workflow "${e}" run "${r.runId}" canceled`,i=new b(o);return r.runtime.cancel(o),r.abortController.signal.aborted||r.abortController.abort(i),this.unregisterActiveRun(r.runId),r.status==="paused"&&await this.finishRunHistory(e,r.runId,r.startedAtMs,{status:"canceled",error:o}),{workflowId:e,runId:r.runId,status:"canceled"}}async delete(e){let t=[...this.activeRunIdsByWorkflow.get(e)??[]];for(let r of t)this.suppressedHistoryRunIds.add(r),await this.cancelRun(e,{runId:r,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 r=this.activeRunIdsByWorkflow.get(t.workflowId);r&&(r.delete(e),r.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 r=[...this.activeRunIdsByWorkflow.get(e)??[]],o=this.slots.get(e)?.latestRunId;if(o&&r.includes(o))return this.activeRuns.get(o);let i=r.at(-1);if(!i)throw new Error(`Workflow "${e}" has no active run`);return this.activeRuns.get(i)}async finishRunHistory(e,t,r,o){!this.runHistory||this.suppressedHistoryRunIds.has(t)||await this.runHistory.finish(e,t,{finishedAt:new Date().toISOString(),durationMs:Date.now()-r,...o}).catch(()=>{})}track(e,t,r,o,i){t.pending++;let s=()=>this.startTrackedRuntime(e,t,r,o),u=(i?t.tail.then(s):s()).finally(()=>{t.pending--});return t.tail=u.catch(()=>{}),u}async startParallel(e,t,r){return this.startTrackedRuntime(e,void 0,t,r)}async startTrackedRuntime(e,t,r,o){let i=new AbortController,s=this.runtimeFactory(r,{...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 u=await s.run(),l={workflowId:e,runId:o.runId,status:u.status,result:u};return u.status==="paused"?a.status="paused":this.unregisterActiveRun(o.runId),l}catch(u){throw this.unregisterActiveRun(o.runId),u}}};function to(n){return(e,t)=>new Y(e,{registry:n.registry,host:n.host,signal:t.signal,checkpoint:n.checkpoint?.(t.workflowId,t.reuseCache?"shared-cache":t.runId),preserveCheckpoint:t.reuseCache===!0,trigger:t.payload,triggerKind:t.type,now:n.now,onNodeStatus:n.emitNodeStatus?(r,o,i)=>n.emitNodeStatus(t.workflowId,r,o,i):void 0,gate:new fe({trigger:t.type,maxNodeExecutions:n.budget.maxNodeExecutions,maxDurationMs:n.budget.maxDurationMs,allowUnattendedKinds:t.permissionScope?.allowUnattendedKinds??n.allowUnattendedKinds,now:n.now?()=>n.now().getTime():void 0})})}function ro(n){let e=n.content??[],t=a=>a.type==="text"&&typeof a.text=="string",r=e.filter(t).map(a=>a.text).join(`
8
- `),o=e.filter(a=>!t(a));if(o.length===0)return r;let i=[...new Set(o.map(a=>a.type??"unknown"))].join(", "),s=`[${o.length} non-text block${o.length===1?"":"s"} omitted (${i})]`;return r?`${r}
9
- ${s}`:s}function no(n){let e=n.findTool,t=n.fetchImpl??fetch;return{async runAgent(r){let o=await n.runAgent({agentId:r.agentId,prompt:r.prompt,signal:r.signal});return[$({text:o,output:o})]},async runModel(r){if(!n.resolveClientForPurpose)throw new Error("workflow model node: no configured model resolver is wired");let o=n.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:r.prompt}],temperature:r.temperature,maxTokens:r.maxTokens,tools:[]},o.apiKey,r.signal))if(s.type==="delta"&&(i+=s.text),s.type==="error")throw new Error(s.message);return[$({text:i,output:i,model:o.model,...r.modelHint?{importedModel:r.modelHint}:{},choices:[{text:i}]})]},async invokeTool(r){let o=e(r.tool);if(!o)throw new Error(`workflow tool node: no qlogicagent tool named "${r.tool}"`);if(!o.execute)throw new Error(`workflow tool node: qlogicagent tool "${r.tool}" is not executable`);let i=r.args;if(n.workspaceCwd&&r.tool==="exec"){let u=i.workdir;(u==null||u==="")&&(i={...i,workdir:n.workspaceCwd})}r.unattended&&n.auditUnattendedTool&&n.auditUnattendedTool({...r,args:i});let s=`wf_${r.tool}_${Date.now().toString(36)}`,a=await o.execute(s,i,r.signal);return[$({result:ro(a),details:a.details??null})]},async httpRequest(r){let o=r.headers;if(r.credentialId){if(!n.resolveCredentialHeaders)throw new Error(`workflow http node: credentialId "${r.credentialId}" set but no credential vault is wired`);o={...o,...n.resolveCredentialHeaders(r.credentialId)}}let i=await t(r.url,{method:r.method||"GET",headers:o,body:r.body===void 0?void 0:typeof r.body=="string"?r.body:JSON.stringify(r.body),signal:r.signal}),s=i.headers.get("content-type")??"";if(s.includes("application/json")){let l=await i.text(),d=l;try{l.length>0&&(d=JSON.parse(l))}catch{d={__unparsedJson:l}}return[$({status:i.status,ok:i.ok,body:d})]}let a=Buffer.from(await i.arrayBuffer()),u=oo(i.headers.get("content-disposition"));return[$({status:i.status,ok:i.ok,bodyBase64:a.toString("base64"),mimeType:s||"application/octet-stream",size:a.byteLength,...u?{filename:u}:{}})]},async invokeMcp(r){let o=await n.invokeMcp({server:r.server,tool:r.tool,args:r.args,signal:r.signal});return[$({result:o})]},async sendChannel(r){if(!n.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 n.sendChannel({channel:r.channel,target:r.target,payload:r.payload,signal:r.signal});return[$({sent:!0,result:o})]},async memory(r){if(!n.memory)throw new Error("workflow memory node: no memory backend injected (handler host wires the project memdir)");return n.memory(r)},async runSubworkflow(r){if(!n.runSubworkflow)throw new Error("workflow subworkflow node: no sub-run backend injected (handler host wires the controller)");return n.runSubworkflow(r)},async approval(r){if(!n.approval)throw new Error("workflow approval node: no approval backend injected (handler host wires the notify/await loop)");return n.approval(r)},async waitWebhook(r){if(!n.waitWebhook)throw new Error("workflow wait(until=webhook): no webhook-wait backend injected (handler host wires the wake registry)");return n.waitWebhook(r)}}}function oo(n){if(!n)return;let e=n.match(/filename\*=UTF-8''([^;]+)/i);if(e)return decodeURIComponent(e[1].trim().replace(/^"|"$/g,""));let t=n.match(/filename=([^;]+)/i);return t?t[1].trim().replace(/^"|"$/g,""):void 0}var Ft=["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"],Lt=["SUN","MON","TUE","WED","THU","FRI","SAT"];function io(n){if(typeof n!="string"||n.trim()==="")throw new Error("cron must be a non-empty string");let e=n.trim().split(/\s+/);if(e.length!==5&&e.length!==6)throw new Error(`cron must have 5 or 6 fields, got ${e.length}: "${n}"`);let t=e.length===6,r=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:Ft},{label:"day-of-week",min:0,max:7,names:Lt}]:[{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:Ft},{label:"day-of-week",min:0,max:7,names:Lt}],o=r.map((u,l)=>({spec:u,raw:e[l],set:so(e[l],r[l])})),i=u=>{let l=o.find(d=>d.spec.label===u);if(!l)throw new Error(`internal: missing cron field ${u}`);return l},s=i("day-of-week"),a=new Set;for(let u of s.set)a.add(u===7?0:u);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 so(n,e){let t=new Set;for(let r of n.split(","))ao(r,e,t);if(t.size===0)throw new Error(`cron ${e.label} expanded to an empty set: "${n}"`);return t}function ao(n,e,t){if(n==="")throw new Error(`cron ${e.label} has an empty list element`);let r=n,o=1,i=n.indexOf("/");if(i!==-1){r=n.slice(0,i);let u=n.slice(i+1);if(!/^\d+$/.test(u)||Number(u)<=0)throw new Error(`cron ${e.label} has an invalid step "/${u}"`);o=Number(u)}let s,a;if(r==="*")s=e.min,a=e.max;else{let u=r.indexOf("-");if(u!==-1){let l=Te(r.slice(0,u),e),d=Te(r.slice(u+1),e);if(l===void 0||d===void 0)throw new Error(`cron ${e.label} has an invalid range "${r}"`);if(l>d)throw new Error(`cron ${e.label} range "${r}" is descending`);s=l,a=d}else{let l=Te(r,e);if(l===void 0)throw new Error(`cron ${e.label} value "${r}" is out of range ${e.min}-${e.max}`);s=l,a=o===1?l:e.max}}for(let u=s;u<=a;u+=o)t.add(u)}function Te(n,e){let t;if(/^\d+$/.test(n))t=Number(n);else if(e.names){let r=e.names.indexOf(n.toUpperCase());if(r===-1)return;t=e.label==="month"?r+1:r}else return;if(!(t<e.min||t>e.max))return t}var uo=5*366+32;function We(n,e){let t=io(n),r=new Date(e);t.hasSeconds?(r.setUTCMilliseconds(0),r.setUTCSeconds(r.getUTCSeconds()+1)):(r.setUTCSeconds(0,0),r.setUTCMinutes(r.getUTCMinutes()+1));for(let o=0;o<uo;o++){if(!t.months.has(r.getUTCMonth()+1)){r.setUTCMonth(r.getUTCMonth()+1,1),r.setUTCHours(0,0,0,0);continue}if(!co(t,r)){r.setUTCDate(r.getUTCDate()+1),r.setUTCHours(0,0,0,0);continue}if(!t.hours.has(r.getUTCHours())){r.setUTCHours(r.getUTCHours()+1,0,0,0);continue}if(!t.minutes.has(r.getUTCMinutes())){r.setUTCMinutes(r.getUTCMinutes()+1,0,0);continue}if(t.hasSeconds&&!t.seconds.has(r.getUTCSeconds())){r.setUTCSeconds(r.getUTCSeconds()+1,0);continue}return r.getTime()}throw new Error(`cron "${n}" has no matching time within ~5 years of ${new Date(e).toISOString()}`)}function co(n,e){let t=n.doms.has(e.getUTCDate()),r=n.dows.has(e.getUTCDay());return n.domRestricted&&n.dowRestricted?t||r:n.domRestricted?t:n.dowRestricted?r:!0}var lo={now:()=>Date.now(),setTimer:(n,e)=>setTimeout(n,e),clearTimer:n=>clearTimeout(n)},Jt=2e9,Oe=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??lo,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 r=this.matchingIds(o=>o.type==="webhook"&&o.path===e).filter(o=>this.passesRateLimit(o,"webhook"));return Promise.all(r.map(o=>this.runWithLifecycle(o,{type:"webhook",payload:t})))}async onImMessage(e,t,r){let o=this.matchingIds(s=>s.type==="im-message"&&s.channel===e&&fo(s.match,t)).filter(s=>this.passesRateLimit(s,"im-message")),i={...r,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[r,o]of this.triggers)e(o)&&t.push(r);return t}registerTrigger(e,t){if(this.unregister(e),this.triggers.set(e,t),t.type==="schedule"){let r=We(t.cron,this.clock.now());this.armCron(e,t.cron,r)}}armCron(e,t,r){let o=Math.max(0,r-this.clock.now()),i={cron:t,fireAt:r,handle:void 0};o>Jt?i.handle=this.clock.setTimer(()=>{this.cronArms.get(e)===i&&this.armCron(e,t,r)},Jt):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 r;try{r=We(t.cron,t.fireAt)}catch(o){this.cronArms.delete(e),this.onError(o,e);return}this.armCron(e,t.cron,r),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 r=this.clock.now(),o=this.lastFireAt.get(e);return o!==void 0&&r-o<this.minTriggerIntervalMs?(this.onTriggerDropped?.(e,t,{sinceLastMs:r-o,minIntervalMs:this.minTriggerIntervalMs}),!1):(this.lastFireAt.set(e,r),!0)}async runWithLifecycle(e,t){this.onRunStarted?.(e,t.type);try{let r=await this.controller.run(e,t);return this.onRunCompleted?.(r,t.type),r}catch(r){throw this.onRunFailed?.(e,t.type,r),r}}};function fo(n,e){return n===void 0?!0:new RegExp(n).test(e)}import{createCipheriv as go,createDecipheriv as po,randomBytes as Kt,randomUUID as mo}from"node:crypto";import{existsSync as F,mkdirSync as Gt,readFileSync as Me,writeFileSync as _e,readdirSync as ho,rmSync as wo}from"node:fs";import{join as X}from"node:path";var Vt="aes-256-gcm",He=class{dir;constructor(e=_()){this.dir=X(e,"credentials")}keyPath(){return X(this.dir,".vault-key")}ensureKey(){F(this.dir)||Gt(this.dir,{recursive:!0});let e=this.keyPath();if(!F(e)){let t=Kt(32);return _e(e,t.toString("base64"),{mode:384}),t}return Buffer.from(Me(e,"utf-8").trim(),"base64")}encrypt(e){let t=this.ensureKey(),r=Kt(12),o=go(Vt,t,r),i=Buffer.concat([o.update(JSON.stringify(e),"utf-8"),o.final()]);return`${r.toString("base64")}.${o.getAuthTag().toString("base64")}.${i.toString("base64")}`}decrypt(e){let t=this.ensureKey(),[r,o,i]=e.split(".");if(!r||!o||!i)throw new Error("credential vault: malformed ciphertext envelope");let s=po(Vt,t,Buffer.from(r,"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 ho(this.dir))if(t.endsWith(".json"))try{let r=JSON.parse(Me(X(this.dir,t),"utf-8"));if(!r||typeof r!="object"||typeof r.id!="string"||typeof r.updatedAt!="string")throw new Error("malformed credential envelope");e.push({id:r.id,type:r.type,label:r.label,createdAt:r.createdAt,updatedAt:r.updatedAt,meta:r.meta})}catch(r){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: ${r instanceof Error?r.message:String(r)}`),e.push({id:o,type:"custom",label:`${o} (corrupted credential file - delete and re-create it)`,createdAt:"",updatedAt:"",corrupt:!0})}return e.sort((t,r)=>r.updatedAt.localeCompare(t.updatedAt))}create(e){zt(e.type,e.data);let t=e.id??`cred_${mo().slice(0,8)}`,r=new Date().toISOString(),o={id:t,type:e.type,label:e.label||t,createdAt:r,updatedAt:r,...e.meta?{meta:e.meta}:{},enc:this.encrypt(e.data)};return F(this.dir)||Gt(this.dir,{recursive:!0}),_e(this.filePath(t),JSON.stringify(o,null,2),{mode:384}),{id:t,type:o.type,label:o.label,createdAt:r,updatedAt:r,meta:o.meta}}get(e){let t=this.filePath(e);if(!F(t))throw new Error(`credential "${e}" not found`);let r=JSON.parse(Me(t,"utf-8"));return{summary:{id:r.id,type:r.type,label:r.label,createdAt:r.createdAt,updatedAt:r.updatedAt,meta:r.meta},data:this.decrypt(r.enc)}}delete(e){let t=this.filePath(e);return F(t)?(wo(t,{force:!0}),!0):!1}updateData(e,t,r){let{summary:o}=this.get(e);zt(o.type,t);let i=new Date().toISOString(),s=o.meta;if(r){s={...o.meta??{},...r};for(let l of Object.keys(s))s[l]===void 0&&delete s[l]}let a={...o,...s!==void 0?{meta:s}:{},updatedAt:i},u={...a,enc:this.encrypt(t)};return _e(this.filePath(e),JSON.stringify(u,null,2),{mode:384}),a}};function Z(n,e,t){if(typeof n[e]!="string"||!n[e])throw new Error(`credential(${t}): "${e}" is required`)}function zt(n,e){switch(n){case"apiKey":Z(e,"headerName",n),Z(e,"value",n);return;case"bearer":Z(e,"token",n);return;case"basic":Z(e,"username",n),Z(e,"password",n);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=n;throw new Error(`credential: unknown type ${JSON.stringify(t)}`)}}}function yo(n,e){switch(n){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=n;throw new Error(`credential: unknown type ${JSON.stringify(t)}`)}}}import{join as Yt}from"node:path";import{mkdir as ko,rm as bo}from"node:fs/promises";function vo(n,e,t){return Yt(ne().getProjectAgentDir(n),"workflows",e,"runs",t)}var qe=class{constructor(e,t,r){this.workflowId=t;this.runId=r;if(!e)throw new Error("FileRunCheckpoint requires a project cwd");if(!t)throw new Error("FileRunCheckpoint requires a workflowId");if(!r)throw new Error("FileRunCheckpoint requires a runId");this.dir=vo(e,t,r),this.file=Yt(this.dir,"cache.json")}workflowId;runId;dir;file;async load(){return D(this.file)}async persist(e){await ko(this.dir,{recursive:!0});let t={workflowId:this.workflowId,runId:this.runId,entries:e,updatedAt:new Date().toISOString()};await C(this.file,t)}async clear(){await bo(this.dir,{recursive:!0,force:!0})}};import*as L from"node:fs";import*as pe from"node:path";var Be=class{file;constructor(e){this.file=pe.join(e,"audit.jsonl")}append(e){try{L.mkdirSync(pe.dirname(this.file),{recursive:!0}),L.appendFileSync(this.file,`${JSON.stringify(e)}
4
+ \u2026 ${i.length-t} more node(s); call workflow.get for the full definition`:"",u=$r(r.def.edges);return`${o}
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)}
10
10
  `,"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 r;try{r=L.readFileSync(this.file,"utf8")}catch{return[]}let o=[];for(let i of r.split(`
11
+ `)}}list(e,t=100){let n;try{n=L.readFileSync(this.file,"utf8")}catch{return[]}let o=[];for(let i of n.split(`
12
12
  `))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 Ue=2,xo=/token|secret|authorization|api[-_]?key|apikey|password|credential|cookie|passphrase|private[-_]?key/i,Po="__CREDENTIAL_REQUIRED__";function me(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function Fe(n,e,t,r,o){if(Array.isArray(n))return n.map((s,a)=>Fe(s,`${e}[${a}]`,t,r,o));if(!me(n))return n;let i={};for(let[s,a]of Object.entries(n)){if(xo.test(s)&&a!==void 0&&a!==null&&a!==""){o.push({type:"custom",label:`${r} ${e}.${s}`,nodeIds:[t]}),i[s]=Po;continue}i[s]=Fe(a,`${e}.${s}`,t,r,o)}return i}function Eo(n){let e=new Map;for(let t of n){let r=e.get(t.label);if(r)for(let o of t.nodeIds)r.nodeIds.includes(o)||r.nodeIds.push(o);else e.set(t.label,{...t,nodeIds:[...t.nodeIds]})}return[...e.values()]}function Ro(n){return`\u8282\u70B9\u300C${n.name??n.id}\u300D`}function Io(n){let e=new Map,t=(r,o)=>{let i=`${r.category}:${r.ref}`,s=e.get(i);s?s.nodeIds.includes(o)||s.nodeIds.push(o):e.set(i,{...r,nodeIds:[o]})};for(let r of n.nodes){let o=r.params??{};switch(r.kind){case"agent":{let i=z(o.agentId);t({category:"agent",kind:"agent",ref:i,label:`Agent: ${i}`},r.id);break}case"tool":{let i=typeof o.tool=="string"?o.tool:"";i&&t({category:"tool",kind:"tool",ref:i,label:`\u5DE5\u5177: ${i}`},r.id);break}case"skill":{let i=typeof o.skill=="string"?o.skill:"";i&&t({category:"skill",kind:"skill",ref:i,label:`\u6280\u80FD: ${i}`},r.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}`:""}`},r.id);break}case"channel":{let i=typeof o.channel=="string"?o.channel:"";i&&t({category:"channel",kind:"channel",ref:i,label:`\u6E20\u9053: ${i}`},r.id);break}case"memory":{t({category:"memory",kind:"memory",ref:"memory",label:"\u8BB0\u5FC6\u8BFB\u5199"},r.id);break}default:break}}return[...e.values()]}function So(n){let e=[],t=n.def.nodes.map(o=>({...o,...o.params!==void 0?{params:Fe(o.params,"params",o.id,Ro(o),e)}:{}})),r={...n.def,nodes:t};return{schemaVersion:Ue,name:n.name,def:r,...n.trigger?{trigger:n.trigger}:{},concurrency:n.concurrency,requires:Io(r),credentialsRequired:Eo(e),meta:{source:"native"}}}function jo(n){let e=typeof n=="string"?JSON.parse(n):n;if(!me(e))throw new Error("workflow bundle: payload must be an object");if(e.schemaVersion!==Ue)throw new Error(`workflow bundle: unsupported schemaVersion ${String(e.schemaVersion)} (expected ${Ue})`);if(typeof e.name!="string"||!e.name)throw new Error("workflow bundle: `name` is required");let t=e.def;if(!me(t)||!Array.isArray(t.nodes)||!Array.isArray(t.edges))throw new Error("workflow bundle: `def.nodes` and `def.edges` are required arrays");let r=e.concurrency;if(r!==void 0&&r!=="queue"&&r!=="skip"&&r!=="parallel")throw new Error(`workflow bundle: invalid concurrency "${String(r)}"`);return{name:e.name,def:t,trigger:me(e.trigger)?e.trigger:void 0,concurrency:r,requires:Array.isArray(e.requires)?e.requires:[],credentialsRequired:Array.isArray(e.credentialsRequired)?e.credentialsRequired:[]}}export{He as CredentialVault,qe as FileRunCheckpoint,cn as HOST_BACKED_KINDS,V as NodeRegistry,v as PatchError,Be as WorkflowAuditStore,Ce as WorkflowController,$e as WorkflowRunHistoryStore,Y as WorkflowRuntime,Oe as WorkflowScheduler,ve as WorkflowStore,Ae as applyPatch,no as createQlaExecutorHost,yo as credentialToHeaders,to as defaultRuntimeFactory,jo as fromWorkflowBundle,ce as hostExecutors,Ne as renderWorkflow,So as toWorkflowBundle,j as workflowsDir};
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};