@codemation/core 0.14.0 → 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 (208) hide show
  1. package/CHANGELOG.md +68 -0
  2. package/dist/{CostCatalogContract-B9aYIqJu.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-C3rIszrW.d.cts → InMemoryRunDataFactory-D2U9azmZ.d.cts} +2 -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-UCpn7luX.d.cts → ItemsInputNormalizer-A5txcOWX.d.cts} +3 -98
  11. package/dist/{ItemsInputNormalizer-B9SdLG24.cjs → ItemsInputNormalizer-C1fv3sMW.cjs} +2 -2
  12. package/dist/ItemsInputNormalizer-C1fv3sMW.cjs.map +1 -0
  13. package/dist/{ItemsInputNormalizer-DoOawd9R.d.ts → ItemsInputNormalizer-D2vrMrX1.d.ts} +2 -62
  14. package/dist/{ItemsInputNormalizer-CZEODg94.js → ItemsInputNormalizer-fUYo4GLV.js} +2 -2
  15. package/dist/ItemsInputNormalizer-fUYo4GLV.js.map +1 -0
  16. package/dist/{RunIntentService-0f3ICjAz.d.cts → RunIntentService-DKxuHTUz.d.cts} +2 -15
  17. package/dist/{RunIntentService-Dx_HHxDX.d.ts → RunIntentService-DrpKli2k.d.ts} +2 -22
  18. package/dist/{agentMcpTypes-B11B3Hd-.d.cts → agentMcpTypes-BHX4RQCC.d.cts} +24 -524
  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-Be0LB0nh.cjs → bootstrap-CTB53rEF.cjs} +9 -60
  24. package/dist/bootstrap-CTB53rEF.cjs.map +1 -0
  25. package/dist/{bootstrap-pSQdsMfa.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-CX9Ql8N1.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-CbJdbIHe.d.ts → index-CRv3_pY3.d.ts} +87 -870
  45. package/dist/{index-uPnD9EE6.d.ts → index-mnLS0iQl.d.ts} +27 -400
  46. package/dist/index.cjs +44 -115
  47. package/dist/index.cjs.map +1 -1
  48. package/dist/index.d.cts +17 -524
  49. package/dist/index.d.ts +5 -5
  50. package/dist/index.js +21 -98
  51. package/dist/index.js.map +1 -1
  52. package/dist/{params-Dwl10Ws9.d.cts → params-CrK4iuG1.d.cts} +2 -11
  53. package/dist/{runtime-CSunvf7A.js → runtime-CBFDpmiz.js} +46 -679
  54. package/dist/runtime-CBFDpmiz.js.map +1 -0
  55. package/dist/{runtime-n2tqRwaf.cjs → runtime-Due-FOZ2.cjs} +69 -752
  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-DhwtDRgs.cjs → workflowTypes-BW6Hhee7.cjs} +4 -229
  64. package/dist/workflowTypes-BW6Hhee7.cjs.map +1 -0
  65. package/dist/{di-CEV6wTc4.js → workflowTypes-DZtBTmKf.js} +3 -162
  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 +0 -25
  77. package/src/authoring/definePollingTrigger.types.ts +18 -152
  78. package/src/authoring/definePollingTriggerInternals.ts +0 -4
  79. package/src/authoring/nodeBaseOptions.types.ts +0 -14
  80. package/src/binaries/boundedReadBinary.types.ts +0 -16
  81. package/src/bootstrap/index.ts +8 -2
  82. package/src/bootstrap/runtime/EngineRuntimeRegistrar.ts +0 -5
  83. package/src/bootstrap/runtime/EngineRuntimeRegistration.types.ts +0 -23
  84. package/src/browser.ts +0 -3
  85. package/src/contracts/AgentBindError.ts +0 -5
  86. package/src/contracts/Clock.ts +0 -1
  87. package/src/contracts/CodemationTelemetryAttributeNames.ts +0 -10
  88. package/src/contracts/NoOpAgentMcpIntegration.ts +0 -6
  89. package/src/contracts/NoOpTelemetrySpanScope.ts +0 -7
  90. package/src/contracts/RetryPolicy.ts +0 -2
  91. package/src/contracts/agentMcpTypes.ts +0 -34
  92. package/src/contracts/assertionTypes.ts +0 -33
  93. package/src/contracts/baseTypes.ts +0 -6
  94. package/src/contracts/collectionTypes.ts +0 -25
  95. package/src/contracts/credentialTypes.ts +13 -60
  96. package/src/contracts/deploymentManifestTypes.ts +158 -0
  97. package/src/contracts/dispatchTypes.ts +29 -0
  98. package/src/contracts/executionPersistenceContracts.ts +0 -33
  99. package/src/contracts/hitlSeamTypes.ts +0 -14
  100. package/src/contracts/humanTaskStoreTypes.ts +0 -2
  101. package/src/contracts/inboxChannelTypes.ts +0 -9
  102. package/src/contracts/index.ts +3 -0
  103. package/src/contracts/itemExpr.ts +0 -18
  104. package/src/contracts/itemMeta.ts +0 -3
  105. package/src/contracts/mcpTypes.ts +0 -16
  106. package/src/contracts/retryPolicySpec.types.ts +0 -10
  107. package/src/contracts/runFinishedAtFactory.ts +0 -1
  108. package/src/contracts/runTypes.ts +0 -74
  109. package/src/contracts/runtimeTypes.ts +4 -131
  110. package/src/contracts/telemetryTypes.ts +0 -7
  111. package/src/contracts/testTriggerTypes.ts +0 -43
  112. package/src/contracts/triggerInvokerTypes.ts +6 -0
  113. package/src/contracts/webhookTypes.ts +0 -8
  114. package/src/contracts/workflowActivationPolicy.ts +0 -5
  115. package/src/contracts/workflowTypes.ts +4 -86
  116. package/src/contracts/workspaceFileTypes.ts +0 -72
  117. package/src/contracts.ts +18 -10
  118. package/src/credentials/CredentialMaterialProvider.types.ts +0 -28
  119. package/src/credentials/ManagedCredentialMaterialWriteError.ts +0 -6
  120. package/src/credentials/ManagedMaterialFetchError.ts +0 -6
  121. package/src/credentials/OAuthFlowExecutor.types.ts +0 -15
  122. package/src/di/CoreTokens.ts +2 -6
  123. package/src/events/ConnectionInvocationEventPublisher.ts +0 -7
  124. package/src/events/NodeEventPublisher.ts +0 -1
  125. package/src/events/runEvents.ts +0 -8
  126. package/src/execution/ActivationEnqueueService.ts +0 -10
  127. package/src/execution/ChildExecutionScopeFactory.ts +0 -13
  128. package/src/execution/FanInMergeByOriginMerger.ts +0 -11
  129. package/src/execution/InProcessRetryRunner.ts +0 -1
  130. package/src/execution/ItemExprResolver.ts +0 -3
  131. package/src/execution/NodeActivationRequestComposer.ts +0 -3
  132. package/src/execution/NodeActivationRequestInputPreparer.ts +0 -5
  133. package/src/execution/NodeExecutionSnapshotFactory.ts +0 -1
  134. package/src/execution/NodeExecutor.ts +1 -17
  135. package/src/execution/NodeSuspensionHandler.ts +1 -39
  136. package/src/execution/PersistedRunStateTerminalBuilder.ts +0 -5
  137. package/src/execution/RunSuspendedError.ts +0 -10
  138. package/src/execution/WorkflowRunExecutionContextFactory.ts +0 -3
  139. package/src/orchestration/AbortControllerFactory.ts +0 -4
  140. package/src/orchestration/Engine.ts +0 -9
  141. package/src/orchestration/NodeExecutionRequestHandlerService.ts +3 -4
  142. package/src/orchestration/RunContinuationService.ts +7 -39
  143. package/src/orchestration/RunStartService.ts +0 -7
  144. package/src/orchestration/TestSuiteOrchestrator.ts +0 -18
  145. package/src/orchestration/TestSuiteRunIdFactory.ts +0 -4
  146. package/src/orchestration/TriggerRuntimeService.ts +3 -2
  147. package/src/planning/CurrentStateFrontierPlanner.ts +0 -1
  148. package/src/planning/RunQueuePlanner.ts +0 -6
  149. package/src/policies/executionLimits/EngineExecutionLimitsPolicy.ts +0 -8
  150. package/src/policies/executionLimits/EngineExecutionLimitsPolicyFactory.ts +0 -3
  151. package/src/runStorage/RunSummaryMapper.ts +0 -1
  152. package/src/runtime/EngineFactory.ts +6 -11
  153. package/src/runtime/RunIntentService.ts +0 -4
  154. package/src/runtime/WorkflowRepositoryWebhookTriggerMatcher.ts +0 -4
  155. package/src/runtime-types/InjectableRuntimeDecoratorComposerRegistry.ts +0 -4
  156. package/src/runtime-types/PersistedRuntimeTypeMetadataStoreRegistry.ts +0 -4
  157. package/src/runtime-types/PersistedRuntimeTypeNameResolver.ts +0 -1
  158. package/src/runtime-types/persistedRuntimeTypeModelRegistry.ts +0 -4
  159. package/src/runtime-types/runtimeTypeDecorators.types.ts +0 -12
  160. package/src/scheduler/ConfigDrivenOffloadPolicy.ts +0 -1
  161. package/src/scheduler/DefaultDrivingScheduler.ts +0 -6
  162. package/src/scheduler/InlineDrivingScheduler.ts +0 -13
  163. package/src/serialization/ItemsInputNormalizer.ts +0 -5
  164. package/src/testing/CapturingScheduler.ts +0 -3
  165. package/src/testing/EngineTestKitRunIdFactory.ts +0 -3
  166. package/src/testing/ItemHarnessNode.ts +0 -3
  167. package/src/testing/ItemHarnessNodeConfig.ts +0 -4
  168. package/src/testing/PrefixedSequentialIdGenerator.ts +0 -3
  169. package/src/testing/RegistrarEngineTestKit.types.ts +0 -2
  170. package/src/testing/RejectingCredentialSessionService.ts +0 -4
  171. package/src/testing/SubWorkflowRunnerTestNode.ts +0 -3
  172. package/src/testing/WorkflowTestHarnessManualTrigger.ts +0 -3
  173. package/src/testing/WorkflowTestKitBuilder.ts +0 -4
  174. package/src/testing/WorkflowTestKitRunNodeWorkflowFactory.ts +0 -3
  175. package/src/testing.ts +0 -3
  176. package/src/triggers/polling/PollingTriggerDedupWindow.ts +0 -4
  177. package/src/triggers/polling/PollingTriggerLogger.ts +0 -5
  178. package/src/triggers/polling/PollingTriggerRuntime.ts +0 -5
  179. package/src/types/index.ts +0 -6
  180. package/src/validation/WorkflowEdgePortValidator.ts +0 -5
  181. package/src/workflow/definition/ConnectionInvocationIdFactory.ts +0 -7
  182. package/src/workflow/definition/ConnectionNodeIdFactory.ts +0 -6
  183. package/src/workflow/definition/NodeIterationIdFactory.ts +0 -13
  184. package/src/workflow/definition/WorkflowExecutableNodeClassifier.ts +0 -6
  185. package/src/workflow/dsl/ChainCursorResolver.ts +0 -20
  186. package/src/workflow/dsl/NodeIdSlugifier.ts +0 -9
  187. package/src/workflow/dsl/WhenBuilder.ts +0 -17
  188. package/src/workflow/dsl/WorkflowDefinitionError.ts +0 -9
  189. package/src/workflow/dsl/workflowBuilderTypes.ts +0 -24
  190. package/src/workflowSnapshots/MissingRuntimeParityGuard.ts +24 -0
  191. package/src/workflowSnapshots/PersistedWorkflowTokenRegistry.ts +0 -6
  192. package/src/workflowSnapshots/WorkflowParityMismatchError.ts +18 -0
  193. package/src/workflowSnapshots/WorkflowSnapshotCodec.ts +0 -5
  194. package/src/workflowSnapshots/index.ts +3 -0
  195. package/dist/EngineRuntimeRegistration.types-BYAmGMdS.d.cts +0 -81
  196. package/dist/EngineRuntimeRegistration.types-CVLI8DsJ.d.ts +0 -44
  197. package/dist/ItemsInputNormalizer-B9SdLG24.cjs.map +0 -1
  198. package/dist/ItemsInputNormalizer-CZEODg94.js.map +0 -1
  199. package/dist/bootstrap-Be0LB0nh.cjs.map +0 -1
  200. package/dist/bootstrap-pSQdsMfa.js.map +0 -1
  201. package/dist/contracts-CK0x6w_G.cjs +0 -74
  202. package/dist/contracts-CK0x6w_G.cjs.map +0 -1
  203. package/dist/contracts-DXdfTdpW.js +0 -50
  204. package/dist/contracts-DXdfTdpW.js.map +0 -1
  205. package/dist/di-CEV6wTc4.js.map +0 -1
  206. package/dist/di-DhwtDRgs.cjs.map +0 -1
  207. package/dist/runtime-CSunvf7A.js.map +0 -1
  208. package/dist/runtime-n2tqRwaf.cjs.map +0 -1
@@ -1,81 +1,26 @@
1
1
  import type { TypeToken } from "../di";
2
2
 
3
- /**
4
- * Metadata returned for a workspace file object.
5
- * Filename and contentType come from the S3 object's custom metadata
6
- * (stamped by the control plane at upload time — story 03).
7
- * The local-fs driver reads them from a companion .meta.json sidecar.
8
- */
9
3
  export interface WorkspaceFileMetadata {
10
- /** Storage key: `<workspaceId>/files/<fileId>` */
11
4
  readonly key: string;
12
- /** Last path segment of the storage key. */
13
5
  readonly fileId: string;
14
- /** Original filename as stamped by the CP at upload time. Empty string if not yet stamped (pre-story-03). */
15
6
  readonly filename: string;
16
7
  readonly contentType: string;
17
8
  readonly size: number;
18
9
  readonly lastModified: Date;
19
10
  }
20
11
 
21
- /**
22
- * Workspace-scoped port for accessing the shared workspace file pool.
23
- * Implemented in `@codemation/host`; nodes reach it via `ctx.resolve(WorkspaceFileStorageToken)`.
24
- *
25
- * Key scheme: `<workspaceId>/files/<fileId>` — but nodes never construct raw keys.
26
- * Use the workspace-level helpers (`listFiles`, `getFileByName`, `getFileById`, `writeFile`) instead.
27
- *
28
- * This adapter is SEPARATE from the run-scoped BinaryStorage — do not confuse the two.
29
- */
30
12
  export interface IWorkspaceFileStorage {
31
- /**
32
- * Lists all files in this workspace, sorted newest-first by lastModified.
33
- * Optional case-insensitive substring filter on filename.
34
- */
35
13
  listFiles(filenameFilter?: string): Promise<ReadonlyArray<WorkspaceFileMetadata>>;
36
14
 
37
- /**
38
- * Returns metadata for the newest file with the given filename in this workspace.
39
- * @throws WorkspaceFileNotFoundError when no file with that name exists.
40
- */
41
15
  getFileByName(filename: string): Promise<WorkspaceFileMetadata>;
42
16
 
43
- /**
44
- * Returns metadata for the file with the given fileId in this workspace.
45
- * @throws WorkspaceFileNotFoundError when no file with that id exists.
46
- */
47
17
  getFileById(fileId: string): Promise<WorkspaceFileMetadata>;
48
18
 
49
- /**
50
- * Returns a non-buffered stream of the stored object's bytes.
51
- * Accepts a full storage key or a fileId (prefixes as needed).
52
- * @throws WorkspaceFileNotFoundError when the key does not exist.
53
- */
54
19
  getStream(key: string): Promise<ReadableStream<Uint8Array>>;
55
20
 
56
- /**
57
- * Writes a file into the workspace's shared file pool.
58
- *
59
- * Generates a new fileId internally; the caller never constructs a raw key.
60
- * Stamps the filename into object metadata so read-side adapters can resolve
61
- * files by name without querying a registry.
62
- *
63
- * Returns the stored file's metadata (fileId, key, filename, contentType, size,
64
- * lastModified). Callers that need concierge visibility must also register a
65
- * WorkspaceFile row on the CP side via the HMAC-paired
66
- * `POST /internal/workspace-files/register` endpoint — see the host-side
67
- * `WorkspaceFileRegistrarClient`.
68
- *
69
- * @param filename Original filename; stored in object metadata.
70
- * @param body Bytes to write (contiguous — required for presigned PUT Content-Length).
71
- * @param contentType MIME type.
72
- */
73
21
  writeFile(filename: string, body: Uint8Array, contentType: string): Promise<WorkspaceFileMetadata>;
74
22
  }
75
23
 
76
- /**
77
- * Error thrown when a requested workspace file key does not exist.
78
- */
79
24
  export class WorkspaceFileNotFoundError extends Error {
80
25
  constructor(readonly key: string) {
81
26
  super(`Workspace file not found: ${key}`);
@@ -83,31 +28,14 @@ export class WorkspaceFileNotFoundError extends Error {
83
28
  }
84
29
  }
85
30
 
86
- /**
87
- * Port for registering a workflow-written file in the CP's WorkspaceFile table.
88
- * Optional: only wired when the host is paired with a control plane.
89
- * Implemented by `WorkspaceFileRegistrarClient` in `@codemation/host`.
90
- * Nodes call this after `writeFile` so the concierge can see the file via
91
- * `list_files` / `get_file`.
92
- */
93
31
  export interface IWorkspaceFileRegistrar {
94
32
  register(meta: WorkspaceFileMetadata): Promise<void>;
95
33
  }
96
34
 
97
- /**
98
- * DI token for the workspace-scoped file storage adapter.
99
- * Registered by `@codemation/host`; resolved by workspace-file nodes via `ctx.resolve(...)`.
100
- */
101
35
  export const WorkspaceFileStorageToken = Symbol.for("codemation.core.WorkspaceFileStorage") as TypeToken<
102
36
  IWorkspaceFileStorage | undefined
103
37
  >;
104
38
 
105
- /**
106
- * DI token for the optional CP registry hook.
107
- * Present only when the host is paired (managed mode). Standalone / local-fs
108
- * deployments leave this undefined — workflow-written files will be in S3/local
109
- * but will not appear in the concierge's list_files.
110
- */
111
39
  export const WorkspaceFileRegistrarToken = Symbol.for("codemation.core.WorkspaceFileRegistrar") as TypeToken<
112
40
  IWorkspaceFileRegistrar | undefined
113
41
  >;
package/src/contracts.ts CHANGED
@@ -1,28 +1,23 @@
1
- // Pure-type-only re-exports. Use this for type-only consumers that should not drag in runtime DSL or factory code.
2
- // This subpath prevents unnecessary compile-graph bloat for packages that only need types like NodeId, Items, etc.
3
-
4
1
  export type * from "./contracts/agentMcpTypes";
2
+ export type { WorkspaceId, DispatchItemMeta, WorkflowDispatch } from "./contracts/dispatchTypes";
3
+ export { serializeDispatch, deserializeDispatch } from "./contracts/dispatchTypes";
5
4
  export * from "./contracts/AgentBindError";
6
5
  export * from "./contracts/NoOpAgentMcpIntegration";
7
6
  export type * from "./contracts/baseTypes";
8
7
  export type * from "./contracts/assertionTypes";
9
- // assertionTypes also exports a runtime helper for deriving pass/fail from a score+threshold.
10
- // We keep the type-only re-export above and surface the helper explicitly here so UI consumers
11
- // (next-host) don't need to re-implement the comparison.
12
8
  export { deriveAssertionPassed, DEFAULT_ASSERTION_PASS_THRESHOLD } from "./contracts/assertionTypes";
13
9
  export type * from "./contracts/params";
14
10
  export type * from "./contracts/retryPolicySpec.types";
15
11
  export type * from "./contracts/CostCatalogContract";
16
12
  export type * from "./contracts/executionPersistenceContracts";
17
13
  export type * from "./contracts/runtimeTypes";
14
+ export type * from "./contracts/triggerInvokerTypes";
18
15
  export type * from "./contracts/telemetryTypes";
19
16
  export type * from "./contracts/testTriggerTypes";
20
17
  export type * from "./contracts/runTypes";
21
18
  export type * from "./contracts/webhookTypes";
22
19
  export type * from "./contracts/workflowTypes";
23
20
 
24
- // credentialTypes mixes types (Credential* interfaces) with runtime (CredentialUnboundError class).
25
- // Export type-only subset for pure type consumers.
26
21
  export type {
27
22
  CredentialTypeId,
28
23
  CredentialInstanceId,
@@ -44,6 +39,8 @@ export type {
44
39
  CredentialInstanceRecord,
45
40
  CredentialSessionFactoryArgs,
46
41
  CredentialSessionFactory,
42
+ CredentialAccessTokenSessionArgs,
43
+ CredentialAccessTokenSessionFactory,
47
44
  CredentialHealthTester,
48
45
  CredentialType,
49
46
  AnyCredentialType,
@@ -51,8 +48,6 @@ export type {
51
48
  CredentialTypeRegistry,
52
49
  } from "./contracts/credentialTypes";
53
50
 
54
- // CostTrackingTelemetryContract mixes types with const runtime values (metric/attribute names).
55
- // Export type-only subset for pure type consumers.
56
51
  export type {
57
52
  CostTrackingComponent,
58
53
  CostTrackingUsageRecord,
@@ -60,3 +55,16 @@ export type {
60
55
  CostTrackingTelemetry,
61
56
  CostTrackingTelemetryFactory,
62
57
  } from "./contracts/CostTrackingTelemetryContract";
58
+
59
+ export type {
60
+ DeploymentManifestSchemaVersion,
61
+ ManifestTriggerConfig,
62
+ ManifestNodeCredentialShape,
63
+ WorkflowDeploymentManifest,
64
+ } from "./contracts/deploymentManifestTypes";
65
+ export {
66
+ DEPLOYMENT_MANIFEST_SCHEMA_VERSION,
67
+ serializeManifest,
68
+ deserializeManifest,
69
+ emitWorkflowManifest,
70
+ } from "./contracts/deploymentManifestTypes";
@@ -1,35 +1,12 @@
1
1
  import type { OAuthMaterial } from "./OAuthFlowExecutor.types";
2
2
 
3
- /**
4
- * Material provider seam — see `docs/design/credentials-oauth-unification.md`,
5
- * "Material provider seam" section. Sits beside the workspace's
6
- * `CredentialStore`; persistence of the row stays at the store, persistence of
7
- * the bytes goes through this provider so they can live at the control plane
8
- * in managed mode.
9
- */
10
-
11
- /**
12
- * Pointer to material bytes. For local rows `ref` is the workspace instance id
13
- * and the bytes co-locate with the row (existing `CredentialOAuth2Material` /
14
- * `CredentialSecretMaterial` tables). For control-plane rows `ref` is the
15
- * CP-side credential id; the workspace stores only the pointer.
16
- */
17
3
  export type CredentialMaterialRef = Readonly<{
18
4
  source: "local" | "control-plane";
19
5
  id: string;
20
6
  }>;
21
7
 
22
- /**
23
- * Decrypted material bytes returned by a provider. Shape matches
24
- * `OAuthMaterial` — every supported credential type today is OAuth-shaped.
25
- */
26
8
  export type MaterialBundle = OAuthMaterial;
27
9
 
28
- /**
29
- * Caller context recorded by the CP material endpoint per fetch (D5 in the
30
- * `credentials-vault` sprint README). The local provider accepts but ignores
31
- * it; standalone mode has no audit log.
32
- */
33
10
  export type CallerContext = Readonly<{
34
11
  workspaceId: string;
35
12
  caller:
@@ -45,11 +22,6 @@ export interface CredentialMaterialProvider {
45
22
  setMaterial(ref: CredentialMaterialRef, material: MaterialBundle): Promise<void>;
46
23
  }
47
24
 
48
- /**
49
- * Thrown by a provider when asked to operate on a `ref.source` it does not
50
- * handle (e.g. the local provider being asked to read `control-plane` bytes).
51
- * Exported so `instanceof`-checks work across the workspace boundary.
52
- */
53
25
  export class IllegalMaterialSourceError extends Error {
54
26
  constructor(
55
27
  public readonly source: CredentialMaterialRef["source"],
@@ -1,9 +1,3 @@
1
- /**
2
- * Thrown by managed-mode providers when `setMaterial` is called. Managed
3
- * credential bytes are owned by the control plane; the workspace must not
4
- * mutate them. See `docs/design/credentials-oauth-unification.md` and
5
- * `planning/sprints/credentials-vault/02-controlplane-material-provider.md`.
6
- */
7
1
  export class ManagedCredentialMaterialWriteError extends Error {
8
2
  constructor(
9
3
  message: string = "managed credentials are owned by the control plane; use the Connected apps page to create or modify them.",
@@ -1,9 +1,3 @@
1
- /**
2
- * Thrown by `ControlPlaneCredentialMaterialProvider` when the control-plane
3
- * material endpoint returns a non-2xx response or a malformed body. Exposes
4
- * the HTTP status and the raw error body so call sites can surface actionable
5
- * detail without parsing strings.
6
- */
7
1
  export class ManagedMaterialFetchError extends Error {
8
2
  constructor(
9
3
  public readonly status: number,
@@ -1,13 +1,3 @@
1
- /**
2
- * Four-concept model for credentials (see docs/design/credentials-oauth-unification.md):
3
- * 1. CredentialType — schema for stored material (e.g. "oauth.google.gmail").
4
- * 2. Credential slot requirement — which types a node or MCP server accepts.
5
- * 3. CredentialInstance — a stored, usable token row in the host's credential store.
6
- * 4. OAuthFlowExecutor (this file) — the only concept that differs between deployment
7
- * modes. DI selects one implementation at boot; the rest of the system programs
8
- * against this interface alone.
9
- */
10
-
11
1
  export interface OAuthFlowStartArgs {
12
2
  readonly typeId: string;
13
3
  readonly scopes: ReadonlyArray<string>;
@@ -34,11 +24,6 @@ export interface OAuthMaterial {
34
24
 
35
25
  export interface OAuthFlowExecutor {
36
26
  start(args: OAuthFlowStartArgs): Promise<OAuthFlowStartResult>;
37
- /**
38
- * Returns the instanceId associated with a pending stateToken without consuming it.
39
- * Used by callback routes to identify the target instance before calling completeCallback.
40
- * Returns undefined when the stateToken is unknown or already consumed.
41
- */
42
27
  lookupInstanceId(stateToken: string): string | undefined;
43
28
  completeCallback(args: OAuthFlowCallbackArgs): Promise<OAuthMaterial>;
44
29
  refresh(args: { typeId: string; instanceId: string; material: OAuthMaterial }): Promise<OAuthMaterial>;
@@ -21,6 +21,7 @@ import type {
21
21
  WorkflowRepository,
22
22
  WorkflowRunnerService,
23
23
  } from "../types";
24
+ import type { TriggerInvoker } from "../contracts/triggerInvokerTypes";
24
25
 
25
26
  export const CoreTokens = {
26
27
  PersistedWorkflowTokenRegistry: Symbol.for(
@@ -51,17 +52,12 @@ export const CoreTokens = {
51
52
  RunEventBus: Symbol.for("codemation.core.RunEventBus") as TypeToken<RunEventBus>,
52
53
  BinaryStorage: Symbol.for("codemation.core.BinaryStorage") as TypeToken<BinaryStorage>,
53
54
  WebhookBasePath: Symbol.for("codemation.core.WebhookBasePath") as TypeToken<string>,
54
- /** Engine execution limits (defaults + optional host overrides). Consumers may bind a custom instance to override. */
55
55
  EngineExecutionLimitsPolicy: Symbol.for(
56
56
  "codemation.core.EngineExecutionLimitsPolicy",
57
57
  ) as TypeToken<EngineExecutionLimitsPolicy>,
58
58
  WorkflowActivationPolicy: Symbol.for(
59
59
  "codemation.core.WorkflowActivationPolicy",
60
60
  ) as TypeToken<WorkflowActivationPolicy>,
61
- /**
62
- * Optional. When registered, AIAgentNode uses it to resolve mcpServers bindings,
63
- * validate scopes, open pool connections, and prepare the MCP ToolSet map.
64
- * Not registered in the default core bootstrap — the host provides the implementation.
65
- */
66
61
  AgentMcpIntegration: Symbol.for("codemation.core.AgentMcpIntegration") as TypeToken<AgentMcpIntegration>,
62
+ TriggerInvoker: Symbol.for("codemation.core.TriggerInvoker") as TypeToken<TriggerInvoker>,
67
63
  } as const;
@@ -2,13 +2,6 @@ import type { ConnectionInvocationRecord } from "../contracts/runTypes";
2
2
  import type { ParentExecutionRef } from "../types";
3
3
  import type { RunEventBus } from "./runEvents";
4
4
 
5
- /**
6
- * Publishes per-invocation lifecycle records onto the run {@link RunEventBus}.
7
- *
8
- * Surgical, per-invocation events let the UI update the right-side inspector
9
- * timeline as each LLM round / tool call transitions through `running` → `completed`
10
- * (or `failed`) without depending on a coarse `runSaved` poll.
11
- */
12
5
  export class ConnectionInvocationEventPublisher {
13
6
  constructor(
14
7
  private readonly eventBus: RunEventBus | undefined,
@@ -1,7 +1,6 @@
1
1
  import type { RunEventBus } from "./runEvents";
2
2
  import type { NodeExecutionSnapshot } from "../types";
3
3
 
4
- /** Publishes node lifecycle snapshots onto the run {@link RunEventBus}. */
5
4
  export class NodeEventPublisher {
6
5
  constructor(private readonly eventBus: RunEventBus | undefined) {}
7
6
 
@@ -2,15 +2,7 @@ import type { TestSuiteRunId } from "../contracts/testTriggerTypes";
2
2
  import type { ConnectionInvocationRecord } from "../contracts/runTypes";
3
3
  import type { NodeExecutionSnapshot, ParentExecutionRef, PersistedRunState, RunId, WorkflowId } from "../types";
4
4
 
5
- /**
6
- * Outcome of a single test case (one workflow run dispatched by the test-suite orchestrator).
7
- * - `running`: workflow still in flight
8
- * - `succeeded`: workflow completed AND all assertions passed (or no assertions)
9
- * - `failed`: workflow failed OR (workflow completed but ≥1 assertion failed)
10
- * - `errored` / `cancelled`: workflow itself errored or was cancelled
11
- */
12
5
  export type TestCaseRunStatus = "running" | "succeeded" | "failed" | "errored" | "cancelled";
13
- /** Aggregate outcome of a TestSuiteRun. */
14
6
  export type TestSuiteRunStatus = "succeeded" | "failed" | "partial" | "errored" | "cancelled";
15
7
 
16
8
  export type RunEvent =
@@ -47,15 +47,7 @@ export type ActivationEnqueueRequest = {
47
47
  planner: RunQueuePlanner;
48
48
  engineCounters?: EngineRunCounters;
49
49
  connectionInvocations?: ReadonlyArray<ConnectionInvocationRecord>;
50
- /**
51
- * Remaining suspension entries after consuming one for a HITL resume.
52
- * When provided, saved alongside the new pending state so they survive the enqueue.
53
- */
54
50
  suspension?: ReadonlyArray<PersistedSuspensionEntry>;
55
- /**
56
- * Resume context to attach to the re-activated node's execution context.
57
- * Written here and consumed by `NodeExecutionRequestHandlerService` when building ctx.
58
- */
59
51
  pendingResume?: PendingResumeEntry;
60
52
  };
61
53
 
@@ -126,8 +118,6 @@ export class ActivationEnqueueService {
126
118
  ...args.previousNodeSnapshotsByNodeId,
127
119
  [args.request.nodeId]: queuedSnapshot,
128
120
  },
129
- // HITL: preserve suspension entries and resume context when re-activating a
130
- // suspended node. Omit fields when not provided (avoids polluting normal enqueue).
131
121
  ...(args.suspension !== undefined ? { suspension: args.suspension } : {}),
132
122
  ...(args.pendingResume !== undefined ? { pendingResume: args.pendingResume } : {}),
133
123
  });
@@ -7,19 +7,6 @@ import type {
7
7
  TelemetrySpanScope,
8
8
  } from "../types";
9
9
 
10
- /**
11
- * Builds a re-rooted child execution context for sub-agent (and other deeply-nested) invocations.
12
- *
13
- * At the orchestrator's `agent.tool.call` boundary the inner runtime needs a ctx whose:
14
- * - `nodeId` is the tool's connection node id (so inner LLM/tool connection ids derive correctly),
15
- * - `activationId` is fresh (so its connection-invocation rows are uniquely identifiable),
16
- * - `telemetry` parents children under the tool-call span (not the orchestrator's node span),
17
- * - `binary` is scoped to the new (nodeId, activationId),
18
- * - `parentInvocationId` points back to the tool-call invocation for downstream lineage.
19
- *
20
- * Registered via factory in {@link EngineRuntimeRegistrar} so constructors stay free of parameter
21
- * decorators (Next/SWC and coverage tooling cannot parse them on in-repo sources).
22
- */
23
10
  export class ChildExecutionScopeFactory {
24
11
  constructor(private readonly activationIdFactory: ActivationIdFactory) {}
25
12
 
@@ -2,17 +2,6 @@ import type { InputPortKey, Item, Items, NodeInputsByPort } from "../types";
2
2
 
3
3
  import { getOriginIndexFromItem } from "../contracts/itemMeta";
4
4
 
5
- /**
6
- * Default fan-in: combine multi-port {@link NodeInputsByPort} into one {@link Items} batch for per-item nodes.
7
- *
8
- * This is used when a single-input per-item node has multiple inbound edges (for example, branch reconverge
9
- * after an `If` / `Switch`). The default behavior is **append / union** (preserving item payloads) with a
10
- * deterministic order:
11
- *
12
- * - When router origin metadata exists (`meta._cm.originIndex`), items are sorted by origin index so the
13
- * downstream batch preserves original ordering across branches.
14
- * - Otherwise, items are appended by port-key order, preserving each port's local order.
15
- */
16
5
  export class FanInMergeByOriginMerger {
17
6
  merge(inputsByPort: NodeInputsByPort): Items {
18
7
  const portKeys = Object.keys(inputsByPort).sort();
@@ -7,7 +7,6 @@ import type { AsyncSleeper } from "./asyncSleeper.types";
7
7
 
8
8
  export type { AsyncSleeper } from "./asyncSleeper.types";
9
9
 
10
- /** Maximum permitted retry attempts — workflow-declared values above this are clamped. */
11
10
  const HARD_MAX_RETRY_ATTEMPTS = 10;
12
11
 
13
12
  type NormalizedPolicy =
@@ -1,9 +1,6 @@
1
1
  import { resolveItemExprsForExecution } from "../contracts/itemExpr";
2
2
  import type { Item, NodeExecutionContext, RunnableNodeConfig } from "../types";
3
3
 
4
- /**
5
- * Resolves {@link import("../contracts/itemExpr").ItemExpr} leaves on runnable config before {@link RunnableNode.execute}.
6
- */
7
4
  export class ItemExprResolver {
8
5
  async resolveConfigForItem<TConfig extends RunnableNodeConfig<any, any>>(
9
6
  ctx: NodeExecutionContext<TConfig>,
@@ -46,9 +46,6 @@ export type PlannedNodeActivationRequest = NodeActivationContextArgs & {
46
46
  nodeDefinition: NodeExecutionDefinition;
47
47
  };
48
48
 
49
- /**
50
- * Builds {@link NodeActivationRequest} values shared by workflow starters and continuation.
51
- */
52
49
  export class NodeActivationRequestComposer {
53
50
  constructor(
54
51
  private readonly activationIdFactory: ActivationIdFactory,
@@ -5,11 +5,6 @@ import type { Item, NodeActivationRequest, RunnableNodeConfig, WorkflowNodeInsta
5
5
  import { FanInMergeByOriginMerger } from "./FanInMergeByOriginMerger";
6
6
  import { NodeInputContractError } from "./NodeInputContractError";
7
7
 
8
- /**
9
- * Validates per-item inputs for {@link RunnableNode} before enqueue persistence (Zod on `item.json`).
10
- * Does not rewrite `item.json` (wire stays as emitted upstream; engine passes parsed input via `execute` args).
11
- * Converts multi-input activations into a single-input batch when the node is per-item only (engine fan-in).
12
- */
13
8
  export class NodeActivationRequestInputPreparer {
14
9
  private readonly fanInMerger = new FanInMergeByOriginMerger();
15
10
 
@@ -71,7 +71,6 @@ export class NodeExecutionSnapshotFactory {
71
71
  inputsByPort: NodeInputsByPort;
72
72
  outputs: NodeOutputs;
73
73
  fromPinnedOutput?: boolean;
74
- /** Override the terminal status for HITL outcomes (defaults to `"completed"`). */
75
74
  hitlStatus?: Extract<
76
75
  NodeExecutionStatus,
77
76
  "hitl-approved" | "hitl-rejected" | "hitl-timeout" | "hitl-auto-accepted" | "hitl-cancelled"
@@ -38,9 +38,7 @@ export class NodeExecutor {
38
38
  private readonly retryRunner: InProcessRetryRunner,
39
39
  itemExprResolver?: ItemExprResolver,
40
40
  outputBehaviorResolver?: RunnableOutputBehaviorResolver,
41
- /** Required for HITL suspension support. When omitted, `SuspensionRequest` throws upward. */
42
41
  private readonly suspensionHandler?: NodeSuspensionHandler,
43
- /** Required alongside `suspensionHandler`. */
44
42
  private readonly loadRunState?: (runId: RunId) => Promise<PersistedRunState | undefined>,
45
43
  ) {
46
44
  this.itemExprResolver = itemExprResolver ?? new ItemExprResolver();
@@ -190,8 +188,6 @@ export class NodeExecutor {
190
188
  const runnableCtx = request.ctx as NodeExecutionContext<RunnableNodeConfig>;
191
189
  const resolvedCtx = await this.itemExprResolver.resolveConfigForItem(runnableCtx, item, i, inputBatch);
192
190
  const baseCtx = this.pickExecutionContext(runnableCtx, resolvedCtx);
193
- // Mint a per-item iteration id and stamp it (with the item index) onto the ctx so connection
194
- // invocations and telemetry written from inside `node.execute` carry the per-item identity.
195
191
  const iterationCtx = {
196
192
  ...baseCtx,
197
193
  iterationId: NodeIterationIdFactory.create(),
@@ -208,9 +204,6 @@ export class NodeExecutor {
208
204
  try {
209
205
  raw = await Promise.resolve(node.execute(args));
210
206
  } catch (e) {
211
- // Use both instanceof AND name check: under tsx/dev with mixed source/dist resolution,
212
- // SuspensionRequest may load as two distinct class objects and instanceof fails. The
213
- // name brand survives the duality because both copies set name="SuspensionRequest".
214
207
  const isSuspension =
215
208
  e instanceof SuspensionRequest ||
216
209
  (e instanceof Error &&
@@ -218,23 +211,17 @@ export class NodeExecutor {
218
211
  typeof (e as { request?: unknown }).request === "object");
219
212
  if (isSuspension) {
220
213
  if (!this.suspensionHandler || !this.loadRunState) {
221
- // Suspension not supported in this executor configuration — propagate as a regular error.
222
214
  throw new Error(
223
215
  `Node ${request.nodeId} threw SuspensionRequest but this NodeExecutor has no suspensionHandler configured.`,
224
216
  { cause: e },
225
217
  );
226
218
  }
227
- // Per-item suspension: load current state, persist the suspension entry, and
228
- // continue processing remaining items. If deliver throws it propagates upward.
229
219
  const state = await this.loadRunState(request.runId);
230
220
  if (!state) {
231
221
  throw new Error(`NodeExecutor: run state not found for runId ${request.runId} during suspension`, {
232
222
  cause: e,
233
223
  });
234
224
  }
235
- // handleSuspension throws RunSuspendedError after persisting — we re-throw it
236
- // to exit the loop immediately. Partial byPort outputs are intentionally dropped
237
- // (TODO: consider stashing outputs of non-suspended items alongside the suspension).
238
225
  await this.suspensionHandler.handle({
239
226
  runId: request.runId,
240
227
  nodeId: request.nodeId,
@@ -244,7 +231,7 @@ export class NodeExecutor {
244
231
  state,
245
232
  telemetry: iterationCtx.telemetry,
246
233
  });
247
- hasSuspension = true; // unreachable — handler always throws, but satisfies TS control-flow
234
+ hasSuspension = true;
248
235
  continue;
249
236
  }
250
237
  throw e;
@@ -264,14 +251,11 @@ export class NodeExecutor {
264
251
  }
265
252
  }
266
253
  if (hasSuspension) {
267
- // Unreachable in practice (suspensionHandler always throws RunSuspendedError) but
268
- // guards against future refactors that might change handler behaviour.
269
254
  throw new RunSuspendedError(request.runId, "unknown");
270
255
  }
271
256
  return byPort as NodeOutputs;
272
257
  }
273
258
 
274
- /** Use resolver ctx only when {@link NodeExecutionContext.config} is non-nullish. */
275
259
  private pickExecutionContext<TConfig extends RunnableNodeConfig<any, any>>(
276
260
  runnableCtx: NodeExecutionContext<TConfig>,
277
261
  resolvedCtx: NodeExecutionContext<TConfig> | null | undefined,
@@ -19,33 +19,12 @@ import { CodemationTelemetryAttributeNames } from "../contracts/CodemationTeleme
19
19
  import { RunSuspendedError } from "./RunSuspendedError";
20
20
  export { RunSuspendedError };
21
21
 
22
- /**
23
- * Handles per-item `SuspensionRequest` catches in the engine's item execution loop.
24
- *
25
- * Responsibilities:
26
- * 1. Generate a `taskId` (UUID v4).
27
- * 2. Persist a `HumanTask` row via `HumanTaskStore.create`.
28
- * 3. Sign a resume URL via `HitlResumeTokenSigner.sign`.
29
- * 4. Enqueue a delayed BullMQ timeout job via `HitlTimeoutJobScheduler.enqueue`.
30
- * 5. Build a `HumanTaskHandle` and call `deliver`.
31
- * 6. Append a `PersistedSuspensionEntry` to the run state and flip status to `"suspended"`.
32
- * 7. Persist via `WorkflowExecutionRepository.save`.
33
- * 8. Throw `RunSuspendedError` so the caller can exit cleanly.
34
- *
35
- * If `deliver` throws, the error propagates up to `NodeExecutionRequestHandlerService`
36
- * which routes it through `resumeFromNodeError` → run status becomes `"failed"`.
37
- *
38
- * `humanTaskStore`, `tokenSigner`, and `timeoutScheduler` are optional —
39
- * when not registered (e.g. in unit tests), the handler still suspends the run but
40
- * skips persistence, token signing, and job scheduling.
41
- */
42
22
  export class NodeSuspensionHandler {
43
23
  constructor(
44
24
  private readonly workflowExecutionRepository: WorkflowExecutionRepository,
45
25
  private readonly humanTaskStore?: HumanTaskStore,
46
26
  private readonly tokenSigner?: HitlResumeTokenSignerSeam,
47
27
  private readonly timeoutScheduler?: HitlTimeoutJobSchedulerSeam,
48
- /** Workspace ID to stamp on HumanTaskRecord in managed mode (T7 security fix). Null in non-managed mode. */
49
28
  private readonly workspaceId?: string,
50
29
  ) {}
51
30
 
@@ -56,7 +35,6 @@ export class NodeSuspensionHandler {
56
35
  itemIndex: number;
57
36
  suspensionRequest: SuspensionRequest;
58
37
  state: PersistedRunState;
59
- /** Telemetry scope of the node's per-item span. Used to emit `hitl.task.*` span events. */
60
38
  telemetry?: TelemetryScope;
61
39
  }): Promise<never> {
62
40
  const taskId = `htask_${globalThis.crypto.randomUUID()}`;
@@ -68,12 +46,11 @@ export class NodeSuspensionHandler {
68
46
  const decisionSchemaHash = this.hashSchema(decisionSchema);
69
47
  const decisionSchemaJson = this.schemaToJson(decisionSchema);
70
48
 
71
- // Build resume token (when signer is available)
72
49
  let resumeUrl = "";
73
50
  let resumeTokenHash = "";
74
51
  if (this.tokenSigner) {
75
52
  const token = this.tokenSigner.sign({ taskId, expiresAt, schemaHash: decisionSchemaHash });
76
- resumeUrl = token; // callers (deliver) receive the raw token; inbox layers wrap into a URL
53
+ resumeUrl = token;
77
54
  resumeTokenHash = this.tokenSigner.hashToken(token);
78
55
  }
79
56
 
@@ -86,7 +63,6 @@ export class NodeSuspensionHandler {
86
63
  ...(metadata !== undefined ? { metadata } : {}),
87
64
  };
88
65
 
89
- // Emit hitl.task.created before calling deliver.
90
66
  const channel = (metadata as Record<string, unknown> | undefined)?.["channel"];
91
67
  await args.telemetry?.addSpanEvent?.({
92
68
  name: "hitl.task.created",
@@ -99,8 +75,6 @@ export class NodeSuspensionHandler {
99
75
  },
100
76
  });
101
77
 
102
- // D5: deliver throws → emit hitl.task.delivery_failed, then propagate upward;
103
- // caller routes to resumeFromNodeError → "failed"
104
78
  let deliveryRef: Awaited<ReturnType<typeof deliver>>;
105
79
  try {
106
80
  deliveryRef = await deliver(handle);
@@ -116,15 +90,11 @@ export class NodeSuspensionHandler {
116
90
  throw deliverError;
117
91
  }
118
92
 
119
- // Persist HumanTask row
120
93
  if (this.humanTaskStore) {
121
94
  const record: HumanTaskRecord = {
122
95
  id: taskId,
123
96
  runId: args.runId,
124
97
  workflowId: args.state.workflowId,
125
- // T7: stamp workspaceId in managed mode so HitlCallbackHandler can assert workspace identity.
126
- // Non-managed mode leaves this undefined (null in DB) — the check in HitlCallbackHandler
127
- // is guarded by `task.workspaceId !== undefined` and is a no-op when null.
128
98
  workspaceId: this.workspaceId ?? undefined,
129
99
  nodeId: args.nodeId,
130
100
  activationId: args.activationId,
@@ -144,7 +114,6 @@ export class NodeSuspensionHandler {
144
114
  await this.humanTaskStore.create(record);
145
115
  }
146
116
 
147
- // Enqueue timeout job
148
117
  if (this.timeoutScheduler) {
149
118
  await this.timeoutScheduler.enqueueTimeoutJob({ taskId, expiresAt });
150
119
  }
@@ -172,13 +141,7 @@ export class NodeSuspensionHandler {
172
141
  throw new RunSuspendedError(args.runId, taskId);
173
142
  }
174
143
 
175
- /**
176
- * Parse a duration string into milliseconds.
177
- * Accepts ISO 8601 durations ("PT24H", "PT30M") and shorthand ("24h", "30m", "1d").
178
- * Throws for unrecognised formats.
179
- */
180
144
  private parseDurationMs(duration: string): number {
181
- // Shorthand: "24h", "30m", "7d", "3600s"
182
145
  const shorthand = /^(\d+(?:\.\d+)?)(s|m|h|d)$/i.exec(duration);
183
146
  if (shorthand) {
184
147
  const value = parseFloat(shorthand[1]!);
@@ -191,7 +154,6 @@ export class NodeSuspensionHandler {
191
154
  };
192
155
  return value * multipliers[unit]!;
193
156
  }
194
- // ISO 8601 duration subset: PTnHnMnS (days handled via P1D)
195
157
  const iso = /^P(?:(\d+)D)?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$/.exec(duration);
196
158
  if (iso) {
197
159
  const days = parseFloat(iso[1] ?? "0");