@codemation/core 0.13.2 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/CHANGELOG.md +167 -0
  2. package/dist/{CostCatalogContract-Dxq1BTyi.d.cts → CostCatalogContract-Dwo-ZamG.d.cts} +2 -2
  3. package/dist/EngineRuntimeRegistration.types-BiNasx3G.d.cts +54 -0
  4. package/dist/EngineRuntimeRegistration.types-Dq4ucrdo.d.ts +21 -0
  5. package/dist/{InMemoryRunDataFactory-Csy2evr_.d.cts → InMemoryRunDataFactory-D2U9azmZ.d.cts} +4 -20
  6. package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs} +1 -1
  7. package/dist/{InMemoryRunEventBusRegistry-Sa86VxuV.cjs.map → InMemoryRunEventBusRegistry-DO0WM9Lw.cjs.map} +1 -1
  8. package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js → InMemoryRunEventBusRegistry-Layt2xgm.js} +1 -1
  9. package/dist/{InMemoryRunEventBusRegistry-Bwunvt1T.js.map → InMemoryRunEventBusRegistry-Layt2xgm.js.map} +1 -1
  10. package/dist/{ItemsInputNormalizer-Bi8m-Ijs.d.cts → ItemsInputNormalizer-A5txcOWX.d.cts} +3 -98
  11. package/dist/{ItemsInputNormalizer-BbQTSEkZ.cjs → ItemsInputNormalizer-C1fv3sMW.cjs} +2 -2
  12. package/dist/ItemsInputNormalizer-C1fv3sMW.cjs.map +1 -0
  13. package/dist/{ItemsInputNormalizer-BYljnXU0.d.ts → ItemsInputNormalizer-D2vrMrX1.d.ts} +2 -62
  14. package/dist/{ItemsInputNormalizer-CSZGMgl3.js → ItemsInputNormalizer-fUYo4GLV.js} +2 -2
  15. package/dist/ItemsInputNormalizer-fUYo4GLV.js.map +1 -0
  16. package/dist/{RunIntentService-BitgkKaT.d.cts → RunIntentService-DKxuHTUz.d.cts} +2 -15
  17. package/dist/{RunIntentService-DYpqfu6D.d.ts → RunIntentService-DrpKli2k.d.ts} +2 -22
  18. package/dist/{agentMcpTypes-DGIwk6Ue.d.cts → agentMcpTypes-BHX4RQCC.d.cts} +25 -518
  19. package/dist/bootstrap/index.cjs +9 -5
  20. package/dist/bootstrap/index.d.cts +32 -106
  21. package/dist/bootstrap/index.d.ts +18 -17
  22. package/dist/bootstrap/index.js +6 -5
  23. package/dist/{bootstrap-DIv-vloi.cjs → bootstrap-CTB53rEF.cjs} +9 -60
  24. package/dist/bootstrap-CTB53rEF.cjs.map +1 -0
  25. package/dist/{bootstrap-Bkd-Nfbn.js → bootstrap-DmqKheCI.js} +6 -57
  26. package/dist/bootstrap-DmqKheCI.js.map +1 -0
  27. package/dist/browser.cjs +12 -11
  28. package/dist/browser.d.cts +4 -4
  29. package/dist/browser.d.ts +3 -3
  30. package/dist/browser.js +3 -2
  31. package/dist/contracts-7L1wJHdk.cjs +569 -0
  32. package/dist/contracts-7L1wJHdk.cjs.map +1 -0
  33. package/dist/contracts-CjJ5CZ7N.js +447 -0
  34. package/dist/contracts-CjJ5CZ7N.js.map +1 -0
  35. package/dist/contracts.cjs +9 -2
  36. package/dist/contracts.d.cts +5 -5
  37. package/dist/contracts.d.ts +2 -2
  38. package/dist/contracts.js +3 -2
  39. package/dist/{executionPersistenceContracts-CN9d7AnL.d.cts → deploymentManifestTypes-B8CDmZZK.d.cts} +65 -81
  40. package/dist/di-C6Ubf9o5.cjs +179 -0
  41. package/dist/di-C6Ubf9o5.cjs.map +1 -0
  42. package/dist/di-Cjiil7U-.js +114 -0
  43. package/dist/di-Cjiil7U-.js.map +1 -0
  44. package/dist/{index-rllWL4r-.d.ts → index-CRv3_pY3.d.ts} +112 -808
  45. package/dist/{index-BSQ2LoIh.d.ts → index-mnLS0iQl.d.ts} +39 -372
  46. package/dist/index.cjs +53 -111
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +50 -438
  49. package/dist/index.d.ts +5 -5
  50. package/dist/index.js +28 -94
  51. package/dist/index.js.map +1 -1
  52. package/dist/{params-DRUr0F5v.d.cts → params-CrK4iuG1.d.cts} +3 -13
  53. package/dist/{runtime-CWPdvJpC.js → runtime-CBFDpmiz.js} +112 -648
  54. package/dist/runtime-CBFDpmiz.js.map +1 -0
  55. package/dist/{runtime-_VdHwGkJ.cjs → runtime-Due-FOZ2.cjs} +137 -717
  56. package/dist/runtime-Due-FOZ2.cjs.map +1 -0
  57. package/dist/testing.cjs +8 -40
  58. package/dist/testing.cjs.map +1 -1
  59. package/dist/testing.d.cts +3 -32
  60. package/dist/testing.d.ts +3 -32
  61. package/dist/testing.js +6 -38
  62. package/dist/testing.js.map +1 -1
  63. package/dist/{di-LP2qSHkY.cjs → workflowTypes-BW6Hhee7.cjs} +4 -230
  64. package/dist/workflowTypes-BW6Hhee7.cjs.map +1 -0
  65. package/dist/{di-tom0pM2h.js → workflowTypes-DZtBTmKf.js} +3 -163
  66. package/dist/workflowTypes-DZtBTmKf.js.map +1 -0
  67. package/package.json +1 -1
  68. package/src/ai/AgentConnectionNodeCollector.ts +0 -4
  69. package/src/ai/AgentMessageConfigNormalizerFactory.ts +0 -4
  70. package/src/ai/AiHost.ts +0 -38
  71. package/src/ai/CallableToolConfig.ts +0 -9
  72. package/src/ai/CallableToolKindToken.ts +0 -4
  73. package/src/authoring/callableTool.types.ts +0 -3
  74. package/src/authoring/defineCollection.types.ts +0 -11
  75. package/src/authoring/defineHumanApprovalNode.types.ts +0 -116
  76. package/src/authoring/defineNode.types.ts +18 -32
  77. package/src/authoring/definePollingTrigger.types.ts +36 -155
  78. package/src/authoring/definePollingTriggerInternals.ts +0 -4
  79. package/src/authoring/index.ts +1 -0
  80. package/src/authoring/nodeBaseOptions.types.ts +4 -0
  81. package/src/binaries/boundedReadBinary.types.ts +0 -16
  82. package/src/bootstrap/index.ts +8 -2
  83. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +0 -5
  84. package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +0 -23
  85. package/src/browser.ts +0 -3
  86. package/src/contracts/AgentBindError.ts +0 -5
  87. package/src/contracts/Clock.ts +0 -1
  88. package/src/contracts/CodemationTelemetryAttributeNames.ts +0 -10
  89. package/src/contracts/NoOpAgentMcpIntegration.ts +0 -6
  90. package/src/contracts/NoOpTelemetrySpanScope.ts +0 -7
  91. package/src/contracts/RetryPolicy.ts +0 -2
  92. package/src/contracts/agentMcpTypes.ts +0 -34
  93. package/src/contracts/assertionTypes.ts +0 -33
  94. package/src/contracts/baseTypes.ts +0 -6
  95. package/src/contracts/collectionTypes.ts +0 -25
  96. package/src/contracts/credentialTypes.ts +13 -60
  97. package/src/contracts/deploymentManifestTypes.ts +158 -0
  98. package/src/contracts/dispatchTypes.ts +29 -0
  99. package/src/contracts/executionPersistenceContracts.ts +0 -33
  100. package/src/contracts/hitlSeamTypes.ts +0 -14
  101. package/src/contracts/humanTaskStoreTypes.ts +0 -2
  102. package/src/contracts/inboxChannelTypes.ts +0 -9
  103. package/src/contracts/index.ts +3 -0
  104. package/src/contracts/itemExpr.ts +7 -21
  105. package/src/contracts/itemMeta.ts +0 -3
  106. package/src/contracts/mcpTypes.ts +0 -16
  107. package/src/contracts/retryPolicySpec.types.ts +0 -10
  108. package/src/contracts/runFinishedAtFactory.ts +0 -1
  109. package/src/contracts/runTypes.ts +0 -74
  110. package/src/contracts/runtimeTypes.ts +4 -131
  111. package/src/contracts/telemetryTypes.ts +0 -7
  112. package/src/contracts/testTriggerTypes.ts +0 -43
  113. package/src/contracts/triggerInvokerTypes.ts +6 -0
  114. package/src/contracts/webhookTypes.ts +0 -8
  115. package/src/contracts/workflowActivationPolicy.ts +0 -5
  116. package/src/contracts/workflowTypes.ts +5 -80
  117. package/src/contracts/workspaceFileTypes.ts +10 -42
  118. package/src/contracts.ts +18 -10
  119. package/src/credentials/CredentialMaterialProvider.types.ts +0 -28
  120. package/src/credentials/ManagedCredentialMaterialWriteError.ts +0 -6
  121. package/src/credentials/ManagedMaterialFetchError.ts +0 -6
  122. package/src/credentials/OAuthFlowExecutor.types.ts +0 -15
  123. package/src/di/CoreTokens.ts +2 -6
  124. package/src/events/ConnectionInvocationEventPublisher.ts +0 -7
  125. package/src/events/NodeEventPublisher.ts +0 -1
  126. package/src/events/runEvents.ts +0 -8
  127. package/src/execution/ActivationEnqueueService.ts +0 -10
  128. package/src/execution/ChildExecutionScopeFactory.ts +0 -13
  129. package/src/execution/FanInMergeByOriginMerger.ts +0 -11
  130. package/src/execution/InProcessRetryRunner.ts +0 -1
  131. package/src/execution/ItemExprResolver.ts +0 -3
  132. package/src/execution/NodeActivationRequestComposer.ts +0 -3
  133. package/src/execution/NodeActivationRequestInputPreparer.ts +0 -5
  134. package/src/execution/NodeExecutionSnapshotFactory.ts +0 -1
  135. package/src/execution/NodeExecutor.ts +1 -17
  136. package/src/execution/NodeOutputNormalizer.ts +8 -1
  137. package/src/execution/NodeSuspensionHandler.ts +1 -39
  138. package/src/execution/PersistedRunStateTerminalBuilder.ts +0 -5
  139. package/src/execution/RunSuspendedError.ts +0 -10
  140. package/src/execution/RunnableOutputBehaviorResolver.ts +12 -0
  141. package/src/execution/WorkflowRunExecutionContextFactory.ts +0 -3
  142. package/src/index.ts +10 -2
  143. package/src/orchestration/AbortControllerFactory.ts +0 -4
  144. package/src/orchestration/Engine.ts +0 -9
  145. package/src/orchestration/NodeExecutionRequestHandlerService.ts +3 -4
  146. package/src/orchestration/RunContinuationService.ts +7 -39
  147. package/src/orchestration/RunStartService.ts +0 -7
  148. package/src/orchestration/TestSuiteOrchestrator.ts +0 -18
  149. package/src/orchestration/TestSuiteRunIdFactory.ts +0 -4
  150. package/src/orchestration/TriggerRuntimeService.ts +3 -2
  151. package/src/planning/CurrentStateFrontierPlanner.ts +0 -1
  152. package/src/planning/RunQueuePlanner.ts +0 -6
  153. package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +0 -8
  154. package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +0 -3
  155. package/src/runStorage/RunSummaryMapper.ts +0 -1
  156. package/src/runtime/EngineFactory.ts +6 -11
  157. package/src/runtime/RunIntentService.ts +0 -4
  158. package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +0 -4
  159. package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +0 -4
  160. package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +0 -4
  161. package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +0 -1
  162. package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +0 -4
  163. package/src/runtime-types/runtimeTypeDecorators.types.ts +0 -12
  164. package/src/scheduler/ConfigDrivenOffloadPolicy.ts +0 -1
  165. package/src/scheduler/DefaultDrivingScheduler.ts +0 -6
  166. package/src/scheduler/InlineDrivingScheduler.ts +0 -13
  167. package/src/serialization/ItemsInputNormalizer.ts +0 -5
  168. package/src/testing/CapturingScheduler.ts +0 -3
  169. package/src/testing/EngineTestKitRunIdFactory.ts +0 -3
  170. package/src/testing/ItemHarnessNode.ts +0 -3
  171. package/src/testing/ItemHarnessNodeConfig.ts +0 -4
  172. package/src/testing/PrefixedSequentialIdGenerator.ts +0 -3
  173. package/src/testing/RegistrarEngineTestKit.types.ts +0 -2
  174. package/src/testing/RejectingCredentialSessionService.ts +0 -4
  175. package/src/testing/SubWorkflowRunnerTestNode.ts +0 -3
  176. package/src/testing/WorkflowTestHarnessManualTrigger.ts +0 -3
  177. package/src/testing/WorkflowTestKitBuilder.ts +0 -4
  178. package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +0 -3
  179. package/src/testing.ts +0 -3
  180. package/src/triggers/polling/PollingTriggerDedupWindow.ts +0 -4
  181. package/src/triggers/polling/PollingTriggerLogger.ts +0 -5
  182. package/src/triggers/polling/PollingTriggerRuntime.ts +0 -5
  183. package/src/types/index.ts +0 -6
  184. package/src/validation/WorkflowEdgePortValidator.ts +0 -5
  185. package/src/workflow/definition/ConnectionInvocationIdFactory.ts +0 -7
  186. package/src/workflow/definition/ConnectionNodeIdFactory.ts +0 -6
  187. package/src/workflow/definition/NodeIterationIdFactory.ts +0 -13
  188. package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +0 -6
  189. package/src/workflow/dsl/ChainCursorResolver.ts +8 -15
  190. package/src/workflow/dsl/NodeIdSlugifier.ts +0 -9
  191. package/src/workflow/dsl/WhenBuilder.ts +49 -2
  192. package/src/workflow/dsl/WorkflowDefinitionError.ts +0 -9
  193. package/src/workflow/dsl/workflowBuilderTypes.ts +5 -0
  194. package/src/workflowSnapshots/MissingRuntimeParityGuard.ts +24 -0
  195. package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +0 -6
  196. package/src/workflowSnapshots/WorkflowParityMismatchError.ts +18 -0
  197. package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +1 -5
  198. package/src/workflowSnapshots/index.ts +3 -0
  199. package/dist/EngineRuntimeRegistration.types-CqcTWexS.d.cts +0 -81
  200. package/dist/EngineRuntimeRegistration.types-Cr75cSfL.d.ts +0 -44
  201. package/dist/ItemsInputNormalizer-BbQTSEkZ.cjs.map +0 -1
  202. package/dist/ItemsInputNormalizer-CSZGMgl3.js.map +0 -1
  203. package/dist/bootstrap-Bkd-Nfbn.js.map +0 -1
  204. package/dist/bootstrap-DIv-vloi.cjs.map +0 -1
  205. package/dist/contracts-CK0x6w_G.cjs +0 -74
  206. package/dist/contracts-CK0x6w_G.cjs.map +0 -1
  207. package/dist/contracts-DXdfTdpW.js +0 -50
  208. package/dist/contracts-DXdfTdpW.js.map +0 -1
  209. package/dist/di-LP2qSHkY.cjs.map +0 -1
  210. package/dist/di-tom0pM2h.js.map +0 -1
  211. package/dist/runtime-CWPdvJpC.js.map +0 -1
  212. package/dist/runtime-_VdHwGkJ.cjs.map +0 -1
@@ -1,7 +1,9 @@
1
- import { E as ConnectionNodeIdFactory, _ as CredentialUnboundError, a as injectable, g as SuspensionRequest, h as BINARY_DEFAULT_MAX_BYTES, v as NodeIterationIdFactory, w as resolveItemExprsForExecution, x as AgentConfigInspector, y as AgentConnectionNodeCollector } from "./di-tom0pM2h.js";
1
+ import { a as SuspensionRequest, c as AgentConnectionNodeCollector, i as BINARY_DEFAULT_MAX_BYTES, o as CredentialUnboundError, s as NodeIterationIdFactory, u as ConnectionNodeIdFactory } from "./workflowTypes-DZtBTmKf.js";
2
+ import { f as AgentConfigInspector, h as resolveItemExprsForExecution } from "./di-Cjiil7U-.js";
3
+ import { a as WorkflowSnapshotCodec, l as node } from "./contracts-CjJ5CZ7N.js";
4
+ import { createHash } from "node:crypto";
2
5
  import { ZodError, z } from "zod";
3
6
  import { ReadableStream } from "node:stream/web";
4
- import { createHash } from "node:crypto";
5
7
 
6
8
  //#region src/contracts/humanTaskStoreTypes.ts
7
9
  const HumanTaskStoreToken = Symbol.for("codemation.core.HumanTaskStore");
@@ -10,12 +12,6 @@ const HumanTaskStoreToken = Symbol.for("codemation.core.HumanTaskStore");
10
12
  //#region src/contracts/hitlSeamTypes.ts
11
13
  const HitlResumeTokenSignerToken = Symbol.for("codemation.core.HitlResumeTokenSigner");
12
14
  const HitlTimeoutJobSchedulerToken = Symbol.for("codemation.core.HitlTimeoutJobScheduler");
13
- /**
14
- * Optional workspace ID injected into NodeSuspensionHandler in managed mode (T7 security fix).
15
- * Allows the handler to stamp the workspaceId on each HumanTaskRecord so HitlCallbackHandler
16
- * can assert workspace identity independently of the HMAC middleware.
17
- * Not registered in non-managed mode; NodeSuspensionHandler defaults to null.
18
- */
19
15
  const HitlWorkspaceIdToken = Symbol.for("codemation.core.HitlWorkspaceId");
20
16
 
21
17
  //#endregion
@@ -30,115 +26,6 @@ var DefinedNodeRegistry = class {
30
26
  }
31
27
  };
32
28
 
33
- //#endregion
34
- //#region src/runtime-types/persistedRuntimeTypeModelRegistry.ts
35
- /** Shared metadata key used to attach persisted runtime-type information to decorated classes. */
36
- const persistedRuntimeTypeMetadataKey = Symbol.for("codemation.core.persistedRuntimeTypeMetadata");
37
- /** Normalizes decorator options so persistence metadata has stable defaults. */
38
- var PersistedRuntimeTypeDecoratorDefaults = class {
39
- static appPackageName = "app";
40
- static apply(options) {
41
- return {
42
- ...options,
43
- packageName: options.packageName ?? this.appPackageName
44
- };
45
- }
46
- };
47
-
48
- //#endregion
49
- //#region src/runtime-types/PersistedRuntimeTypeNameResolver.ts
50
- /** Resolves the persisted type name from either an explicit override or the class name itself. */
51
- var PersistedRuntimeTypeNameResolver = class {
52
- static resolve(target, override) {
53
- const resolved = override ?? target.name;
54
- if (!resolved) throw new Error("Persisted runtime token metadata requires a named class or an explicit decorator name override.");
55
- return resolved;
56
- }
57
- };
58
-
59
- //#endregion
60
- //#region src/runtime-types/StackTraceCallSitePathResolver.ts
61
- var StackTraceCallSitePathResolver = class {
62
- static resolve(decoratorFileUrl) {
63
- const stack = (/* @__PURE__ */ new Error()).stack ?? "";
64
- for (const line of stack.split("\n")) {
65
- const candidate = this.extractPath(line.trim());
66
- if (!candidate) continue;
67
- if (candidate === decoratorFileUrl || candidate.includes("runtimeTypeDecorators")) continue;
68
- return candidate;
69
- }
70
- }
71
- static extractPath(line) {
72
- const fileUrlMatch = line.match(/file:\/\/[^\s)]+/);
73
- if (fileUrlMatch) return fileUrlMatch[0];
74
- const parenMatch = line.match(/\((\/[^)]+)\)/);
75
- if (parenMatch) return parenMatch[1];
76
- return line.match(/at (\/[^\s]+)/)?.[1];
77
- }
78
- };
79
-
80
- //#endregion
81
- //#region src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts
82
- /**
83
- * Defines and retrieves persisted runtime metadata on decorated classes.
84
- * The metadata is attached as a non-enumerable property so runtime objects stay serializable.
85
- */
86
- var PersistedRuntimeTypeMetadataStore = class {
87
- static define(target, kind, options, decoratorFileUrl) {
88
- const normalizedOptions = PersistedRuntimeTypeDecoratorDefaults.apply(options);
89
- const metadata = {
90
- persistedName: PersistedRuntimeTypeNameResolver.resolve(target, normalizedOptions.name),
91
- kind,
92
- packageName: normalizedOptions.packageName ?? PersistedRuntimeTypeDecoratorDefaults.appPackageName,
93
- sourceHint: normalizedOptions.moduleUrl ?? StackTraceCallSitePathResolver.resolve(decoratorFileUrl)
94
- };
95
- Object.defineProperty(target, persistedRuntimeTypeMetadataKey, {
96
- configurable: false,
97
- enumerable: false,
98
- writable: false,
99
- value: metadata
100
- });
101
- }
102
- static get(target) {
103
- if (!target || typeof target !== "function" && typeof target !== "object") return;
104
- return target[persistedRuntimeTypeMetadataKey];
105
- }
106
- };
107
-
108
- //#endregion
109
- //#region src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts
110
- /**
111
- * Applies both tsyringe injectability and persisted runtime metadata in one decorator.
112
- * This keeps runtime-type decorators thin while still recording enough data for snapshot hydration.
113
- */
114
- var InjectableRuntimeDecoratorComposer = class {
115
- static compose(kind, options, decoratorFileUrl) {
116
- return (target) => {
117
- injectable()(target);
118
- PersistedRuntimeTypeMetadataStore.define(target, kind, options, decoratorFileUrl);
119
- };
120
- }
121
- };
122
-
123
- //#endregion
124
- //#region src/runtime-types/runtimeTypeDecorators.types.ts
125
- /** Reads persisted runtime metadata from a decorated class or object. */
126
- function getPersistedRuntimeTypeMetadata(target) {
127
- return PersistedRuntimeTypeMetadataStore.get(target);
128
- }
129
- /** Marks a class as a persisted node runtime type and an injectable tsyringe service. */
130
- function node(options = {}) {
131
- return InjectableRuntimeDecoratorComposer.compose("node", options, import.meta.url);
132
- }
133
- /** Marks a class as a persisted tool runtime type and an injectable tsyringe service. */
134
- function tool(options = {}) {
135
- return InjectableRuntimeDecoratorComposer.compose("tool", options, import.meta.url);
136
- }
137
- /** Marks a class as a persisted chat-model runtime type and an injectable tsyringe service. */
138
- function chatModel(options = {}) {
139
- return InjectableRuntimeDecoratorComposer.compose("chatModel", options, import.meta.url);
140
- }
141
-
142
29
  //#endregion
143
30
  //#region src/authoring/defineNode.types.ts
144
31
  const definedNodeCredentialRequirementFactory = {
@@ -206,9 +93,13 @@ function defineNode(options) {
206
93
  icon = options.icon;
207
94
  inputSchema = options.inputSchema;
208
95
  keepBinaries = options.keepBinaries ?? false;
209
- constructor(name, config, id) {
96
+ id;
97
+ description;
98
+ constructor(name, config, idOrOptions) {
210
99
  this.name = name;
211
- this.id = id;
100
+ const resolved = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
101
+ this.id = resolved?.id;
102
+ this.description = resolved?.description;
212
103
  this.config = config;
213
104
  }
214
105
  config;
@@ -224,8 +115,8 @@ function defineNode(options) {
224
115
  key: options.key,
225
116
  title: options.title,
226
117
  description: options.description,
227
- create(config, name = options.title, id) {
228
- return new DefinedRunnableNodeConfig(name, config, id);
118
+ create(config, name = options.title, idOrOptions) {
119
+ return new DefinedRunnableNodeConfig(name, config, idOrOptions);
229
120
  },
230
121
  register(context) {
231
122
  context.registerNode(DefinedNodeRuntime);
@@ -255,9 +146,13 @@ function defineBatchNode(options) {
255
146
  kind = "node";
256
147
  type = DefinedNodeRuntime;
257
148
  icon = options.icon;
258
- constructor(name, config, id) {
149
+ id;
150
+ description;
151
+ constructor(name, config, idOrOptions) {
259
152
  this.name = name;
260
- this.id = id;
153
+ const resolved = typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;
154
+ this.id = resolved?.id;
155
+ this.description = resolved?.description;
261
156
  this.config = config;
262
157
  }
263
158
  config;
@@ -273,8 +168,8 @@ function defineBatchNode(options) {
273
168
  key: options.key,
274
169
  title: options.title,
275
170
  description: options.description,
276
- create(config, name = options.title, id) {
277
- return new DefinedRunnableNodeConfig(name, config, id);
171
+ create(config, name = options.title, idOrOptions) {
172
+ return new DefinedRunnableNodeConfig(name, config, idOrOptions);
278
173
  },
279
174
  register(context) {
280
175
  context.registerNode(DefinedNodeRuntime);
@@ -286,60 +181,9 @@ function defineBatchNode(options) {
286
181
 
287
182
  //#endregion
288
183
  //#region src/authoring/defineHumanApprovalNode.types.ts
289
- /**
290
- * Returns `true` when `node` was created by {@link defineHumanApprovalNode}.
291
- * Uses the `humanApprovalToolBehavior` typed field as the discriminant.
292
- */
293
184
  function isHumanApprovalNode(node$1) {
294
185
  return typeof node$1 === "object" && node$1 !== null && "humanApprovalToolBehavior" in node$1 && typeof node$1.humanApprovalToolBehavior === "object";
295
186
  }
296
- /**
297
- * Authoring helper that compiles a HITL approval channel down to a regular
298
- * {@link defineNode}-backed node with `SuspensionRequest` semantics.
299
- *
300
- * **Fast-forward decision semantics:**
301
- * - On the first `execute` call (no `ctx.resumeContext`): throws a `SuspensionRequest`
302
- * that calls the author's `deliver`. The engine persists the suspension and continues.
303
- * - On resume (`ctx.resumeContext` set): calls `onDecision`/`onTimeout` as appropriate,
304
- * merges a `decision` key into `item.json`, and returns an item with the original
305
- * `binary` map passed by reference (no copy).
306
- *
307
- * **Output shape per item:**
308
- * ```ts
309
- * // Input: { json: { invoiceId: 42 }, binary?: {...} }
310
- * // Output: { json: { invoiceId: 42, decision: { status: "approved", actor, decidedAt } }, binary: <unchanged> }
311
- * ```
312
- * If `item.json` already has a `decision` key it is **overwritten**. Namespace as
313
- * needed if your schema reserves that key for another purpose.
314
- *
315
- * **Predicate persistence:**
316
- * The `approvedPredicate` function is NOT serialized to the suspension record (except
317
- * as an audit-only string via `toString()`). On resume, the workflow definition is
318
- * reloaded from code at process start and the predicate closure is rebuilt naturally.
319
- * If a deploy ships a changed predicate between suspend and resume, the *new* predicate
320
- * runs — document this in your runbook when the predicate carries business logic that
321
- * may change across deploys.
322
- *
323
- * @example
324
- * ```ts
325
- * export const slackApprovalNode = defineHumanApprovalNode({
326
- * key: "my-plugin.slackApproval",
327
- * title: "Slack Approval",
328
- * channel: "slack",
329
- * configSchema: z.object({ channel: z.string(), message: z.string() }),
330
- * decisionSchema: z.object({ approved: z.boolean(), note: z.string().optional() }),
331
- *
332
- * async deliver({ task, config, item }, ctx) {
333
- * const ts = await postSlackMessage(config.channel, `Approve? <${task.resumeUrl}>`);
334
- * return { channel: config.channel, ts };
335
- * },
336
- *
337
- * async onDecision({ decision, actor, delivery }, ctx) {
338
- * await updateSlackMessage(delivery.channel, delivery.ts, decision.approved ? "✅" : "❌");
339
- * },
340
- * });
341
- * ```
342
- */
343
187
  function defineHumanApprovalNode(opts) {
344
188
  const resolvedPredicate = resolveApprovedPredicate(opts.decisionSchema, opts.approvedPredicate);
345
189
  const timeout = opts.defaultTimeout ?? "24h";
@@ -441,10 +285,12 @@ async function handleResume(item, resumeContext, decisionSchema, resolvedPredica
441
285
  //#endregion
442
286
  //#region src/workflow/dsl/WhenBuilder.ts
443
287
  var WhenBuilder = class WhenBuilder {
444
- constructor(wf, from, branchPort) {
288
+ armEndpoint;
289
+ constructor(wf, from, branchPort, priorEndpoints = []) {
445
290
  this.wf = wf;
446
291
  this.from = from;
447
292
  this.branchPort = branchPort;
293
+ this.priorEndpoints = priorEndpoints;
448
294
  }
449
295
  addBranch(steps) {
450
296
  const created = [];
@@ -465,20 +311,48 @@ var WhenBuilder = class WhenBuilder {
465
311
  return nodeId ? { nodeId } : { nodeId: r };
466
312
  });
467
313
  }
314
+ this.armEndpoint = prev ? {
315
+ node: prev,
316
+ output: "main",
317
+ inputPortHint: this.branchPort
318
+ } : {
319
+ node: this.from,
320
+ output: this.branchPort,
321
+ inputPortHint: this.branchPort
322
+ };
468
323
  return this;
469
324
  }
470
325
  when = (branch, steps, ...more) => {
471
326
  const list = Array.isArray(steps) ? steps : [steps, ...more];
472
327
  const port = branch ? "true" : "false";
473
- const b = new WhenBuilder(this.wf, this.from, port);
328
+ const b = new WhenBuilder(this.wf, this.from, port, this.accumulatedEndpoints);
474
329
  b.addBranch(list);
475
330
  return b;
476
331
  };
332
+ then(config) {
333
+ return this.toCursor().then(config);
334
+ }
335
+ humanApproval(node$1, config, metadata) {
336
+ return this.toCursor().humanApproval(node$1, config, metadata);
337
+ }
477
338
  build() {
478
339
  return this.wf.build();
479
340
  }
341
+ get accumulatedEndpoints() {
342
+ return this.armEndpoint ? [...this.priorEndpoints, this.armEndpoint] : this.priorEndpoints;
343
+ }
344
+ toCursor() {
345
+ return new ChainCursor(this.wf, this.accumulatedEndpoints);
346
+ }
480
347
  };
481
348
 
349
+ //#endregion
350
+ //#region src/workflow/dsl/workflowBuilderTypes.ts
351
+ function mergeForward(config) {
352
+ config.mergeJson = true;
353
+ return config;
354
+ }
355
+
482
356
  //#endregion
483
357
  //#region src/workflow/dsl/ChainCursorResolver.ts
484
358
  var ChainCursor = class ChainCursor {
@@ -496,6 +370,10 @@ var ChainCursor = class ChainCursor {
496
370
  ...inputPortHint ? { inputPortHint } : {}
497
371
  }]);
498
372
  }
373
+ thenMerge(config) {
374
+ mergeForward(config);
375
+ return this.then(config);
376
+ }
499
377
  thenIntoInputHints(config) {
500
378
  const next = this.wf.add(config);
501
379
  for (const e of this.endpoints) this.wf.connect(e.node, next, e.output, e.inputPortHint ?? "in");
@@ -564,21 +442,6 @@ var ChainCursor = class ChainCursor {
564
442
  }
565
443
  return new ChainCursor(this.wf, nextEndpoints);
566
444
  }
567
- /**
568
- * Chainable shorthand for `.then(node.create(config, metadata?.name, metadata?.nodeId))`.
569
- *
570
- * Signals to readers that this step suspends the run and waits for a human decision.
571
- * Throws at workflow-build time if `node` was not created via `defineHumanApprovalNode`.
572
- *
573
- * @example
574
- * ```ts
575
- * workflow
576
- * .trigger(...)
577
- * .humanApproval(inboxApproval, { title: "Approve?", body: "...", priority: "normal" })
578
- * .then(nextStep.create(...))
579
- * .build();
580
- * ```
581
- */
582
445
  humanApproval(node$1, config, metadata) {
583
446
  if (!isHumanApprovalNode(node$1)) throw new Error(`.humanApproval() requires a node created via defineHumanApprovalNode (got '${node$1.key ?? String(node$1)}').`);
584
447
  return this.then(node$1.create(config, metadata?.name, metadata?.nodeId));
@@ -595,15 +458,6 @@ var ChainCursor = class ChainCursor {
595
458
 
596
459
  //#endregion
597
460
  //#region src/workflow/dsl/NodeIdSlugifier.ts
598
- /**
599
- * Converts a human-readable node label into a stable, URL-safe identifier segment.
600
- *
601
- * Rules:
602
- * - Lowercase the entire string.
603
- * - Replace every run of characters outside `[a-z0-9]` with a single `-`.
604
- * - Strip any leading or trailing `-` characters.
605
- * - Return `""` for blank/empty input.
606
- */
607
461
  const NodeIdSlugifier = { slugify(label) {
608
462
  if (!label) return "";
609
463
  return label.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
@@ -611,15 +465,6 @@ const NodeIdSlugifier = { slugify(label) {
611
465
 
612
466
  //#endregion
613
467
  //#region src/workflow/dsl/WorkflowDefinitionError.ts
614
- /**
615
- * Thrown by {@link WorkflowBuilder.build} when the workflow definition is structurally invalid.
616
- *
617
- * Common causes:
618
- * - A node has an empty effective id (label is blank and no explicit `id` was given).
619
- * - Two or more nodes share the same effective id (label slugs collide or explicit ids clash).
620
- *
621
- * Fix: provide an explicit `id:` on the offending node configs.
622
- */
623
468
  var WorkflowDefinitionError = class extends Error {
624
469
  constructor(message) {
625
470
  super(message);
@@ -731,17 +576,10 @@ var WorkflowBuilder = class {
731
576
 
732
577
  //#endregion
733
578
  //#region src/workflow/definition/ConnectionInvocationIdFactory.ts
734
- /**
735
- * Unique ids for persisted connection invocation history rows (LLM/tool calls under an owning node).
736
- *
737
- * Uses Web Crypto's `randomUUID` so this module is safe in browser-bundle contexts —
738
- * paired with `NodeIterationIdFactory` which had the same `node:crypto` regression.
739
- */
740
579
  var ConnectionInvocationIdFactory = class {
741
580
  static create() {
742
581
  return `cinv_${globalThis.crypto.randomUUID()}`;
743
582
  }
744
- /** Deterministic id for tests when a stable sequence is needed. */
745
583
  static createForTest(runId, connectionNodeId, sequence) {
746
584
  return `cinv_${runId}_${connectionNodeId}_${sequence}`;
747
585
  }
@@ -749,9 +587,6 @@ var ConnectionInvocationIdFactory = class {
749
587
 
750
588
  //#endregion
751
589
  //#region src/workflow/definition/WorkflowExecutableNodeClassifier.ts
752
- /**
753
- * Derives which workflow nodes participate in the main execution graph vs connection-only children.
754
- */
755
590
  var WorkflowExecutableNodeClassifier = class {
756
591
  connectionOwnedIds;
757
592
  constructor(workflow) {
@@ -771,9 +606,6 @@ var WorkflowExecutableNodeClassifier = class {
771
606
  for (const connection of workflow.connections ?? []) for (const childId of connection.childNodeIds) ids.add(childId);
772
607
  return ids;
773
608
  }
774
- /**
775
- * Resolves the default start node: first trigger, else first executable node with no incoming edges from executable nodes.
776
- */
777
609
  findDefaultExecutableStartNodeId(workflow) {
778
610
  const firstTrigger = workflow.nodes.find((n) => n.kind === "trigger" && this.isExecutableNodeId(n.id))?.id;
779
611
  if (firstTrigger) return firstTrigger;
@@ -838,13 +670,6 @@ var DefaultWorkflowGraphFactory = class {
838
670
 
839
671
  //#endregion
840
672
  //#region src/events/ConnectionInvocationEventPublisher.ts
841
- /**
842
- * Publishes per-invocation lifecycle records onto the run {@link RunEventBus}.
843
- *
844
- * Surgical, per-invocation events let the UI update the right-side inspector
845
- * timeline as each LLM round / tool call transitions through `running` → `completed`
846
- * (or `failed`) without depending on a coarse `runSaved` poll.
847
- */
848
673
  var ConnectionInvocationEventPublisher = class {
849
674
  constructor(eventBus, parent) {
850
675
  this.eventBus = eventBus;
@@ -872,7 +697,6 @@ var ConnectionInvocationEventPublisher = class {
872
697
 
873
698
  //#endregion
874
699
  //#region src/events/NodeEventPublisher.ts
875
- /** Publishes node lifecycle snapshots onto the run {@link RunEventBus}. */
876
700
  var NodeEventPublisher = class {
877
701
  constructor(eventBus) {
878
702
  this.eventBus = eventBus;
@@ -892,19 +716,6 @@ var NodeEventPublisher = class {
892
716
 
893
717
  //#endregion
894
718
  //#region src/binaries/boundedReadBinary.types.ts
895
- /**
896
- * Reads all bytes from an already-opened binary stream into a contiguous `Uint8Array`.
897
- *
898
- * Safety contract:
899
- * - `attachment.size` is checked against `maxBytes` *before* any allocation (no OOM).
900
- * - A single buffer of exactly `attachment.size` is pre-allocated; the stream fills it
901
- * directly — no chunks array, no doubling.
902
- * - A byte-count mismatch between the declared size and actual stream content is an error.
903
- *
904
- * This is the single canonical implementation; `ExecutionBinaryService.getBytes`,
905
- * `getText`, and `getJson` all delegate here. The per-package `readBinaryBody` helpers
906
- * in `core-nodes` and `core-nodes-ocr` have been removed in favour of this function.
907
- */
908
719
  async function boundedReadBinary(result, attachment, maxBytes = BINARY_DEFAULT_MAX_BYTES) {
909
720
  if (attachment.size > maxBytes) throw new Error(`Binary attachment size ${attachment.size} bytes exceeds maxBytes ${maxBytes}. Raise the node's maxBytes setting if this document is expected to be larger.`);
910
721
  const out = new Uint8Array(attachment.size);
@@ -921,18 +732,15 @@ async function boundedReadBinary(result, attachment, maxBytes = BINARY_DEFAULT_M
921
732
  if (offset !== out.byteLength) throw new Error(`Binary stream produced ${offset} bytes but attachment declared size ${attachment.size}.`);
922
733
  return out;
923
734
  }
924
- /** Shared implementation of `getBytes` used by both binary-service classes. */
925
735
  async function readBinaryAsBytes(storage, attachment, maxBytes) {
926
736
  const result = await storage.openReadStream(attachment.storageKey);
927
737
  if (!result) throw new Error("Binary attachment stream is unavailable.");
928
738
  return boundedReadBinary(result, attachment, maxBytes);
929
739
  }
930
- /** Shared implementation of `getText` used by both binary-service classes. */
931
740
  async function readBinaryAsText(storage, attachment, maxBytes) {
932
741
  const bytes = await readBinaryAsBytes(storage, attachment, maxBytes);
933
742
  return new TextDecoder().decode(bytes);
934
743
  }
935
- /** Shared implementation of `getJson` used by both binary-service classes. */
936
744
  async function readBinaryAsJson(storage, attachment, maxBytes) {
937
745
  const text = await readBinaryAsText(storage, attachment, maxBytes);
938
746
  try {
@@ -1276,19 +1084,6 @@ var ActivationEnqueueService = class {
1276
1084
 
1277
1085
  //#endregion
1278
1086
  //#region src/execution/ChildExecutionScopeFactory.ts
1279
- /**
1280
- * Builds a re-rooted child execution context for sub-agent (and other deeply-nested) invocations.
1281
- *
1282
- * At the orchestrator's `agent.tool.call` boundary the inner runtime needs a ctx whose:
1283
- * - `nodeId` is the tool's connection node id (so inner LLM/tool connection ids derive correctly),
1284
- * - `activationId` is fresh (so its connection-invocation rows are uniquely identifiable),
1285
- * - `telemetry` parents children under the tool-call span (not the orchestrator's node span),
1286
- * - `binary` is scoped to the new (nodeId, activationId),
1287
- * - `parentInvocationId` points back to the tool-call invocation for downstream lineage.
1288
- *
1289
- * Registered via factory in {@link EngineRuntimeRegistrar} so constructors stay free of parameter
1290
- * decorators (Next/SWC and coverage tooling cannot parse them on in-repo sources).
1291
- */
1292
1087
  var ChildExecutionScopeFactory = class {
1293
1088
  constructor(activationIdFactory) {
1294
1089
  this.activationIdFactory = activationIdFactory;
@@ -1318,9 +1113,6 @@ var ChildExecutionScopeFactory = class {
1318
1113
 
1319
1114
  //#endregion
1320
1115
  //#region src/contracts/itemMeta.ts
1321
- /**
1322
- * Reads `meta._cm.originIndex` when present (used for fan-in merge-by-origin and Merge routing).
1323
- */
1324
1116
  function getOriginIndexFromItem(item) {
1325
1117
  const v = (item.meta?._cm)?.originIndex;
1326
1118
  return typeof v === "number" && Number.isFinite(v) ? v : void 0;
@@ -1328,17 +1120,6 @@ function getOriginIndexFromItem(item) {
1328
1120
 
1329
1121
  //#endregion
1330
1122
  //#region src/execution/FanInMergeByOriginMerger.ts
1331
- /**
1332
- * Default fan-in: combine multi-port {@link NodeInputsByPort} into one {@link Items} batch for per-item nodes.
1333
- *
1334
- * This is used when a single-input per-item node has multiple inbound edges (for example, branch reconverge
1335
- * after an `If` / `Switch`). The default behavior is **append / union** (preserving item payloads) with a
1336
- * deterministic order:
1337
- *
1338
- * - When router origin metadata exists (`meta._cm.originIndex`), items are sorted by origin index so the
1339
- * downstream batch preserves original ordering across branches.
1340
- * - Otherwise, items are appended by port-key order, preserving each port's local order.
1341
- */
1342
1123
  var FanInMergeByOriginMerger = class {
1343
1124
  merge(inputsByPort) {
1344
1125
  const portKeys = Object.keys(inputsByPort).sort();
@@ -1388,11 +1169,6 @@ var NodeInputContractError = class extends Error {
1388
1169
 
1389
1170
  //#endregion
1390
1171
  //#region src/execution/NodeActivationRequestInputPreparer.ts
1391
- /**
1392
- * Validates per-item inputs for {@link RunnableNode} before enqueue persistence (Zod on `item.json`).
1393
- * Does not rewrite `item.json` (wire stays as emitted upstream; engine passes parsed input via `execute` args).
1394
- * Converts multi-input activations into a single-input batch when the node is per-item only (engine fan-in).
1395
- */
1396
1172
  var NodeActivationRequestInputPreparer = class {
1397
1173
  fanInMerger = new FanInMergeByOriginMerger();
1398
1174
  constructor(workflowNodeInstanceFactory) {
@@ -1539,13 +1315,11 @@ var RetryPolicy = class {
1539
1315
  if (!Number.isFinite(maxAttempts) || maxAttempts < 1 || !Number.isInteger(maxAttempts)) throw new Error(`RetryPolicy.maxAttempts must be a positive integer, got ${maxAttempts}`);
1540
1316
  if (!Number.isFinite(delayMs) || delayMs < 0) throw new Error(`RetryPolicy.delayMs must be a non-negative finite number, got ${delayMs}`);
1541
1317
  }
1542
- /** Default for HTTP-style transient failures: 3 tries, 1s between attempts. */
1543
1318
  static defaultForHttp = {
1544
1319
  kind: "fixed",
1545
1320
  maxAttempts: 3,
1546
1321
  delayMs: 1e3
1547
1322
  };
1548
- /** Default for LLM / agent calls: 3 tries, 2s fixed backoff. */
1549
1323
  static defaultForAiAgent = {
1550
1324
  kind: "fixed",
1551
1325
  maxAttempts: 3,
@@ -1615,12 +1389,6 @@ var NoOpTelemetryArtifactReference = class {
1615
1389
 
1616
1390
  //#endregion
1617
1391
  //#region src/contracts/NoOpTelemetrySpanScope.ts
1618
- /**
1619
- * Standalone no-op {@link NodeExecutionTelemetry} value used as the return for `asNodeTelemetry`.
1620
- *
1621
- * Defined here (instead of in `NoOpNodeExecutionTelemetry.ts`) so that {@link NoOpTelemetrySpanScope}
1622
- * can return it without importing the other module — both no-ops share this leaf.
1623
- */
1624
1392
  const noOpNodeExecutionTelemetry = {
1625
1393
  traceId: "00000000000000000000000000000000",
1626
1394
  spanId: "0000000000000000",
@@ -1655,7 +1423,6 @@ const noOpTelemetrySpanScope = {
1655
1423
  };
1656
1424
  var NoOpTelemetrySpanScope = class {
1657
1425
  static value = noOpTelemetrySpanScope;
1658
- /** Internal: the shared no-op {@link NodeExecutionTelemetry} that {@link NoOpNodeExecutionTelemetry} re-exposes. */
1659
1426
  static nodeExecutionTelemetryValue = noOpNodeExecutionTelemetry;
1660
1427
  };
1661
1428
 
@@ -1692,7 +1459,6 @@ var NoOpExecutionTelemetryFactory = class {
1692
1459
 
1693
1460
  //#endregion
1694
1461
  //#region src/contracts/workflowActivationPolicy.ts
1695
- /** Default for tests and harnesses: every workflow is treated as active (legacy behavior). */
1696
1462
  var AllWorkflowsActiveWorkflowActivationPolicy = class {
1697
1463
  isActive(_workflowId) {
1698
1464
  return true;
@@ -1712,25 +1478,15 @@ var CodemationTelemetryAttributeNames = class {
1712
1478
  static connectionInvocationId = "codemation.connection.invocation_id";
1713
1479
  static toolName = "codemation.tool.name";
1714
1480
  static traceParentRunId = "codemation.parent.run.id";
1715
- /** Per-item iteration that emitted this span/metric. Set on spans recorded inside a runnable per-item loop. */
1716
1481
  static iterationId = "codemation.iteration.id";
1717
- /** Item index (0-based) of the iteration. */
1718
1482
  static iterationIndex = "codemation.iteration.index";
1719
- /** Set when this span/metric was recorded under a sub-agent triggered by an outer LLM/tool call. */
1720
1483
  static parentInvocationId = "codemation.parent.invocation_id";
1721
- /** MCP server id on spans created for callTool invocations. */
1722
1484
  static mcpServerId = "mcp.server_id";
1723
- /** MCP tool name on spans created for callTool invocations. */
1724
1485
  static mcpToolName = "mcp.tool_name";
1725
- /** Terminal node-execution status (e.g. `"hitl-approved"`, `"hitl-rejected"`) on HITL outcome spans. */
1726
1486
  static nodeExecutionStatus = "codemation.node.execution_status";
1727
- /** Populated on run-halted spans; discriminates the halt reason (e.g. `"hitl-rejected"`). */
1728
1487
  static runHaltReason = "codemation.run.halt_reason";
1729
- /** Human task ID on `hitl.task.*` span events. */
1730
1488
  static hitlTaskId = "codemation.hitl.task_id";
1731
- /** HITL channel name (e.g. `"inbox"`, `"control-plane-inbox"`) on `hitl.task.*` span events. */
1732
1489
  static hitlChannel = "codemation.hitl.channel";
1733
- /** Decision outcome (e.g. `"approved"`, `"rejected"`) on `hitl.task.decided` span events. */
1734
1490
  static hitlDecisionStatus = "codemation.hitl.decision_status";
1735
1491
  };
1736
1492
 
@@ -1945,7 +1701,6 @@ var CatalogBackedCostTrackingTelemetryFactory = class {
1945
1701
 
1946
1702
  //#endregion
1947
1703
  //#region src/execution/InProcessRetryRunner.ts
1948
- /** Maximum permitted retry attempts — workflow-declared values above this are clamped. */
1949
1704
  const HARD_MAX_RETRY_ATTEMPTS = 10;
1950
1705
  var InProcessRetryRunner = class InProcessRetryRunner {
1951
1706
  constructor(sleeper) {
@@ -2037,9 +1792,6 @@ var InProcessRetryRunner = class InProcessRetryRunner {
2037
1792
 
2038
1793
  //#endregion
2039
1794
  //#region src/execution/ItemExprResolver.ts
2040
- /**
2041
- * Resolves {@link import("../contracts/itemExpr").ItemExpr} leaves on runnable config before {@link RunnableNode.execute}.
2042
- */
2043
1795
  var ItemExprResolver = class {
2044
1796
  async resolveConfigForItem(ctx, item, itemIndex, items) {
2045
1797
  if (!ctx) throw new Error("ItemExprResolver.resolveConfigForItem: ctx is required");
@@ -2085,10 +1837,16 @@ var NodeOutputNormalizer = class {
2085
1837
  isItemLike(value) {
2086
1838
  return typeof value === "object" && value !== null && "json" in value;
2087
1839
  }
1840
+ isPlainJsonObject(value) {
1841
+ return typeof value === "object" && value !== null && !Array.isArray(value);
1842
+ }
2088
1843
  applyOutput(baseItem, next, behavior) {
2089
1844
  const explicitBinary = next.binary;
2090
1845
  return {
2091
- json: next.json,
1846
+ json: behavior.mergeJson && this.isPlainJsonObject(baseItem.json) && this.isPlainJsonObject(next.json) ? {
1847
+ ...baseItem.json,
1848
+ ...next.json
1849
+ } : next.json,
2092
1850
  ...explicitBinary !== void 0 ? { binary: explicitBinary } : behavior.keepBinaries && baseItem.binary ? { binary: baseItem.binary } : {},
2093
1851
  ...next.meta ? { meta: next.meta } : {},
2094
1852
  ...next.paired ? { paired: next.paired } : {}
@@ -2100,11 +1858,17 @@ var NodeOutputNormalizer = class {
2100
1858
  //#region src/execution/RunnableOutputBehaviorResolver.ts
2101
1859
  var RunnableOutputBehaviorResolver = class {
2102
1860
  resolve(config) {
2103
- return { keepBinaries: this.isKeepBinariesEnabled(config) };
1861
+ return {
1862
+ keepBinaries: this.isKeepBinariesEnabled(config),
1863
+ mergeJson: this.isMergeJsonEnabled(config)
1864
+ };
2104
1865
  }
2105
1866
  isKeepBinariesEnabled(config) {
2106
1867
  return config.keepBinaries === true;
2107
1868
  }
1869
+ isMergeJsonEnabled(config) {
1870
+ return config.mergeJson === true;
1871
+ }
2108
1872
  };
2109
1873
 
2110
1874
  //#endregion
@@ -2117,9 +1881,6 @@ var InProcessRetryRunnerFactory = class {
2117
1881
 
2118
1882
  //#endregion
2119
1883
  //#region src/execution/NodeActivationRequestComposer.ts
2120
- /**
2121
- * Builds {@link NodeActivationRequest} values shared by workflow starters and continuation.
2122
- */
2123
1884
  var NodeActivationRequestComposer = class {
2124
1885
  constructor(activationIdFactory, credentialResolverFactory) {
2125
1886
  this.activationIdFactory = activationIdFactory;
@@ -2211,16 +1972,6 @@ var NodeActivationRequestComposer = class {
2211
1972
 
2212
1973
  //#endregion
2213
1974
  //#region src/execution/RunSuspendedError.ts
2214
- /**
2215
- * Internal sentinel thrown by {@link NodeSuspensionHandler} after persisting a suspension
2216
- * entry. `NodeExecutionRequestHandlerService` catches this specifically and returns cleanly —
2217
- * no continuation call, preventing `resumeFromNodeResult` / `resumeFromNodeError` from
2218
- * overwriting the `"suspended"` run status.
2219
- *
2220
- * The `Error` suffix satisfies the ESLint `no-manual-di-new` allowlist. This is NOT a
2221
- * user-facing error — it is an engine-internal control-flow primitive and should NOT be
2222
- * exported from the public barrel.
2223
- */
2224
1975
  var RunSuspendedError = class extends Error {
2225
1976
  constructor(runId, taskId) {
2226
1977
  super(`RunSuspendedError: run ${runId} suspended on task ${taskId}`);
@@ -2397,7 +2148,6 @@ var NodeExecutor = class {
2397
2148
  if (hasSuspension) throw new RunSuspendedError(request.runId, "unknown");
2398
2149
  return byPort;
2399
2150
  }
2400
- /** Use resolver ctx only when {@link NodeExecutionContext.config} is non-nullish. */
2401
2151
  pickExecutionContext(runnableCtx, resolvedCtx) {
2402
2152
  if (resolvedCtx != null && resolvedCtx.config != null) return resolvedCtx;
2403
2153
  return runnableCtx;
@@ -2498,246 +2248,41 @@ var MissingRuntimeNode = class {
2498
2248
  };
2499
2249
 
2500
2250
  //#endregion
2501
- //#region src/workflowSnapshots/MissingRuntimeTrigger.ts
2502
- var MissingRuntimeTrigger = class {
2503
- kind = "trigger";
2504
- outputPorts = ["main"];
2505
- async setup(_ctx) {}
2506
- async execute(items) {
2507
- return { main: items };
2508
- }
2509
- };
2510
-
2511
- //#endregion
2512
- //#region src/workflowSnapshots/PersistedRuntimeTypeIdFactory.ts
2513
- var PersistedRuntimeTypeIdFactory = class {
2514
- static fromMetadata(args) {
2515
- const metadata = getPersistedRuntimeTypeMetadata(args.type);
2516
- if (!metadata) return;
2517
- const packageName = metadata.packageName;
2518
- if (!packageName) return;
2519
- return `${packageName}::${metadata.persistedName}`;
2251
+ //#region src/workflowSnapshots/WorkflowParityMismatchError.ts
2252
+ var WorkflowParityMismatchError = class extends Error {
2253
+ name = "WorkflowParityMismatchError";
2254
+ missingNodes;
2255
+ constructor(missingNodes) {
2256
+ const labels = missingNodes.map((n) => `${n.nodeId} (token: ${n.missingTokenId ?? "unknown"})`).join(", ");
2257
+ super(`Workflow parity mismatch: nodes resolve to MissingRuntime and cannot execute: ${labels}`);
2258
+ this.missingNodes = missingNodes;
2520
2259
  }
2521
2260
  };
2522
2261
 
2523
2262
  //#endregion
2524
- //#region src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts
2525
- var PersistedWorkflowTokenRegistry = class {
2526
- tokensById = /* @__PURE__ */ new Map();
2527
- tokenIdsByToken = /* @__PURE__ */ new Map();
2528
- /**
2529
- * Register a token with its package ID. Token ID is inferred as `packageId::tokenName`.
2530
- */
2531
- register(type, packageId, persistedNameOverride) {
2532
- const tokenId = `${packageId}::${persistedNameOverride ?? this.displayNameForTypeToken(type)}`;
2533
- this.tokensById.set(tokenId, type);
2534
- this.tokenIdsByToken.set(type, tokenId);
2535
- return tokenId;
2536
- }
2537
- /**
2538
- * Register all decorated runtime types discovered in workflows.
2539
- */
2540
- registerFromWorkflows(workflows) {
2541
- for (const workflow of workflows) for (const node$1 of workflow.nodes) {
2542
- this.registerDecoratedType(node$1.type);
2543
- this.registerDecoratedType(node$1.config.type);
2544
- this.registerNestedTypes(node$1.config);
2545
- }
2546
- }
2547
- registerDecoratedType(type) {
2548
- if (this.tokenIdsByToken.has(type)) return;
2549
- const tokenId = PersistedRuntimeTypeIdFactory.fromMetadata({ type });
2550
- if (!tokenId) return;
2551
- this.tokensById.set(tokenId, type);
2552
- this.tokenIdsByToken.set(type, tokenId);
2553
- }
2554
- registerNestedTypes(value) {
2555
- if (Array.isArray(value)) {
2556
- for (const entry of value) this.registerNestedTypes(entry);
2557
- return;
2558
- }
2559
- if (!value || typeof value !== "object") return;
2560
- const record = value;
2561
- const type = this.asTypeToken(record.type);
2562
- if (type) this.registerDecoratedType(type);
2563
- for (const v of Object.values(record)) this.registerNestedTypes(v);
2564
- }
2565
- displayNameForTypeToken(token) {
2566
- if (typeof token === "function" && token.name) return token.name;
2567
- if (typeof token === "string") return token;
2568
- return "";
2569
- }
2570
- asTypeToken(value) {
2571
- if (typeof value === "function" || typeof value === "string" || typeof value === "symbol") return value;
2572
- }
2573
- getTokenId(token) {
2574
- const existing = this.tokenIdsByToken.get(token);
2575
- if (existing) return existing;
2576
- const tokenId = PersistedRuntimeTypeIdFactory.fromMetadata({ type: token });
2577
- if (!tokenId) return;
2578
- this.tokensById.set(tokenId, token);
2579
- this.tokenIdsByToken.set(token, tokenId);
2580
- return tokenId;
2581
- }
2582
- resolve(tokenId) {
2583
- return this.tokensById.get(tokenId);
2263
+ //#region src/workflowSnapshots/MissingRuntimeParityGuard.ts
2264
+ var MissingRuntimeParityGuard = class {
2265
+ constructor(marker) {
2266
+ this.marker = marker;
2267
+ }
2268
+ assertNone(workflow, nodeIds) {
2269
+ const missing = (nodeIds ? workflow.nodes.filter((n) => nodeIds.includes(n.id)) : workflow.nodes).filter((n) => this.marker.isMarked(n.config)).map((n) => ({
2270
+ nodeId: n.id,
2271
+ kind: n.kind,
2272
+ missingTokenId: n.config.missingTokenId
2273
+ }));
2274
+ if (missing.length > 0) throw new WorkflowParityMismatchError(missing);
2584
2275
  }
2585
2276
  };
2586
2277
 
2587
2278
  //#endregion
2588
- //#region src/workflowSnapshots/WorkflowSnapshotCodec.ts
2589
- var WorkflowSnapshotCodec = class {
2590
- constructor(tokenRegistry) {
2591
- this.tokenRegistry = tokenRegistry;
2592
- }
2593
- create(workflow) {
2594
- return {
2595
- id: workflow.id,
2596
- name: workflow.name,
2597
- workflowErrorHandlerConfigured: workflow.workflowErrorHandler !== void 0,
2598
- ...workflow.connections !== void 0 && workflow.connections.length > 0 ? { connections: workflow.connections } : {},
2599
- nodes: workflow.nodes.map((node$1) => {
2600
- const inspectorSummaryRows = this.safeInspectorSummary(node$1.config);
2601
- return {
2602
- id: node$1.id,
2603
- kind: node$1.kind,
2604
- name: node$1.name,
2605
- nodeTokenId: this.resolveTokenId(node$1.type),
2606
- configTokenId: this.resolveTokenId(node$1.config.type),
2607
- tokenName: this.resolveTokenName(node$1.type),
2608
- configTokenName: this.resolveTokenName(node$1.config.type),
2609
- config: this.serializeConfig(node$1.config),
2610
- ...inspectorSummaryRows !== void 0 ? { inspectorSummary: inspectorSummaryRows } : {}
2611
- };
2612
- }),
2613
- edges: workflow.edges.map((edge) => ({
2614
- from: {
2615
- nodeId: edge.from.nodeId,
2616
- output: edge.from.output
2617
- },
2618
- to: {
2619
- nodeId: edge.to.nodeId,
2620
- input: edge.to.input
2621
- }
2622
- }))
2623
- };
2624
- }
2625
- hydrate(snapshotNode, liveConfig) {
2626
- const hydrated = this.mergeValue(liveConfig, snapshotNode.config);
2627
- const configToken = this.tokenRegistry.resolve(snapshotNode.configTokenId);
2628
- Object.assign(hydrated, {
2629
- type: configToken ?? liveConfig.type,
2630
- kind: snapshotNode.kind
2631
- });
2632
- if (snapshotNode.name && !("name" in hydrated && hydrated.name)) Object.assign(hydrated, { name: snapshotNode.name });
2633
- return hydrated;
2634
- }
2635
- serializeConfig(config) {
2636
- try {
2637
- const cloned = JSON.parse(JSON.stringify(config));
2638
- this.injectTokenIds(cloned, config);
2639
- return cloned;
2640
- } catch {
2641
- const fallback = {
2642
- kind: config.kind,
2643
- name: config.name,
2644
- id: config.id,
2645
- icon: config.icon,
2646
- execution: config.execution
2647
- };
2648
- this.injectTokenIds(fallback, config);
2649
- return fallback;
2650
- }
2651
- }
2652
- /**
2653
- * Safely call `config.inspectorSummary()` and return a plain JSON-safe array, or undefined.
2654
- * Returns undefined if the method is absent, throws, or produces no valid rows.
2655
- */
2656
- safeInspectorSummary(config) {
2657
- const fn = config.inspectorSummary;
2658
- if (typeof fn !== "function") return void 0;
2659
- let raw;
2660
- try {
2661
- raw = fn.call(config);
2662
- } catch {
2663
- return;
2664
- }
2665
- if (!Array.isArray(raw)) return void 0;
2666
- const rows = [];
2667
- for (const entry of raw) {
2668
- if (!entry || typeof entry !== "object") continue;
2669
- const { label, value } = entry;
2670
- if (typeof label !== "string" || typeof value !== "string") continue;
2671
- const trimmedLabel = label.trim();
2672
- if (trimmedLabel.length === 0) continue;
2673
- rows.push({
2674
- label: trimmedLabel,
2675
- value
2676
- });
2677
- }
2678
- return rows.length > 0 ? rows : void 0;
2679
- }
2680
- injectTokenIds(target, source) {
2681
- const type = this.asTypeToken(source.type);
2682
- if (type) target.tokenId = this.tokenRegistry.getTokenId(type) ?? this.resolveTokenName(type) ?? "unknown";
2683
- for (const [key, value] of Object.entries(source)) {
2684
- if (key === "type" || value == null) continue;
2685
- if (Array.isArray(value)) {
2686
- const targetArray = target[key];
2687
- if (Array.isArray(targetArray)) value.forEach((item, index) => {
2688
- if (item && typeof item === "object" && targetArray[index] && typeof targetArray[index] === "object") this.injectTokenIds(targetArray[index], item);
2689
- });
2690
- continue;
2691
- }
2692
- if (typeof value === "object") {
2693
- const targetValue = target[key];
2694
- if (targetValue && typeof targetValue === "object") this.injectTokenIds(targetValue, value);
2695
- }
2696
- }
2697
- }
2698
- mergeValue(liveValue, snapshotValue) {
2699
- const liveRecord = this.asRecord(liveValue);
2700
- const snapshotRecord = this.asRecord(snapshotValue);
2701
- const hydrated = Object.create(liveValue && typeof liveValue === "object" ? Object.getPrototypeOf(liveValue) ?? Object.prototype : Object.prototype);
2702
- for (const [key, value] of Object.entries(snapshotRecord)) hydrated[key] = this.mergeNestedValue(liveRecord[key], value);
2703
- this.restoreNonSerializableProperties(liveRecord, hydrated);
2704
- this.restoreTypeProperty(hydrated);
2705
- return hydrated;
2706
- }
2707
- mergeNestedValue(liveValue, snapshotValue) {
2708
- if (Array.isArray(snapshotValue)) {
2709
- const liveArray = Array.isArray(liveValue) ? liveValue : [];
2710
- return snapshotValue.map((entry, index) => this.mergeNestedValue(liveArray[index], entry));
2711
- }
2712
- if (snapshotValue && typeof snapshotValue === "object") return this.mergeValue(liveValue, snapshotValue);
2713
- return snapshotValue;
2714
- }
2715
- restoreNonSerializableProperties(liveRecord, hydrated) {
2716
- for (const [key, value] of Object.entries(liveRecord)) if (typeof value === "function" || typeof value === "symbol") hydrated[key] = value;
2717
- for (const sym of Object.getOwnPropertySymbols(liveRecord)) hydrated[sym] = liveRecord[sym];
2718
- }
2719
- restoreTypeProperty(record) {
2720
- const tokenId = typeof record.tokenId === "string" ? record.tokenId : void 0;
2721
- if (!tokenId) return;
2722
- const type = this.tokenRegistry.resolve(tokenId);
2723
- if (type) record.type = type;
2724
- }
2725
- resolveTokenId(token) {
2726
- return this.tokenRegistry.getTokenId(token) ?? this.resolveTokenName(token) ?? "unknown";
2727
- }
2728
- resolveTokenName(token) {
2729
- if (typeof token === "function" && token.name) return token.name;
2730
- if (typeof token === "string") return token;
2731
- }
2732
- asTypeToken(value) {
2733
- if (typeof value === "function" || typeof value === "string" || typeof value === "symbol") return value;
2734
- }
2735
- asRecord(value) {
2736
- if (!value || typeof value !== "object" || Array.isArray(value)) return {};
2737
- const record = value;
2738
- const out = { ...record };
2739
- for (const sym of Object.getOwnPropertySymbols(value)) out[sym] = record[sym];
2740
- return out;
2279
+ //#region src/workflowSnapshots/MissingRuntimeTrigger.ts
2280
+ var MissingRuntimeTrigger = class {
2281
+ kind = "trigger";
2282
+ outputPorts = ["main"];
2283
+ async setup(_ctx) {}
2284
+ async execute(items) {
2285
+ return { main: items };
2741
2286
  }
2742
2287
  };
2743
2288
 
@@ -3006,9 +2551,6 @@ var NodeRunStateWriterFactory = class {
3006
2551
 
3007
2552
  //#endregion
3008
2553
  //#region src/execution/PersistedRunStateTerminalBuilder.ts
3009
- /**
3010
- * Merges common terminal-run fields onto a loaded {@link PersistedRunState} without repeating object literals.
3011
- */
3012
2554
  var PersistedRunStateTerminalBuilder = class {
3013
2555
  mergeTerminal(args) {
3014
2556
  return {
@@ -3106,9 +2648,6 @@ var RunStateSemantics = class {
3106
2648
 
3107
2649
  //#endregion
3108
2650
  //#region src/execution/WorkflowRunExecutionContextFactory.ts
3109
- /**
3110
- * Shared {@link ExecutionContextFactory#create} wiring for workflow runners (base context before node-specific fields).
3111
- */
3112
2651
  var WorkflowRunExecutionContextFactory = class {
3113
2652
  constructor(executionContextFactory, credentialResolverFactory) {
3114
2653
  this.executionContextFactory = executionContextFactory;
@@ -3227,7 +2766,7 @@ var WorkflowTopology = class WorkflowTopology {
3227
2766
  //#endregion
3228
2767
  //#region src/orchestration/RunContinuationService.ts
3229
2768
  var RunContinuationService = class {
3230
- constructor(activationIdFactory, workflowExecutionRepository, runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy) {
2769
+ constructor(activationIdFactory, workflowExecutionRepository, runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy, parityGuard) {
3231
2770
  this.activationIdFactory = activationIdFactory;
3232
2771
  this.workflowExecutionRepository = workflowExecutionRepository;
3233
2772
  this.runDataFactory = runDataFactory;
@@ -3245,6 +2784,7 @@ var RunContinuationService = class {
3245
2784
  this.policyErrorServices = policyErrorServices;
3246
2785
  this.terminalPersistence = terminalPersistence;
3247
2786
  this.executionLimitsPolicy = executionLimitsPolicy;
2787
+ this.parityGuard = parityGuard;
3248
2788
  }
3249
2789
  async markNodeRunning(args) {
3250
2790
  const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(args.runId), this.workflowExecutionRepository.loadSchedulingState(args.runId)]);
@@ -3487,6 +3027,7 @@ var RunContinuationService = class {
3487
3027
  nodeDefinition: def
3488
3028
  });
3489
3029
  try {
3030
+ this.parityGuard.assertNone(wf, [next.nodeId]);
3490
3031
  const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
3491
3032
  runId: state.runId,
3492
3033
  workflowId: state.workflowId,
@@ -3658,20 +3199,6 @@ var RunContinuationService = class {
3658
3199
  async waitForWebhookResponse(runId) {
3659
3200
  return await this.waiters.waitForWebhookResponse(runId);
3660
3201
  }
3661
- /**
3662
- * Re-activate a previously suspended run item with a human decision.
3663
- *
3664
- * Called by the HITL resume endpoint. This method:
3665
- * 1. Loads `PersistedRunState` and locates the suspension entry by `taskId`.
3666
- * 2. Removes the entry from the `suspension` array; if empty, run stays `"suspended"` until
3667
- * enqueue flips it to `"pending"`.
3668
- * 3. Writes `pendingResume` onto the state so `NodeExecutionRequestHandlerService` can
3669
- * splice `resumeContext` into the node's execution context.
3670
- * 4. Reconstructs the original input from `outputsByNode` of the upstream node and
3671
- * enqueues a new activation via `activationEnqueueService`.
3672
- *
3673
- * @throws if the run is not found, not suspended, or the `taskId` is unknown.
3674
- */
3675
3202
  async resumeRun(args) {
3676
3203
  const state = await this.workflowExecutionRepository.load(args.runId);
3677
3204
  if (!state) throw new Error(`Unknown runId: ${args.runId}`);
@@ -3730,6 +3257,7 @@ var RunContinuationService = class {
3730
3257
  batchId,
3731
3258
  input: resumeInput
3732
3259
  });
3260
+ this.parityGuard.assertNone(wf, [suspensionEntry.nodeId]);
3733
3261
  const { result, queuedSnapshot } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
3734
3262
  runId: state.runId,
3735
3263
  workflowId: state.workflowId,
@@ -3964,6 +3492,7 @@ var RunContinuationService = class {
3964
3492
  nodeDefinition: nextDefinition
3965
3493
  });
3966
3494
  try {
3495
+ this.parityGuard.assertNone(args.workflow, [next.nodeId]);
3967
3496
  const { queuedSnapshot, result } = await this.activationEnqueueService.enqueueActivationWithSnapshot({
3968
3497
  runId: args.state.runId,
3969
3498
  workflowId: args.state.workflowId,
@@ -4078,10 +3607,6 @@ var RunContinuationService = class {
4078
3607
  engineMaxSubworkflowDepth: state.executionOptions?.maxSubworkflowDepth ?? fb.maxSubworkflowDepth
4079
3608
  };
4080
3609
  }
4081
- /**
4082
- * Next activation could not be enqueued (e.g. input contract / mapping failed in the preparer).
4083
- * Marks the target node failed and terminates the run.
4084
- */
4085
3610
  async terminateRunAfterActivationEnqueueRejected(args) {
4086
3611
  const finishedAt = args.completedAt;
4087
3612
  const inputsByPort = NodeInputsByPortFactory.fromRequest(args.request);
@@ -4138,11 +3663,6 @@ var RunContinuationService = class {
4138
3663
  this.waiters.resolveRunCompletion(result);
4139
3664
  return result;
4140
3665
  }
4141
- /**
4142
- * Inspects node outputs for a `decision.status` written by `defineHumanApprovalNode`.
4143
- * Returns the first-class HITL node status and halt classification, or `undefined`
4144
- * when the node is not a HITL approval node.
4145
- */
4146
3666
  resolveHitlStatus(outputs) {
4147
3667
  const firstItem = outputs?.main?.[0];
4148
3668
  const decisionStatus = firstItem && typeof firstItem === "object" && "json" in firstItem && firstItem.json && typeof firstItem.json === "object" && "decision" in firstItem.json && firstItem.json.decision && typeof firstItem.json.decision === "object" && "status" in firstItem.json.decision ? firstItem.json.decision.status : void 0;
@@ -4183,7 +3703,6 @@ var CurrentStateFrontierPlanner = class CurrentStateFrontierPlanner {
4183
3703
  constructor(topology) {
4184
3704
  this.topology = topology;
4185
3705
  }
4186
- /** Composition-root-friendly factory (avoids `new` at orchestration call sites under ESLint manual-DI rules). */
4187
3706
  static createFromTopology(topology) {
4188
3707
  return new CurrentStateFrontierPlanner(topology);
4189
3708
  }
@@ -4935,12 +4454,6 @@ var DefaultDrivingScheduler = class {
4935
4454
  }
4936
4455
  return await this.prepareInlineDispatch(request);
4937
4456
  }
4938
- /**
4939
- * Scheduler precedence is explicit:
4940
- * 1. run-intent override (`executionOptions.localOnly`)
4941
- * 2. node-level execution hint / queue policy
4942
- * 3. container-default scheduler policy fallback
4943
- */
4944
4457
  async selectScheduler(request) {
4945
4458
  if (request.executionOptions?.localOnly) return {
4946
4459
  mode: "local",
@@ -5006,14 +4519,6 @@ var InlineDrivingScheduler = class {
5006
4519
  setContinuation(continuation) {
5007
4520
  this.continuation = continuation;
5008
4521
  }
5009
- /**
5010
- * Prevents new drain cycles from being scheduled and waits for all currently-running
5011
- * drains to complete. Call before closing the DB connection or rolling back test transactions
5012
- * to ensure no in-flight writes hit a closed/rolled-back connection.
5013
- *
5014
- * Bounded: only the drains already in-flight at call time are awaited. Runs that keep
5015
- * re-scheduling will not schedule new work once stopped is set.
5016
- */
5017
4522
  async stop() {
5018
4523
  this.stopped = true;
5019
4524
  if (this.activeDrainPromises.size > 0) await Promise.allSettled(this.activeDrainPromises);
@@ -5125,24 +4630,16 @@ var LocalOnlyScheduler = class {
5125
4630
 
5126
4631
  //#endregion
5127
4632
  //#region src/policies/executionLimits/EngineExecutionLimitsPolicy.ts
5128
- /** Framework defaults for {@link EngineExecutionLimitsPolicy} (merged with host `runtime.engineExecutionLimits`). */
5129
4633
  const ENGINE_EXECUTION_LIMITS_DEFAULTS = {
5130
4634
  defaultMaxNodeActivations: 1e5,
5131
4635
  hardMaxNodeActivations: 1e5,
5132
4636
  defaultMaxSubworkflowDepth: 32,
5133
4637
  hardMaxSubworkflowDepth: 32
5134
4638
  };
5135
- /**
5136
- * Resolves per-run execution limits: defaults, hard ceilings, and subworkflow depth for new runs.
5137
- */
5138
4639
  var EngineExecutionLimitsPolicy = class {
5139
4640
  constructor(config = ENGINE_EXECUTION_LIMITS_DEFAULTS) {
5140
4641
  this.config = config;
5141
4642
  }
5142
- /**
5143
- * Effective options for a new root run (depth 0): defaults merged with engine ceilings.
5144
- * Replaces a separate one-method factory for root-run bootstrap.
5145
- */
5146
4643
  createRootExecutionOptions() {
5147
4644
  return this.mergeExecutionOptionsForNewRun(void 0, void 0);
5148
4645
  }
@@ -5370,10 +4867,6 @@ var InMemoryRunDataFactory = class {
5370
4867
 
5371
4868
  //#endregion
5372
4869
  //#region src/triggers/polling/PollingTriggerDedupWindow.ts
5373
- /**
5374
- * Merges processed-ID windows for polling triggers, capping the total to avoid unbounded growth.
5375
- * Plugin code receives an instance of this class via {@link PollingTriggerHandle.dedup}.
5376
- */
5377
4870
  var PollingTriggerDedupWindow = class PollingTriggerDedupWindow {
5378
4871
  static defaultCapN = 2e3;
5379
4872
  merge(previous, incoming, capN = PollingTriggerDedupWindow.defaultCapN) {
@@ -5387,11 +4880,6 @@ var PollingTriggerDedupWindow = class PollingTriggerDedupWindow {
5387
4880
 
5388
4881
  //#endregion
5389
4882
  //#region src/triggers/polling/PollingTriggerRuntime.ts
5390
- /**
5391
- * Generic polling-trigger runtime. Owns the set-interval loop, overlap guard, and persistence.
5392
- * Constructed by {@link import("../../runtime/EngineFactory").EngineFactory} and exposed to plugin
5393
- * authors via {@link import("../../contracts/runtimeTypes").TriggerSetupContext}.polling.
5394
- */
5395
4883
  var PollingTriggerRuntime = class {
5396
4884
  activeTriggers = /* @__PURE__ */ new Set();
5397
4885
  intervalsByTrigger = /* @__PURE__ */ new Map();
@@ -5493,7 +4981,7 @@ var NoOpPollingTriggerLogger = class {
5493
4981
  //#endregion
5494
4982
  //#region src/orchestration/NodeExecutionRequestHandlerService.ts
5495
4983
  var NodeExecutionRequestHandlerService = class {
5496
- constructor(workflowExecutionRepository, workflowSnapshotResolver, runDataFactory, runExecutionContextFactory, nodeStatePublisherFactory, nodeActivationRequestComposer, nodeExecutor, continuation, executionLimitsPolicy) {
4984
+ constructor(workflowExecutionRepository, workflowSnapshotResolver, runDataFactory, runExecutionContextFactory, nodeStatePublisherFactory, nodeActivationRequestComposer, nodeExecutor, continuation, executionLimitsPolicy, parityGuard) {
5497
4985
  this.workflowExecutionRepository = workflowExecutionRepository;
5498
4986
  this.workflowSnapshotResolver = workflowSnapshotResolver;
5499
4987
  this.runDataFactory = runDataFactory;
@@ -5503,6 +4991,7 @@ var NodeExecutionRequestHandlerService = class {
5503
4991
  this.nodeExecutor = nodeExecutor;
5504
4992
  this.continuation = continuation;
5505
4993
  this.executionLimitsPolicy = executionLimitsPolicy;
4994
+ this.parityGuard = parityGuard;
5506
4995
  }
5507
4996
  async handleNodeExecutionRequest(request) {
5508
4997
  const [state, schedulingState] = await Promise.all([this.workflowExecutionRepository.load(request.runId), this.workflowExecutionRepository.loadSchedulingState(request.runId)]);
@@ -5586,6 +5075,7 @@ var NodeExecutionRequestHandlerService = class {
5586
5075
  });
5587
5076
  let outputs;
5588
5077
  try {
5078
+ this.parityGuard.assertNone(workflow, [request.nodeId]);
5589
5079
  outputs = await this.nodeExecutor.execute(activationRequest);
5590
5080
  } catch (error) {
5591
5081
  if (error instanceof RunSuspendedError) return;
@@ -5760,12 +5250,6 @@ var RunQueuePlanner = class {
5760
5250
  const received = queueEntry.collect.received;
5761
5251
  for (const input$1 of queueEntry.collect.expectedInputs ?? []) if (!(input$1 in received)) received[input$1] = [];
5762
5252
  }
5763
- /**
5764
- * Matches `CurrentStateFrontierPlanner.buildFrontierQueue`: anything that is not exactly one input
5765
- * port named `in` participates in multi-port collect (Merge after `If` branches, etc.). Routing must
5766
- * not depend solely on `nodeInstances.get(toNodeId)?.executeMulti`, or a Merge can be enqueued as a
5767
- * single-input job and `NodeExecutor` will call `execute` on a multi-input-only implementation.
5768
- */
5769
5253
  usesTopologyCollectMerge(toNodeId) {
5770
5254
  const expectedInputs = this.topology.expectedInputsByNode.get(toNodeId) ?? [];
5771
5255
  if (expectedInputs.length !== 1 || expectedInputs[0] !== "in") return true;
@@ -6165,11 +5649,6 @@ var EngineWaiters = class {
6165
5649
 
6166
5650
  //#endregion
6167
5651
  //#region src/orchestration/Engine.ts
6168
- /**
6169
- * Runtime facade for orchestration, continuation, triggers, and webhook routing.
6170
- * Prefer {@link import("../intents/RunIntentService").RunIntentService} for host/HTTP invocation boundaries.
6171
- * The class token is exported from `@codemation/core/bootstrap` (not the main `@codemation/core` barrel).
6172
- */
6173
5652
  var Engine = class {
6174
5653
  constructor(deps) {
6175
5654
  this.deps = deps;
@@ -6243,10 +5722,6 @@ var Engine = class {
6243
5722
  async waitForWebhookResponse(runId) {
6244
5723
  return await this.deps.runContinuationService.waitForWebhookResponse(runId);
6245
5724
  }
6246
- /**
6247
- * Re-activate a suspended run item with a human decision (HITL).
6248
- * The HTTP resume endpoint calls this; this method exposes the engine primitive.
6249
- */
6250
5725
  async resumeRun(args) {
6251
5726
  return await this.deps.runContinuationService.resumeRun(args);
6252
5727
  }
@@ -6257,11 +5732,6 @@ var Engine = class {
6257
5732
 
6258
5733
  //#endregion
6259
5734
  //#region src/runtime/EngineFactory.ts
6260
- /**
6261
- * Composes the {@link Engine} graph from {@link EngineCompositionDeps}. Production wiring usually goes through
6262
- * {@link import("../bootstrap/runtime/EngineRuntimeRegistrar").EngineRuntimeRegistrar}; this factory remains for tests and custom composition.
6263
- * Exported from `@codemation/core/bootstrap` (not the main `@codemation/core` barrel).
6264
- */
6265
5735
  var EngineFactory = class {
6266
5736
  create(deps) {
6267
5737
  const waiters = new EngineWaiters();
@@ -6273,7 +5743,9 @@ var EngineFactory = class {
6273
5743
  const workflowSnapshotCodec = deps.workflowSnapshotCodec ?? new WorkflowSnapshotCodec(deps.tokenRegistry);
6274
5744
  const missingRuntimeFallbacks = deps.missingRuntimeFallbacks ?? new MissingRuntimeFallbacks();
6275
5745
  const workflowSnapshotResolver = new WorkflowSnapshotResolver(deps.workflowRepository, deps.tokenRegistry, workflowSnapshotCodec, missingRuntimeFallbacks);
6276
- const semantics = new RunStateSemantics(new MissingRuntimeExecutionMarker());
5746
+ const missingRuntimeExecutionMarker = new MissingRuntimeExecutionMarker();
5747
+ const semantics = new RunStateSemantics(missingRuntimeExecutionMarker);
5748
+ const parityGuard = new MissingRuntimeParityGuard(missingRuntimeExecutionMarker);
6277
5749
  const nodeActivationRequestInputPreparer = new NodeActivationRequestInputPreparer(deps.workflowNodeInstanceFactory);
6278
5750
  const activationEnqueueService = new ActivationEnqueueService(deps.activationScheduler, deps.workflowExecutionRepository, nodeEventPublisher, nodeActivationRequestInputPreparer);
6279
5751
  const runExecutionContextFactory = new WorkflowRunExecutionContextFactory(deps.executionContextFactory, credentialResolverFactory);
@@ -6283,8 +5755,8 @@ var EngineFactory = class {
6283
5755
  const terminalPersistence = new RunTerminalPersistenceCoordinator(deps.workflowExecutionRepository, storagePolicyEvaluator);
6284
5756
  const policyErrorServices = new WorkflowPolicyErrorServices(deps.nodeResolver);
6285
5757
  const runStartService = new RunStartService(deps.runIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, workflowSnapshotCodec, planningFactory, nodeStatePublisherFactory, runExecutionContextFactory, nodeActivationRequestComposer, activationEnqueueService, semantics, waiters, deps.workflowPolicyRuntimeDefaults, executionLimitsPolicy, nodeEventPublisher, persistedRunStateTerminalBuilder);
6286
- const runContinuationService = new RunContinuationService(deps.activationIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy);
6287
- const nodeExecutionRequestHandler = new NodeExecutionRequestHandlerService(deps.workflowExecutionRepository, workflowSnapshotResolver, deps.runDataFactory, runExecutionContextFactory, nodeStatePublisherFactory, nodeActivationRequestComposer, deps.nodeExecutor, runContinuationService, executionLimitsPolicy);
5758
+ const runContinuationService = new RunContinuationService(deps.activationIdFactory, deps.workflowExecutionRepository, deps.runDataFactory, runExecutionContextFactory, workflowSnapshotResolver, planningFactory, nodeStatePublisherFactory, credentialResolverFactory, nodeActivationRequestComposer, persistedRunStateTerminalBuilder, activationEnqueueService, nodeEventPublisher, semantics, waiters, policyErrorServices, terminalPersistence, executionLimitsPolicy, parityGuard);
5759
+ const nodeExecutionRequestHandler = new NodeExecutionRequestHandlerService(deps.workflowExecutionRepository, workflowSnapshotResolver, deps.runDataFactory, runExecutionContextFactory, nodeStatePublisherFactory, nodeActivationRequestComposer, deps.nodeExecutor, runContinuationService, executionLimitsPolicy, parityGuard);
6288
5760
  const pollingTriggerLogger = deps.pollingTriggerLogger ?? new NoOpPollingTriggerLogger();
6289
5761
  const pollingTriggerDedupWindow = new PollingTriggerDedupWindow();
6290
5762
  const pollingTriggerRuntime = new PollingTriggerRuntime(deps.triggerSetupStateRepository, pollingTriggerLogger);
@@ -6467,10 +5939,6 @@ var RunIntentService = class {
6467
5939
  };
6468
5940
  })]);
6469
5941
  }
6470
- /**
6471
- * Webhook-triggered runs always force inline execution first.
6472
- * This is the highest-precedence scheduler override: it wins over node hints and container defaults.
6473
- */
6474
5942
  createWebhookExecutionOptions() {
6475
5943
  return {
6476
5944
  localOnly: true,
@@ -6489,10 +5957,6 @@ var RunIntentServiceFactory = class {
6489
5957
 
6490
5958
  //#endregion
6491
5959
  //#region src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts
6492
- /**
6493
- * Resolves webhook HTTP routes from the live workflow repository (no trigger setup / registration).
6494
- * Maintains an in-memory index keyed by user-defined endpoint path for O(1) lookups after reload.
6495
- */
6496
5960
  var WorkflowRepositoryWebhookTriggerMatcher = class {
6497
5961
  routeByPath = /* @__PURE__ */ new Map();
6498
5962
  engineRoutesActive = false;
@@ -6582,5 +6046,5 @@ var WorkflowRepositoryWebhookTriggerMatcherFactory = class {
6582
6046
  };
6583
6047
 
6584
6048
  //#endregion
6585
- export { CostTrackingTelemetryAttributeNames as $, PersistedWorkflowTokenRegistry as A, node as At, CatalogBackedCostTrackingTelemetryFactory as B, HumanTaskStoreToken as Bt, DefaultDrivingScheduler as C, WhenBuilder as Ct, NodeInstanceFactoryFactory as D, defineNode as Dt, StaticCostCatalog as E, defineBatchNode as Et, InProcessRetryRunnerFactory as F, PersistedRuntimeTypeNameResolver as Ft, AllWorkflowsActiveWorkflowActivationPolicy as G, CodemationTelemetryMetricNames as H, RunnableOutputBehaviorResolver as I, DefinedNodeRegistry as It, NoOpNodeExecutionTelemetry as J, NoOpExecutionTelemetryFactory as K, NodeOutputNormalizer as L, HitlResumeTokenSignerToken as Lt, NodeExecutorFactory as M, InjectableRuntimeDecoratorComposer as Mt, NodeExecutor as N, PersistedRuntimeTypeMetadataStore as Nt, NodeInstanceFactory as O, chatModel as Ot, RunSuspendedError as P, StackTraceCallSitePathResolver as Pt, NoOpCostTrackingTelemetry as Q, ItemExprResolver as R, HitlTimeoutJobSchedulerToken as Rt, HintOnlyOffloadPolicy as S, ChainCursor as St, RunPolicySnapshotFactory as T, isHumanApprovalNode as Tt, GenAiTelemetryAttributeNames as U, DefaultExecutionContextFactory as V, CodemationTelemetryAttributeNames as W, NoOpTelemetryArtifactReference as X, NoOpTelemetrySpanScope as Y, NoOpCostTrackingTelemetryFactory as Z, RunTerminalPersistenceCoordinator as _, WorkflowExecutableNodeClassifier as _t, InMemoryLiveWorkflowRepository as a, isPortsEmission as at, LocalOnlyScheduler as b, WorkflowDefinitionError as bt, EngineFactory as c, CredentialResolverFactory as ct, PollingTriggerRuntime as d, DefaultExecutionBinaryService as dt, CostTrackingTelemetryMetricNames as et, PollingTriggerDedupWindow as f, UnavailableBinaryStorage as ft, WorkflowPolicyErrorServices as g, WorkflowExecutableNodeClassifierFactory as gt, WorkflowStoragePolicyEvaluator as h, DefaultWorkflowGraphFactory as ht, RunIntentService as i, emitPorts as it, MissingRuntimeTriggerToken as j, tool as jt, WorkflowSnapshotCodec as k, getPersistedRuntimeTypeMetadata as kt, Engine as l, getOriginIndexFromItem as lt, InMemoryBinaryStorage as m, ConnectionInvocationEventPublisher as mt, WorkflowRepositoryWebhookTriggerMatcher as n, RetryPolicy as nt, EngineWorkflowRunnerServiceFactory as o, isUnbrandedPortsEmissionShape as ot, InMemoryRunDataFactory as p, NodeEventPublisher as pt, NoOpExecutionTelemetry as q, RunIntentServiceFactory as r, NoRetryPolicy as rt, EngineWorkflowRunnerService as s, DefaultAsyncSleeper as st, WorkflowRepositoryWebhookTriggerMatcherFactory as t, ExpRetryPolicy as tt, NoOpPollingTriggerLogger as u, ChildExecutionScopeFactory as ut, ENGINE_EXECUTION_LIMITS_DEFAULTS as v, ConnectionInvocationIdFactory as vt, ConfigDrivenOffloadPolicy as w, defineHumanApprovalNode as wt, InlineDrivingScheduler as x, NodeIdSlugifier as xt, EngineExecutionLimitsPolicy as y, WorkflowBuilder as yt, InProcessRetryRunner as z, HitlWorkspaceIdToken as zt };
6586
- //# sourceMappingURL=runtime-CWPdvJpC.js.map
6049
+ export { CostTrackingTelemetryAttributeNames as $, WorkflowParityMismatchError as A, HitlResumeTokenSignerToken as At, CatalogBackedCostTrackingTelemetryFactory as B, DefaultDrivingScheduler as C, mergeForward as Ct, NodeInstanceFactoryFactory as D, defineBatchNode as Dt, StaticCostCatalog as E, isHumanApprovalNode as Et, InProcessRetryRunnerFactory as F, AllWorkflowsActiveWorkflowActivationPolicy as G, CodemationTelemetryMetricNames as H, RunnableOutputBehaviorResolver as I, NoOpNodeExecutionTelemetry as J, NoOpExecutionTelemetryFactory as K, NodeOutputNormalizer as L, NodeExecutorFactory as M, HitlWorkspaceIdToken as Mt, NodeExecutor as N, HumanTaskStoreToken as Nt, NodeInstanceFactory as O, defineNode as Ot, RunSuspendedError as P, NoOpCostTrackingTelemetry as Q, ItemExprResolver as R, HintOnlyOffloadPolicy as S, ChainCursor as St, RunPolicySnapshotFactory as T, defineHumanApprovalNode as Tt, GenAiTelemetryAttributeNames as U, DefaultExecutionContextFactory as V, CodemationTelemetryAttributeNames as W, NoOpTelemetryArtifactReference as X, NoOpTelemetrySpanScope as Y, NoOpCostTrackingTelemetryFactory as Z, RunTerminalPersistenceCoordinator as _, WorkflowExecutableNodeClassifier as _t, InMemoryLiveWorkflowRepository as a, isPortsEmission as at, LocalOnlyScheduler as b, WorkflowDefinitionError as bt, EngineFactory as c, CredentialResolverFactory as ct, PollingTriggerRuntime as d, DefaultExecutionBinaryService as dt, CostTrackingTelemetryMetricNames as et, PollingTriggerDedupWindow as f, UnavailableBinaryStorage as ft, WorkflowPolicyErrorServices as g, WorkflowExecutableNodeClassifierFactory as gt, WorkflowStoragePolicyEvaluator as h, DefaultWorkflowGraphFactory as ht, RunIntentService as i, emitPorts as it, MissingRuntimeTriggerToken as j, HitlTimeoutJobSchedulerToken as jt, MissingRuntimeParityGuard as k, DefinedNodeRegistry as kt, Engine as l, getOriginIndexFromItem as lt, InMemoryBinaryStorage as m, ConnectionInvocationEventPublisher as mt, WorkflowRepositoryWebhookTriggerMatcher as n, RetryPolicy as nt, EngineWorkflowRunnerServiceFactory as o, isUnbrandedPortsEmissionShape as ot, InMemoryRunDataFactory as p, NodeEventPublisher as pt, NoOpExecutionTelemetry as q, RunIntentServiceFactory as r, NoRetryPolicy as rt, EngineWorkflowRunnerService as s, DefaultAsyncSleeper as st, WorkflowRepositoryWebhookTriggerMatcherFactory as t, ExpRetryPolicy as tt, NoOpPollingTriggerLogger as u, ChildExecutionScopeFactory as ut, ENGINE_EXECUTION_LIMITS_DEFAULTS as v, ConnectionInvocationIdFactory as vt, ConfigDrivenOffloadPolicy as w, WhenBuilder as wt, InlineDrivingScheduler as x, NodeIdSlugifier as xt, EngineExecutionLimitsPolicy as y, WorkflowBuilder as yt, InProcessRetryRunner as z };
6050
+ //# sourceMappingURL=runtime-CBFDpmiz.js.map