tubeless 0.3.2 → 0.3.3

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 (71) hide show
  1. package/dist/agent/default-tool-files.js +58 -38
  2. package/dist/agent/default-tool-files.js.map +1 -1
  3. package/dist/core/child-execution.js +1 -1
  4. package/dist/core/child-execution.js.map +1 -1
  5. package/dist/core/lifecycle.js +19 -7
  6. package/dist/core/lifecycle.js.map +1 -1
  7. package/dist/core/pipeline-diagnostics.d.ts +14 -1
  8. package/dist/core/pipeline-diagnostics.js +39 -0
  9. package/dist/core/pipeline-diagnostics.js.map +1 -1
  10. package/dist/core/pipeline-finalizer.js +2 -1
  11. package/dist/core/pipeline-finalizer.js.map +1 -1
  12. package/dist/core/pipeline-step-builders.d.ts +63 -0
  13. package/dist/core/pipeline-step-builders.js +140 -0
  14. package/dist/core/pipeline-step-builders.js.map +1 -0
  15. package/dist/core/pipeline-step-types.d.ts +160 -0
  16. package/dist/core/pipeline-step-types.js +2 -0
  17. package/dist/core/pipeline-step-types.js.map +1 -0
  18. package/dist/core/pipeline-steps.d.ts +9 -164
  19. package/dist/core/pipeline-steps.js +8 -137
  20. package/dist/core/pipeline-steps.js.map +1 -1
  21. package/dist/core/step-log-scope.d.ts +12 -0
  22. package/dist/core/step-log-scope.js +14 -0
  23. package/dist/core/step-log-scope.js.map +1 -0
  24. package/dist/reporter/interactive-reporter.js +126 -18
  25. package/dist/reporter/interactive-reporter.js.map +1 -1
  26. package/dist/reporter/live-ticker-frame.d.ts +10 -2
  27. package/dist/reporter/live-ticker-frame.js +49 -28
  28. package/dist/reporter/live-ticker-frame.js.map +1 -1
  29. package/dist/reporter/live-ticker-worker.js +3 -5
  30. package/dist/reporter/live-ticker-worker.js.map +1 -1
  31. package/dist/reporter/live-ticker.js +3 -4
  32. package/dist/reporter/live-ticker.js.map +1 -1
  33. package/dist/studio/run-store-ui-client-browser.js +4 -4
  34. package/dist/studio/run-store-ui-client.d.ts +0 -53
  35. package/dist/studio/run-store-ui-client.js +5 -393
  36. package/dist/studio/run-store-ui-client.js.map +1 -1
  37. package/dist/studio/run-store-ui-common.d.ts +7 -0
  38. package/dist/studio/run-store-ui-common.js +11 -0
  39. package/dist/studio/run-store-ui-common.js.map +1 -0
  40. package/dist/studio/run-store-ui-launch.d.ts +27 -0
  41. package/dist/studio/run-store-ui-launch.js +230 -0
  42. package/dist/studio/run-store-ui-launch.js.map +1 -0
  43. package/dist/studio/run-store-ui-pipelines.d.ts +9 -0
  44. package/dist/studio/run-store-ui-pipelines.js +93 -0
  45. package/dist/studio/run-store-ui-pipelines.js.map +1 -0
  46. package/dist/studio/run-store-ui-runs.d.ts +29 -0
  47. package/dist/studio/run-store-ui-runs.js +74 -0
  48. package/dist/studio/run-store-ui-runs.js.map +1 -0
  49. package/dist/utilities/cache-key.js +2 -14
  50. package/dist/utilities/cache-key.js.map +1 -1
  51. package/dist/workbench/workbench-command-execution.js +2 -1
  52. package/dist/workbench/workbench-command-execution.js.map +1 -1
  53. package/dist/workbench/workbench-commands.js +7 -28
  54. package/dist/workbench/workbench-commands.js.map +1 -1
  55. package/dist/workbench/workbench-history.js +8 -16
  56. package/dist/workbench/workbench-history.js.map +1 -1
  57. package/dist/workbench/workbench-run.js +27 -39
  58. package/dist/workbench/workbench-run.js.map +1 -1
  59. package/dist/workbench/workbench-subcommand.d.ts +67 -0
  60. package/dist/workbench/workbench-subcommand.js +28 -0
  61. package/dist/workbench/workbench-subcommand.js.map +1 -1
  62. package/dist/workbench/workbench-ui.js +13 -17
  63. package/dist/workbench/workbench-ui.js.map +1 -1
  64. package/docs/agent-guide.md +188 -143
  65. package/docs/agents.md +3 -1
  66. package/docs/api-reference.md +12 -12
  67. package/docs/api-report.json +5 -5
  68. package/docs/child-pipeline-composition.md +2 -1
  69. package/docs/cli.md +28 -2
  70. package/docs/studio.md +3 -1
  71. package/package.json +4 -4
@@ -1,3 +1,4 @@
1
+ import { REQUIRED_OUTPUTS_MISSING_CODE } from "./pipeline-diagnostics.js";
1
2
  const REQUIRED_FINALIZER_OUTPUTS = Symbol("tubeless.requiredFinalizerOutputs");
2
3
  export function requiredFinalizerMetadata(finalize) {
3
4
  if (finalize && typeof finalize !== "function") {
@@ -18,7 +19,7 @@ export function requireOutputs(requiredSteps, finalize) {
18
19
  const invoke = (requiredStepIds, outputs, context) => {
19
20
  const missingStepIds = requiredStepIds.filter((stepId) => !Object.prototype.hasOwnProperty.call(outputs, stepId));
20
21
  if (missingStepIds.length > 0) {
21
- throw new Error(`Required pipeline outputs missing: ${missingStepIds.join(", ")}`);
22
+ throw Object.assign(new Error(`Required pipeline outputs missing: ${missingStepIds.join(", ")}`), { code: REQUIRED_OUTPUTS_MISSING_CODE });
22
23
  }
23
24
  // SAFETY: every required step id was verified present above, so the partial
24
25
  // outputs contain all required keys and are a complete required-outputs map.
@@ -1 +1 @@
1
- {"version":3,"file":"pipeline-finalizer.js","sourceRoot":"","sources":["../../src/core/pipeline-finalizer.ts"],"names":[],"mappings":"AAIA,MAAM,0BAA0B,GAAkB,MAAM,CAAC,mCAAmC,CAAC,CAAC;AAW9F,MAAM,UAAU,yBAAyB,CACvC,QAAyE;IAEzE,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QACvB,OAAO,yBAAyB,CAC9B,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CACrD,CAAC;IACJ,CAAC;IACD,yEAAyE;IACzE,mEAAmE;IACnE,OACE,QACD,EAAE,CAAC,0BAA0B,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,aAA6B,EAC7B,QAG+B;IAK/B,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,CACb,eAAkC,EAClC,OAAyD,EACzD,OAA+D,EAC/D,EAAE;QACF,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CACnE,CAAC;QACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACrF,CAAC;QACD,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,QAAQ,CAAC,OAA6D,EAAE,OAAO,CAAC,CAAC;IAC1F,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CACxB,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CACF,MAAM,CACJ,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAC1C,OAAO,EACP,OAAO,CACR,CAAC;IACJ,MAAM,QAAQ,GAA4D,MAAM,CAAC,MAAM,CAAC;QACtF,OAAO,EAAE,CAAC,eAAkC,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;YACrD,OAAO,CACL,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE,0BAA0B,EAAE;QACnE,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["import type { AnyStep, StepOutput } from \"./pipeline-steps.js\";\nimport type { StepsOptions } from \"./pipeline-definition.js\";\nimport type { PipelineExecutionContext } from \"./pipeline-types.js\";\n\nconst REQUIRED_FINALIZER_OUTPUTS: unique symbol = Symbol(\"tubeless.requiredFinalizerOutputs\");\n\nexport interface RequiredFinalizerMetadata<TOptions extends object> {\n readonly steps: readonly AnyStep<TOptions>[];\n compile(requiredStepIds: readonly string[]): (...args: never[]) => unknown;\n}\n\ntype RequiredPipelineOutputs<TSteps extends readonly AnyStep[]> = {\n [S in TSteps[number] as S[\"id\"]]-?: StepOutput<S>;\n};\n\nexport function requiredFinalizerMetadata<TOptions extends object>(\n finalize: AnyStep<TOptions> | ((...args: never[]) => unknown) | undefined\n): RequiredFinalizerMetadata<TOptions> | undefined {\n if (finalize && typeof finalize !== \"function\") {\n const id = finalize.id;\n return requiredFinalizerMetadata<TOptions>(\n requireOutputs([finalize], (outputs) => outputs[id])\n );\n }\n // SAFETY: `requireOutputs` stamps internal compilation metadata onto the\n // finalizer; the intersection only exposes that optional property.\n return (\n finalize as { [REQUIRED_FINALIZER_OUTPUTS]?: RequiredFinalizerMetadata<TOptions> } | undefined\n )?.[REQUIRED_FINALIZER_OUTPUTS];\n}\n\n/**\n * Build a finalizer that only runs when every listed step published an output.\n * Presence is checked by output slot, so a successfully published `undefined`\n * remains distinct from a structural skip or failure.\n */\nexport function requireOutputs<const TRequiredSteps extends readonly AnyStep[], TResult>(\n requiredSteps: TRequiredSteps,\n finalize: (\n outputs: RequiredPipelineOutputs<TRequiredSteps>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => TResult | Promise<TResult>\n): (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n) => TResult | Promise<TResult> {\n const uniqueRequiredSteps = [...new Set(requiredSteps)];\n const invoke = (\n requiredStepIds: readonly string[],\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => {\n const missingStepIds = requiredStepIds.filter(\n (stepId) => !Object.prototype.hasOwnProperty.call(outputs, stepId)\n );\n if (missingStepIds.length > 0) {\n throw new Error(`Required pipeline outputs missing: ${missingStepIds.join(\", \")}`);\n }\n // SAFETY: every required step id was verified present above, so the partial\n // outputs contain all required keys and are a complete required-outputs map.\n return finalize(outputs as unknown as RequiredPipelineOutputs<TRequiredSteps>, context);\n };\n const requiredFinalizer = (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) =>\n invoke(\n uniqueRequiredSteps.map((step) => step.id),\n outputs,\n context\n );\n const metadata: RequiredFinalizerMetadata<StepsOptions<TRequiredSteps>> = Object.freeze({\n compile: (requiredStepIds: readonly string[]) => {\n const snapshot = Object.freeze([...requiredStepIds]);\n return (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => invoke(snapshot, outputs, context);\n },\n steps: Object.freeze([...uniqueRequiredSteps]),\n });\n Object.defineProperty(requiredFinalizer, REQUIRED_FINALIZER_OUTPUTS, {\n value: metadata,\n });\n return requiredFinalizer;\n}\n"]}
1
+ {"version":3,"file":"pipeline-finalizer.js","sourceRoot":"","sources":["../../src/core/pipeline-finalizer.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAC;AAE1E,MAAM,0BAA0B,GAAkB,MAAM,CAAC,mCAAmC,CAAC,CAAC;AAW9F,MAAM,UAAU,yBAAyB,CACvC,QAAyE;IAEzE,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QAC/C,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QACvB,OAAO,yBAAyB,CAC9B,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CACrD,CAAC;IACJ,CAAC;IACD,yEAAyE;IACzE,mEAAmE;IACnE,OACE,QACD,EAAE,CAAC,0BAA0B,CAAC,CAAC;AAClC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAC5B,aAA6B,EAC7B,QAG+B;IAK/B,MAAM,mBAAmB,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,CACb,eAAkC,EAClC,OAAyD,EACzD,OAA+D,EAC/D,EAAE;QACF,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAC3C,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CACnE,CAAC;QACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,MAAM,CAAC,MAAM,CACjB,IAAI,KAAK,CAAC,sCAAsC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAC5E,EAAE,IAAI,EAAE,6BAA6B,EAAE,CACxC,CAAC;QACJ,CAAC;QACD,4EAA4E;QAC5E,6EAA6E;QAC7E,OAAO,QAAQ,CAAC,OAA6D,EAAE,OAAO,CAAC,CAAC;IAC1F,CAAC,CAAC;IACF,MAAM,iBAAiB,GAAG,CACxB,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CACF,MAAM,CACJ,mBAAmB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAC1C,OAAO,EACP,OAAO,CACR,CAAC;IACJ,MAAM,QAAQ,GAA4D,MAAM,CAAC,MAAM,CAAC;QACtF,OAAO,EAAE,CAAC,eAAkC,EAAE,EAAE;YAC9C,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;YACrD,OAAO,CACL,OAAyD,EACzD,OAA+D,EAC/D,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1C,CAAC;QACD,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC;KAC/C,CAAC,CAAC;IACH,MAAM,CAAC,cAAc,CAAC,iBAAiB,EAAE,0BAA0B,EAAE;QACnE,KAAK,EAAE,QAAQ;KAChB,CAAC,CAAC;IACH,OAAO,iBAAiB,CAAC;AAC3B,CAAC","sourcesContent":["import type { AnyStep, StepOutput } from \"./pipeline-steps.js\";\nimport type { StepsOptions } from \"./pipeline-definition.js\";\nimport type { PipelineExecutionContext } from \"./pipeline-types.js\";\nimport { REQUIRED_OUTPUTS_MISSING_CODE } from \"./pipeline-diagnostics.js\";\n\nconst REQUIRED_FINALIZER_OUTPUTS: unique symbol = Symbol(\"tubeless.requiredFinalizerOutputs\");\n\nexport interface RequiredFinalizerMetadata<TOptions extends object> {\n readonly steps: readonly AnyStep<TOptions>[];\n compile(requiredStepIds: readonly string[]): (...args: never[]) => unknown;\n}\n\ntype RequiredPipelineOutputs<TSteps extends readonly AnyStep[]> = {\n [S in TSteps[number] as S[\"id\"]]-?: StepOutput<S>;\n};\n\nexport function requiredFinalizerMetadata<TOptions extends object>(\n finalize: AnyStep<TOptions> | ((...args: never[]) => unknown) | undefined\n): RequiredFinalizerMetadata<TOptions> | undefined {\n if (finalize && typeof finalize !== \"function\") {\n const id = finalize.id;\n return requiredFinalizerMetadata<TOptions>(\n requireOutputs([finalize], (outputs) => outputs[id])\n );\n }\n // SAFETY: `requireOutputs` stamps internal compilation metadata onto the\n // finalizer; the intersection only exposes that optional property.\n return (\n finalize as { [REQUIRED_FINALIZER_OUTPUTS]?: RequiredFinalizerMetadata<TOptions> } | undefined\n )?.[REQUIRED_FINALIZER_OUTPUTS];\n}\n\n/**\n * Build a finalizer that only runs when every listed step published an output.\n * Presence is checked by output slot, so a successfully published `undefined`\n * remains distinct from a structural skip or failure.\n */\nexport function requireOutputs<const TRequiredSteps extends readonly AnyStep[], TResult>(\n requiredSteps: TRequiredSteps,\n finalize: (\n outputs: RequiredPipelineOutputs<TRequiredSteps>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => TResult | Promise<TResult>\n): (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n) => TResult | Promise<TResult> {\n const uniqueRequiredSteps = [...new Set(requiredSteps)];\n const invoke = (\n requiredStepIds: readonly string[],\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => {\n const missingStepIds = requiredStepIds.filter(\n (stepId) => !Object.prototype.hasOwnProperty.call(outputs, stepId)\n );\n if (missingStepIds.length > 0) {\n throw Object.assign(\n new Error(`Required pipeline outputs missing: ${missingStepIds.join(\", \")}`),\n { code: REQUIRED_OUTPUTS_MISSING_CODE }\n );\n }\n // SAFETY: every required step id was verified present above, so the partial\n // outputs contain all required keys and are a complete required-outputs map.\n return finalize(outputs as unknown as RequiredPipelineOutputs<TRequiredSteps>, context);\n };\n const requiredFinalizer = (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) =>\n invoke(\n uniqueRequiredSteps.map((step) => step.id),\n outputs,\n context\n );\n const metadata: RequiredFinalizerMetadata<StepsOptions<TRequiredSteps>> = Object.freeze({\n compile: (requiredStepIds: readonly string[]) => {\n const snapshot = Object.freeze([...requiredStepIds]);\n return (\n outputs: Partial<RequiredPipelineOutputs<TRequiredSteps>>,\n context: PipelineExecutionContext<StepsOptions<TRequiredSteps>>\n ) => invoke(snapshot, outputs, context);\n },\n steps: Object.freeze([...uniqueRequiredSteps]),\n });\n Object.defineProperty(requiredFinalizer, REQUIRED_FINALIZER_OUTPUTS, {\n value: metadata,\n });\n return requiredFinalizer;\n}\n"]}
@@ -0,0 +1,63 @@
1
+ import type { PipelineMetadata } from "../tracing/graph-metadata.js";
2
+ import type { ArtifactLoader, ArtifactSaver } from "./pipeline-artifacts.js";
3
+ import { createIterationRunner } from "./iteration.js";
4
+ import type { AnyStep, AnyStepDryRunHandler, ChildPipelineStepDefinitionBase, MappedChildPipelineStepDefinition, StepDefinitionBody, StepSkipPredicate } from "./pipeline-step-types.js";
5
+ import type { Pipeline, PipelineRun, PipelineStepContext, RemoteStepAdapter, StandardSchemaV1 } from "./pipeline-types.js";
6
+ /**
7
+ * Runtime construction for each step kind. `createSteps` owns the typed overloads;
8
+ * these builders receive the erased definitions and the factory's `buildStep`.
9
+ */
10
+ export type BuildStep<TOptions extends object> = (id: string, definition: StepDefinitionBody<TOptions>) => AnyStep<TOptions>;
11
+ type AnyDeps<TOptions extends object> = readonly AnyStep<TOptions>[];
12
+ type AnySkip<TOptions extends object> = StepSkipPredicate<TOptions, AnyDeps<TOptions>, AnyDeps<TOptions>, unknown>;
13
+ type ArtifactStepFields<TOptions extends object> = Omit<StepDefinitionBody<TOptions>, "run" | "dryRun" | "cache" | "outputSchema" | "skip"> & {
14
+ cache?: unknown;
15
+ skip?: AnySkip<TOptions>;
16
+ };
17
+ /** Read an artifact as an ordinary step, publishing only its typed value. */
18
+ export declare function buildLoadArtifactStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, definition: ArtifactStepFields<TOptions> & {
19
+ dryRun?: "skip" | ArtifactLoader<Record<string, unknown>, unknown, TOptions>;
20
+ load: ArtifactLoader<Record<string, unknown>, unknown, TOptions>;
21
+ }): AnyStep<TOptions>;
22
+ /** Write an artifact as an ordinary step. Dry runs skip unless a preview is supplied. */
23
+ export declare function buildSaveArtifactStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, definition: ArtifactStepFields<TOptions> & {
24
+ dryRun?: "skip" | ArtifactSaver<Record<string, unknown>, unknown, TOptions>;
25
+ save: ArtifactSaver<Record<string, unknown>, unknown, TOptions>;
26
+ }): AnyStep<TOptions>;
27
+ /** Erased `fromPipeline` definition. */
28
+ export type SingleChildStepConfig<TOptions extends object> = ChildPipelineStepDefinitionBase<TOptions, AnyDeps<TOptions>, AnyDeps<TOptions>, Pipeline<object, unknown>> & {
29
+ skip?: AnySkip<TOptions>;
30
+ mapResult?: (value: unknown, result: PipelineRun<unknown>, context: PipelineStepContext<TOptions>) => unknown;
31
+ };
32
+ export declare function buildPipelineStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, config: SingleChildStepConfig<TOptions>): AnyStep<TOptions>;
33
+ /** Erased `fromRemote` definition. */
34
+ export interface RemoteStepConfig<TOptions extends object> {
35
+ adapter: RemoteStepAdapter<object, unknown, unknown>;
36
+ mapInput(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;
37
+ outputSchema: StandardSchemaV1;
38
+ dependsOn?: AnyDeps<TOptions>;
39
+ optionalDependsOn?: AnyDeps<TOptions>;
40
+ skipAfterFailureOf?: AnyDeps<TOptions>;
41
+ name?: string;
42
+ description?: string;
43
+ metadata?: PipelineMetadata;
44
+ dryRun?: "skip" | AnyStepDryRunHandler<TOptions>;
45
+ skip?: AnySkip<TOptions>;
46
+ }
47
+ export declare function buildRemoteStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, config: RemoteStepConfig<TOptions>): AnyStep<TOptions>;
48
+ /** Erased `forEachPipeline` definition. */
49
+ export type MappedChildStepConfig<TOptions extends object> = MappedChildPipelineStepDefinition<TOptions, AnyDeps<TOptions>, AnyDeps<TOptions>, Pipeline<object, unknown>, unknown> & {
50
+ mapResult?: (value: unknown, result: PipelineRun<unknown>, item: unknown, index: number, context: PipelineStepContext<TOptions>) => unknown;
51
+ skip?: AnySkip<TOptions>;
52
+ };
53
+ export declare function buildMappedPipelineStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, config: MappedChildStepConfig<TOptions>): AnyStep<TOptions>;
54
+ /** Erased `iteratePipeline` definition. */
55
+ export type IterationStepConfig<TOptions extends object> = Omit<Parameters<typeof createIterationRunner<TOptions>>[0], "stepId"> & {
56
+ name?: string;
57
+ description?: string;
58
+ metadata?: PipelineMetadata;
59
+ dependsOn?: AnyDeps<TOptions>;
60
+ dryRun?: "skip";
61
+ };
62
+ export declare function buildIterationStep<TOptions extends object>(buildStep: BuildStep<TOptions>, id: string, definition: IterationStepConfig<TOptions>): AnyStep<TOptions>;
63
+ export {};
@@ -0,0 +1,140 @@
1
+ import { createMappedChildRunner, createSingleChildRunner } from "./child-execution.js";
2
+ import { createIterationRunner } from "./iteration.js";
3
+ import { STEP_NESTED_PIPELINE, STEP_REMOTE } from "./pipeline-step-metadata.js";
4
+ /** Read an artifact as an ordinary step, publishing only its typed value. */
5
+ export function buildLoadArtifactStep(buildStep, id, definition) {
6
+ const { cache, load, dryRun, ...fields } = definition;
7
+ if (cache !== undefined)
8
+ throw new Error("Artifact helpers cannot configure caching");
9
+ const wrap = (handler) => async (inputs, context) => {
10
+ const loaded = await handler(inputs, context);
11
+ context.recordArtifact({ operation: "read", artifact: loaded.artifact });
12
+ return loaded.value;
13
+ };
14
+ return buildStep(id, {
15
+ ...fields,
16
+ run: wrap(load),
17
+ dryRun: typeof dryRun === "function" ? wrap(dryRun) : dryRun,
18
+ });
19
+ }
20
+ /** Write an artifact as an ordinary step. Dry runs skip unless a preview is supplied. */
21
+ export function buildSaveArtifactStep(buildStep, id, definition) {
22
+ const { cache, save, dryRun, ...fields } = definition;
23
+ if (cache !== undefined)
24
+ throw new Error("Artifact helpers cannot configure caching");
25
+ const wrap = (handler) => async (inputs, context) => {
26
+ const saved = await handler(inputs, context);
27
+ context.recordArtifact({ operation: "write", artifact: saved.artifact });
28
+ return saved.value;
29
+ };
30
+ return buildStep(id, {
31
+ ...fields,
32
+ run: wrap(save),
33
+ dryRun: typeof dryRun === "function" ? wrap(dryRun) : "skip",
34
+ });
35
+ }
36
+ export function buildPipelineStep(buildStep, id, config) {
37
+ const definition = {
38
+ [STEP_NESTED_PIPELINE]: {
39
+ mode: "single",
40
+ pipelineId: config.pipeline.id,
41
+ identity: config.pipeline.definition?.identity,
42
+ stepIds: config.pipeline.stepIds,
43
+ },
44
+ dependsOn: config.dependsOn,
45
+ optionalDependsOn: config.optionalDependsOn,
46
+ skipAfterFailureOf: config.skipAfterFailureOf,
47
+ name: config.name,
48
+ description: config.description,
49
+ metadata: config.metadata,
50
+ dryRun: config.dryRun,
51
+ run: createSingleChildRunner({ ...config, stepId: id }),
52
+ };
53
+ const skip = config.skip;
54
+ if (skip !== undefined) {
55
+ definition.skip = skip;
56
+ }
57
+ return buildStep(id, definition);
58
+ }
59
+ export function buildRemoteStep(buildStep, id, config) {
60
+ const remote = { engine: config.adapter.engine };
61
+ if (config.adapter.target !== undefined)
62
+ remote.target = config.adapter.target;
63
+ const definition = {
64
+ [STEP_REMOTE]: remote,
65
+ dependsOn: config.dependsOn,
66
+ optionalDependsOn: config.optionalDependsOn,
67
+ skipAfterFailureOf: config.skipAfterFailureOf,
68
+ name: config.name,
69
+ description: config.description,
70
+ metadata: config.metadata,
71
+ dryRun: config.dryRun,
72
+ outputSchema: config.outputSchema,
73
+ run: (inputs, context) => config.adapter.invoke(config.mapInput(inputs, context), context),
74
+ };
75
+ const skip = config.skip;
76
+ if (skip !== undefined) {
77
+ definition.skip = skip;
78
+ }
79
+ return buildStep(id, definition);
80
+ }
81
+ export function buildMappedPipelineStep(buildStep, id, config) {
82
+ const configuredConcurrency = config.concurrency;
83
+ if (typeof configuredConcurrency === "number" &&
84
+ (!Number.isInteger(configuredConcurrency) || configuredConcurrency < 1)) {
85
+ throw new RangeError(`forEachPipeline concurrency must be a positive finite integer, got ${configuredConcurrency}`);
86
+ }
87
+ const definition = {
88
+ [STEP_NESTED_PIPELINE]: {
89
+ mode: "for-each",
90
+ concurrency: typeof configuredConcurrency === "function" ? "dynamic" : (configuredConcurrency ?? 1),
91
+ pipelineId: config.pipeline.id,
92
+ identity: config.pipeline.definition?.identity,
93
+ stepIds: config.pipeline.stepIds,
94
+ },
95
+ dependsOn: config.dependsOn,
96
+ optionalDependsOn: config.optionalDependsOn,
97
+ skipAfterFailureOf: config.skipAfterFailureOf,
98
+ name: config.name,
99
+ description: config.description,
100
+ metadata: config.metadata,
101
+ dryRun: config.dryRun,
102
+ run: createMappedChildRunner({ ...config, stepId: id }),
103
+ };
104
+ const skip = config.skip;
105
+ if (skip !== undefined) {
106
+ definition.skip = skip;
107
+ }
108
+ return buildStep(id, definition);
109
+ }
110
+ export function buildIterationStep(buildStep, id, definition) {
111
+ if (!Number.isSafeInteger(definition.maxIterations) || definition.maxIterations < 1) {
112
+ throw new RangeError("iteratePipeline maxIterations must be a positive safe integer");
113
+ }
114
+ const controls = definition.controls ? structuredClone(definition.controls) : undefined;
115
+ if (controls) {
116
+ if (controls.targets)
117
+ Object.freeze(controls.targets);
118
+ if (controls.stepIds)
119
+ Object.freeze(controls.stepIds);
120
+ Object.freeze(controls);
121
+ }
122
+ const config = { ...definition, stepId: id, controls };
123
+ return buildStep(id, {
124
+ [STEP_NESTED_PIPELINE]: {
125
+ mode: "iterate",
126
+ maxIterations: config.maxIterations,
127
+ controls: config.controls,
128
+ pipelineId: config.pipeline.id,
129
+ identity: config.pipeline.definition?.identity,
130
+ stepIds: config.pipeline.stepIds,
131
+ },
132
+ name: config.name,
133
+ description: config.description,
134
+ metadata: config.metadata,
135
+ dependsOn: config.dependsOn,
136
+ dryRun: config.dryRun,
137
+ run: createIterationRunner(config),
138
+ });
139
+ }
140
+ //# sourceMappingURL=pipeline-step-builders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-step-builders.js","sourceRoot":"","sources":["../../src/core/pipeline-step-builders.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineMetadata } from \"../tracing/graph-metadata.js\";\nimport type { ArtifactLoader, ArtifactSaver } from \"./pipeline-artifacts.js\";\nimport { createMappedChildRunner, createSingleChildRunner } from \"./child-execution.js\";\nimport { createIterationRunner } from \"./iteration.js\";\nimport { STEP_NESTED_PIPELINE, STEP_REMOTE } from \"./pipeline-step-metadata.js\";\nimport type {\n AnyStep,\n AnyStepDryRunHandler,\n ChildPipelineStepDefinitionBase,\n MappedChildPipelineStepDefinition,\n StepDefinitionBody,\n StepSkipPredicate,\n} from \"./pipeline-step-types.js\";\nimport type {\n Pipeline,\n PipelinePlanStep,\n PipelineRun,\n PipelineStepContext,\n RemoteStepAdapter,\n StandardSchemaV1,\n} from \"./pipeline-types.js\";\n\n/**\n * Runtime construction for each step kind. `createSteps` owns the typed overloads;\n * these builders receive the erased definitions and the factory's `buildStep`.\n */\nexport type BuildStep<TOptions extends object> = (\n id: string,\n definition: StepDefinitionBody<TOptions>\n) => AnyStep<TOptions>;\n\ntype AnyDeps<TOptions extends object> = readonly AnyStep<TOptions>[];\ntype AnySkip<TOptions extends object> = StepSkipPredicate<\n TOptions,\n AnyDeps<TOptions>,\n AnyDeps<TOptions>,\n unknown\n>;\n\ntype ArtifactStepFields<TOptions extends object> = Omit<\n StepDefinitionBody<TOptions>,\n \"run\" | \"dryRun\" | \"cache\" | \"outputSchema\" | \"skip\"\n> & {\n cache?: unknown;\n skip?: AnySkip<TOptions>;\n};\n\n/** Read an artifact as an ordinary step, publishing only its typed value. */\nexport function buildLoadArtifactStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n definition: ArtifactStepFields<TOptions> & {\n dryRun?: \"skip\" | ArtifactLoader<Record<string, unknown>, unknown, TOptions>;\n load: ArtifactLoader<Record<string, unknown>, unknown, TOptions>;\n }\n): AnyStep<TOptions> {\n const { cache, load, dryRun, ...fields } = definition;\n if (cache !== undefined) throw new Error(\"Artifact helpers cannot configure caching\");\n const wrap =\n (handler: typeof load) =>\n async (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) => {\n const loaded = await handler(inputs, context);\n context.recordArtifact({ operation: \"read\", artifact: loaded.artifact });\n return loaded.value;\n };\n return buildStep(id, {\n ...fields,\n run: wrap(load),\n dryRun: typeof dryRun === \"function\" ? wrap(dryRun) : dryRun,\n });\n}\n\n/** Write an artifact as an ordinary step. Dry runs skip unless a preview is supplied. */\nexport function buildSaveArtifactStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n definition: ArtifactStepFields<TOptions> & {\n dryRun?: \"skip\" | ArtifactSaver<Record<string, unknown>, unknown, TOptions>;\n save: ArtifactSaver<Record<string, unknown>, unknown, TOptions>;\n }\n): AnyStep<TOptions> {\n const { cache, save, dryRun, ...fields } = definition;\n if (cache !== undefined) throw new Error(\"Artifact helpers cannot configure caching\");\n const wrap =\n (handler: typeof save) =>\n async (inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>) => {\n const saved = await handler(inputs, context);\n context.recordArtifact({ operation: \"write\", artifact: saved.artifact });\n return saved.value;\n };\n return buildStep(id, {\n ...fields,\n run: wrap(save),\n dryRun: typeof dryRun === \"function\" ? wrap(dryRun) : \"skip\",\n });\n}\n\n/** Erased `fromPipeline` definition. */\nexport type SingleChildStepConfig<TOptions extends object> = ChildPipelineStepDefinitionBase<\n TOptions,\n AnyDeps<TOptions>,\n AnyDeps<TOptions>,\n Pipeline<object, unknown>\n> & {\n skip?: AnySkip<TOptions>;\n mapResult?: (\n value: unknown,\n result: PipelineRun<unknown>,\n context: PipelineStepContext<TOptions>\n ) => unknown;\n};\n\nexport function buildPipelineStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n config: SingleChildStepConfig<TOptions>\n): AnyStep<TOptions> {\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"single\" as const,\n pipelineId: config.pipeline.id,\n identity: config.pipeline.definition?.identity,\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 metadata: config.metadata,\n dryRun: config.dryRun,\n run: createSingleChildRunner({ ...config, stepId: id }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n definition.skip = skip;\n }\n return buildStep(id, definition);\n}\n\n/** Erased `fromRemote` definition. */\nexport interface RemoteStepConfig<TOptions extends object> {\n adapter: RemoteStepAdapter<object, unknown, unknown>;\n mapInput(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;\n outputSchema: StandardSchemaV1;\n dependsOn?: AnyDeps<TOptions>;\n optionalDependsOn?: AnyDeps<TOptions>;\n skipAfterFailureOf?: AnyDeps<TOptions>;\n name?: string;\n description?: string;\n metadata?: PipelineMetadata;\n dryRun?: \"skip\" | AnyStepDryRunHandler<TOptions>;\n skip?: AnySkip<TOptions>;\n}\n\nexport function buildRemoteStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n config: RemoteStepConfig<TOptions>\n): AnyStep<TOptions> {\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 metadata: config.metadata,\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 definition.skip = skip;\n }\n return buildStep(id, definition);\n}\n\n/** Erased `forEachPipeline` definition. */\nexport type MappedChildStepConfig<TOptions extends object> = MappedChildPipelineStepDefinition<\n TOptions,\n AnyDeps<TOptions>,\n AnyDeps<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?: AnySkip<TOptions>;\n};\n\nexport function buildMappedPipelineStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n config: MappedChildStepConfig<TOptions>\n): AnyStep<TOptions> {\n const configuredConcurrency = config.concurrency;\n if (\n typeof configuredConcurrency === \"number\" &&\n (!Number.isInteger(configuredConcurrency) || configuredConcurrency < 1)\n ) {\n throw new RangeError(\n `forEachPipeline concurrency must be a positive finite integer, got ${configuredConcurrency}`\n );\n }\n const definition: StepDefinitionBody<TOptions> = {\n [STEP_NESTED_PIPELINE]: {\n mode: \"for-each\" as const,\n concurrency:\n typeof configuredConcurrency === \"function\" ? \"dynamic\" : (configuredConcurrency ?? 1),\n pipelineId: config.pipeline.id,\n identity: config.pipeline.definition?.identity,\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 metadata: config.metadata,\n dryRun: config.dryRun,\n run: createMappedChildRunner({ ...config, stepId: id }),\n };\n\n const skip = config.skip;\n if (skip !== undefined) {\n definition.skip = skip;\n }\n return buildStep(id, definition);\n}\n\n/** Erased `iteratePipeline` definition. */\nexport type IterationStepConfig<TOptions extends object> = Omit<\n Parameters<typeof createIterationRunner<TOptions>>[0],\n \"stepId\"\n> & {\n name?: string;\n description?: string;\n metadata?: PipelineMetadata;\n dependsOn?: AnyDeps<TOptions>;\n dryRun?: \"skip\";\n};\n\nexport function buildIterationStep<TOptions extends object>(\n buildStep: BuildStep<TOptions>,\n id: string,\n definition: IterationStepConfig<TOptions>\n): AnyStep<TOptions> {\n if (!Number.isSafeInteger(definition.maxIterations) || definition.maxIterations < 1) {\n throw new RangeError(\"iteratePipeline maxIterations must be a positive safe integer\");\n }\n const controls = definition.controls ? structuredClone(definition.controls) : undefined;\n if (controls) {\n if (controls.targets) Object.freeze(controls.targets);\n if (controls.stepIds) Object.freeze(controls.stepIds);\n Object.freeze(controls);\n }\n const config = { ...definition, stepId: id, controls };\n return buildStep(id, {\n [STEP_NESTED_PIPELINE]: {\n mode: \"iterate\",\n maxIterations: config.maxIterations,\n controls: config.controls,\n pipelineId: config.pipeline.id,\n identity: config.pipeline.definition?.identity,\n stepIds: config.pipeline.stepIds,\n },\n name: config.name,\n description: config.description,\n metadata: config.metadata,\n dependsOn: config.dependsOn,\n dryRun: config.dryRun,\n run: createIterationRunner(config),\n });\n}\n"]}
@@ -0,0 +1,160 @@
1
+ import type { PipelineMetadata } from "../tracing/graph-metadata.js";
2
+ import type { CompiledStepCache, StepCache } from "./pipeline-cache.js";
3
+ import type { ToMappedChildStepProgressOptions } from "./mapped-child-progress.js";
4
+ import type { STEP_AGENT, STEP_CACHE, STEP_NESTED_PIPELINE, STEP_OPTIONS_SCHEMA, STEP_ORCHESTRATION, STEP_REMOTE } from "./pipeline-step-metadata.js";
5
+ import type { InferSchemaInput, Pipeline, PipelineExecutionContext, PipelinePlanStep, PipelineRunControls, PipelineStepContext, RemoteStepAdapter, StandardSchemaV1, StepSkipDecision } from "./pipeline-types.js";
6
+ /**
7
+ * A step's dependencies are references to the dependency's own step object, not string ids
8
+ * into a hand-maintained output-type map. This buys two things no amount of extra generics
9
+ * on a string-keyed design could:
10
+ * - a step used before its dependency exists is a compile error (JS temporal dead zone on
11
+ * `const`), so out-of-order and self/cyclic dependencies are caught by the language, not
12
+ * a bespoke runtime check
13
+ * - each step only ever states its own id/deps; the output-type map is derived, never
14
+ * restated, and callers of `definePipeline`/`createSteps` never write out its generics
15
+ */
16
+ export type AnyStepDryRunHandler<TOptions extends object> = {
17
+ bivarianceHack(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown | Promise<unknown>;
18
+ }["bivarianceHack"];
19
+ /** Runtime shape shared by every declared pipeline step. */
20
+ export interface AnyStep<TOptions extends object = object> {
21
+ readonly [STEP_ORCHESTRATION]?: true;
22
+ readonly [STEP_AGENT]?: NonNullable<PipelinePlanStep["agent"]>;
23
+ readonly [STEP_NESTED_PIPELINE]?: NonNullable<PipelinePlanStep["nestedPipeline"]>;
24
+ readonly [STEP_REMOTE]?: NonNullable<PipelinePlanStep["remote"]>;
25
+ readonly [STEP_OPTIONS_SCHEMA]?: StandardSchemaV1;
26
+ readonly id: string;
27
+ readonly dependsOn?: readonly AnyStep<TOptions>[];
28
+ readonly optionalDependsOn?: readonly AnyStep<TOptions>[];
29
+ readonly skipAfterFailureOf?: readonly AnyStep<TOptions>[];
30
+ /** Optional human-facing display name. Stable machine identity remains `id`. */
31
+ readonly name?: string;
32
+ readonly description?: string;
33
+ readonly metadata?: PipelineMetadata;
34
+ /**
35
+ * Dry-run policy. Omitted runs the normal handler, `"skip"` structurally
36
+ * skips it, and a handler substitutes for `run` while preserving its output.
37
+ */
38
+ readonly dryRun?: "skip" | AnyStepDryRunHandler<TOptions>;
39
+ /** Optional Standard Schema for values published by this step. */
40
+ readonly outputSchema?: StandardSchemaV1;
41
+ /** Explicit output caching for ordinary deterministic steps only. */
42
+ readonly cache?: boolean | StepCache<Record<string, unknown>, TOptions>;
43
+ readonly [STEP_CACHE]?: CompiledStepCache<TOptions>;
44
+ /**
45
+ * Optional runtime skip. Return a non-empty reason (or `{ reason, value }`) to
46
+ * skip without calling `run`. Policy skips unlock dependents; structural skips
47
+ * (dry-run, filtered, …) do not use this hook.
48
+ */
49
+ skip?(inputs: Record<string, unknown>, context: PipelineExecutionContext<TOptions>): StepSkipDecision | Promise<StepSkipDecision>;
50
+ run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): unknown;
51
+ }
52
+ /** The step fields that `buildStep` merges onto the id-bearing shell. */
53
+ export type StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, "id">;
54
+ /** Typed pipeline step carrying its stable ID, output, and option types. */
55
+ export interface Step<TId extends string, TOut, TOptions extends object, TInputOptions extends object = TOptions, TRunOut = TOut, TOptionsSchema extends StandardSchemaV1 | undefined = StandardSchemaV1 | undefined> extends AnyStep<TOptions> {
56
+ readonly [STEP_OPTIONS_SCHEMA]?: TOptionsSchema;
57
+ readonly id: TId;
58
+ run(inputs: Record<string, unknown>, context: PipelineStepContext<TOptions>): TRunOut | Promise<TRunOut>;
59
+ /** Type-only: carries this step's output type for sibling inference. Never set at runtime. */
60
+ readonly __outputType?: TOut;
61
+ /** Type-only: carries pre-validation run options for pipeline call-site inference. */
62
+ readonly __inputOptionsType?: TInputOptions;
63
+ }
64
+ /**
65
+ * Extract a step's output type for dependency typing.
66
+ * Prefer matching `Step<…, TOut, …>` over `{ __outputType?: infer T }`: optional-property
67
+ * inference collapses `TOut | undefined` to `TOut`, which hides policy-skip widening.
68
+ */
69
+ export type StepOutput<S> = S extends Step<string, infer TOut, infer _TOptions, infer _TInputOptions, infer _TRunOut> ? TOut : never;
70
+ export interface StepToken {
71
+ readonly id: string;
72
+ readonly __outputType?: unknown;
73
+ }
74
+ export type RequiredInputs<TDeps extends readonly StepToken[]> = {
75
+ [S in TDeps[number] as S["id"]]: StepOutput<S>;
76
+ };
77
+ export type OptionalInputs<TDeps extends readonly StepToken[]> = {
78
+ [S in TDeps[number] as S["id"]]?: StepOutput<S>;
79
+ };
80
+ export type PipelineResultOf<TPipeline> = TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId> ? TResult : never;
81
+ export type PipelineOptionsOf<TPipeline> = TPipeline extends Pipeline<infer TOptions, unknown, infer _TStepId, infer _TTargetId> ? TOptions : never;
82
+ export type PipelineRunControlsOf<TPipeline> = TPipeline extends Pipeline<infer _TOptions, unknown, infer TStepId, infer TTargetId> ? PipelineRunControls<TStepId, TTargetId> : never;
83
+ export type ChildPipelineStepDefinitionBase<TParentOptions extends object, TDeps extends readonly AnyStep<TParentOptions>[], TOptionalDeps extends readonly AnyStep<TParentOptions>[], TChildPipeline extends Pipeline<object, unknown>> = {
84
+ pipeline: TChildPipeline;
85
+ dependsOn?: TDeps;
86
+ optionalDependsOn?: TOptionalDeps;
87
+ skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];
88
+ name?: string;
89
+ description?: string;
90
+ metadata?: PipelineMetadata;
91
+ dryRun?: "skip";
92
+ controls?: PipelineRunControlsOf<TChildPipeline> | ((inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>) => PipelineRunControlsOf<TChildPipeline>);
93
+ } & ([TParentOptions] extends [PipelineOptionsOf<NoInfer<TChildPipeline>>] ? {
94
+ mapOptions?(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>): PipelineOptionsOf<TChildPipeline>;
95
+ } : {
96
+ mapOptions(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>): PipelineOptionsOf<TChildPipeline>;
97
+ });
98
+ /** Child step without policy skip (dependents see the full child result type). */
99
+ export type ChildPipelineStepDefinition<TParentOptions extends object, TDeps extends readonly AnyStep<TParentOptions>[], TOptionalDeps extends readonly AnyStep<TParentOptions>[], TChildPipeline extends Pipeline<object, unknown>> = ChildPipelineStepDefinitionBase<TParentOptions, TDeps, TOptionalDeps, TChildPipeline>;
100
+ /**
101
+ * Presentation options for opaque `forEachPipeline` progress.
102
+ * Defaults are domain-neutral (`N/M items · K running · key/step`).
103
+ * Override `formatMessage` when a domain wants its own noun (images, shards, …).
104
+ */
105
+ export type MappedChildProgressOptions = ToMappedChildStepProgressOptions;
106
+ export type MappedChildPipelineStepDefinition<TParentOptions extends object, TDeps extends readonly AnyStep<TParentOptions>[], TOptionalDeps extends readonly AnyStep<TParentOptions>[], TChildPipeline extends Pipeline<object, unknown>, TItem> = {
107
+ pipeline: TChildPipeline;
108
+ dependsOn?: TDeps;
109
+ optionalDependsOn?: TOptionalDeps;
110
+ skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];
111
+ name?: string;
112
+ description?: string;
113
+ metadata?: PipelineMetadata;
114
+ dryRun?: "skip";
115
+ items(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>): readonly TItem[] | Promise<readonly TItem[]>;
116
+ key(item: TItem, index: number): string;
117
+ concurrency?: number | ((inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>) => number);
118
+ /**
119
+ * How the opaque parent step reports live fan-out progress.
120
+ * Purely presentational — does not change scheduling or results.
121
+ */
122
+ progress?: MappedChildProgressOptions;
123
+ controls?: PipelineRunControlsOf<TChildPipeline> | ((item: TItem, index: number, inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>) => PipelineRunControlsOf<TChildPipeline>);
124
+ mapOptions(item: TItem, index: number, inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TParentOptions>): PipelineOptionsOf<TChildPipeline>;
125
+ };
126
+ export type StepSkipPredicate<TOptions extends object, TDeps extends readonly AnyStep<TOptions>[], TOptionalDeps extends readonly AnyStep<TOptions>[], TOut, TDecision extends StepSkipDecision<TOut> = StepSkipDecision<TOut>> = (inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineExecutionContext<TOptions>) => TDecision | Promise<TDecision>;
127
+ export type PolicySkippedOutput<TOut, TDecision> = [
128
+ Exclude<Awaited<TDecision>, false | null | undefined>
129
+ ] extends [{
130
+ reason: string;
131
+ value: unknown;
132
+ }] ? TOut : TOut | undefined;
133
+ export type StepDryRunPolicy<TOptions extends object, TDeps extends readonly AnyStep<TOptions>[], TOptionalDeps extends readonly AnyStep<TOptions>[], TOut> = "skip" | ((inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineStepContext<TOptions>) => TOut | Promise<TOut>);
134
+ export type PlainStepFields<TOptions extends object, TDeps extends readonly AnyStep<TOptions>[], TOptionalDeps extends readonly AnyStep<TOptions>[], TOut> = {
135
+ dependsOn?: TDeps;
136
+ optionalDependsOn?: TOptionalDeps;
137
+ skipAfterFailureOf?: readonly AnyStep<TOptions>[];
138
+ name?: string;
139
+ description?: string;
140
+ metadata?: PipelineMetadata;
141
+ dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;
142
+ outputSchema?: never;
143
+ cache?: boolean | StepCache<RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, TOptions>;
144
+ run(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineStepContext<TOptions>): TOut | Promise<TOut>;
145
+ };
146
+ export type SchemaStepFields<TOptions extends object, TDeps extends readonly AnyStep<TOptions>[], TOptionalDeps extends readonly AnyStep<TOptions>[], TSchema extends StandardSchemaV1> = Omit<PlainStepFields<TOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>, "outputSchema"> & {
147
+ outputSchema: TSchema;
148
+ };
149
+ export type RemoteStepDefinitionBase<TParentOptions extends object, TDeps extends readonly AnyStep<TParentOptions>[], TOptionalDeps extends readonly AnyStep<TParentOptions>[], TPayload, TSchema extends StandardSchemaV1> = {
150
+ adapter: RemoteStepAdapter<TParentOptions, TPayload, InferSchemaInput<TSchema>>;
151
+ mapInput(inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, context: PipelineStepContext<TParentOptions>): TPayload;
152
+ outputSchema: TSchema;
153
+ dependsOn?: TDeps;
154
+ optionalDependsOn?: TOptionalDeps;
155
+ skipAfterFailureOf?: readonly AnyStep<TParentOptions>[];
156
+ name?: string;
157
+ description?: string;
158
+ metadata?: PipelineMetadata;
159
+ dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;
160
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pipeline-step-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline-step-types.js","sourceRoot":"","sources":["../../src/core/pipeline-step-types.ts"],"names":[],"mappings":"","sourcesContent":["import type { PipelineMetadata } from \"../tracing/graph-metadata.js\";\nimport type { CompiledStepCache, StepCache } from \"./pipeline-cache.js\";\nimport type { ToMappedChildStepProgressOptions } from \"./mapped-child-progress.js\";\nimport type {\n STEP_AGENT,\n STEP_CACHE,\n STEP_NESTED_PIPELINE,\n STEP_OPTIONS_SCHEMA,\n STEP_ORCHESTRATION,\n STEP_REMOTE,\n} from \"./pipeline-step-metadata.js\";\nimport type {\n InferSchemaInput,\n Pipeline,\n PipelineExecutionContext,\n PipelinePlanStep,\n PipelineRunControls,\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 */\nexport type AnyStepDryRunHandler<TOptions extends object> = {\n bivarianceHack(\n inputs: Record<string, unknown>,\n context: PipelineStepContext<TOptions>\n ): unknown | Promise<unknown>;\n}[\"bivarianceHack\"];\n\n/** Runtime shape shared by every declared pipeline step. */\nexport interface AnyStep<TOptions extends object = object> {\n readonly [STEP_ORCHESTRATION]?: true;\n readonly [STEP_AGENT]?: NonNullable<PipelinePlanStep[\"agent\"]>;\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 readonly metadata?: PipelineMetadata;\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 /** Explicit output caching for ordinary deterministic steps only. */\n readonly cache?: boolean | StepCache<Record<string, unknown>, TOptions>;\n readonly [STEP_CACHE]?: CompiledStepCache<TOptions>;\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. */\nexport type StepDefinitionBody<TOptions extends object> = Omit<AnyStep<TOptions>, \"id\">;\n\n/** Typed pipeline step carrying its stable ID, output, and option types. */\nexport interface Step<\n TId extends string,\n TOut,\n TOptions extends object,\n TInputOptions extends object = TOptions,\n TRunOut = TOut,\n TOptionsSchema extends StandardSchemaV1 | undefined = StandardSchemaV1 | undefined,\n> extends AnyStep<TOptions> {\n readonly [STEP_OPTIONS_SCHEMA]?: TOptionsSchema;\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\nexport interface StepToken {\n readonly id: string;\n readonly __outputType?: unknown;\n}\n\nexport type RequiredInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]: StepOutput<S>;\n};\n\nexport type OptionalInputs<TDeps extends readonly StepToken[]> = {\n [S in TDeps[number] as S[\"id\"]]?: StepOutput<S>;\n};\n\nexport type PipelineResultOf<TPipeline> =\n TPipeline extends Pipeline<object, infer TResult, infer _TStepId, infer _TTargetId>\n ? TResult\n : never;\n\nexport type PipelineOptionsOf<TPipeline> =\n TPipeline extends Pipeline<infer TOptions, unknown, infer _TStepId, infer _TTargetId>\n ? TOptions\n : never;\n\nexport type PipelineRunControlsOf<TPipeline> =\n TPipeline extends Pipeline<infer _TOptions, unknown, infer TStepId, infer TTargetId>\n ? PipelineRunControls<TStepId, TTargetId>\n : never;\n\nexport type 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 metadata?: PipelineMetadata;\n dryRun?: \"skip\";\n controls?:\n | PipelineRunControlsOf<TChildPipeline>\n | ((\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => PipelineRunControlsOf<TChildPipeline>);\n} & ([TParentOptions] extends [PipelineOptionsOf<NoInfer<TChildPipeline>>]\n ? {\n mapOptions?(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineOptionsOf<TChildPipeline>;\n }\n : {\n mapOptions(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineOptionsOf<TChildPipeline>;\n });\n\n/** Child step without policy skip (dependents see the full child result type). */\nexport type 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\nexport type 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 metadata?: PipelineMetadata;\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 controls?:\n | PipelineRunControlsOf<TChildPipeline>\n | ((\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ) => PipelineRunControlsOf<TChildPipeline>);\n mapOptions(\n item: TItem,\n index: number,\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TParentOptions>\n ): PipelineOptionsOf<TChildPipeline>;\n};\n\nexport type StepSkipPredicate<\n TOptions extends object,\n TDeps extends readonly AnyStep<TOptions>[],\n TOptionalDeps extends readonly AnyStep<TOptions>[],\n TOut,\n TDecision extends StepSkipDecision<TOut> = StepSkipDecision<TOut>,\n> = (\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineExecutionContext<TOptions>\n) => TDecision | Promise<TDecision>;\n\nexport type PolicySkippedOutput<TOut, TDecision> = [\n Exclude<Awaited<TDecision>, false | null | undefined>,\n] extends [{ reason: string; value: unknown }]\n ? TOut\n : TOut | undefined;\n\nexport type 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\nexport type 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 metadata?: PipelineMetadata;\n dryRun?: StepDryRunPolicy<TOptions, TDeps, TOptionalDeps, TOut>;\n outputSchema?: never;\n cache?: boolean | StepCache<RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>, TOptions>;\n run(\n inputs: RequiredInputs<TDeps> & OptionalInputs<TOptionalDeps>,\n context: PipelineStepContext<TOptions>\n ): TOut | Promise<TOut>;\n};\n\nexport type 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\nexport type 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 metadata?: PipelineMetadata;\n dryRun?: StepDryRunPolicy<TParentOptions, TDeps, TOptionalDeps, InferSchemaInput<TSchema>>;\n};\n"]}