tubeless 0.2.2 → 0.2.4

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 (199) hide show
  1. package/README.md +52 -52
  2. package/dist/cli/cli-types.d.ts +1 -1
  3. package/dist/cli/cli-types.js.map +1 -1
  4. package/dist/cli/cli.d.ts +2 -4
  5. package/dist/cli/cli.js +1 -3
  6. package/dist/cli/cli.js.map +1 -1
  7. package/dist/core/child-execution.js +9 -4
  8. package/dist/core/child-execution.js.map +1 -1
  9. package/dist/core/lifecycle.d.ts +1 -1
  10. package/dist/core/lifecycle.js +2 -0
  11. package/dist/core/lifecycle.js.map +1 -1
  12. package/dist/core/pipeline-compiler.d.ts +17 -0
  13. package/dist/core/pipeline-compiler.js +44 -0
  14. package/dist/core/pipeline-compiler.js.map +1 -0
  15. package/dist/core/pipeline-definition-validation.d.ts +4 -0
  16. package/dist/core/pipeline-definition-validation.js +101 -0
  17. package/dist/core/pipeline-definition-validation.js.map +1 -0
  18. package/dist/core/pipeline-definition.d.ts +28 -0
  19. package/dist/core/pipeline-definition.js +2 -0
  20. package/dist/core/pipeline-definition.js.map +1 -0
  21. package/dist/core/pipeline-disposition.d.ts +26 -0
  22. package/dist/core/pipeline-disposition.js +44 -0
  23. package/dist/core/pipeline-disposition.js.map +1 -0
  24. package/dist/core/pipeline-errors.d.ts +8 -0
  25. package/dist/core/pipeline-errors.js +20 -0
  26. package/dist/core/pipeline-errors.js.map +1 -0
  27. package/dist/core/pipeline-execute.d.ts +3 -1
  28. package/dist/core/pipeline-execute.js +136 -396
  29. package/dist/core/pipeline-execute.js.map +1 -1
  30. package/dist/core/pipeline-finalizer.d.ts +18 -0
  31. package/dist/core/pipeline-finalizer.js +37 -0
  32. package/dist/core/pipeline-finalizer.js.map +1 -0
  33. package/dist/core/pipeline-graph.d.ts +23 -0
  34. package/dist/core/pipeline-graph.js +135 -0
  35. package/dist/core/pipeline-graph.js.map +1 -0
  36. package/dist/core/pipeline-identity.d.ts +5 -0
  37. package/dist/core/pipeline-identity.js +11 -0
  38. package/dist/core/pipeline-identity.js.map +1 -0
  39. package/dist/core/pipeline-mermaid.d.ts +4 -0
  40. package/dist/core/pipeline-mermaid.js +56 -0
  41. package/dist/core/pipeline-mermaid.js.map +1 -0
  42. package/dist/core/pipeline-plan.d.ts +5 -94
  43. package/dist/core/pipeline-plan.js +5 -392
  44. package/dist/core/pipeline-plan.js.map +1 -1
  45. package/dist/core/pipeline-run-state.d.ts +49 -0
  46. package/dist/core/pipeline-run-state.js +284 -0
  47. package/dist/core/pipeline-run-state.js.map +1 -0
  48. package/dist/core/pipeline-step-executor.d.ts +20 -0
  49. package/dist/core/pipeline-step-executor.js +52 -0
  50. package/dist/core/pipeline-step-executor.js.map +1 -0
  51. package/dist/core/pipeline-step-metadata.d.ts +4 -0
  52. package/dist/core/pipeline-step-metadata.js +5 -0
  53. package/dist/core/pipeline-step-metadata.js.map +1 -0
  54. package/dist/core/pipeline-steps.d.ts +1 -1
  55. package/dist/core/pipeline-steps.js +1 -1
  56. package/dist/core/pipeline-steps.js.map +1 -1
  57. package/dist/core/pipeline-types.d.ts +17 -8
  58. package/dist/core/pipeline-types.js +8 -0
  59. package/dist/core/pipeline-types.js.map +1 -1
  60. package/dist/core/pipeline-validation.d.ts +6 -0
  61. package/dist/core/pipeline-validation.js +41 -0
  62. package/dist/core/pipeline-validation.js.map +1 -0
  63. package/dist/core/pipeline.d.ts +8 -9
  64. package/dist/core/pipeline.js +9 -6
  65. package/dist/core/pipeline.js.map +1 -1
  66. package/dist/node/node.d.ts +0 -3
  67. package/dist/node/node.js +0 -3
  68. package/dist/node/node.js.map +1 -1
  69. package/dist/reporter/reporter-entry.d.ts +1 -2
  70. package/dist/reporter/reporter-entry.js +1 -2
  71. package/dist/reporter/reporter-entry.js.map +1 -1
  72. package/dist/run-store/run-store-codec.d.ts +4 -0
  73. package/dist/run-store/run-store-codec.js +31 -0
  74. package/dist/run-store/run-store-codec.js.map +1 -0
  75. package/dist/run-store/run-store-ndjson.js +2 -295
  76. package/dist/run-store/run-store-ndjson.js.map +1 -1
  77. package/dist/run-store/run-store-sqlite.js +41 -38
  78. package/dist/run-store/run-store-sqlite.js.map +1 -1
  79. package/dist/run-store/run-store.d.ts +4 -3
  80. package/dist/run-store/run-store.js +38 -195
  81. package/dist/run-store/run-store.js.map +1 -1
  82. package/dist/studio/run-store-ui-client-app.d.ts +12 -0
  83. package/dist/studio/run-store-ui-client-app.js +224 -0
  84. package/dist/studio/run-store-ui-client-app.js.map +1 -0
  85. package/dist/studio/run-store-ui-client-browser.d.ts +1 -0
  86. package/dist/studio/run-store-ui-client-browser.js +2 -0
  87. package/dist/studio/run-store-ui-client-commands.d.ts +18 -0
  88. package/dist/studio/run-store-ui-client-commands.js +98 -0
  89. package/dist/studio/run-store-ui-client-commands.js.map +1 -0
  90. package/dist/studio/run-store-ui-client-form.d.ts +11 -0
  91. package/dist/studio/run-store-ui-client-form.js +54 -0
  92. package/dist/studio/run-store-ui-client-form.js.map +1 -0
  93. package/dist/studio/run-store-ui-client-modals.d.ts +20 -0
  94. package/dist/studio/run-store-ui-client-modals.js +154 -0
  95. package/dist/studio/run-store-ui-client-modals.js.map +1 -0
  96. package/dist/studio/run-store-ui-client-model.d.ts +19 -0
  97. package/dist/studio/run-store-ui-client-model.js +189 -0
  98. package/dist/studio/run-store-ui-client-model.js.map +1 -0
  99. package/dist/studio/run-store-ui-client-runs.d.ts +24 -0
  100. package/dist/studio/run-store-ui-client-runs.js +78 -0
  101. package/dist/studio/run-store-ui-client-runs.js.map +1 -0
  102. package/dist/studio/run-store-ui-client-shared.d.ts +22 -0
  103. package/dist/studio/run-store-ui-client-shared.js +63 -0
  104. package/dist/studio/run-store-ui-client-shared.js.map +1 -0
  105. package/dist/studio/run-store-ui-client-transport.d.ts +25 -0
  106. package/dist/studio/run-store-ui-client-transport.js +317 -0
  107. package/dist/studio/run-store-ui-client-transport.js.map +1 -0
  108. package/dist/studio/run-store-ui-client.d.ts +2 -14
  109. package/dist/studio/run-store-ui-client.js +9 -1360
  110. package/dist/studio/run-store-ui-client.js.map +1 -1
  111. package/dist/studio/run-store-ui-page.d.ts +2 -2
  112. package/dist/studio/run-store-ui-page.js +7 -71
  113. package/dist/studio/run-store-ui-page.js.map +1 -1
  114. package/dist/studio/run-store-ui.d.ts +1 -1
  115. package/dist/studio/run-store-ui.js +43 -25
  116. package/dist/studio/run-store-ui.js.map +1 -1
  117. package/dist/tracing/tracing-codec.d.ts +5 -0
  118. package/dist/tracing/tracing-codec.js +13 -0
  119. package/dist/tracing/tracing-codec.js.map +1 -0
  120. package/dist/tracing/tracing-constants.d.ts +4 -0
  121. package/dist/tracing/tracing-constants.js +5 -0
  122. package/dist/tracing/tracing-constants.js.map +1 -0
  123. package/dist/tracing/tracing-contracts.d.ts +31 -0
  124. package/dist/tracing/tracing-contracts.js +2 -0
  125. package/dist/tracing/tracing-contracts.js.map +1 -0
  126. package/dist/tracing/tracing-internal.d.ts +1 -1
  127. package/dist/tracing/tracing-internal.js +116 -81
  128. package/dist/tracing/tracing-internal.js.map +1 -1
  129. package/dist/tracing/tracing-schema.d.ts +809 -0
  130. package/dist/tracing/tracing-schema.js +429 -0
  131. package/dist/tracing/tracing-schema.js.map +1 -0
  132. package/dist/tracing/tracing.d.ts +2 -54
  133. package/dist/tracing/tracing.js.map +1 -1
  134. package/dist/tracing/wire-schema.d.ts +50 -0
  135. package/dist/tracing/wire-schema.js +193 -0
  136. package/dist/tracing/wire-schema.js.map +1 -0
  137. package/dist/workbench/pipeline-module.js +4 -4
  138. package/dist/workbench/pipeline-module.js.map +1 -1
  139. package/dist/workbench/workbench-entry.d.ts +2 -0
  140. package/dist/workbench/workbench-entry.js +3 -0
  141. package/dist/workbench/workbench-entry.js.map +1 -0
  142. package/dist/workbench/workbench-history.js +8 -1
  143. package/dist/workbench/workbench-history.js.map +1 -1
  144. package/dist/workbench/workbench-ui.js +39 -43
  145. package/dist/workbench/workbench-ui.js.map +1 -1
  146. package/docs/README.md +22 -15
  147. package/docs/agent-guide.md +62 -68
  148. package/docs/agent-skills.md +59 -0
  149. package/docs/api-reference.md +14 -178
  150. package/docs/api-report.json +13 -215
  151. package/docs/child-pipeline-composition.md +139 -193
  152. package/docs/cli.md +86 -64
  153. package/docs/comparison.md +64 -62
  154. package/docs/concepts.md +210 -281
  155. package/docs/getting-started.md +61 -49
  156. package/docs/llms.txt +8 -8
  157. package/docs/recipes.md +42 -45
  158. package/docs/remote-step-composition.md +69 -74
  159. package/docs/studio.md +110 -73
  160. package/examples/catalog/pipelines/enrich.ts +2 -2
  161. package/examples/catalog/scripts/enrich.ts +1 -1
  162. package/examples/catalog/scripts/import.ts +1 -1
  163. package/examples/catalog/scripts/publish.ts +1 -1
  164. package/examples/catalog/tubeless.project.ts +6 -3
  165. package/examples/cli-job.ts +1 -1
  166. package/examples/host-embedding.ts +4 -5
  167. package/examples/live-tui.ts +1 -1
  168. package/examples/peloton.ts +1 -1
  169. package/examples/remote-steps.ts +8 -5
  170. package/examples/tracing.ts +96 -5
  171. package/package.json +17 -64
  172. package/skills/tubeless/SKILL.md +85 -0
  173. package/skills/tubeless-make-pipeline/SKILL.md +126 -0
  174. package/dist/node/env.d.ts +0 -1
  175. package/dist/node/env.js +0 -8
  176. package/dist/node/env.js.map +0 -1
  177. package/dist/node/file-utils.d.ts +0 -3
  178. package/dist/node/file-utils.js +0 -17
  179. package/dist/node/file-utils.js.map +0 -1
  180. package/dist/node/paths.d.ts +0 -8
  181. package/dist/node/paths.js +0 -19
  182. package/dist/node/paths.js.map +0 -1
  183. package/dist/reporter/prompt-select.d.ts +0 -80
  184. package/dist/reporter/prompt-select.js +0 -197
  185. package/dist/reporter/prompt-select.js.map +0 -1
  186. package/dist/studio/run-store-ui-client-source.d.ts +0 -1
  187. package/dist/studio/run-store-ui-client-source.js +0 -1
  188. package/dist/tracing/tracing-json.d.ts +0 -11
  189. package/dist/tracing/tracing-json.js +0 -8
  190. package/dist/tracing/tracing-json.js.map +0 -1
  191. package/dist/tracing/tracing-otel.d.ts +0 -35
  192. package/dist/tracing/tracing-otel.js +0 -60
  193. package/dist/tracing/tracing-otel.js.map +0 -1
  194. package/dist/workbench/workbench-studio.d.ts +0 -29
  195. package/dist/workbench/workbench-studio.js +0 -61
  196. package/dist/workbench/workbench-studio.js.map +0 -1
  197. package/examples/catalog/tubeless.studio.ts +0 -20
  198. package/examples/local-observability.ts +0 -105
  199. package/examples/rendering.ts +0 -34
@@ -0,0 +1,52 @@
1
+ import { validateStandardSchema } from "./pipeline-validation.js";
2
+ function normalizeStepSkipDecision(decision) {
3
+ if (decision == null || decision === false)
4
+ return null;
5
+ if (typeof decision === "string") {
6
+ const reason = decision.trim();
7
+ return reason.length > 0 ? { reason } : null;
8
+ }
9
+ if (typeof decision === "object" && typeof decision.reason === "string") {
10
+ const reason = decision.reason.trim();
11
+ if (reason.length === 0)
12
+ return null;
13
+ return { reason, value: decision.value };
14
+ }
15
+ return null;
16
+ }
17
+ export async function evaluateStepSkip(step, inputs, context) {
18
+ if (typeof step.skip !== "function")
19
+ return null;
20
+ return normalizeStepSkipDecision(await step.skip(inputs, context));
21
+ }
22
+ export async function validateStepOutput(step, value, boundary) {
23
+ return step.outputSchema
24
+ ? validateStandardSchema(step.outputSchema, value, boundary)
25
+ : Promise.resolve(value);
26
+ }
27
+ export async function executeStepAttempt(input) {
28
+ const { step } = input;
29
+ let acceptsProgress = true;
30
+ const stepContext = {
31
+ ...input.context,
32
+ attemptId: input.attemptId,
33
+ log: input.log,
34
+ reportAttempt: input.onReportAttempt,
35
+ reportProgress: (progress) => {
36
+ if (acceptsProgress)
37
+ input.onProgress(progress);
38
+ },
39
+ };
40
+ let output;
41
+ try {
42
+ output =
43
+ input.dryRun && typeof step.dryRun === "function"
44
+ ? await step.dryRun(input.inputs, stepContext)
45
+ : await step.run(input.inputs, stepContext);
46
+ }
47
+ finally {
48
+ acceptsProgress = false;
49
+ }
50
+ return validateStepOutput(step, output, input.outputBoundary);
51
+ }
52
+ //# sourceMappingURL=pipeline-step-executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-step-executor.js","sourceRoot":"","sources":["../../src/core/pipeline-step-executor.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAOlE,SAAS,yBAAyB,CAAC,QAA0B;IAC3D,IAAI,QAAQ,IAAI,IAAI,IAAI,QAAQ,KAAK,KAAK;QAAE,OAAO,IAAI,CAAC;IACxD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/C,CAAC;IACD,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,OAAO,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACrC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC;IAC3C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAuB,EACvB,MAA+B,EAC/B,OAA2C;IAE3C,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,UAAU;QAAE,OAAO,IAAI,CAAC;IACjD,OAAO,yBAAyB,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAuB,EACvB,KAAc,EACd,QAAgB;IAEhB,OAAO,IAAI,CAAC,YAAY;QACtB,CAAC,CAAC,sBAAsB,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC5D,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAA0B,KAUjE;IACC,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,IAAI,eAAe,GAAG,IAAI,CAAC;IAC3B,MAAM,WAAW,GAAG;QAClB,GAAG,KAAK,CAAC,OAAO;QAChB,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,aAAa,EAAE,KAAK,CAAC,eAAe;QACpC,cAAc,EAAE,CAAC,QAA8B,EAAE,EAAE;YACjD,IAAI,eAAe;gBAAE,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAClD,CAAC;KACF,CAAC;IACF,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM;YACJ,KAAK,CAAC,MAAM,IAAI,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU;gBAC/C,CAAC,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;gBAC9C,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClD,CAAC;YAAS,CAAC;QACT,eAAe,GAAG,KAAK,CAAC;IAC1B,CAAC;IACD,OAAO,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;AAChE,CAAC","sourcesContent":["import type { AnyStep } from \"./pipeline-steps.js\";\nimport type {\n PipelineExecutionContext,\n PipelineLogger,\n PipelineStepProgress,\n StepSkipDecision,\n} from \"./pipeline-types.js\";\nimport type { PipelineTraceAttributes } from \"../tracing/tracing-contracts.js\";\nimport { validateStandardSchema } from \"./pipeline-validation.js\";\n\nexport interface NormalizedStepSkipDecision {\n reason: string;\n value?: unknown;\n}\n\nfunction normalizeStepSkipDecision(decision: StepSkipDecision): NormalizedStepSkipDecision | null {\n if (decision == null || decision === false) return null;\n if (typeof decision === \"string\") {\n const reason = decision.trim();\n return reason.length > 0 ? { reason } : null;\n }\n if (typeof decision === \"object\" && typeof decision.reason === \"string\") {\n const reason = decision.reason.trim();\n if (reason.length === 0) return null;\n return { reason, value: decision.value };\n }\n return null;\n}\n\nexport async function evaluateStepSkip<TOptions extends object>(\n step: AnyStep<TOptions>,\n inputs: Record<string, unknown>,\n context: PipelineExecutionContext<TOptions>\n): Promise<NormalizedStepSkipDecision | null> {\n if (typeof step.skip !== \"function\") return null;\n return normalizeStepSkipDecision(await step.skip(inputs, context));\n}\n\nexport async function validateStepOutput<TOptions extends object>(\n step: AnyStep<TOptions>,\n value: unknown,\n boundary: string\n): Promise<unknown> {\n return step.outputSchema\n ? validateStandardSchema(step.outputSchema, value, boundary)\n : Promise.resolve(value);\n}\n\nexport async function executeStepAttempt<TOptions extends object>(input: {\n attemptId: string;\n context: PipelineExecutionContext<TOptions>;\n dryRun: boolean;\n inputs: Record<string, unknown>;\n log: PipelineLogger;\n onProgress(progress: PipelineStepProgress): void;\n onReportAttempt(attempt: number, attributes?: PipelineTraceAttributes): void;\n outputBoundary: string;\n step: AnyStep<TOptions>;\n}): Promise<unknown> {\n const { step } = input;\n let acceptsProgress = true;\n const stepContext = {\n ...input.context,\n attemptId: input.attemptId,\n log: input.log,\n reportAttempt: input.onReportAttempt,\n reportProgress: (progress: PipelineStepProgress) => {\n if (acceptsProgress) input.onProgress(progress);\n },\n };\n let output: unknown;\n try {\n output =\n input.dryRun && typeof step.dryRun === \"function\"\n ? await step.dryRun(input.inputs, stepContext)\n : await step.run(input.inputs, stepContext);\n } finally {\n acceptsProgress = false;\n }\n return validateStepOutput(step, output, input.outputBoundary);\n}\n"]}
@@ -0,0 +1,4 @@
1
+ export declare const PIPELINE_FINALIZE_STEP_ID = "__finalize__";
2
+ export declare const STEP_OPTIONS_SCHEMA: unique symbol;
3
+ export declare const STEP_NESTED_PIPELINE: unique symbol;
4
+ export declare const STEP_REMOTE: unique symbol;
@@ -0,0 +1,5 @@
1
+ export const PIPELINE_FINALIZE_STEP_ID = "__finalize__";
2
+ export const STEP_OPTIONS_SCHEMA = Symbol("tubeless.stepOptionsSchema");
3
+ export const STEP_NESTED_PIPELINE = Symbol("tubeless.stepNestedPipeline");
4
+ export const STEP_REMOTE = Symbol("tubeless.stepRemote");
5
+ //# sourceMappingURL=pipeline-step-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-step-metadata.js","sourceRoot":"","sources":["../../src/core/pipeline-step-metadata.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,yBAAyB,GAAG,cAAc,CAAC;AAExD,MAAM,CAAC,MAAM,mBAAmB,GAAkB,MAAM,CAAC,4BAA4B,CAAC,CAAC;AACvF,MAAM,CAAC,MAAM,oBAAoB,GAAkB,MAAM,CAAC,6BAA6B,CAAC,CAAC;AACzF,MAAM,CAAC,MAAM,WAAW,GAAkB,MAAM,CAAC,qBAAqB,CAAC,CAAC","sourcesContent":["export const PIPELINE_FINALIZE_STEP_ID = \"__finalize__\";\n\nexport const STEP_OPTIONS_SCHEMA: unique symbol = Symbol(\"tubeless.stepOptionsSchema\");\nexport const STEP_NESTED_PIPELINE: unique symbol = Symbol(\"tubeless.stepNestedPipeline\");\nexport const STEP_REMOTE: unique symbol = Symbol(\"tubeless.stepRemote\");\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { ToMappedChildStepProgressOptions } from "./mapped-child-progress.js";
2
- import { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE } from "./pipeline-plan.js";
2
+ import { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE } from "./pipeline-step-metadata.js";
3
3
  import type { InferSchemaInput, InferSchemaOutput, Pipeline, PipelineExecutionContext, PipelinePlanStep, PipelineRun, PipelineRunOptions, PipelineStepContext, RemoteStepAdapter, StandardSchemaV1, StepSkipDecision } from "./pipeline-types.js";
4
4
  /**
5
5
  * A step's dependencies are references to the dependency's own step object, not string ids
@@ -1,6 +1,6 @@
1
1
  import { createMappedChildRunner, createSingleChildRunner, } from "./child-execution.js";
2
2
  import { isPipelineCancellation, PipelineExecutionError } from "./pipeline-execute.js";
3
- import { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE } from "./pipeline-plan.js";
3
+ import { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE, } from "./pipeline-step-metadata.js";
4
4
  export function createSteps(optionsSchema) {
5
5
  return createStepFactory(optionsSchema);
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-steps.js","sourceRoot":"","sources":["../../src/core/pipeline-steps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createMappedChildRunner,\n createSingleChildRunner,\n type MappedChildExecutionConfig,\n type SingleChildExecutionConfig,\n} from \"./child-execution.js\";\nimport type { ToMappedChildStepProgressOptions } from \"./mapped-child-progress.js\";\nimport { isPipelineCancellation, PipelineExecutionError } from \"./pipeline-execute.js\";\nimport { STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_REMOTE } from \"./pipeline-plan.js\";\nimport type {\n InferSchemaInput,\n InferSchemaOutput,\n Pipeline,\n PipelineExecutionContext,\n PipelinePlanStep,\n PipelineRun,\n PipelineRunOptions,\n PipelineStepContext,\n RemoteStepAdapter,\n StandardSchemaV1,\n StepSkipDecision,\n} from \"./pipeline-types.js\";\n\n/**\n * A step's dependencies are references to the dependency's own step object, not string ids\n * into a hand-maintained output-type map. This buys two things no amount of extra generics\n * on a string-keyed design could:\n * - a step used before its dependency exists is a compile error (JS temporal dead zone on\n * `const`), so out-of-order and self/cyclic dependencies are caught by the language, not\n * a bespoke runtime check\n * - each step only ever states its own id/deps; the output-type map is derived, never\n * restated, and callers of `definePipeline`/`createSteps` never write out its generics\n */\ntype AnyStepDryRunHandler<TOptions extends object> = {\n bivarianceHack(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): unknown | Promise<unknown>;\n}[\"bivarianceHack\"];\n\nexport interface AnyStep<TOptions extends object = object> {\n readonly [STEP_NESTED_PIPELINE]?: NonNullable<PipelinePlanStep[\"nestedPipeline\"]>;\n readonly [STEP_REMOTE]?: NonNullable<PipelinePlanStep[\"remote\"]>;\n readonly [STEP_OPTIONS_SCHEMA]?: StandardSchemaV1;\n readonly id: string;\n readonly dependsOn?: readonly AnyStep<TOptions>[];\n readonly optionalDependsOn?: readonly AnyStep<TOptions>[];\n readonly skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n readonly name?: string;\n readonly description?: string;\n /**\n * Dry-run policy. Omitted runs the normal handler, `\"skip\"` structurally\n * skips it, and a handler substitutes for `run` while preserving its output.\n */\n readonly dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n /** Optional Standard Schema for values published by this step. */\n readonly outputSchema?: StandardSchemaV1;\n /**\n * Optional runtime skip. Return a non-empty reason (or `{ reason, value }`) to\n * skip without calling `run`. Policy skips unlock dependents; structural skips\n * (dry-run, filtered, …) do not use this hook.\n */\n skip?(\n inputs: Record<string, unknown>,\n context: PipelineExecutionContext<TOptions>\n ): StepSkipDecision | Promise<StepSkipDecision>;\n run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n}\n\n/** The step fields that `buildStep` merges onto the id-bearing shell. */\ntype StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, \"id\">;\n\nexport interface Step<\n TId extends string,\n TOut,\n TOptions extends object,\n TInputOptions extends object = TOptions,\n TRunOut = TOut,\n> extends AnyStep<TOptions> {\n readonly id: TId;\n run(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): TRunOut | Promise<TRunOut>;\n /** Type-only: carries this step's output type for sibling inference. Never set at runtime. */\n readonly __outputType?: TOut;\n /** Type-only: carries pre-validation run options for pipeline call-site inference. */\n readonly __inputOptionsType?: TInputOptions;\n}\n\n/**\n * Extract a step's output type for dependency typing.\n * Prefer matching `Step<…, TOut, …>` over `{ __outputType?: infer T }`: optional-property\n * inference collapses `TOut | undefined` to `TOut`, which hides policy-skip widening.\n */\nexport type StepOutput<S> =\n S extends Step<string, infer TOut, infer _TOptions, infer _TInputOptions, infer _TRunOut>\n ? TOut\n : never;\n\ninterface StepToken {\n readonly id: string;\n readonly __outputType?: unknown;\n}\n\ntype RequiredInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]: StepOutput<S>;\n};\n\ntype OptionalInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]?: StepOutput<S>;\n};\n\ntype PipelineResultOf<TPipeline> =\n TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId>\n ? TResult\n : never;\n\ntype PipelineRunOptionsOf<TPipeline> =\n TPipeline extends Pipeline<infer TOptions, unknown, infer TStepId, infer TTargetId>\n ? PipelineRunOptions<TOptions, TStepId, TTargetId>\n : never;\n\ntype ChildPipelineStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n mapOptions(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\n/** Child step without policy skip (dependents see the full child result type). */\ntype ChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = ChildPipelineStepDefinitionBase<TParentOptions, TDeps, TOptionalDeps, TChildPipeline>;\n\n/**\n * Presentation options for opaque `forEachPipeline` progress.\n * Defaults are domain-neutral (`N/M items · K running · key/step`).\n * Override `formatMessage` when a domain wants its own noun (images, shards, …).\n */\nexport type MappedChildProgressOptions = ToMappedChildStepProgressOptions;\n\ntype MappedChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n items(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): readonly TItem[] | Promise<readonly TItem[]>;\n key(item: TItem, index: number): string;\n concurrency?:\n | number\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => number);\n /**\n * How the opaque parent step reports live fan-out progress.\n * Purely presentational — does not change scheduling or results.\n */\n progress?: MappedChildProgressOptions;\n mapOptions(\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\ntype StepSkipPredicate<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = (\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TOptions>\n) => StepSkipDecision<TOut> | Promise<StepSkipDecision<TOut>>;\n\ntype StepDryRunPolicy<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> =\n | \"skip\"\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ) => TOut | Promise<TOut>);\n\ntype PlainStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = {\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;\n outputSchema?: never;\n run(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ): TOut | Promise<TOut>;\n};\n\ntype SchemaStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TSchema extends StandardSchemaV1,\n> = Omit<\n PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>,\n \"outputSchema\"\n> & {\n outputSchema: TSchema;\n};\n\ninterface StepConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n /** Ordinary steps never policy-skip, so dependents receive their full output. */\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & { skip?: never }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & { skip?: never }\n ): Step<TId, TOut, TOptions, TInputOptions>;\n\n /** Explicit policy-skip constructor; dependents receive `TOut | undefined`. */\n skippable: SkippableStepConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableStepConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;\n }\n ): Step<TId, TOut | undefined, TOptions, TInputOptions>;\n}\n\ninterface FromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;\n\n skippable: SkippableFromPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>>\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;\n}\n\ninterface ForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[], TOptions, TInputOptions>;\n\n skippable: SkippableForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip:\n | StepSkipPredicate<\n TOptions,\n TDeps,\n TOptionalDeps,\n readonly PipelineResultOf<TChildPipeline>[]\n >\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;\n}\n\ntype RemoteStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TPayload,\n TSchema extends StandardSchemaV1,\n> = {\n adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;\n mapInput(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TParentOptions>\n ): TPayload;\n outputSchema: TSchema;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;\n};\n\ninterface FromRemoteConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip?: never;\n }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n skippable: SkippableFromRemoteConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromRemoteConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n}\n\nexport interface StepFactory<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> extends StepConstructor<TOptions, TInputOptions> {\n fromPipeline: FromPipelineConstructor<TOptions, TInputOptions>;\n fromRemote: FromRemoteConstructor<TOptions, TInputOptions>;\n forEachPipeline: ForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\n/**\n * Returns a step factory scoped to one pipeline's domain options. Pass built-in\n * run controls as the second argument to `run` / `runOrThrow`. Child\n * `mapOptions` may still return domain options plus those controls.\n */\nexport function createSteps<TOptions extends object = {}>(): StepFactory<TOptions>;\nexport function createSteps<const TSchema extends StandardSchemaV1<object, object>>(\n optionsSchema: TSchema\n): StepFactory<InferSchemaOutput<TSchema>, InferSchemaInput<TSchema>>;\nexport function createSteps(optionsSchema?: StandardSchemaV1<object, object>): StepFactory<object> {\n return createStepFactory<object>(optionsSchema);\n}\n\nfunction createStepFactory<TOptions extends object, TInputOptions extends object = TOptions>(\n optionsSchema?: StandardSchemaV1\n): StepFactory<TOptions, TInputOptions> {\n // Runtime construction is deliberately simple; the public factory owns the\n // distinction between ordinary and explicitly skippable constructors.\n const buildStep = (id: string, definition: StepDefinitionBody<TOptions>): AnyStep<TOptions> => {\n // SAFETY: `definition` carries the step's own fields; spreading it onto the\n // id-bearing shell yields a value whose shape matches `AnyStep<TOptions>`.\n const built = { id, ...definition } as AnyStep<TOptions>;\n if (optionsSchema) {\n Object.defineProperty(built, STEP_OPTIONS_SCHEMA, { value: optionsSchema });\n }\n return built;\n };\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromPipeline` constructor signature it is assigned to.\n const fromPipeline = ((\n id: string,\n config: ChildPipelineStepDefinitionBase<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>\n > & {\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"single\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline` and `mapResult`; the runner\n // derives `mapOptions` from the same fields, so the config is a valid\n // single-child execution config at runtime.\n run: createSingleChildRunner(config as SingleChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromPipeline\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromRemote` constructor signature it is assigned to.\n const fromRemote = ((\n id: string,\n config: {\n adapter: RemoteStepAdapter<object, unknown, unknown>;\n mapInput: (\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n outputSchema: StandardSchemaV1;\n dependsOn?: readonly AnyStep<TOptions>[];\n optionalDependsOn?: readonly AnyStep<TOptions>[];\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const remote: NonNullable<PipelinePlanStep[\"remote\"]> = { engine: config.adapter.engine };\n if (config.adapter.target !== undefined) remote.target = config.adapter.target;\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_REMOTE]: remote,\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n outputSchema: config.outputSchema,\n run: (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) =>\n config.adapter.invoke(config.mapInput(inputs, context), context),\n };\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromRemote\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `forEachPipeline` constructor signature it is assigned to.\n const forEachPipeline = ((\n id: string,\n config: MappedChildPipelineStepDefinition<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>,\n unknown\n > & {\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n item: unknown,\n index: number,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"for-each\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline`, `items`, `key`, and `mapResult`;\n // the runner derives the rest from those fields, so the config is a valid\n // mapped-child execution config at runtime.\n run: createMappedChildRunner(config as MappedChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"forEachPipeline\"];\n\n // SAFETY: `buildStep` is a callable; attaching the constructor properties\n // yields exactly the `StepFactory` surface (call + skippable + fromPipeline +\n // forEachPipeline), so the single assertion is sound.\n const factory = Object.assign(buildStep, {\n skippable: buildStep,\n fromPipeline,\n fromRemote,\n forEachPipeline,\n }) as StepFactory<TOptions, TInputOptions>;\n // SAFETY: `fromPipeline` is the same callable as `factory.fromPipeline`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromPipeline.skippable = fromPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromPipeline\"][\"skippable\"];\n // SAFETY: `fromRemote` is the same callable as `factory.fromRemote`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromRemote.skippable = fromRemote as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromRemote\"][\"skippable\"];\n // SAFETY: `forEachPipeline` is the same callable as `factory.forEachPipeline`;\n // it carries the skippable variant, so the assignment is sound.\n factory.forEachPipeline.skippable = forEachPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"forEachPipeline\"][\"skippable\"];\n\n return factory;\n}\n"]}
1
+ {"version":3,"file":"pipeline-steps.js","sourceRoot":"","sources":["../../src/core/pipeline-steps.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n createMappedChildRunner,\n createSingleChildRunner,\n type MappedChildExecutionConfig,\n type SingleChildExecutionConfig,\n} from \"./child-execution.js\";\nimport type { ToMappedChildStepProgressOptions } from \"./mapped-child-progress.js\";\nimport { isPipelineCancellation, PipelineExecutionError } from \"./pipeline-execute.js\";\nimport {\n STEP_NESTED_PIPELINE,\n STEP_OPTIONS_SCHEMA,\n STEP_REMOTE,\n} from \"./pipeline-step-metadata.js\";\nimport type {\n InferSchemaInput,\n InferSchemaOutput,\n Pipeline,\n PipelineExecutionContext,\n PipelinePlanStep,\n PipelineRun,\n PipelineRunOptions,\n PipelineStepContext,\n RemoteStepAdapter,\n StandardSchemaV1,\n StepSkipDecision,\n} from \"./pipeline-types.js\";\n\n/**\n * A step's dependencies are references to the dependency's own step object, not string ids\n * into a hand-maintained output-type map. This buys two things no amount of extra generics\n * on a string-keyed design could:\n * - a step used before its dependency exists is a compile error (JS temporal dead zone on\n * `const`), so out-of-order and self/cyclic dependencies are caught by the language, not\n * a bespoke runtime check\n * - each step only ever states its own id/deps; the output-type map is derived, never\n * restated, and callers of `definePipeline`/`createSteps` never write out its generics\n */\ntype AnyStepDryRunHandler<TOptions extends object> = {\n bivarianceHack(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): unknown | Promise<unknown>;\n}[\"bivarianceHack\"];\n\nexport interface AnyStep<TOptions extends object = object> {\n readonly [STEP_NESTED_PIPELINE]?: NonNullable<PipelinePlanStep[\"nestedPipeline\"]>;\n readonly [STEP_REMOTE]?: NonNullable<PipelinePlanStep[\"remote\"]>;\n readonly [STEP_OPTIONS_SCHEMA]?: StandardSchemaV1;\n readonly id: string;\n readonly dependsOn?: readonly AnyStep<TOptions>[];\n readonly optionalDependsOn?: readonly AnyStep<TOptions>[];\n readonly skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n readonly name?: string;\n readonly description?: string;\n /**\n * Dry-run policy. Omitted runs the normal handler, `\"skip\"` structurally\n * skips it, and a handler substitutes for `run` while preserving its output.\n */\n readonly dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n /** Optional Standard Schema for values published by this step. */\n readonly outputSchema?: StandardSchemaV1;\n /**\n * Optional runtime skip. Return a non-empty reason (or `{ reason, value }`) to\n * skip without calling `run`. Policy skips unlock dependents; structural skips\n * (dry-run, filtered, …) do not use this hook.\n */\n skip?(\n inputs: Record<string, unknown>,\n context: PipelineExecutionContext<TOptions>\n ): StepSkipDecision | Promise<StepSkipDecision>;\n run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n}\n\n/** The step fields that `buildStep` merges onto the id-bearing shell. */\ntype StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, \"id\">;\n\nexport interface Step<\n TId extends string,\n TOut,\n TOptions extends object,\n TInputOptions extends object = TOptions,\n TRunOut = TOut,\n> extends AnyStep<TOptions> {\n readonly id: TId;\n run(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): TRunOut | Promise<TRunOut>;\n /** Type-only: carries this step's output type for sibling inference. Never set at runtime. */\n readonly __outputType?: TOut;\n /** Type-only: carries pre-validation run options for pipeline call-site inference. */\n readonly __inputOptionsType?: TInputOptions;\n}\n\n/**\n * Extract a step's output type for dependency typing.\n * Prefer matching `Step<…, TOut, …>` over `{ __outputType?: infer T }`: optional-property\n * inference collapses `TOut | undefined` to `TOut`, which hides policy-skip widening.\n */\nexport type StepOutput<S> =\n S extends Step<string, infer TOut, infer _TOptions, infer _TInputOptions, infer _TRunOut>\n ? TOut\n : never;\n\ninterface StepToken {\n readonly id: string;\n readonly __outputType?: unknown;\n}\n\ntype RequiredInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]: StepOutput<S>;\n};\n\ntype OptionalInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]?: StepOutput<S>;\n};\n\ntype PipelineResultOf<TPipeline> =\n TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId>\n ? TResult\n : never;\n\ntype PipelineRunOptionsOf<TPipeline> =\n TPipeline extends Pipeline<infer TOptions, unknown, infer TStepId, infer TTargetId>\n ? PipelineRunOptions<TOptions, TStepId, TTargetId>\n : never;\n\ntype ChildPipelineStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n mapOptions(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\n/** Child step without policy skip (dependents see the full child result type). */\ntype ChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n> = ChildPipelineStepDefinitionBase<TParentOptions, TDeps, TOptionalDeps, TChildPipeline>;\n\n/**\n * Presentation options for opaque `forEachPipeline` progress.\n * Defaults are domain-neutral (`N/M items · K running · key/step`).\n * Override `formatMessage` when a domain wants its own noun (images, shards, …).\n */\nexport type MappedChildProgressOptions = ToMappedChildStepProgressOptions;\n\ntype MappedChildPipelineStepDefinition<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n> = {\n pipeline: TChildPipeline;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\";\n items(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): readonly TItem[] | Promise<readonly TItem[]>;\n key(item: TItem, index: number): string;\n concurrency?:\n | number\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => number);\n /**\n * How the opaque parent step reports live fan-out progress.\n * Purely presentational — does not change scheduling or results.\n */\n progress?: MappedChildProgressOptions;\n mapOptions(\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineRunOptionsOf<TChildPipeline>;\n};\n\ntype StepSkipPredicate<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = (\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TOptions>\n) => StepSkipDecision<TOut> | Promise<StepSkipDecision<TOut>>;\n\ntype StepDryRunPolicy<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> =\n | \"skip\"\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ) => TOut | Promise<TOut>);\n\ntype PlainStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n> = {\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;\n outputSchema?: never;\n run(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ): TOut | Promise<TOut>;\n};\n\ntype SchemaStepFields<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TSchema extends StandardSchemaV1,\n> = Omit<\n PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>,\n \"outputSchema\"\n> & {\n outputSchema: TSchema;\n};\n\ninterface StepConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n /** Ordinary steps never policy-skip, so dependents receive their full output. */\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & { skip?: never }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & { skip?: never }\n ): Step<TId, TOut, TOptions, TInputOptions>;\n\n /** Explicit policy-skip constructor; dependents receive `TOut | undefined`. */\n skippable: SkippableStepConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableStepConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: SchemaStepFields<TOptions, TDeps, TOptionalDeps, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n\n <\n TId extends string,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n TOut = unknown,\n >(\n id: TId,\n definition: PlainStepFields<TOptions, TDeps, TOptionalDeps, TOut> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, TOut> | undefined;\n }\n ): Step<TId, TOut | undefined, TOptions, TInputOptions>;\n}\n\ninterface FromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinition<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline>, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut>, TOptions, TInputOptions>;\n\n skippable: SkippableFromPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, PipelineResultOf<TChildPipeline>>\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, PipelineResultOf<TChildPipeline> | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: ChildPipelineStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TChildPipeline> & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<Awaited<TOut>>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, Awaited<TOut> | undefined, TOptions, TInputOptions>;\n}\n\ninterface ForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[], TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip?: never;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[], TOptions, TInputOptions>;\n\n skippable: SkippableForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableForEachPipelineConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip:\n | StepSkipPredicate<\n TOptions,\n TDeps,\n TOptionalDeps,\n readonly PipelineResultOf<TChildPipeline>[]\n >\n | undefined;\n mapResult?: undefined;\n }\n ): Step<TId, readonly PipelineResultOf<TChildPipeline>[] | undefined, TOptions, TInputOptions>;\n\n <\n TId extends string,\n TChildPipeline extends Pipeline<object, unknown>,\n TItem,\n TOut,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: MappedChildPipelineStepDefinition<\n TOptions,\n TDeps,\n TOptionalDeps,\n TChildPipeline,\n TItem\n > & {\n skip: StepSkipPredicate<TOptions, TDeps, TOptionalDeps, NoInfer<readonly TOut[]>> | undefined;\n mapResult(\n value: PipelineResultOf<TChildPipeline>,\n result: PipelineRun<PipelineResultOf<TChildPipeline>>,\n item: TItem,\n index: number,\n context: PipelineStepContext<TOptions>\n ): TOut;\n }\n ): Step<TId, readonly TOut[] | undefined, TOptions, TInputOptions>;\n}\n\ntype RemoteStepDefinitionBase<\n TParentOptions extends object,\n TDeps extends readonly AnyStep<TParentOptions>[],\n TOptionalDeps extends readonly AnyStep<TParentOptions>[],\n TPayload,\n TSchema extends StandardSchemaV1,\n> = {\n adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;\n mapInput(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TParentOptions>\n ): TPayload;\n outputSchema: TSchema;\n dependsOn?: TDeps;\n optionalDependsOn?: TOptionalDeps;\n skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];\n name?: string;\n description?: string;\n dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;\n};\n\ninterface FromRemoteConstructor<TOptions extends object, TInputOptions extends object = TOptions> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip?: never;\n }\n ): Step<TId, InferSchemaOutput<TSchema>, TOptions, TInputOptions, InferSchemaInput<TSchema>>;\n\n skippable: SkippableFromRemoteConstructor<TOptions, TInputOptions>;\n}\n\ninterface SkippableFromRemoteConstructor<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> {\n <\n TId extends string,\n TSchema extends StandardSchemaV1,\n TPayload,\n const TDeps extends readonly AnyStep<TOptions>[] = [],\n const TOptionalDeps extends readonly AnyStep<TOptions>[] = [],\n >(\n id: TId,\n definition: RemoteStepDefinitionBase<TOptions, TDeps, TOptionalDeps, TPayload, TSchema> & {\n skip:\n | StepSkipPredicate<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>\n | undefined;\n }\n ): Step<\n TId,\n InferSchemaOutput<TSchema> | undefined,\n TOptions,\n TInputOptions,\n InferSchemaInput<TSchema>\n >;\n}\n\nexport interface StepFactory<\n TOptions extends object,\n TInputOptions extends object = TOptions,\n> extends StepConstructor<TOptions, TInputOptions> {\n fromPipeline: FromPipelineConstructor<TOptions, TInputOptions>;\n fromRemote: FromRemoteConstructor<TOptions, TInputOptions>;\n forEachPipeline: ForEachPipelineConstructor<TOptions, TInputOptions>;\n}\n\n/**\n * Returns a step factory scoped to one pipeline's domain options. Pass built-in\n * run controls as the second argument to `run` / `runOrThrow`. Child\n * `mapOptions` may still return domain options plus those controls.\n */\nexport function createSteps<TOptions extends object = {}>(): StepFactory<TOptions>;\nexport function createSteps<const TSchema extends StandardSchemaV1<object, object>>(\n optionsSchema: TSchema\n): StepFactory<InferSchemaOutput<TSchema>, InferSchemaInput<TSchema>>;\nexport function createSteps(optionsSchema?: StandardSchemaV1<object, object>): StepFactory<object> {\n return createStepFactory<object>(optionsSchema);\n}\n\nfunction createStepFactory<TOptions extends object, TInputOptions extends object = TOptions>(\n optionsSchema?: StandardSchemaV1\n): StepFactory<TOptions, TInputOptions> {\n // Runtime construction is deliberately simple; the public factory owns the\n // distinction between ordinary and explicitly skippable constructors.\n const buildStep = (id: string, definition: StepDefinitionBody<TOptions>): AnyStep<TOptions> => {\n // SAFETY: `definition` carries the step's own fields; spreading it onto the\n // id-bearing shell yields a value whose shape matches `AnyStep<TOptions>`.\n const built = { id, ...definition } as AnyStep<TOptions>;\n if (optionsSchema) {\n Object.defineProperty(built, STEP_OPTIONS_SCHEMA, { value: optionsSchema });\n }\n return built;\n };\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromPipeline` constructor signature it is assigned to.\n const fromPipeline = ((\n id: string,\n config: ChildPipelineStepDefinitionBase<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>\n > & {\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"single\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline` and `mapResult`; the runner\n // derives `mapOptions` from the same fields, so the config is a valid\n // single-child execution config at runtime.\n run: createSingleChildRunner(config as SingleChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromPipeline\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `fromRemote` constructor signature it is assigned to.\n const fromRemote = ((\n id: string,\n config: {\n adapter: RemoteStepAdapter<object, unknown, unknown>;\n mapInput: (\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n outputSchema: StandardSchemaV1;\n dependsOn?: readonly AnyStep<TOptions>[];\n optionalDependsOn?: readonly AnyStep<TOptions>[];\n skipAfterFailureOf?: readonly AnyStep<TOptions>[];\n name?: string;\n description?: string;\n dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const remote: NonNullable<PipelinePlanStep[\"remote\"]> = { engine: config.adapter.engine };\n if (config.adapter.target !== undefined) remote.target = config.adapter.target;\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_REMOTE]: remote,\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n outputSchema: config.outputSchema,\n run: (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) =>\n config.adapter.invoke(config.mapInput(inputs, context), context),\n };\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"fromRemote\"];\n\n // SAFETY: the closure's parameter and return shapes match the\n // `forEachPipeline` constructor signature it is assigned to.\n const forEachPipeline = ((\n id: string,\n config: MappedChildPipelineStepDefinition<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n Pipeline<object, unknown>,\n unknown\n > & {\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n item: unknown,\n index: number,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n skip?: StepSkipPredicate<\n TOptions,\n readonly AnyStep<TOptions>[],\n readonly AnyStep<TOptions>[],\n unknown\n >;\n }\n ) => {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"for-each\" as const,\n pipelineId: config.pipeline.id,\n stepIds: config.pipeline.stepIds,\n },\n dependsOn: config.dependsOn,\n optionalDependsOn: config.optionalDependsOn,\n skipAfterFailureOf: config.skipAfterFailureOf,\n name: config.name,\n description: config.description,\n dryRun: config.dryRun,\n // SAFETY: the config carries `pipeline`, `items`, `key`, and `mapResult`;\n // the runner derives the rest from those fields, so the config is a valid\n // mapped-child execution config at runtime.\n run: createMappedChildRunner(config as MappedChildExecutionConfig<TOptions>, {\n createExecutionError: (result, message) => new PipelineExecutionError(result, message),\n isCancellation: (error, childContext) => isPipelineCancellation(error, childContext),\n }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n // SAFETY: each constructor preserves the skip predicate's dependency inputs and context.\n definition.skip = (inputs, context) => skip(inputs as never, context);\n }\n return buildStep(id, definition);\n }) as StepFactory<TOptions, TInputOptions>[\"forEachPipeline\"];\n\n // SAFETY: `buildStep` is a callable; attaching the constructor properties\n // yields exactly the `StepFactory` surface (call + skippable + fromPipeline +\n // forEachPipeline), so the single assertion is sound.\n const factory = Object.assign(buildStep, {\n skippable: buildStep,\n fromPipeline,\n fromRemote,\n forEachPipeline,\n }) as StepFactory<TOptions, TInputOptions>;\n // SAFETY: `fromPipeline` is the same callable as `factory.fromPipeline`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromPipeline.skippable = fromPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromPipeline\"][\"skippable\"];\n // SAFETY: `fromRemote` is the same callable as `factory.fromRemote`; it\n // carries the skippable variant, so the assignment is sound.\n factory.fromRemote.skippable = fromRemote as StepFactory<\n TOptions,\n TInputOptions\n >[\"fromRemote\"][\"skippable\"];\n // SAFETY: `forEachPipeline` is the same callable as `factory.forEachPipeline`;\n // it carries the skippable variant, so the assignment is sound.\n factory.forEachPipeline.skippable = forEachPipeline as StepFactory<\n TOptions,\n TInputOptions\n >[\"forEachPipeline\"][\"skippable\"];\n\n return factory;\n}\n"]}
@@ -1,21 +1,22 @@
1
1
  import type { RUN_MODEL_VERSION } from "./pipeline-ids.js";
2
- import type { PipelineTraceAttributes, PipelineTraceContext, PipelineTracingOptions } from "../tracing/tracing.js";
2
+ import type { PipelineErrorKindContract, PipelineErrorPhaseContract } from "../tracing/tracing-schema.js";
3
+ import type { PipelineTraceAttributes, PipelineTraceContext, PipelineTracingOptions } from "../tracing/tracing-contracts.js";
3
4
  export interface PipelineLogger {
4
5
  error(message?: unknown, ...optionalParams: unknown[]): void;
5
6
  log(message?: unknown, ...optionalParams: unknown[]): void;
6
7
  warn(message?: unknown, ...optionalParams: unknown[]): void;
7
8
  }
8
9
  export interface PipelineContext {
10
+ /** Optional caller-owned identifier used to correlate separate executions. */
11
+ correlationId?: string;
9
12
  cwd: string;
10
13
  /** Hook sets run in order and failures are isolated per set. */
11
14
  hooks?: PipelineHooks | readonly PipelineHooks[];
12
15
  log: PipelineLogger;
13
16
  /** Timestamp source for persisted run records. Defaults to `Date.now`. */
14
17
  now?: () => number;
15
- /** Optional caller-owned parent run identity for nested or resumed orchestration. */
18
+ /** Optional package-generated execution identity of this run's parent. */
16
19
  parentRunId?: string;
17
- /** Optional caller-owned run identity. A unique ID is generated when omitted. */
18
- runId?: string;
19
20
  signal?: AbortSignal;
20
21
  sleep?: (durationMs: number, signal?: AbortSignal) => Promise<void>;
21
22
  /** Optional structured lifecycle tracing configuration for this run. */
@@ -44,6 +45,8 @@ export interface PipelineRuntime extends PipelineContext {
44
45
  sleep: (durationMs: number, signal?: AbortSignal) => Promise<void>;
45
46
  }
46
47
  export interface PipelineExecutionContext<TOptions extends object> extends PipelineRuntime {
48
+ /** Caller-owned identifier shared by related executions, when supplied. */
49
+ correlationId?: string;
47
50
  dryRun: boolean;
48
51
  options: TOptions;
49
52
  /** Stable identity for this execution, whether or not tracing is configured. */
@@ -102,10 +105,14 @@ export interface RemoteStepAdapter<TOptions extends object, TPayload, TResult> {
102
105
  readonly target?: string;
103
106
  invoke(payload: TPayload, context: PipelineStepContext<TOptions>): Promise<TResult>;
104
107
  }
105
- export type PipelineErrorPhase = "definition" | "execution" | "finalization" | "planning";
106
- export type PipelineErrorKind = "cancellation" | "child" | "definition" | "finalization" | "selection" | "step" | "validation";
107
- /** Stable package-owned codes for pipeline errors. */
108
- export type PipelineErrorCode = "TUBELESS_CHILD_FAILED" | "TUBELESS_DEFINITION_DEPENDENCY_CONTRADICTORY" | "TUBELESS_DEFINITION_DEPENDENCY_CYCLE" | "TUBELESS_DEFINITION_DEPENDENCY_DUPLICATE" | "TUBELESS_DEFINITION_DEPENDENCY_NOT_IN_STEPS" | "TUBELESS_DEFINITION_DEPENDENCY_SELF_REFERENCE" | "TUBELESS_DEFINITION_FINALIZER_STEP_NOT_IN_STEPS" | "TUBELESS_DEFINITION_PIPELINE_ID_BLANK" | "TUBELESS_DEFINITION_OPTIONS_SCHEMA_CONFLICT" | "TUBELESS_DEFINITION_STEP_ID_BLANK" | "TUBELESS_DEFINITION_STEP_ID_RESERVED" | "TUBELESS_DEFINITION_STEP_IDS_DUPLICATE" | "TUBELESS_DEFINITION_STEP_NAME_BLANK" | "TUBELESS_DEFINITION_TARGET_FINALIZER_MISMATCH" | "TUBELESS_DEFINITION_TARGET_NOT_IN_STEPS" | "TUBELESS_DEFINITION_TARGETS_DUPLICATE" | "TUBELESS_FINALIZATION_CANCELLED" | "TUBELESS_FINALIZATION_FAILED" | "TUBELESS_FINAL_RESULT_VALIDATION_FAILED" | "TUBELESS_OPTIONS_VALIDATION_FAILED" | "TUBELESS_PLANNING_SELECTION_CONFLICT" | "TUBELESS_PLANNING_STEP_SELECTION_DUPLICATE" | "TUBELESS_PLANNING_STEP_SELECTION_EMPTY" | "TUBELESS_PLANNING_STEP_UNKNOWN" | "TUBELESS_PLANNING_TARGET_SELECTION_DUPLICATE" | "TUBELESS_PLANNING_TARGET_SELECTION_EMPTY" | "TUBELESS_PLANNING_TARGET_UNDECLARED" | "TUBELESS_PLANNING_TARGET_UNKNOWN" | "TUBELESS_RUN_CANCELLED" | "TUBELESS_STEP_OUTPUT_VALIDATION_FAILED" | "TUBELESS_STEP_FAILED";
108
+ export type PipelineErrorPhase = PipelineErrorPhaseContract;
109
+ export type PipelineErrorKind = PipelineErrorKindContract;
110
+ /** Ordered catalog of every stable package-owned pipeline error code. */
111
+ export declare const PIPELINE_ERROR_CODES: readonly ["TUBELESS_CHILD_FAILED", "TUBELESS_DEFINITION_DEPENDENCY_CONTRADICTORY", "TUBELESS_DEFINITION_DEPENDENCY_CYCLE", "TUBELESS_DEFINITION_DEPENDENCY_DUPLICATE", "TUBELESS_DEFINITION_DEPENDENCY_NOT_IN_STEPS", "TUBELESS_DEFINITION_DEPENDENCY_SELF_REFERENCE", "TUBELESS_DEFINITION_FINALIZER_STEP_NOT_IN_STEPS", "TUBELESS_DEFINITION_PIPELINE_ID_BLANK", "TUBELESS_DEFINITION_OPTIONS_SCHEMA_CONFLICT", "TUBELESS_DEFINITION_STEP_ID_BLANK", "TUBELESS_DEFINITION_STEP_ID_RESERVED", "TUBELESS_DEFINITION_STEP_IDS_DUPLICATE", "TUBELESS_DEFINITION_STEP_NAME_BLANK", "TUBELESS_DEFINITION_TARGET_FINALIZER_MISMATCH", "TUBELESS_DEFINITION_TARGET_NOT_IN_STEPS", "TUBELESS_DEFINITION_TARGETS_DUPLICATE", "TUBELESS_FINALIZATION_CANCELLED", "TUBELESS_FINALIZATION_FAILED", "TUBELESS_FINAL_RESULT_VALIDATION_FAILED", "TUBELESS_OPTIONS_VALIDATION_FAILED", "TUBELESS_PLANNING_SELECTION_CONFLICT", "TUBELESS_PLANNING_STEP_SELECTION_DUPLICATE", "TUBELESS_PLANNING_STEP_SELECTION_EMPTY", "TUBELESS_PLANNING_STEP_UNKNOWN", "TUBELESS_PLANNING_TARGET_SELECTION_DUPLICATE", "TUBELESS_PLANNING_TARGET_SELECTION_EMPTY", "TUBELESS_PLANNING_TARGET_UNDECLARED", "TUBELESS_PLANNING_TARGET_UNKNOWN", "TUBELESS_RUN_CANCELLED", "TUBELESS_STEP_OUTPUT_VALIDATION_FAILED", "TUBELESS_STEP_FAILED"];
112
+ /** Stable package-owned code for a pipeline error. */
113
+ export type PipelineErrorCode = (typeof PIPELINE_ERROR_CODES)[number];
114
+ /** Return whether an unknown value is a stable package-owned pipeline error code. */
115
+ export declare function isPipelineErrorCode(value: unknown): value is PipelineErrorCode;
109
116
  /** One dependency-free Standard Schema issue normalized for reports and traces. */
110
117
  export interface PipelineValidationIssue {
111
118
  message: string;
@@ -226,6 +233,8 @@ export type PipelineStepReportStatus = PipelineStepReport["status"];
226
233
  export type PipelineRunStatus = "cancelled" | "completed" | "failed";
227
234
  /** Versioned public record returned for one pipeline execution. */
228
235
  export interface PipelineRun<TResult = unknown> {
236
+ /** Caller-owned identifier shared by related executions, when supplied. */
237
+ correlationId?: string;
229
238
  pipelineId: string;
230
239
  dryRun: boolean;
231
240
  errors: PipelineError[];
@@ -1,3 +1,11 @@
1
+ import { PIPELINE_ERROR_CODES as PIPELINE_ERROR_CODE_VALUES } from "../tracing/tracing-schema.js";
2
+ /** Ordered catalog of every stable package-owned pipeline error code. */
3
+ export const PIPELINE_ERROR_CODES = Object.freeze(PIPELINE_ERROR_CODE_VALUES);
4
+ const pipelineErrorCodeSet = new Set(PIPELINE_ERROR_CODES);
5
+ /** Return whether an unknown value is a stable package-owned pipeline error code. */
6
+ export function isPipelineErrorCode(value) {
7
+ return typeof value === "string" && pipelineErrorCodeSet.has(value);
8
+ }
1
9
  /** Layout directions for generated Mermaid flowcharts. */
2
10
  export const PIPELINE_MERMAID_DIRECTIONS = ["BT", "LR", "RL", "TB", "TD"];
3
11
  //# sourceMappingURL=pipeline-types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-types.js","sourceRoot":"","sources":["../../src/core/pipeline-types.ts"],"names":[],"mappings":"AA6cA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC","sourcesContent":["import type { RUN_MODEL_VERSION } from \"./pipeline-ids.js\";\nimport type {\n PipelineTraceAttributes,\n PipelineTraceContext,\n PipelineTracingOptions,\n} from \"../tracing/tracing.js\";\n\nexport interface PipelineLogger {\n error(message?: unknown, ...optionalParams: unknown[]): void;\n log(message?: unknown, ...optionalParams: unknown[]): void;\n warn(message?: unknown, ...optionalParams: unknown[]): void;\n}\n\nexport interface PipelineContext {\n cwd: string;\n /** Hook sets run in order and failures are isolated per set. */\n hooks?: PipelineHooks | readonly PipelineHooks[];\n log: PipelineLogger;\n /** Timestamp source for persisted run records. Defaults to `Date.now`. */\n now?: () => number;\n /** Optional caller-owned parent run identity for nested or resumed orchestration. */\n parentRunId?: string;\n /** Optional caller-owned run identity. A unique ID is generated when omitted. */\n runId?: string;\n signal?: AbortSignal;\n sleep?: (durationMs: number, signal?: AbortSignal) => Promise<void>;\n /** Optional structured lifecycle tracing configuration for this run. */\n tracing?: PipelineTracingOptions;\n}\n\nexport interface PipelineRunControls<\n TStepId extends string = string,\n TTargetId extends string = string,\n> {\n continueOnError?: boolean;\n dryRun?: boolean;\n /**\n * Run only these steps; omitted or undefined runs every step. An empty array\n * is invalid and fails planning/execution instead of silently running nothing.\n */\n stepIds?: readonly TStepId[];\n /**\n * Run these declared pipeline targets and the upstream work required to\n * reach them. Required inputs and failure gates are included recursively;\n * optional-only inputs are not. Cannot be combined with exact `stepIds`\n * filtering.\n */\n targets?: readonly TTargetId[];\n}\n\n/** Domain input plus built-in controls. Child `mapOptions` still returns this mix. */\nexport type PipelineRunOptions<\n TOptions extends object = object,\n TStepId extends string = string,\n TTargetId extends string = string,\n> = TOptions & PipelineRunControls<TStepId, TTargetId>;\nexport interface PipelineRuntime extends PipelineContext {\n now: () => number;\n sleep: (durationMs: number, signal?: AbortSignal) => Promise<void>;\n}\n\nexport interface PipelineExecutionContext<TOptions extends object> extends PipelineRuntime {\n dryRun: boolean;\n options: TOptions;\n /** Stable identity for this execution, whether or not tracing is configured. */\n runId: string;\n /** Parent execution identity when this run was started by another run. */\n parentRunId?: string;\n /** Stable identities for this traced run; absent unless `context.tracing` is configured. */\n trace?: PipelineTraceContext;\n}\n\n/**\n * Optional indented detail row under a parent step's progress.\n * Domain-agnostic: mapped children, nested work units, per-file status, etc.\n */\nexport type PipelineStepProgressDetailStatus =\n | \"cancelled\"\n | \"completed\"\n | \"failed\"\n | \"pending\"\n | \"running\"\n | \"skipped\";\n\nexport interface PipelineStepProgressDetail {\n /** Stable identity for the row (item key, path, job id, …). */\n id: string;\n /** Optional display name; identity remains `id`. */\n name?: string;\n /** Indentation relative to direct child rows (0). Rows are in tree preorder. */\n depth?: number;\n /** Inner work counts, independent of the parent's lifecycle count. */\n completed?: number;\n total?: number;\n /** Short status text shown after the id. */\n label?: string;\n /** Controls the detail row symbol. Defaults to `running`. */\n status?: PipelineStepProgressDetailStatus;\n}\n\nexport interface PipelineStepProgress {\n /** Work completed so far. Values outside the reported total are allowed but renderers may clamp them. */\n completed: number;\n /** Total work when known. Omit for indeterminate progress. */\n total?: number;\n /** Optional short status shown next to the step. Prefer one-line summaries. */\n message?: string;\n /**\n * Optional multi-line detail rows for capable reporters (interactive TTY).\n * Keep the parent `message` as a summary; put per-item status here so high\n * concurrency does not collapse onto one truncated line.\n */\n details?: readonly PipelineStepProgressDetail[];\n}\n\nexport interface PipelineStepContext<\n TOptions extends object,\n> extends PipelineExecutionContext<TOptions> {\n /** Stable identity for this execution of the current step. */\n attemptId: string;\n /** Emit a retry/attempt trace event for this step when tracing is enabled. */\n reportAttempt(attempt: number, attributes?: PipelineTraceAttributes): void;\n /** Publish the latest progress snapshot for this step. */\n reportProgress(progress: PipelineStepProgress): void;\n}\n\nexport interface RemoteStepAdapter<TOptions extends object, TPayload, TResult> {\n /** Presentation only. The kernel never switches on this. */\n readonly engine: string;\n /** Function name, workflow type, URL, queue. Presentation only. */\n readonly target?: string;\n invoke(payload: TPayload, context: PipelineStepContext<TOptions>): Promise<TResult>;\n}\n\nexport type PipelineErrorPhase = \"definition\" | \"execution\" | \"finalization\" | \"planning\";\n\nexport type PipelineErrorKind =\n | \"cancellation\"\n | \"child\"\n | \"definition\"\n | \"finalization\"\n | \"selection\"\n | \"step\"\n | \"validation\";\n\n/** Stable package-owned codes for pipeline errors. */\nexport type PipelineErrorCode =\n | \"TUBELESS_CHILD_FAILED\"\n | \"TUBELESS_DEFINITION_DEPENDENCY_CONTRADICTORY\"\n | \"TUBELESS_DEFINITION_DEPENDENCY_CYCLE\"\n | \"TUBELESS_DEFINITION_DEPENDENCY_DUPLICATE\"\n | \"TUBELESS_DEFINITION_DEPENDENCY_NOT_IN_STEPS\"\n | \"TUBELESS_DEFINITION_DEPENDENCY_SELF_REFERENCE\"\n | \"TUBELESS_DEFINITION_FINALIZER_STEP_NOT_IN_STEPS\"\n | \"TUBELESS_DEFINITION_PIPELINE_ID_BLANK\"\n | \"TUBELESS_DEFINITION_OPTIONS_SCHEMA_CONFLICT\"\n | \"TUBELESS_DEFINITION_STEP_ID_BLANK\"\n | \"TUBELESS_DEFINITION_STEP_ID_RESERVED\"\n | \"TUBELESS_DEFINITION_STEP_IDS_DUPLICATE\"\n | \"TUBELESS_DEFINITION_STEP_NAME_BLANK\"\n | \"TUBELESS_DEFINITION_TARGET_FINALIZER_MISMATCH\"\n | \"TUBELESS_DEFINITION_TARGET_NOT_IN_STEPS\"\n | \"TUBELESS_DEFINITION_TARGETS_DUPLICATE\"\n | \"TUBELESS_FINALIZATION_CANCELLED\"\n | \"TUBELESS_FINALIZATION_FAILED\"\n | \"TUBELESS_FINAL_RESULT_VALIDATION_FAILED\"\n | \"TUBELESS_OPTIONS_VALIDATION_FAILED\"\n | \"TUBELESS_PLANNING_SELECTION_CONFLICT\"\n | \"TUBELESS_PLANNING_STEP_SELECTION_DUPLICATE\"\n | \"TUBELESS_PLANNING_STEP_SELECTION_EMPTY\"\n | \"TUBELESS_PLANNING_STEP_UNKNOWN\"\n | \"TUBELESS_PLANNING_TARGET_SELECTION_DUPLICATE\"\n | \"TUBELESS_PLANNING_TARGET_SELECTION_EMPTY\"\n | \"TUBELESS_PLANNING_TARGET_UNDECLARED\"\n | \"TUBELESS_PLANNING_TARGET_UNKNOWN\"\n | \"TUBELESS_RUN_CANCELLED\"\n | \"TUBELESS_STEP_OUTPUT_VALIDATION_FAILED\"\n | \"TUBELESS_STEP_FAILED\";\n\n/** One dependency-free Standard Schema issue normalized for reports and traces. */\nexport interface PipelineValidationIssue {\n message: string;\n path?: readonly (number | string)[];\n}\n\n/** Bounded diagnostics for a failed or cancelled runtime fan-out. */\nexport interface PipelineFanOutFailure {\n /** Original input position, including when the key is truncated. */\n index: number;\n /** At most 1024 UTF-16 code units; do not rerun by key when keyTruncated is true. */\n key: string;\n keyTruncated: boolean;\n cancelled: boolean;\n error: PipelineErrorCause;\n}\n\nexport interface PipelineFanOutDiagnostics {\n /** Failed started items, in input order; at most 32 entries. */\n failures: readonly PipelineFanOutFailure[];\n /** Total failed started items, including omitted diagnostics. */\n failureCount: number;\n omittedFailureCount: number;\n /** Scheduler failure is separate and never assigned an item key. */\n schedulerError?: PipelineErrorCause;\n}\n\nexport interface PipelineError {\n /** Present for aggregated fan-out failures; absent for setup errors. */\n fanOut?: PipelineFanOutDiagnostics;\n /** Bounded, JSON-safe snapshot of the thrown error's cause chain. */\n cause?: PipelineErrorCause;\n code: PipelineErrorCode;\n kind: PipelineErrorKind;\n message: string;\n phase: PipelineErrorPhase;\n /** Present when a Standard Schema rejected a boundary value. */\n issues?: readonly PipelineValidationIssue[];\n stepId?: string;\n /** Machine-readable code copied from the original thrown error, when present. */\n sourceCode?: string;\n stack?: string;\n}\n\n/** Dependency-free subset of the Standard Schema V1 protocol. */\nexport interface StandardSchemaV1<TInput = unknown, TOutput = TInput> {\n readonly \"~standard\": StandardSchemaV1Props<TInput, TOutput>;\n}\n\nexport interface StandardSchemaV1Props<TInput = unknown, TOutput = TInput> {\n readonly types?: { readonly input: TInput; readonly output: TOutput };\n readonly validate: (\n value: unknown,\n options?: { readonly libraryOptions?: Record<string, unknown> }\n ) => StandardSchemaV1Result<TOutput> | Promise<StandardSchemaV1Result<TOutput>>;\n readonly vendor: string;\n readonly version: 1;\n}\n\nexport type StandardSchemaV1Result<TOutput> =\n | { readonly issues?: undefined; readonly value: TOutput }\n | { readonly issues: readonly StandardSchemaV1Issue[] };\n\nexport interface StandardSchemaV1Issue {\n readonly message: string;\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[];\n}\n\n/** Infer the accepted input type from a Standard Schema without importing its package. */\nexport type InferSchemaInput<TSchema extends StandardSchemaV1> = NonNullable<\n TSchema[\"~standard\"][\"types\"]\n>[\"input\"];\n\n/** Infer the validated output type from a Standard Schema without importing its package. */\nexport type InferSchemaOutput<TSchema extends StandardSchemaV1> = NonNullable<\n TSchema[\"~standard\"][\"types\"]\n>[\"output\"];\n\nexport interface PipelineErrorCause {\n cause?: PipelineErrorCause;\n message: string;\n name?: string;\n /** Machine-readable code copied from this cause, when present. */\n sourceCode?: string;\n}\n\ninterface PipelineStepReportBase {\n /** Present when the step started an execution attempt. */\n attemptId?: string;\n id: string;\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n name?: string;\n description?: string;\n /** Wall-clock time when this terminal report was recorded. */\n finishedAtMs: number;\n /** Wall-clock time when execution began; absent when the step never started. */\n startedAtMs?: number;\n}\n\nexport interface PipelineStepCompleteReport extends PipelineStepReportBase {\n attemptId: string;\n startedAtMs: number;\n status: \"completed\";\n}\n\nexport interface PipelineStepSkippedReport extends PipelineStepReportBase {\n /** Dependency that blocked this step, when applicable. */\n dependencyId?: string;\n /** Human-readable skip detail, especially for policy and fail-fast skips. */\n message?: string;\n reason: PipelineStepSkipReason;\n status: \"skipped\";\n}\n\nexport interface PipelineStepCancelledReport extends PipelineStepReportBase {\n error: PipelineError;\n status: \"cancelled\";\n}\n\nexport interface PipelineStepFailedReport extends PipelineStepReportBase {\n attemptId: string;\n error: PipelineError;\n startedAtMs: number;\n status: \"failed\";\n}\n\n/** Terminal state recorded for one step after a run. */\nexport type PipelineStepReport =\n | PipelineStepCancelledReport\n | PipelineStepFailedReport\n | PipelineStepSkippedReport\n | PipelineStepCompleteReport;\n\nexport type PipelineStepReportStatus = PipelineStepReport[\"status\"];\n\n/** Terminal disposition of a completed run record. */\nexport type PipelineRunStatus = \"cancelled\" | \"completed\" | \"failed\";\n\n/** Versioned public record returned for one pipeline execution. */\nexport interface PipelineRun<TResult = unknown> {\n pipelineId: string;\n dryRun: boolean;\n errors: PipelineError[];\n finalized: boolean;\n finishedAtMs: number;\n parentRunId?: string;\n runId: string;\n startedAtMs: number;\n status: PipelineRunStatus;\n steps: PipelineStepReport[];\n value?: TResult;\n version: typeof RUN_MODEL_VERSION;\n}\n\n/**\n * Why a step did not run. Built-in structural reasons keep dependency semantics;\n * `\"policy\"` is an intentional skip from `step.skip()` (still unlocks dependents).\n */\nexport type PipelineStepSkipReason =\n | \"dry-run\"\n | \"failed-dependency\"\n | \"fail-fast\"\n | \"filtered\"\n | \"policy\"\n | \"unmet-dependency\";\n\n/**\n * Decision from an optional `skip` predicate.\n * - falsy / `false` → run the step\n * - non-empty string → skip with that message (`reason: \"policy\"`); the step's\n * published output is `undefined`\n * - `{ reason, value? }` → skip and optionally publish `value` for dependents\n * (`value` may be intentionally `undefined` if passed explicitly)\n *\n * Policy skips unlock required dependents. Because a bare-string skip (or a\n * `{ reason }` without `value`) publishes `undefined`, any step that declares\n * `skip` is typed so dependents see `TOut | undefined`. Prefer returning\n * `{ reason, value }` on every skip path when dependents need a real output.\n */\nexport type StepSkipDecision<TOut = unknown> =\n | false\n | null\n | undefined\n | string\n | { reason: string; value?: TOut };\n\n/** One observable status in a step's planned → running → terminal lifecycle. */\nexport type PipelineStepStatus =\n | { pipelineId: string; status: \"planned\"; step: PipelinePlanStep }\n | {\n attemptId: string;\n pipelineId: string;\n progress?: PipelineStepProgress;\n status: \"running\";\n step: PipelinePlanStep;\n }\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepCancelledReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepFailedReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepSkippedReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepCompleteReport);\n\nexport type PipelineStepLifecycleStatus = PipelineStepStatus[\"status\"];\n\nexport type PipelineStepPlannedEvent = Extract<PipelineStepStatus, { status: \"planned\" }>;\ntype PipelineStepRunningStatus = Extract<PipelineStepStatus, { status: \"running\" }>;\nexport type PipelineStepStartEvent = Omit<PipelineStepRunningStatus, \"progress\"> & {\n progress?: undefined;\n};\nexport type PipelineStepProgressEvent = Omit<PipelineStepRunningStatus, \"progress\"> & {\n progress: PipelineStepProgress;\n};\nexport type PipelineStepCancelledEvent = Extract<PipelineStepStatus, { status: \"cancelled\" }>;\nexport type PipelineStepFailedEvent = Extract<PipelineStepStatus, { status: \"failed\" }>;\nexport type PipelineStepSkippedEvent = Extract<PipelineStepStatus, { status: \"skipped\" }>;\nexport type PipelineStepCompleteEvent = Extract<PipelineStepStatus, { status: \"completed\" }>;\n\nexport interface PipelineHooks<TResult = unknown> {\n onFinalizeComplete?(event: { durationMs: number; pipelineId: string; value: TResult }): void;\n onFinalizeError?(event: { durationMs: number; error: PipelineError; pipelineId: string }): void;\n onFinalizeStart?(event: { pipelineId: string }): void;\n onPipelineComplete?(event: PipelineRun<TResult>): void;\n onPipelineStart?(event: PipelinePlan): void;\n onStepCancel?(event: PipelineStepCancelledEvent): void;\n onStepFail?(event: PipelineStepFailedEvent): void;\n onStepPlan?(event: PipelineStepPlannedEvent): void;\n onStepProgress?(event: PipelineStepProgressEvent): void;\n onStepSkip?(event: PipelineStepSkippedEvent): void;\n onStepStart?(event: PipelineStepStartEvent): void;\n onStepStatus?(event: PipelineStepStatus): void;\n onStepComplete?(event: PipelineStepCompleteEvent): void;\n}\n\n/** Machine-readable explanation of why a planned step was included or omitted. */\nexport type PipelineStepSelectionReason =\n | { kind: \"all\" }\n | { kind: \"exact\" }\n | { kind: \"target\"; targetId: string }\n | { dependentId: string; kind: \"required-dependency\"; targetId: string }\n | { dependentId: string; kind: \"failure-gate\"; targetId: string }\n | { dependentId: string; kind: \"optional-only\"; targetId: string }\n | { kind: \"outside-target-closure\" }\n | { kind: \"not-selected\" };\n\nexport interface PipelinePlanStep {\n dependencies: string[];\n description?: string;\n /** How this step behaves when the pipeline is run with `dryRun: true`. */\n dryRun: \"custom\" | \"run\" | \"skip\";\n id: string;\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n name?: string;\n /** Static child structure when this opaque step executes another pipeline. */\n nestedPipeline?: {\n /** One child execution or one child execution per runtime item. */\n mode: \"single\" | \"for-each\";\n pipelineId: string;\n /** All declared child step ids; runtime selection may execute only a subset. */\n stepIds: readonly string[];\n };\n /** Static remote adapter metadata when this opaque step calls an external engine. */\n remote?: {\n engine: string;\n target?: string;\n };\n optionalDependencies: string[];\n /** True when the step's runtime policy may elect not to run it. */\n runtimeSkipPossible: boolean;\n selected: boolean;\n /** Stable reasons for selection or omission; shared prerequisites can have several. */\n selectionReasons: readonly PipelineStepSelectionReason[];\n skipAfterFailureOf: string[];\n skipReason?: PipelineStepSkipReason;\n}\n\nexport interface PipelinePlan {\n dryRun: boolean;\n errors: PipelineError[];\n ok: boolean;\n pipelineId: string;\n steps: PipelinePlanStep[];\n}\n\n/** Layout directions for generated Mermaid flowcharts. */\nexport const PIPELINE_MERMAID_DIRECTIONS = [\"BT\", \"LR\", \"RL\", \"TB\", \"TD\"] as const;\nexport type PipelineMermaidDirection = (typeof PIPELINE_MERMAID_DIRECTIONS)[number];\n\nexport interface PipelineMermaidOptions {\n /** Mermaid flowchart direction. Defaults to top-down (`TD`). */\n direction?: PipelineMermaidDirection;\n /** Append each operational description to its node label. Defaults to false. */\n includeDescriptions?: boolean;\n}\n\nexport interface Pipeline<\n TOptions extends object,\n TResult,\n TStepId extends string = string,\n TTargetId extends string = TStepId,\n> {\n readonly id: string;\n /** Stable definition-order step ids for discovery surfaces such as CLI help. */\n readonly stepIds: readonly TStepId[];\n /** Stable declared goal ids that support dependency-aware target execution. */\n readonly targetIds: readonly TTargetId[];\n plan(controls?: PipelineRunControls<TStepId, TTargetId>): PipelinePlan;\n run(\n options: TOptions,\n controls?: PipelineRunControls<TStepId, TTargetId>,\n context?: Partial<PipelineContext>\n ): Promise<PipelineRun<TResult>>;\n runOrThrow(\n options: TOptions,\n controls?: PipelineRunControls<TStepId, TTargetId>,\n context?: Partial<PipelineContext>\n ): Promise<TResult>;\n /** Generate a static Mermaid flowchart without running or planning the pipeline. */\n toMermaid(options?: PipelineMermaidOptions): string;\n}\n"]}
1
+ {"version":3,"file":"pipeline-types.js","sourceRoot":"","sources":["../../src/core/pipeline-types.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,IAAI,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAgJlG,yEAAyE;AACzE,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC;AAK9E,MAAM,oBAAoB,GAAwB,IAAI,GAAG,CAAC,oBAAoB,CAAC,CAAC;AAEhF,qFAAqF;AACrF,MAAM,UAAU,mBAAmB,CAAC,KAAc;IAChD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AACtE,CAAC;AA8RD,0DAA0D;AAC1D,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC","sourcesContent":["import type { RUN_MODEL_VERSION } from \"./pipeline-ids.js\";\nimport { PIPELINE_ERROR_CODES as PIPELINE_ERROR_CODE_VALUES } from \"../tracing/tracing-schema.js\";\nimport type {\n PipelineErrorKindContract,\n PipelineErrorPhaseContract,\n} from \"../tracing/tracing-schema.js\";\nimport type {\n PipelineTraceAttributes,\n PipelineTraceContext,\n PipelineTracingOptions,\n} from \"../tracing/tracing-contracts.js\";\n\nexport interface PipelineLogger {\n error(message?: unknown, ...optionalParams: unknown[]): void;\n log(message?: unknown, ...optionalParams: unknown[]): void;\n warn(message?: unknown, ...optionalParams: unknown[]): void;\n}\n\nexport interface PipelineContext {\n /** Optional caller-owned identifier used to correlate separate executions. */\n correlationId?: string;\n cwd: string;\n /** Hook sets run in order and failures are isolated per set. */\n hooks?: PipelineHooks | readonly PipelineHooks[];\n log: PipelineLogger;\n /** Timestamp source for persisted run records. Defaults to `Date.now`. */\n now?: () => number;\n /** Optional package-generated execution identity of this run's parent. */\n parentRunId?: string;\n signal?: AbortSignal;\n sleep?: (durationMs: number, signal?: AbortSignal) => Promise<void>;\n /** Optional structured lifecycle tracing configuration for this run. */\n tracing?: PipelineTracingOptions;\n}\n\nexport interface PipelineRunControls<\n TStepId extends string = string,\n TTargetId extends string = string,\n> {\n continueOnError?: boolean;\n dryRun?: boolean;\n /**\n * Run only these steps; omitted or undefined runs every step. An empty array\n * is invalid and fails planning/execution instead of silently running nothing.\n */\n stepIds?: readonly TStepId[];\n /**\n * Run these declared pipeline targets and the upstream work required to\n * reach them. Required inputs and failure gates are included recursively;\n * optional-only inputs are not. Cannot be combined with exact `stepIds`\n * filtering.\n */\n targets?: readonly TTargetId[];\n}\n\n/** Domain input plus built-in controls. Child `mapOptions` still returns this mix. */\nexport type PipelineRunOptions<\n TOptions extends object = object,\n TStepId extends string = string,\n TTargetId extends string = string,\n> = TOptions & PipelineRunControls<TStepId, TTargetId>;\nexport interface PipelineRuntime extends PipelineContext {\n now: () => number;\n sleep: (durationMs: number, signal?: AbortSignal) => Promise<void>;\n}\n\nexport interface PipelineExecutionContext<TOptions extends object> extends PipelineRuntime {\n /** Caller-owned identifier shared by related executions, when supplied. */\n correlationId?: string;\n dryRun: boolean;\n options: TOptions;\n /** Stable identity for this execution, whether or not tracing is configured. */\n runId: string;\n /** Parent execution identity when this run was started by another run. */\n parentRunId?: string;\n /** Stable identities for this traced run; absent unless `context.tracing` is configured. */\n trace?: PipelineTraceContext;\n}\n\n/**\n * Optional indented detail row under a parent step's progress.\n * Domain-agnostic: mapped children, nested work units, per-file status, etc.\n */\nexport type PipelineStepProgressDetailStatus =\n | \"cancelled\"\n | \"completed\"\n | \"failed\"\n | \"pending\"\n | \"running\"\n | \"skipped\";\n\nexport interface PipelineStepProgressDetail {\n /** Stable identity for the row (item key, path, job id, …). */\n id: string;\n /** Optional display name; identity remains `id`. */\n name?: string;\n /** Indentation relative to direct child rows (0). Rows are in tree preorder. */\n depth?: number;\n /** Inner work counts, independent of the parent's lifecycle count. */\n completed?: number;\n total?: number;\n /** Short status text shown after the id. */\n label?: string;\n /** Controls the detail row symbol. Defaults to `running`. */\n status?: PipelineStepProgressDetailStatus;\n}\n\nexport interface PipelineStepProgress {\n /** Work completed so far. Values outside the reported total are allowed but renderers may clamp them. */\n completed: number;\n /** Total work when known. Omit for indeterminate progress. */\n total?: number;\n /** Optional short status shown next to the step. Prefer one-line summaries. */\n message?: string;\n /**\n * Optional multi-line detail rows for capable reporters (interactive TTY).\n * Keep the parent `message` as a summary; put per-item status here so high\n * concurrency does not collapse onto one truncated line.\n */\n details?: readonly PipelineStepProgressDetail[];\n}\n\nexport interface PipelineStepContext<\n TOptions extends object,\n> extends PipelineExecutionContext<TOptions> {\n /** Stable identity for this execution of the current step. */\n attemptId: string;\n /** Emit a retry/attempt trace event for this step when tracing is enabled. */\n reportAttempt(attempt: number, attributes?: PipelineTraceAttributes): void;\n /** Publish the latest progress snapshot for this step. */\n reportProgress(progress: PipelineStepProgress): void;\n}\n\nexport interface RemoteStepAdapter<TOptions extends object, TPayload, TResult> {\n /** Presentation only. The kernel never switches on this. */\n readonly engine: string;\n /** Function name, workflow type, URL, queue. Presentation only. */\n readonly target?: string;\n invoke(payload: TPayload, context: PipelineStepContext<TOptions>): Promise<TResult>;\n}\n\nexport type PipelineErrorPhase = PipelineErrorPhaseContract;\n\nexport type PipelineErrorKind = PipelineErrorKindContract;\n\n/** Ordered catalog of every stable package-owned pipeline error code. */\nexport const PIPELINE_ERROR_CODES = Object.freeze(PIPELINE_ERROR_CODE_VALUES);\n\n/** Stable package-owned code for a pipeline error. */\nexport type PipelineErrorCode = (typeof PIPELINE_ERROR_CODES)[number];\n\nconst pipelineErrorCodeSet: ReadonlySet<string> = new Set(PIPELINE_ERROR_CODES);\n\n/** Return whether an unknown value is a stable package-owned pipeline error code. */\nexport function isPipelineErrorCode(value: unknown): value is PipelineErrorCode {\n return typeof value === \"string\" && pipelineErrorCodeSet.has(value);\n}\n\n/** One dependency-free Standard Schema issue normalized for reports and traces. */\nexport interface PipelineValidationIssue {\n message: string;\n path?: readonly (number | string)[];\n}\n\n/** Bounded diagnostics for a failed or cancelled runtime fan-out. */\nexport interface PipelineFanOutFailure {\n /** Original input position, including when the key is truncated. */\n index: number;\n /** At most 1024 UTF-16 code units; do not rerun by key when keyTruncated is true. */\n key: string;\n keyTruncated: boolean;\n cancelled: boolean;\n error: PipelineErrorCause;\n}\n\nexport interface PipelineFanOutDiagnostics {\n /** Failed started items, in input order; at most 32 entries. */\n failures: readonly PipelineFanOutFailure[];\n /** Total failed started items, including omitted diagnostics. */\n failureCount: number;\n omittedFailureCount: number;\n /** Scheduler failure is separate and never assigned an item key. */\n schedulerError?: PipelineErrorCause;\n}\n\nexport interface PipelineError {\n /** Present for aggregated fan-out failures; absent for setup errors. */\n fanOut?: PipelineFanOutDiagnostics;\n /** Bounded, JSON-safe snapshot of the thrown error's cause chain. */\n cause?: PipelineErrorCause;\n code: PipelineErrorCode;\n kind: PipelineErrorKind;\n message: string;\n phase: PipelineErrorPhase;\n /** Present when a Standard Schema rejected a boundary value. */\n issues?: readonly PipelineValidationIssue[];\n stepId?: string;\n /** Machine-readable code copied from the original thrown error, when present. */\n sourceCode?: string;\n stack?: string;\n}\n\n/** Dependency-free subset of the Standard Schema V1 protocol. */\nexport interface StandardSchemaV1<TInput = unknown, TOutput = TInput> {\n readonly \"~standard\": StandardSchemaV1Props<TInput, TOutput>;\n}\n\nexport interface StandardSchemaV1Props<TInput = unknown, TOutput = TInput> {\n readonly types?: { readonly input: TInput; readonly output: TOutput };\n readonly validate: (\n value: unknown,\n options?: { readonly libraryOptions?: Record<string, unknown> }\n ) => StandardSchemaV1Result<TOutput> | Promise<StandardSchemaV1Result<TOutput>>;\n readonly vendor: string;\n readonly version: 1;\n}\n\nexport type StandardSchemaV1Result<TOutput> =\n | { readonly issues?: undefined; readonly value: TOutput }\n | { readonly issues: readonly StandardSchemaV1Issue[] };\n\nexport interface StandardSchemaV1Issue {\n readonly message: string;\n readonly path?: readonly (PropertyKey | { readonly key: PropertyKey })[];\n}\n\n/** Infer the accepted input type from a Standard Schema without importing its package. */\nexport type InferSchemaInput<TSchema extends StandardSchemaV1> = NonNullable<\n TSchema[\"~standard\"][\"types\"]\n>[\"input\"];\n\n/** Infer the validated output type from a Standard Schema without importing its package. */\nexport type InferSchemaOutput<TSchema extends StandardSchemaV1> = NonNullable<\n TSchema[\"~standard\"][\"types\"]\n>[\"output\"];\n\nexport interface PipelineErrorCause {\n cause?: PipelineErrorCause;\n message: string;\n name?: string;\n /** Machine-readable code copied from this cause, when present. */\n sourceCode?: string;\n}\n\ninterface PipelineStepReportBase {\n /** Present when the step started an execution attempt. */\n attemptId?: string;\n id: string;\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n name?: string;\n description?: string;\n /** Wall-clock time when this terminal report was recorded. */\n finishedAtMs: number;\n /** Wall-clock time when execution began; absent when the step never started. */\n startedAtMs?: number;\n}\n\nexport interface PipelineStepCompleteReport extends PipelineStepReportBase {\n attemptId: string;\n startedAtMs: number;\n status: \"completed\";\n}\n\nexport interface PipelineStepSkippedReport extends PipelineStepReportBase {\n /** Dependency that blocked this step, when applicable. */\n dependencyId?: string;\n /** Human-readable skip detail, especially for policy and fail-fast skips. */\n message?: string;\n reason: PipelineStepSkipReason;\n status: \"skipped\";\n}\n\nexport interface PipelineStepCancelledReport extends PipelineStepReportBase {\n error: PipelineError;\n status: \"cancelled\";\n}\n\nexport interface PipelineStepFailedReport extends PipelineStepReportBase {\n attemptId: string;\n error: PipelineError;\n startedAtMs: number;\n status: \"failed\";\n}\n\n/** Terminal state recorded for one step after a run. */\nexport type PipelineStepReport =\n | PipelineStepCancelledReport\n | PipelineStepFailedReport\n | PipelineStepSkippedReport\n | PipelineStepCompleteReport;\n\nexport type PipelineStepReportStatus = PipelineStepReport[\"status\"];\n\n/** Terminal disposition of a completed run record. */\nexport type PipelineRunStatus = \"cancelled\" | \"completed\" | \"failed\";\n\n/** Versioned public record returned for one pipeline execution. */\nexport interface PipelineRun<TResult = unknown> {\n /** Caller-owned identifier shared by related executions, when supplied. */\n correlationId?: string;\n pipelineId: string;\n dryRun: boolean;\n errors: PipelineError[];\n finalized: boolean;\n finishedAtMs: number;\n parentRunId?: string;\n runId: string;\n startedAtMs: number;\n status: PipelineRunStatus;\n steps: PipelineStepReport[];\n value?: TResult;\n version: typeof RUN_MODEL_VERSION;\n}\n\n/**\n * Why a step did not run. Built-in structural reasons keep dependency semantics;\n * `\"policy\"` is an intentional skip from `step.skip()` (still unlocks dependents).\n */\nexport type PipelineStepSkipReason =\n | \"dry-run\"\n | \"failed-dependency\"\n | \"fail-fast\"\n | \"filtered\"\n | \"policy\"\n | \"unmet-dependency\";\n\n/**\n * Decision from an optional `skip` predicate.\n * - falsy / `false` → run the step\n * - non-empty string → skip with that message (`reason: \"policy\"`); the step's\n * published output is `undefined`\n * - `{ reason, value? }` → skip and optionally publish `value` for dependents\n * (`value` may be intentionally `undefined` if passed explicitly)\n *\n * Policy skips unlock required dependents. Because a bare-string skip (or a\n * `{ reason }` without `value`) publishes `undefined`, any step that declares\n * `skip` is typed so dependents see `TOut | undefined`. Prefer returning\n * `{ reason, value }` on every skip path when dependents need a real output.\n */\nexport type StepSkipDecision<TOut = unknown> =\n | false\n | null\n | undefined\n | string\n | { reason: string; value?: TOut };\n\n/** One observable status in a step's planned → running → terminal lifecycle. */\nexport type PipelineStepStatus =\n | { pipelineId: string; status: \"planned\"; step: PipelinePlanStep }\n | {\n attemptId: string;\n pipelineId: string;\n progress?: PipelineStepProgress;\n status: \"running\";\n step: PipelinePlanStep;\n }\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepCancelledReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepFailedReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepSkippedReport)\n | ({ pipelineId: string; step: PipelinePlanStep } & PipelineStepCompleteReport);\n\nexport type PipelineStepLifecycleStatus = PipelineStepStatus[\"status\"];\n\nexport type PipelineStepPlannedEvent = Extract<PipelineStepStatus, { status: \"planned\" }>;\ntype PipelineStepRunningStatus = Extract<PipelineStepStatus, { status: \"running\" }>;\nexport type PipelineStepStartEvent = Omit<PipelineStepRunningStatus, \"progress\"> & {\n progress?: undefined;\n};\nexport type PipelineStepProgressEvent = Omit<PipelineStepRunningStatus, \"progress\"> & {\n progress: PipelineStepProgress;\n};\nexport type PipelineStepCancelledEvent = Extract<PipelineStepStatus, { status: \"cancelled\" }>;\nexport type PipelineStepFailedEvent = Extract<PipelineStepStatus, { status: \"failed\" }>;\nexport type PipelineStepSkippedEvent = Extract<PipelineStepStatus, { status: \"skipped\" }>;\nexport type PipelineStepCompleteEvent = Extract<PipelineStepStatus, { status: \"completed\" }>;\n\nexport interface PipelineHooks<TResult = unknown> {\n onFinalizeComplete?(event: { durationMs: number; pipelineId: string; value: TResult }): void;\n onFinalizeError?(event: { durationMs: number; error: PipelineError; pipelineId: string }): void;\n onFinalizeStart?(event: { pipelineId: string }): void;\n onPipelineComplete?(event: PipelineRun<TResult>): void;\n onPipelineStart?(event: PipelinePlan): void;\n onStepCancel?(event: PipelineStepCancelledEvent): void;\n onStepFail?(event: PipelineStepFailedEvent): void;\n onStepPlan?(event: PipelineStepPlannedEvent): void;\n onStepProgress?(event: PipelineStepProgressEvent): void;\n onStepSkip?(event: PipelineStepSkippedEvent): void;\n onStepStart?(event: PipelineStepStartEvent): void;\n onStepStatus?(event: PipelineStepStatus): void;\n onStepComplete?(event: PipelineStepCompleteEvent): void;\n}\n\n/** Machine-readable explanation of why a planned step was included or omitted. */\nexport type PipelineStepSelectionReason =\n | { kind: \"all\" }\n | { kind: \"exact\" }\n | { kind: \"target\"; targetId: string }\n | { dependentId: string; kind: \"required-dependency\"; targetId: string }\n | { dependentId: string; kind: \"failure-gate\"; targetId: string }\n | { dependentId: string; kind: \"optional-only\"; targetId: string }\n | { kind: \"outside-target-closure\" }\n | { kind: \"not-selected\" };\n\nexport interface PipelinePlanStep {\n dependencies: string[];\n description?: string;\n /** How this step behaves when the pipeline is run with `dryRun: true`. */\n dryRun: \"custom\" | \"run\" | \"skip\";\n id: string;\n /** Optional human-facing display name. Stable machine identity remains `id`. */\n name?: string;\n /** Static child structure when this opaque step executes another pipeline. */\n nestedPipeline?: {\n /** One child execution or one child execution per runtime item. */\n mode: \"single\" | \"for-each\";\n pipelineId: string;\n /** All declared child step ids; runtime selection may execute only a subset. */\n stepIds: readonly string[];\n };\n /** Static remote adapter metadata when this opaque step calls an external engine. */\n remote?: {\n engine: string;\n target?: string;\n };\n optionalDependencies: string[];\n /** True when the step's runtime policy may elect not to run it. */\n runtimeSkipPossible: boolean;\n selected: boolean;\n /** Stable reasons for selection or omission; shared prerequisites can have several. */\n selectionReasons: readonly PipelineStepSelectionReason[];\n skipAfterFailureOf: string[];\n skipReason?: PipelineStepSkipReason;\n}\n\nexport interface PipelinePlan {\n dryRun: boolean;\n errors: PipelineError[];\n ok: boolean;\n pipelineId: string;\n steps: PipelinePlanStep[];\n}\n\n/** Layout directions for generated Mermaid flowcharts. */\nexport const PIPELINE_MERMAID_DIRECTIONS = [\"BT\", \"LR\", \"RL\", \"TB\", \"TD\"] as const;\nexport type PipelineMermaidDirection = (typeof PIPELINE_MERMAID_DIRECTIONS)[number];\n\nexport interface PipelineMermaidOptions {\n /** Mermaid flowchart direction. Defaults to top-down (`TD`). */\n direction?: PipelineMermaidDirection;\n /** Append each operational description to its node label. Defaults to false. */\n includeDescriptions?: boolean;\n}\n\nexport interface Pipeline<\n TOptions extends object,\n TResult,\n TStepId extends string = string,\n TTargetId extends string = TStepId,\n> {\n readonly id: string;\n /** Stable definition-order step ids for discovery surfaces such as CLI help. */\n readonly stepIds: readonly TStepId[];\n /** Stable declared goal ids that support dependency-aware target execution. */\n readonly targetIds: readonly TTargetId[];\n plan(controls?: PipelineRunControls<TStepId, TTargetId>): PipelinePlan;\n run(\n options: TOptions,\n controls?: PipelineRunControls<TStepId, TTargetId>,\n context?: Partial<PipelineContext>\n ): Promise<PipelineRun<TResult>>;\n runOrThrow(\n options: TOptions,\n controls?: PipelineRunControls<TStepId, TTargetId>,\n context?: Partial<PipelineContext>\n ): Promise<TResult>;\n /** Generate a static Mermaid flowchart without running or planning the pipeline. */\n toMermaid(options?: PipelineMermaidOptions): string;\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import type { InferSchemaOutput, PipelineValidationIssue, StandardSchemaV1 } from "./pipeline-types.js";
2
+ export declare class PipelineBoundaryValidationError extends Error {
3
+ readonly issues: readonly PipelineValidationIssue[];
4
+ constructor(message: string, issues: readonly PipelineValidationIssue[], cause?: unknown);
5
+ }
6
+ export declare function validateStandardSchema<TSchema extends StandardSchemaV1>(schema: TSchema, value: unknown, boundary: string): Promise<InferSchemaOutput<TSchema>>;
@@ -0,0 +1,41 @@
1
+ export class PipelineBoundaryValidationError extends Error {
2
+ issues;
3
+ constructor(message, issues, cause) {
4
+ super(message, cause === undefined ? undefined : { cause });
5
+ this.issues = issues;
6
+ this.name = "PipelineBoundaryValidationError";
7
+ }
8
+ }
9
+ function normalizeValidationPath(path) {
10
+ if (!path || path.length === 0)
11
+ return undefined;
12
+ return path.map((segment) => {
13
+ const key = typeof segment === "object" && segment !== null ? segment.key : segment;
14
+ return typeof key === "number" || typeof key === "string" ? key : String(key);
15
+ });
16
+ }
17
+ function renderValidationIssue(issue) {
18
+ const location = issue.path?.map(String).join(".");
19
+ return location ? `${location}: ${issue.message}` : issue.message;
20
+ }
21
+ export async function validateStandardSchema(schema, value, boundary) {
22
+ let result;
23
+ try {
24
+ result = await schema["~standard"].validate(value);
25
+ }
26
+ catch (error) {
27
+ throw new PipelineBoundaryValidationError(`${boundary} schema (${schema["~standard"].vendor}) threw while validating`, [], error);
28
+ }
29
+ if (result.issues) {
30
+ const issues = result.issues.map((issue) => {
31
+ const path = normalizeValidationPath(issue.path);
32
+ const normalized = { message: issue.message };
33
+ if (path)
34
+ normalized.path = path;
35
+ return normalized;
36
+ });
37
+ throw new PipelineBoundaryValidationError(`${boundary} validation failed: ${issues.map(renderValidationIssue).join("; ")}`, issues);
38
+ }
39
+ return result.value;
40
+ }
41
+ //# sourceMappingURL=pipeline-validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-validation.js","sourceRoot":"","sources":["../../src/core/pipeline-validation.ts"],"names":[],"mappings":"AAQA,MAAM,OAAO,+BAAgC,SAAQ,KAAK;IAG7C,MAAM;IAFjB,YACE,OAAe,EACN,MAA0C,EACnD,KAAe;QAEf,KAAK,CAAC,OAAO,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;sBAHnD,MAAM;QAIf,IAAI,CAAC,IAAI,GAAG,iCAAiC,CAAC;IAChD,CAAC;CACF;AAED,SAAS,uBAAuB,CAC9B,IAAmC;IAEnC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;QACpF,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,qBAAqB,CAAC,KAA8B;IAC3D,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC,CAAC,CAAC,GAAG,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;AACpE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAAe,EACf,KAAc,EACd,QAAgB;IAEhB,IAAI,MAA0D,CAAC;IAC/D,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,+BAA+B,CACvC,GAAG,QAAQ,YAAY,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,0BAA0B,EAC3E,EAAE,EACF,KAAK,CACN,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,MAAM,IAAI,GAAG,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACjD,MAAM,UAAU,GAA4B,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;YACvE,IAAI,IAAI;gBAAE,UAAU,CAAC,IAAI,GAAG,IAAI,CAAC;YACjC,OAAO,UAAU,CAAC;QACpB,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,+BAA+B,CACvC,GAAG,QAAQ,uBAAuB,MAAM,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAChF,MAAM,CACP,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC;AACtB,CAAC","sourcesContent":["import type {\n InferSchemaOutput,\n PipelineValidationIssue,\n StandardSchemaV1,\n StandardSchemaV1Issue,\n StandardSchemaV1Result,\n} from \"./pipeline-types.js\";\n\nexport class PipelineBoundaryValidationError extends Error {\n constructor(\n message: string,\n readonly issues: readonly PipelineValidationIssue[],\n cause?: unknown\n ) {\n super(message, cause === undefined ? undefined : { cause });\n this.name = \"PipelineBoundaryValidationError\";\n }\n}\n\nfunction normalizeValidationPath(\n path: StandardSchemaV1Issue[\"path\"]\n): readonly (number | string)[] | undefined {\n if (!path || path.length === 0) return undefined;\n return path.map((segment) => {\n const key = typeof segment === \"object\" && segment !== null ? segment.key : segment;\n return typeof key === \"number\" || typeof key === \"string\" ? key : String(key);\n });\n}\n\nfunction renderValidationIssue(issue: PipelineValidationIssue): string {\n const location = issue.path?.map(String).join(\".\");\n return location ? `${location}: ${issue.message}` : issue.message;\n}\n\nexport async function validateStandardSchema<TSchema extends StandardSchemaV1>(\n schema: TSchema,\n value: unknown,\n boundary: string\n): Promise<InferSchemaOutput<TSchema>> {\n let result: StandardSchemaV1Result<InferSchemaOutput<TSchema>>;\n try {\n result = await schema[\"~standard\"].validate(value);\n } catch (error) {\n throw new PipelineBoundaryValidationError(\n `${boundary} schema (${schema[\"~standard\"].vendor}) threw while validating`,\n [],\n error\n );\n }\n if (result.issues) {\n const issues = result.issues.map((issue) => {\n const path = normalizeValidationPath(issue.path);\n const normalized: PipelineValidationIssue = { message: issue.message };\n if (path) normalized.path = path;\n return normalized;\n });\n throw new PipelineBoundaryValidationError(\n `${boundary} validation failed: ${issues.map(renderValidationIssue).join(\"; \")}`,\n issues\n );\n }\n return result.value;\n}\n"]}
@@ -1,16 +1,16 @@
1
- import { defaultPipelineContext, PipelineExecutionError } from "./pipeline-execute.js";
2
- import { createRunId, RUN_MODEL_VERSION } from "./pipeline-ids.js";
3
- import { PIPELINE_FINALIZE_STEP_ID, PipelineDefinitionError, requireOutputs, type PipelineDefinition } from "./pipeline-plan.js";
4
- import type { StepIds, StepsInputOptions, TargetIds } from "./pipeline-plan.js";
1
+ import { PipelineExecutionError } from "./pipeline-execute.js";
2
+ import { RUN_MODEL_VERSION } from "./pipeline-ids.js";
3
+ import type { PipelineDefinition, StepIds, StepsInputOptions, TargetIds } from "./pipeline-definition.js";
4
+ import { PipelineDefinitionError } from "./pipeline-errors.js";
5
+ import { requireOutputs } from "./pipeline-finalizer.js";
5
6
  import type { AnyStep } from "./pipeline-steps.js";
6
7
  import type { InferSchemaOutput, Pipeline, StandardSchemaV1 } from "./pipeline-types.js";
7
- export { createRunId, PIPELINE_FINALIZE_STEP_ID, PipelineExecutionError, RUN_MODEL_VERSION };
8
- export { PIPELINE_MERMAID_DIRECTIONS } from "./pipeline-types.js";
8
+ export { PipelineExecutionError, RUN_MODEL_VERSION };
9
+ export { isPipelineErrorCode, PIPELINE_ERROR_CODES, PIPELINE_MERMAID_DIRECTIONS, } from "./pipeline-types.js";
9
10
  export { createSteps } from "./pipeline-steps.js";
10
- export { defaultPipelineContext };
11
11
  export { PipelineDefinitionError, requireOutputs };
12
12
  export type { PipelineLogger, PipelineContext, PipelineRunControls, PipelineRunOptions, PipelineRuntime, PipelineExecutionContext, PipelineStepProgressDetailStatus, PipelineStepProgressDetail, PipelineStepProgress, PipelineStepContext, RemoteStepAdapter, PipelineErrorPhase, PipelineErrorKind, PipelineErrorCode, PipelineValidationIssue, PipelineError, PipelineFanOutDiagnostics, PipelineFanOutFailure, StandardSchemaV1, StandardSchemaV1Props, StandardSchemaV1Result, StandardSchemaV1Issue, InferSchemaInput, InferSchemaOutput, PipelineErrorCause, PipelineStepCompleteReport, PipelineStepSkippedReport, PipelineStepCancelledReport, PipelineStepFailedReport, PipelineStepReport, PipelineStepReportStatus, PipelineRunStatus, PipelineRun, PipelineStepSkipReason, StepSkipDecision, PipelineStepStatus, PipelineStepLifecycleStatus, PipelineStepPlannedEvent, PipelineStepStartEvent, PipelineStepProgressEvent, PipelineStepCancelledEvent, PipelineStepFailedEvent, PipelineStepSkippedEvent, PipelineStepCompleteEvent, PipelineHooks, PipelineStepSelectionReason, PipelinePlanStep, PipelinePlan, PipelineMermaidDirection, PipelineMermaidOptions, Pipeline, } from "./pipeline-types.js";
13
- export type { PipelineDefinition } from "./pipeline-plan.js";
13
+ export type { PipelineDefinition } from "./pipeline-definition.js";
14
14
  export type { AnyStep, Step, MappedChildProgressOptions, StepFactory } from "./pipeline-steps.js";
15
15
  type DuplicateStepIds<TSteps extends readonly AnyStep[], TSeen extends string = never> = TSteps extends readonly [infer THead, ...infer TTail] ? THead extends AnyStep ? TTail extends readonly AnyStep[] ? THead["id"] extends TSeen ? THead["id"] | DuplicateStepIds<TTail, TSeen> : DuplicateStepIds<TTail, TSeen | THead["id"]> : never : never : never;
16
16
  type CheckedStepTuple<TSteps extends readonly AnyStep[]> = string extends StepIds<TSteps> ? unknown : DuplicateStepIds<TSteps> extends never ? unknown : {
@@ -18,4 +18,3 @@ type CheckedStepTuple<TSteps extends readonly AnyStep[]> = string extends StepId
18
18
  readonly __duplicateStepIds: DuplicateStepIds<TSteps>;
19
19
  };
20
20
  export declare function definePipeline<const TSteps extends readonly AnyStep[], TResult = unknown, const TTargets extends readonly TSteps[number][] = readonly [], const TResultSchema extends StandardSchemaV1 | undefined = undefined>(definition: PipelineDefinition<TSteps, TResult, TTargets, TResultSchema> & CheckedStepTuple<TSteps>): Pipeline<StepsInputOptions<TSteps>, TResultSchema extends StandardSchemaV1 ? InferSchemaOutput<TResultSchema> : TResult, StepIds<TSteps>, TargetIds<TTargets>>;
21
- export { formatMappedChildProgressMessage, mappedChildProgressDetails, mappedChildProgressUnits, toMappedChildStepProgress, type FormatMappedChildProgressOptions, type MappedChildProgressDetail, type MappedChildProgressSnapshot, type MappedChildProgressUnits, type ToMappedChildStepProgressOptions, } from "./mapped-child-progress.js";
@@ -1,10 +1,14 @@
1
1
  import { defaultPipelineContext, executePlannedRun, PipelineExecutionError, resolvePipelineRuntime, } from "./pipeline-execute.js";
2
- import { createRunId, RUN_MODEL_VERSION } from "./pipeline-ids.js";
3
- import { PIPELINE_FINALIZE_STEP_ID, PipelineDefinitionError, requireOutputs, buildPipelinePlan, brandCompiledPipeline, compilePipeline, EXECUTE_COMPILED_RUN, renderPipelineMermaid, } from "./pipeline-plan.js";
4
- export { createRunId, PIPELINE_FINALIZE_STEP_ID, PipelineExecutionError, RUN_MODEL_VERSION };
5
- export { PIPELINE_MERMAID_DIRECTIONS } from "./pipeline-types.js";
2
+ import { RUN_MODEL_VERSION } from "./pipeline-ids.js";
3
+ import { compilePipeline } from "./pipeline-compiler.js";
4
+ import { PipelineDefinitionError } from "./pipeline-errors.js";
5
+ import { requireOutputs } from "./pipeline-finalizer.js";
6
+ import { brandCompiledPipeline, EXECUTE_COMPILED_RUN } from "./pipeline-identity.js";
7
+ import { renderPipelineMermaid } from "./pipeline-mermaid.js";
8
+ import { buildPipelinePlan } from "./pipeline-plan.js";
9
+ export { PipelineExecutionError, RUN_MODEL_VERSION };
10
+ export { isPipelineErrorCode, PIPELINE_ERROR_CODES, PIPELINE_MERMAID_DIRECTIONS, } from "./pipeline-types.js";
6
11
  export { createSteps } from "./pipeline-steps.js";
7
- export { defaultPipelineContext };
8
12
  export { PipelineDefinitionError, requireOutputs };
9
13
  function snapshotRunControls(controls) {
10
14
  const { continueOnError, dryRun, stepIds, targets } = controls;
@@ -65,5 +69,4 @@ export function definePipeline(definition) {
65
69
  brandCompiledPipeline(pipeline);
66
70
  return pipeline;
67
71
  }
68
- export { formatMappedChildProgressMessage, mappedChildProgressDetails, mappedChildProgressUnits, toMappedChildStepProgress, } from "./mapped-child-progress.js";
69
72
  //# sourceMappingURL=pipeline.js.map