tubeless 0.1.2 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -43
- package/dist/cli/cli-command.d.ts +5 -0
- package/dist/{cli-command.js → cli/cli-command.js} +5 -5
- package/dist/cli/cli-command.js.map +1 -0
- package/dist/cli/cli-exit.d.ts +26 -0
- package/dist/cli/cli-exit.js +69 -0
- package/dist/cli/cli-exit.js.map +1 -0
- package/dist/{cli-parser.d.ts → cli/cli-parser.d.ts} +0 -1
- package/dist/cli/cli-parser.js.map +1 -0
- package/dist/{cli-pipeline-command.d.ts → cli/cli-pipeline-command.d.ts} +3 -4
- package/dist/{cli-pipeline-command.js → cli/cli-pipeline-command.js} +5 -8
- package/dist/cli/cli-pipeline-command.js.map +1 -0
- package/dist/{cli-types.d.ts → cli/cli-types.d.ts} +2 -3
- package/dist/{cli-types.js → cli/cli-types.js} +3 -0
- package/dist/cli/cli-types.js.map +1 -0
- package/dist/{cli.d.ts → cli/cli.d.ts} +2 -3
- package/dist/{cli.js → cli/cli.js} +2 -2
- package/dist/cli/cli.js.map +1 -0
- package/dist/{pipeline-command-marker.d.ts → cli/pipeline-command-marker.d.ts} +0 -1
- package/dist/cli/pipeline-command-marker.js.map +1 -0
- package/dist/{child-execution.d.ts → core/child-execution.d.ts} +21 -3
- package/dist/{child-execution.js → core/child-execution.js} +169 -53
- package/dist/core/child-execution.js.map +1 -0
- package/dist/{lifecycle.d.ts → core/lifecycle.d.ts} +5 -4
- package/dist/{lifecycle.js → core/lifecycle.js} +13 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/{mapped-child-progress.d.ts → core/mapped-child-progress.d.ts} +1 -2
- package/dist/core/mapped-child-progress.js.map +1 -0
- package/dist/{pipeline-diagnostics.d.ts → core/pipeline-diagnostics.d.ts} +1 -2
- package/dist/core/pipeline-diagnostics.js.map +1 -0
- package/dist/{pipeline-execute.d.ts → core/pipeline-execute.d.ts} +6 -5
- package/dist/{pipeline-execute.js → core/pipeline-execute.js} +116 -52
- package/dist/core/pipeline-execute.js.map +1 -0
- package/dist/{pipeline-ids.d.ts → core/pipeline-ids.d.ts} +0 -1
- package/dist/core/pipeline-ids.js.map +1 -0
- package/dist/core/pipeline-plan.d.ts +97 -0
- package/dist/{pipeline-plan.js → core/pipeline-plan.js} +161 -57
- package/dist/core/pipeline-plan.js.map +1 -0
- package/dist/core/pipeline-steps.d.ts +215 -0
- package/dist/core/pipeline-steps.js +134 -0
- package/dist/core/pipeline-steps.js.map +1 -0
- package/dist/core/pipeline-types.d.ts +414 -0
- package/dist/core/pipeline-types.js +3 -0
- package/dist/core/pipeline-types.js.map +1 -0
- package/dist/core/pipeline.d.ts +21 -0
- package/dist/core/pipeline.js +69 -0
- package/dist/core/pipeline.js.map +1 -0
- package/dist/{progress.d.ts → core/progress.d.ts} +1 -2
- package/dist/core/progress.js.map +1 -0
- package/dist/node/atomic-text.d.ts +1 -0
- package/dist/node/atomic-text.js +21 -0
- package/dist/node/atomic-text.js.map +1 -0
- package/dist/{checkpoint.d.ts → node/checkpoint.d.ts} +4 -3
- package/dist/{checkpoint.js → node/checkpoint.js} +18 -26
- package/dist/node/checkpoint.js.map +1 -0
- package/dist/{env.d.ts → node/env.d.ts} +0 -1
- package/dist/node/env.js.map +1 -0
- package/dist/{file-utils.d.ts → node/file-utils.d.ts} +0 -1
- package/dist/node/file-utils.js +17 -0
- package/dist/node/file-utils.js.map +1 -0
- package/dist/{node.d.ts → node/node.d.ts} +0 -1
- package/dist/node/node.js.map +1 -0
- package/dist/{paths.d.ts → node/paths.d.ts} +0 -1
- package/dist/node/paths.js.map +1 -0
- package/dist/{render.d.ts → render/render.d.ts} +1 -2
- package/dist/{render.js → render/render.js} +24 -7
- package/dist/render/render.js.map +1 -0
- package/dist/{interactive-reporter.d.ts → reporter/interactive-reporter.d.ts} +1 -2
- package/dist/{interactive-reporter.js → reporter/interactive-reporter.js} +16 -1
- package/dist/reporter/interactive-reporter.js.map +1 -0
- package/dist/reporter/live-ticker-supervisor.d.ts +1 -0
- package/dist/reporter/live-ticker-supervisor.js +44 -0
- package/dist/reporter/live-ticker-supervisor.js.map +1 -0
- package/dist/reporter/live-ticker-worker.d.ts +1 -0
- package/dist/reporter/live-ticker-worker.js +107 -0
- package/dist/reporter/live-ticker-worker.js.map +1 -0
- package/dist/{live-ticker.d.ts → reporter/live-ticker.d.ts} +3 -4
- package/dist/{live-ticker.js → reporter/live-ticker.js} +206 -202
- package/dist/reporter/live-ticker.js.map +1 -0
- package/dist/{prompt-select.d.ts → reporter/prompt-select.d.ts} +3 -4
- package/dist/reporter/prompt-select.js.map +1 -0
- package/dist/{reporter-entry.d.ts → reporter/reporter-entry.d.ts} +0 -1
- package/dist/reporter/reporter-entry.js.map +1 -0
- package/dist/{reporter.d.ts → reporter/reporter.d.ts} +1 -3
- package/dist/{reporter.js → reporter/reporter.js} +2 -2
- package/dist/reporter/reporter.js.map +1 -0
- package/dist/run-store/run-store-ndjson.d.ts +19 -0
- package/dist/run-store/run-store-ndjson.js +398 -0
- package/dist/run-store/run-store-ndjson.js.map +1 -0
- package/dist/run-store/run-store-sqlite.d.ts +34 -0
- package/dist/run-store/run-store-sqlite.js +384 -0
- package/dist/run-store/run-store-sqlite.js.map +1 -0
- package/dist/{run-store.d.ts → run-store/run-store.d.ts} +17 -5
- package/dist/{run-store.js → run-store/run-store.js} +52 -4
- package/dist/run-store/run-store.js.map +1 -0
- package/dist/studio/run-store-ui-client-source.d.ts +1 -0
- package/dist/studio/run-store-ui-client-source.js +1 -0
- package/dist/studio/run-store-ui-client.d.ts +16 -0
- package/dist/studio/run-store-ui-client.js +1393 -0
- package/dist/studio/run-store-ui-client.js.map +1 -0
- package/dist/studio/run-store-ui-http.d.ts +13 -0
- package/dist/studio/run-store-ui-http.js +46 -0
- package/dist/studio/run-store-ui-http.js.map +1 -0
- package/dist/studio/run-store-ui-page.d.ts +7 -0
- package/dist/studio/run-store-ui-page.js +359 -0
- package/dist/studio/run-store-ui-page.js.map +1 -0
- package/dist/{run-store-ui-protocol.d.ts → studio/run-store-ui-protocol.d.ts} +2 -3
- package/dist/studio/run-store-ui-protocol.js.map +1 -0
- package/dist/{run-store-ui-state.d.ts → studio/run-store-ui-state.d.ts} +2 -3
- package/dist/{run-store-ui-state.js → studio/run-store-ui-state.js} +1 -1
- package/dist/studio/run-store-ui-state.js.map +1 -0
- package/dist/{run-store-ui.d.ts → studio/run-store-ui.d.ts} +2 -3
- package/dist/{run-store-ui.js → studio/run-store-ui.js} +50 -29
- package/dist/studio/run-store-ui.js.map +1 -0
- package/dist/{testing.d.ts → testing/testing.d.ts} +3 -4
- package/dist/{testing.js → testing/testing.js} +4 -4
- package/dist/testing/testing.js.map +1 -0
- package/dist/tracing/trace-exporter-error.d.ts +10 -0
- package/dist/tracing/trace-exporter-error.js +12 -0
- package/dist/tracing/trace-exporter-error.js.map +1 -0
- package/dist/{tracing-internal.d.ts → tracing/tracing-internal.d.ts} +1 -2
- package/dist/{tracing-internal.js → tracing/tracing-internal.js} +58 -3
- package/dist/tracing/tracing-internal.js.map +1 -0
- package/dist/{tracing-json.d.ts → tracing/tracing-json.d.ts} +1 -2
- package/dist/tracing/tracing-json.js.map +1 -0
- package/dist/{tracing-otel.d.ts → tracing/tracing-otel.d.ts} +0 -1
- package/dist/tracing/tracing-otel.js.map +1 -0
- package/dist/{tracing.d.ts → tracing/tracing.d.ts} +19 -6
- package/dist/tracing/tracing.js +55 -0
- package/dist/tracing/tracing.js.map +1 -0
- package/dist/{abort.d.ts → utilities/abort.d.ts} +0 -1
- package/dist/utilities/abort.js.map +1 -0
- package/dist/{batch.d.ts → utilities/batch.d.ts} +12 -1
- package/dist/{batch.js → utilities/batch.js} +20 -5
- package/dist/utilities/batch.js.map +1 -0
- package/dist/utilities/collections.d.ts +2 -0
- package/dist/utilities/collections.js +13 -0
- package/dist/utilities/collections.js.map +1 -0
- package/dist/{rate-limit.d.ts → utilities/rate-limit.d.ts} +0 -1
- package/dist/utilities/rate-limit.js.map +1 -0
- package/dist/{retry.d.ts → utilities/retry.d.ts} +0 -1
- package/dist/utilities/retry.js.map +1 -0
- package/dist/utilities/tubeless-error.d.ts +2 -0
- package/dist/utilities/tubeless-error.js +16 -0
- package/dist/utilities/tubeless-error.js.map +1 -0
- package/dist/{pipeline-module.d.ts → workbench/pipeline-module.d.ts} +2 -10
- package/dist/{pipeline-module.js → workbench/pipeline-module.js} +2 -6
- package/dist/workbench/pipeline-module.js.map +1 -0
- package/dist/{workbench-bin.d.ts → workbench/workbench-bin.d.ts} +0 -1
- package/dist/workbench/workbench-bin.js.map +1 -0
- package/dist/{workbench-graph.d.ts → workbench/workbench-graph.d.ts} +0 -1
- package/dist/workbench/workbench-graph.js +64 -0
- package/dist/workbench/workbench-graph.js.map +1 -0
- package/dist/workbench/workbench-history.d.ts +2 -0
- package/dist/workbench/workbench-history.js +179 -0
- package/dist/workbench/workbench-history.js.map +1 -0
- package/dist/{workbench-inspect.d.ts → workbench/workbench-inspect.d.ts} +0 -1
- package/dist/workbench/workbench-inspect.js +70 -0
- package/dist/workbench/workbench-inspect.js.map +1 -0
- package/dist/workbench/workbench-list.d.ts +2 -0
- package/dist/workbench/workbench-list.js +53 -0
- package/dist/workbench/workbench-list.js.map +1 -0
- package/dist/{workbench-plan.d.ts → workbench/workbench-plan.d.ts} +0 -1
- package/dist/workbench/workbench-plan.js +67 -0
- package/dist/workbench/workbench-plan.js.map +1 -0
- package/dist/workbench/workbench-project-loader.d.ts +32 -0
- package/dist/workbench/workbench-project-loader.js +122 -0
- package/dist/workbench/workbench-project-loader.js.map +1 -0
- package/dist/workbench/workbench-project.d.ts +27 -0
- package/dist/workbench/workbench-project.js +66 -0
- package/dist/workbench/workbench-project.js.map +1 -0
- package/dist/{workbench-run.d.ts → workbench/workbench-run.d.ts} +1 -3
- package/dist/workbench/workbench-run.js +400 -0
- package/dist/workbench/workbench-run.js.map +1 -0
- package/dist/{workbench-shared.d.ts → workbench/workbench-shared.d.ts} +12 -33
- package/dist/{workbench-shared.js → workbench/workbench-shared.js} +80 -64
- package/dist/workbench/workbench-shared.js.map +1 -0
- package/dist/{workbench-studio.d.ts → workbench/workbench-studio.d.ts} +5 -2
- package/dist/{workbench-studio.js → workbench/workbench-studio.js} +5 -1
- package/dist/workbench/workbench-studio.js.map +1 -0
- package/dist/workbench/workbench-subcommand.d.ts +23 -0
- package/dist/workbench/workbench-subcommand.js +20 -0
- package/dist/workbench/workbench-subcommand.js.map +1 -0
- package/dist/{workbench-trampoline.d.ts → workbench/workbench-trampoline.d.ts} +0 -1
- package/dist/workbench/workbench-trampoline.js.map +1 -0
- package/dist/{workbench-ui.d.ts → workbench/workbench-ui.d.ts} +0 -1
- package/dist/workbench/workbench-ui.js +361 -0
- package/dist/workbench/workbench-ui.js.map +1 -0
- package/dist/{workbench.d.ts → workbench/workbench.d.ts} +0 -1
- package/dist/{workbench.js → workbench/workbench.js} +9 -1
- package/dist/workbench/workbench.js.map +1 -0
- package/docs/README.md +15 -13
- package/docs/agent-guide.md +69 -19
- package/docs/api-reference.md +45 -18
- package/docs/api-report.json +71 -35
- package/docs/assets/logo.svg +17 -0
- package/docs/assets/social.svg +60 -0
- package/docs/child-pipeline-composition.md +68 -17
- package/docs/cli.md +92 -8
- package/docs/comparison.md +6 -1
- package/docs/concepts.md +54 -21
- package/docs/getting-started.md +6 -4
- package/docs/llms.txt +13 -4
- package/docs/recipes.md +38 -23
- package/docs/remote-step-composition.md +131 -0
- package/docs/studio.md +56 -20
- package/examples/best-effort.ts +8 -4
- package/examples/catalog/pipelines/enrich.ts +104 -0
- package/examples/catalog/pipelines/import.ts +11 -5
- package/examples/catalog/scripts/enrich.ts +22 -0
- package/examples/catalog/tubeless.project.ts +40 -0
- package/examples/catalog/tubeless.studio.ts +6 -2
- package/examples/child-pipeline.ts +1 -0
- package/examples/cli-job.ts +1 -0
- package/examples/fan-out-progress.ts +13 -2
- package/examples/host-embedding.ts +45 -0
- package/examples/local-observability.ts +35 -10
- package/examples/peloton.ts +365 -0
- package/examples/publish-with-gates.ts +1 -1
- package/examples/remote-steps.ts +109 -0
- package/examples/rows.txt +3 -0
- package/examples/tracing.ts +17 -8
- package/examples/typed-import.ts +1 -0
- package/examples/validated-boundaries.ts +1 -0
- package/package.json +74 -61
- package/dist/abort.d.ts.map +0 -1
- package/dist/abort.js.map +0 -1
- package/dist/batch.d.ts.map +0 -1
- package/dist/batch.js.map +0 -1
- package/dist/checkpoint.d.ts.map +0 -1
- package/dist/checkpoint.js.map +0 -1
- package/dist/child-execution.d.ts.map +0 -1
- package/dist/child-execution.js.map +0 -1
- package/dist/cli-command.d.ts +0 -29
- package/dist/cli-command.d.ts.map +0 -1
- package/dist/cli-command.js.map +0 -1
- package/dist/cli-parser.d.ts.map +0 -1
- package/dist/cli-parser.js.map +0 -1
- package/dist/cli-pipeline-command.d.ts.map +0 -1
- package/dist/cli-pipeline-command.js.map +0 -1
- package/dist/cli-types.d.ts.map +0 -1
- package/dist/cli-types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/env.d.ts.map +0 -1
- package/dist/env.js.map +0 -1
- package/dist/file-utils.d.ts.map +0 -1
- package/dist/file-utils.js +0 -35
- package/dist/file-utils.js.map +0 -1
- package/dist/interactive-reporter.d.ts.map +0 -1
- package/dist/interactive-reporter.js.map +0 -1
- package/dist/lifecycle.d.ts.map +0 -1
- package/dist/lifecycle.js.map +0 -1
- package/dist/live-ticker.d.ts.map +0 -1
- package/dist/live-ticker.js.map +0 -1
- package/dist/mapped-child-progress.d.ts.map +0 -1
- package/dist/mapped-child-progress.js.map +0 -1
- package/dist/node.d.ts.map +0 -1
- package/dist/node.js.map +0 -1
- package/dist/paths.d.ts.map +0 -1
- package/dist/paths.js.map +0 -1
- package/dist/pipeline-command-marker.d.ts.map +0 -1
- package/dist/pipeline-command-marker.js.map +0 -1
- package/dist/pipeline-diagnostics.d.ts.map +0 -1
- package/dist/pipeline-diagnostics.js.map +0 -1
- package/dist/pipeline-execute.d.ts.map +0 -1
- package/dist/pipeline-execute.js.map +0 -1
- package/dist/pipeline-ids.d.ts.map +0 -1
- package/dist/pipeline-ids.js.map +0 -1
- package/dist/pipeline-module.d.ts.map +0 -1
- package/dist/pipeline-module.js.map +0 -1
- package/dist/pipeline-plan.d.ts +0 -57
- package/dist/pipeline-plan.d.ts.map +0 -1
- package/dist/pipeline-plan.js.map +0 -1
- package/dist/pipeline.d.ts +0 -590
- package/dist/pipeline.d.ts.map +0 -1
- package/dist/pipeline.js +0 -256
- package/dist/pipeline.js.map +0 -1
- package/dist/progress.d.ts.map +0 -1
- package/dist/progress.js.map +0 -1
- package/dist/prompt-select.d.ts.map +0 -1
- package/dist/prompt-select.js.map +0 -1
- package/dist/rate-limit.d.ts.map +0 -1
- package/dist/rate-limit.js.map +0 -1
- package/dist/render.d.ts.map +0 -1
- package/dist/render.js.map +0 -1
- package/dist/reporter-entry.d.ts.map +0 -1
- package/dist/reporter-entry.js.map +0 -1
- package/dist/reporter.d.ts.map +0 -1
- package/dist/reporter.js.map +0 -1
- package/dist/retry.d.ts.map +0 -1
- package/dist/retry.js.map +0 -1
- package/dist/run-store-sqlite.d.ts +0 -12
- package/dist/run-store-sqlite.d.ts.map +0 -1
- package/dist/run-store-sqlite.js +0 -187
- package/dist/run-store-sqlite.js.map +0 -1
- package/dist/run-store-ui-http.d.ts +0 -5
- package/dist/run-store-ui-http.d.ts.map +0 -1
- package/dist/run-store-ui-http.js +0 -19
- package/dist/run-store-ui-http.js.map +0 -1
- package/dist/run-store-ui-page.d.ts +0 -2
- package/dist/run-store-ui-page.d.ts.map +0 -1
- package/dist/run-store-ui-page.js +0 -842
- package/dist/run-store-ui-page.js.map +0 -1
- package/dist/run-store-ui-protocol.d.ts.map +0 -1
- package/dist/run-store-ui-protocol.js.map +0 -1
- package/dist/run-store-ui-state.d.ts.map +0 -1
- package/dist/run-store-ui-state.js.map +0 -1
- package/dist/run-store-ui.d.ts.map +0 -1
- package/dist/run-store-ui.js.map +0 -1
- package/dist/run-store.d.ts.map +0 -1
- package/dist/run-store.js.map +0 -1
- package/dist/testing.d.ts.map +0 -1
- package/dist/testing.js.map +0 -1
- package/dist/tracing-internal.d.ts.map +0 -1
- package/dist/tracing-internal.js.map +0 -1
- package/dist/tracing-json.d.ts.map +0 -1
- package/dist/tracing-json.js.map +0 -1
- package/dist/tracing-otel.d.ts.map +0 -1
- package/dist/tracing-otel.js.map +0 -1
- package/dist/tracing.d.ts.map +0 -1
- package/dist/tracing.js +0 -2
- package/dist/tracing.js.map +0 -1
- package/dist/workbench-bin.d.ts.map +0 -1
- package/dist/workbench-bin.js.map +0 -1
- package/dist/workbench-graph.d.ts.map +0 -1
- package/dist/workbench-graph.js +0 -65
- package/dist/workbench-graph.js.map +0 -1
- package/dist/workbench-inspect.d.ts.map +0 -1
- package/dist/workbench-inspect.js +0 -66
- package/dist/workbench-inspect.js.map +0 -1
- package/dist/workbench-plan.d.ts.map +0 -1
- package/dist/workbench-plan.js +0 -66
- package/dist/workbench-plan.js.map +0 -1
- package/dist/workbench-run.d.ts.map +0 -1
- package/dist/workbench-run.js +0 -115
- package/dist/workbench-run.js.map +0 -1
- package/dist/workbench-shared.d.ts.map +0 -1
- package/dist/workbench-shared.js.map +0 -1
- package/dist/workbench-studio.d.ts.map +0 -1
- package/dist/workbench-studio.js.map +0 -1
- package/dist/workbench-trampoline.d.ts.map +0 -1
- package/dist/workbench-trampoline.js.map +0 -1
- package/dist/workbench-ui.d.ts.map +0 -1
- package/dist/workbench-ui.js +0 -301
- package/dist/workbench-ui.js.map +0 -1
- package/dist/workbench.d.ts.map +0 -1
- package/dist/workbench.js.map +0 -1
- /package/dist/{cli-parser.js → cli/cli-parser.js} +0 -0
- /package/dist/{pipeline-command-marker.js → cli/pipeline-command-marker.js} +0 -0
- /package/dist/{mapped-child-progress.js → core/mapped-child-progress.js} +0 -0
- /package/dist/{pipeline-diagnostics.js → core/pipeline-diagnostics.js} +0 -0
- /package/dist/{pipeline-ids.js → core/pipeline-ids.js} +0 -0
- /package/dist/{progress.js → core/progress.js} +0 -0
- /package/dist/{env.js → node/env.js} +0 -0
- /package/dist/{node.js → node/node.js} +0 -0
- /package/dist/{paths.js → node/paths.js} +0 -0
- /package/dist/{prompt-select.js → reporter/prompt-select.js} +0 -0
- /package/dist/{reporter-entry.js → reporter/reporter-entry.js} +0 -0
- /package/dist/{run-store-ui-protocol.js → studio/run-store-ui-protocol.js} +0 -0
- /package/dist/{tracing-json.js → tracing/tracing-json.js} +0 -0
- /package/dist/{tracing-otel.js → tracing/tracing-otel.js} +0 -0
- /package/dist/{abort.js → utilities/abort.js} +0 -0
- /package/dist/{rate-limit.js → utilities/rate-limit.js} +0 -0
- /package/dist/{retry.js → utilities/retry.js} +0 -0
- /package/dist/{workbench-bin.js → workbench/workbench-bin.js} +0 -0
- /package/dist/{workbench-trampoline.js → workbench/workbench-trampoline.js} +0 -0
package/README.md
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
<img
|
|
1
|
+
<p align="center">
|
|
2
|
+
<a href="https://chetmancini.github.io/tubeless/">
|
|
3
|
+
<img src="docs/assets/logo.svg" width="72" height="72" alt="Tubeless">
|
|
4
|
+
</a>
|
|
5
|
+
</p>
|
|
6
|
+
<h1 align="center">Tubeless</h1>
|
|
7
|
+
<p align="center">
|
|
8
|
+
Define a typed graph. Plan a target. Run it from Node.
|
|
9
|
+
</p>
|
|
10
|
+
<p align="center">
|
|
11
|
+
<a href="https://www.npmjs.com/package/tubeless"><img alt="npm" src="https://img.shields.io/npm/v/tubeless?style=flat-square&labelColor=121212&color=c4a046"></a>
|
|
12
|
+
<a href="https://github.com/chetmancini/tubeless/actions/workflows/check.yml"><img alt="check" src="https://img.shields.io/github/actions/workflow/status/chetmancini/tubeless/check.yml?style=flat-square&label=check&labelColor=121212&color=2f6f4a"></a>
|
|
13
|
+
<a href="./LICENSE"><img alt="MIT" src="https://img.shields.io/npm/l/tubeless?style=flat-square&labelColor=121212&color=c4c0b4"></a>
|
|
14
|
+
</p>
|
|
4
15
|
|
|
5
16
|
Typed, observable data pipelines you import from TypeScript or run from a Bun
|
|
6
17
|
CLI. It is a library, not a hosted workflow engine or a Make/npm-scripts
|
|
7
|
-
replacement.
|
|
8
|
-
|
|
9
|
-
The first public version is `0.1.0`. The API is still being proven; expect
|
|
10
|
-
change before 1.0.
|
|
18
|
+
replacement. The public line is `0.1.x`; expect API change before 1.0.
|
|
11
19
|
|
|
12
20
|
```sh
|
|
13
21
|
npm install tubeless
|
|
14
22
|
```
|
|
15
23
|
|
|
16
|
-
Also
|
|
24
|
+
Also `pnpm add tubeless`, `yarn add tubeless`, or `bun add tubeless`. Library
|
|
17
25
|
imports are ESM-only on Node.js 22+. The `tubeless` CLI requires Bun 1.3.14+;
|
|
18
26
|
`npx tubeless` works anywhere with Bun installed and otherwise prints Bun
|
|
19
|
-
install instructions. Linux and macOS are supported; Windows is
|
|
20
|
-
|
|
27
|
+
install instructions. Linux and macOS are supported; Windows is untested. See
|
|
28
|
+
[install and runtime](./docs/getting-started.md#install).
|
|
21
29
|
|
|
22
30
|
## Quick start
|
|
23
31
|
|
|
@@ -58,48 +66,48 @@ graph.
|
|
|
58
66
|
## Inspect, plan, or run
|
|
59
67
|
|
|
60
68
|
```sh
|
|
61
|
-
bunx tubeless
|
|
62
|
-
bunx tubeless
|
|
63
|
-
bunx tubeless
|
|
64
|
-
bunx tubeless run ./pipelines/my-command.ts -- --source input.json --target publish
|
|
69
|
+
bunx tubeless list # reads ./tubeless.project.ts
|
|
70
|
+
bunx tubeless inspect import-rows
|
|
71
|
+
bunx tubeless run import-rows -- --source input.json
|
|
65
72
|
```
|
|
66
73
|
|
|
67
|
-
The
|
|
68
|
-
|
|
69
|
-
|
|
74
|
+
The project manifest explicitly registers stable command IDs, module paths, and
|
|
75
|
+
execution cwd without scanning the filesystem. The CLI loads TypeScript modules
|
|
76
|
+
with Bun; existing file-oriented commands remain available. Application flags
|
|
77
|
+
go after `--`. `history` lists recorded
|
|
78
|
+
`--store` runs or reads a finished `--trace` artifact without opening the studio. See
|
|
70
79
|
[the CLI](./docs/cli.md) and [the local studio](./docs/studio.md).
|
|
71
80
|
|
|
72
81
|
## Choose the right pattern
|
|
73
82
|
|
|
74
|
-
| You need to…
|
|
75
|
-
|
|
|
76
|
-
| Run typed steps in dependency order
|
|
77
|
-
| Validate external boundary values
|
|
78
|
-
| Preview writes safely
|
|
79
|
-
| Skip work intentionally at runtime
|
|
80
|
-
| Continue independent work after a failure
|
|
81
|
-
| Reuse a pipeline inside another
|
|
82
|
-
| Run
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
83
|
+
| You need to… | Start with |
|
|
84
|
+
| -------------------------------------------- | ------------------------------------------------------------------------- |
|
|
85
|
+
| Run typed steps in dependency order | [Sequential pipeline](./examples/typed-import.ts) |
|
|
86
|
+
| Validate external boundary values | [Validated boundaries](./examples/validated-boundaries.ts) |
|
|
87
|
+
| Preview writes safely | [Dry runs and write gates](./examples/publish-with-gates.ts) |
|
|
88
|
+
| Skip work intentionally at runtime | [Conditional step](./examples/conditional-step.ts) |
|
|
89
|
+
| Continue independent work after a failure | [Best-effort execution](./examples/best-effort.ts) |
|
|
90
|
+
| Reuse a pipeline inside another | [Child pipeline](./examples/child-pipeline.ts) |
|
|
91
|
+
| Run a step on another engine | [Remote steps](./examples/remote-steps.ts) |
|
|
92
|
+
| Run one child pipeline for many items | [Fan-out and progress](./examples/fan-out-progress.ts) |
|
|
93
|
+
| Resume long API work safely | [Retry, rate limit, and checkpoint](./examples/resumable-enrichment.ts) |
|
|
94
|
+
| Watch the live TTY reporter | [Live TUI](./examples/live-tui.ts) |
|
|
95
|
+
| Watch many primitives on a road-race weekend | [Peloton pipeline](./examples/peloton.ts) |
|
|
96
|
+
| Turn a pipeline into a typed script | [Pipeline CLI](./examples/cli-job.ts) |
|
|
97
|
+
| Render plans and errors consistently | [Human and JSON rendering](./examples/rendering.ts) |
|
|
98
|
+
| Test deterministic execution | [Cancellation and test injection](./examples/cancellation-and-testing.ts) |
|
|
99
|
+
| Export lifecycle telemetry | [Structured tracing](./examples/tracing.ts) |
|
|
100
|
+
| Persist and inspect local runs | [Local observability](./examples/local-observability.ts) |
|
|
90
101
|
|
|
91
102
|
The [recipe index](./docs/recipes.md) explains when to use each pattern.
|
|
92
103
|
|
|
93
|
-
##
|
|
104
|
+
## Docs
|
|
94
105
|
|
|
95
|
-
|
|
96
|
-
- [CLI](./docs/cli.md)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- [Documentation map](./docs/README.md)
|
|
101
|
-
- [Generated API inventory](./docs/api-reference.md)
|
|
102
|
-
- [Agent guide](./docs/agent-guide.md)
|
|
106
|
+
[Website](https://chetmancini.github.io/tubeless/) ·
|
|
107
|
+
[Getting started](./docs/getting-started.md) · [CLI](./docs/cli.md) ·
|
|
108
|
+
[Studio](./docs/studio.md) · [Concepts](./docs/concepts.md) ·
|
|
109
|
+
[Comparison](./docs/comparison.md) · [API](./docs/api-reference.md) ·
|
|
110
|
+
[Agents](./docs/agent-guide.md)
|
|
103
111
|
|
|
104
112
|
## Contributing
|
|
105
113
|
|
|
@@ -109,4 +117,4 @@ through [SECURITY.md](./SECURITY.md).
|
|
|
109
117
|
|
|
110
118
|
## License
|
|
111
119
|
|
|
112
|
-
MIT
|
|
120
|
+
[MIT](./LICENSE)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type CliCommand, type CliCommandConfig, type CliContext, type CliParams, type CliParamsSchema } from "./cli-types.js";
|
|
2
|
+
export declare function createCommand<const TSchema extends CliParamsSchema, TResult = void>(config: CliCommandConfig<TSchema, TResult>, prepareContext?: (values: CliParams<TSchema>, context: CliContext) => CliContext, mainExits?: {
|
|
3
|
+
validation?: number;
|
|
4
|
+
}): CliCommand<TSchema, TResult>;
|
|
5
|
+
export declare function defineCommand<const TSchema extends CliParamsSchema, TResult = void>(config: CliCommandConfig<TSchema, TResult>): CliCommand<TSchema, TResult>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as path from "path";
|
|
2
|
-
import { openCheckpoint } from "
|
|
2
|
+
import { openCheckpoint } from "../node/checkpoint.js";
|
|
3
3
|
import { assertNoDuplicateFlags, assertValidEnvironmentFallbacks, assertValidMultipleParams, assertValidPositionals, buildEffectiveSchema, commandDescriptor, renderHelp, resolveParam, tokenize, } from "./cli-parser.js";
|
|
4
4
|
import { CliHelpRequested, CliValidationError, } from "./cli-types.js";
|
|
5
|
-
import { isCliValidationError, isPipelineExecutionError, toExitCode } from "./
|
|
6
|
-
|
|
5
|
+
import { isCliValidationError, isPipelineExecutionError, toExitCode } from "./cli-exit.js";
|
|
6
|
+
function resolveContext(overrides) {
|
|
7
7
|
return {
|
|
8
8
|
cwd: overrides?.cwd ?? process.cwd(),
|
|
9
9
|
env: overrides?.env ?? process.env,
|
|
@@ -19,7 +19,7 @@ const SIGINT_EXIT_CODE = 130;
|
|
|
19
19
|
* `parse()` mutate process-global signal handlers. Embedded callers can pass
|
|
20
20
|
* their own signal through the context instead.
|
|
21
21
|
*/
|
|
22
|
-
|
|
22
|
+
function manageMainSignal(context) {
|
|
23
23
|
if (context.signal) {
|
|
24
24
|
return { context, wasInterrupted: () => false, cleanup: () => { } };
|
|
25
25
|
}
|
|
@@ -45,7 +45,7 @@ export function manageMainSignal(context) {
|
|
|
45
45
|
* matter what `run` does with `context.checkpoint` (`record`/`flush`/`clear`, directly or
|
|
46
46
|
* via `withCheckpointedBatch`).
|
|
47
47
|
*/
|
|
48
|
-
|
|
48
|
+
function inMemoryCheckpointView(seed) {
|
|
49
49
|
const entries = new Map(seed);
|
|
50
50
|
return {
|
|
51
51
|
has: (key) => entries.has(key),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-command.js","sourceRoot":"","sources":["../../src/cli/cli-command.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from \"path\";\nimport { openCheckpoint, type CheckpointStore } from \"../node/checkpoint.js\";\nimport {\n assertNoDuplicateFlags,\n assertValidEnvironmentFallbacks,\n assertValidMultipleParams,\n assertValidPositionals,\n buildEffectiveSchema,\n commandDescriptor,\n renderHelp,\n resolveParam,\n tokenize,\n type ResolvedParamValue,\n} from \"./cli-parser.js\";\nimport {\n CliHelpRequested,\n CliValidationError,\n type CliCommand,\n type CliCommandConfig,\n type CliContext,\n type CliParams,\n type CliParamsSchema,\n type CliParseResult,\n} from \"./cli-types.js\";\nimport { isCliValidationError, isPipelineExecutionError, toExitCode } from \"./cli-exit.js\";\n\nfunction resolveContext(overrides?: Partial<CliContext>): CliContext {\n return {\n cwd: overrides?.cwd ?? process.cwd(),\n env: overrides?.env ?? process.env,\n log: overrides?.log ?? console,\n pipelineContext: overrides?.pipelineContext,\n signal: overrides?.signal,\n checkpoint: overrides?.checkpoint,\n };\n}\n\ninterface ManagedMainSignal {\n context: CliContext;\n wasInterrupted(): boolean;\n cleanup(): void;\n}\n\nconst SIGINT_EXIT_CODE = 130;\n\n/**\n * Give real CLI entrypoints graceful cancellation without making `run()` or\n * `parse()` mutate process-global signal handlers. Embedded callers can pass\n * their own signal through the context instead.\n */\nfunction manageMainSignal(context: CliContext): ManagedMainSignal {\n if (context.signal) {\n return { context, wasInterrupted: () => false, cleanup: () => {} };\n }\n\n const controller = new AbortController();\n let interrupted = false;\n const onSigint = (): void => {\n interrupted = true;\n context.log.warn(\"SIGINT received; cancelling pipeline work.\");\n controller.abort();\n };\n process.once(\"SIGINT\", onSigint);\n\n return {\n context: { ...context, signal: controller.signal },\n wasInterrupted: () => interrupted,\n cleanup: () => process.removeListener(\"SIGINT\", onSigint),\n };\n}\n\n/**\n * An in-memory-only `CheckpointStore` seeded from `seed`: reads and `record()` behave\n * exactly like a real store for the rest of this run, but `flush()`/`clear()` never touch\n * disk. Every dry-run path hands `run` one of these instead of the real store — the\n * managed-checkpoint contract is that a dry run never writes to the checkpoint file, no\n * matter what `run` does with `context.checkpoint` (`record`/`flush`/`clear`, directly or\n * via `withCheckpointedBatch`).\n */\nfunction inMemoryCheckpointView(seed: ReadonlyMap<string, unknown>): CheckpointStore {\n const entries = new Map(seed);\n return {\n has: (key) => entries.has(key),\n record: (key, meta) => {\n entries.set(key, meta);\n },\n entries: () => entries,\n flush: () => {},\n clear: () => {\n entries.clear();\n },\n };\n}\n\nexport function createCommand<const TSchema extends CliParamsSchema, TResult = void>(\n config: CliCommandConfig<TSchema, TResult>,\n prepareContext?: (values: CliParams<TSchema>, context: CliContext) => CliContext,\n mainExits?: { validation?: number }\n): CliCommand<TSchema, TResult> {\n const effectiveParams = buildEffectiveSchema(config.params, config.checkpoint);\n assertNoDuplicateFlags(effectiveParams);\n assertValidMultipleParams(effectiveParams);\n assertValidEnvironmentFallbacks(effectiveParams);\n const positionals = [...(config.positionals ?? [])];\n assertValidPositionals(positionals, effectiveParams);\n const descriptor = commandDescriptor(config, effectiveParams, positionals);\n\n function parseWithContext(argv: readonly string[], context: CliContext): CliParseResult<TSchema> {\n const helpText = renderHelp(\n descriptor.name,\n descriptor.description,\n effectiveParams,\n positionals\n );\n\n const tokenized = tokenize(argv, effectiveParams, positionals);\n if (tokenized.help) {\n return { kind: \"help\", helpText };\n }\n\n const errors = [...tokenized.errors];\n const values: Record<string, ResolvedParamValue> = {};\n for (const [key, param] of Object.entries(effectiveParams)) {\n const argvValue = tokenized.values.get(key);\n const envValue = argvValue === undefined && param.env ? context.env?.[param.env] : undefined;\n values[key] = resolveParam(\n key,\n param,\n argvValue ?? envValue,\n context.cwd,\n errors,\n argvValue !== undefined ? \"argv\" : envValue !== undefined ? \"env\" : \"default\"\n );\n }\n\n if (errors.length > 0) {\n return { kind: \"error\", errors, helpText };\n }\n\n // SAFETY: `values` was populated by `resolveParam` for every key in `effectiveParams`,\n // which is exactly the schema `TSchema` describes, so its runtime shape matches `CliParams<TSchema>`.\n const typedValues = values as CliParams<TSchema>;\n const validationErrors = config.validate?.(typedValues, context) ?? [];\n if (validationErrors.length > 0) {\n return { kind: \"error\", errors: validationErrors, helpText };\n }\n\n return { kind: \"values\", values: typedValues };\n }\n\n function parse(\n argv: readonly string[] = process.argv.slice(2),\n contextOverrides?: Partial<CliContext>\n ): CliParseResult<TSchema> {\n return parseWithContext(argv, resolveContext(contextOverrides));\n }\n\n function parseStructuredWithContext(\n structuredValues: Record<string, unknown>,\n context: CliContext\n ): CliParseResult<TSchema> {\n const helpText = renderHelp(\n descriptor.name,\n descriptor.description,\n effectiveParams,\n positionals\n );\n const errors: string[] = [];\n const values: Record<string, ResolvedParamValue> = {};\n for (const key of Object.keys(structuredValues)) {\n if (!Object.prototype.hasOwnProperty.call(effectiveParams, key)) {\n errors.push(`Unknown parameter: ${key}`);\n }\n }\n for (const [key, param] of Object.entries(effectiveParams)) {\n const provided = structuredValues[key];\n const raw = normalizeStructuredValue(key, param, provided, errors);\n if (provided !== undefined && raw === undefined) {\n values[key] = undefined;\n continue;\n }\n const envValue = raw === undefined && param.env ? context.env?.[param.env] : undefined;\n values[key] = resolveParam(\n key,\n param,\n raw ?? envValue,\n context.cwd,\n errors,\n raw !== undefined ? \"argv\" : envValue !== undefined ? \"env\" : \"default\"\n );\n }\n if (errors.length > 0) return { kind: \"error\", errors, helpText };\n // SAFETY: `values` was populated by `resolveParam` for every key in `effectiveParams`,\n // which is exactly the schema `TSchema` describes, so its runtime shape matches `CliParams<TSchema>`.\n const typedValues = values as CliParams<TSchema>;\n const validationErrors = config.validate?.(typedValues, context) ?? [];\n return validationErrors.length > 0\n ? { kind: \"error\", errors: validationErrors, helpText }\n : { kind: \"values\", values: typedValues };\n }\n\n /**\n * No-op unless `config.checkpoint` is set. Respects a caller-provided `context.checkpoint`\n * override (e.g. a stub in tests) instead of opening the real file. Otherwise opens (or\n * clears, if not resuming) the checkpoint before `run` is called — never on the `--help`/\n * error paths, since those return before this is reached.\n */\n function attachCheckpoint(context: CliContext, values: CliParams<TSchema>): CliContext {\n const checkpointConfig = config.checkpoint;\n if (!checkpointConfig) {\n return context;\n }\n const resolvedPath = path.isAbsolute(checkpointConfig.path)\n ? checkpointConfig.path\n : path.join(context.cwd, checkpointConfig.path);\n // A caller-provided context.checkpoint (e.g. a stub in tests) is used as the\n // underlying store instead of opening the real file, but every rule below — fresh\n // clearing, dry-run wrapping, resume detection/logging — still applies to it; only\n // the \"where does the store come from\" step is skipped.\n const store = context.checkpoint ?? openCheckpoint(resolvedPath);\n const hadExisting = store.entries().size > 0;\n\n if (values.resume) {\n if (hadExisting) {\n context.log.log(\n `Resuming from checkpoint: ${store.entries().size} item(s) already recorded.`\n );\n } else {\n // Without this, --resume against a missing/wrong-path/already-cleared checkpoint\n // silently starts fresh — the exact failure mode that's dangerous for\n // clearOnSuccess: false workflows, where \"fresh\" quietly means \"reprocess\n // everything already done\".\n context.log.warn(\n `--resume was passed, but no checkpoint was found at ${resolvedPath}; starting fresh.`\n );\n }\n // A dry run must never write to the checkpoint file, even while resuming — an\n // in-memory view seeded with the real entries previews it accurately without risk.\n return {\n ...context,\n checkpoint: values.dryRun ? inMemoryCheckpointView(store.entries()) : store,\n };\n }\n\n if (!hadExisting) {\n return {\n ...context,\n checkpoint: values.dryRun ? inMemoryCheckpointView(store.entries()) : store,\n };\n }\n\n if (values.dryRun) {\n // Dry run must not touch the file — neither clearing it nor writing new progress —\n // but the preview should still reflect what a real fresh run would see: an empty\n // \"done\" set, not the stale entries a --resume invocation would use.\n context.log.log(\"Dry run: leaving existing checkpoint untouched (would start fresh).\");\n return { ...context, checkpoint: inMemoryCheckpointView(new Map()) };\n }\n\n store.clear();\n context.log.log(\"Starting fresh — cleared existing checkpoint.\");\n return { ...context, checkpoint: store };\n }\n\n /** No-op unless `config.checkpoint` is set, a store is attached, and the run wasn't a dry run. */\n function finalizeCheckpoint(context: CliContext, values: CliParams<TSchema>): void {\n const checkpointConfig = config.checkpoint;\n if (!checkpointConfig || !context.checkpoint || values.dryRun) {\n return;\n }\n if (checkpointConfig.clearOnSuccess === false) {\n return;\n }\n context.checkpoint.clear();\n }\n\n async function executeValues(values: CliParams<TSchema>, context: CliContext): Promise<TResult> {\n const preparedContext = prepareContext?.(values, context) ?? context;\n const runContext = attachCheckpoint(preparedContext, values);\n const value = await config.run(values, runContext);\n finalizeCheckpoint(runContext, values);\n return value;\n }\n\n function parseValues(\n values: Record<string, unknown>,\n contextOverrides?: Partial<CliContext>\n ): CliParseResult<TSchema> {\n const context = resolveContext(contextOverrides);\n return parseStructuredWithContext(values, context);\n }\n\n async function execute(\n values: CliParams<TSchema>,\n contextOverrides?: Partial<CliContext>\n ): Promise<TResult> {\n return executeValues(values, resolveContext(contextOverrides));\n }\n\n async function run(\n argv: readonly string[] = process.argv.slice(2),\n contextOverrides?: Partial<CliContext>\n ): Promise<TResult> {\n const context = resolveContext(contextOverrides);\n const result = parseWithContext(argv, context);\n if (result.kind === \"help\") throw new CliHelpRequested(result.helpText);\n if (result.kind === \"error\") throw new CliValidationError(result.errors, result.helpText);\n return executeValues(result.values, context);\n }\n\n async function main(\n argv: readonly string[] = process.argv.slice(2),\n contextOverrides?: Partial<CliContext>\n ): Promise<void> {\n const context = resolveContext(contextOverrides);\n let result: CliParseResult<TSchema>;\n try {\n result = parseWithContext(argv, context);\n } catch (error) {\n context.log.error(error instanceof Error ? (error.stack ?? error.message) : String(error));\n process.exitCode =\n mainExits || isCliValidationError(error) || isPipelineExecutionError(error)\n ? toExitCode(error)\n : 1;\n return;\n }\n if (result.kind === \"help\") {\n context.log.log(result.helpText);\n process.exitCode = 0;\n return;\n }\n if (result.kind === \"error\") {\n for (const error of result.errors) {\n context.log.error(`Error: ${error}`);\n }\n context.log.error(\"\");\n context.log.error(result.helpText);\n process.exitCode = mainExits?.validation ?? 1;\n return;\n }\n const managedSignal = manageMainSignal(context);\n try {\n const preparedContext =\n prepareContext?.(result.values, managedSignal.context) ?? managedSignal.context;\n const runContext = attachCheckpoint(preparedContext, result.values);\n await config.run(result.values, runContext);\n if (!managedSignal.wasInterrupted()) {\n finalizeCheckpoint(runContext, result.values);\n }\n } catch (error) {\n context.log.error(error instanceof Error ? (error.stack ?? error.message) : String(error));\n process.exitCode = managedSignal.wasInterrupted()\n ? SIGINT_EXIT_CODE\n : mainExits || isCliValidationError(error) || isPipelineExecutionError(error)\n ? toExitCode(error)\n : 1;\n } finally {\n if (managedSignal.wasInterrupted()) {\n process.exitCode = SIGINT_EXIT_CODE;\n }\n managedSignal.cleanup();\n }\n }\n\n return { descriptor, execute, parse, parseValues, run, main };\n}\n\nfunction normalizeStructuredValue(\n key: string,\n param: CliParamsSchema[string],\n value: unknown,\n errors: string[]\n): string | boolean | string[] | undefined {\n if (value === undefined) return undefined;\n const label = `--${param.flag ?? key}`;\n if (param.type === \"boolean\") {\n if (typeof value === \"boolean\") return value;\n errors.push(`${label} must be a boolean value.`);\n return undefined;\n }\n if ((param.type === \"number\" || param.type === \"string\") && param.multiple === true) {\n if (!Array.isArray(value)) {\n errors.push(`${label} must be an array.`);\n return undefined;\n }\n if (param.type === \"number\") {\n if (!value.every((item) => typeof item === \"number\" && Number.isFinite(item))) {\n errors.push(`${label} must contain only finite numbers.`);\n return undefined;\n }\n return value.map(String);\n }\n if (!value.every((item) => typeof item === \"string\")) {\n errors.push(`${label} must contain only strings.`);\n return undefined;\n }\n return [...value];\n }\n if (param.type === \"number\") {\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n errors.push(`${label} must be a finite number.`);\n return undefined;\n }\n return String(value);\n }\n if (typeof value !== \"string\") {\n errors.push(`${label} must be a string value.`);\n return undefined;\n }\n return value;\n}\n\nexport function defineCommand<const TSchema extends CliParamsSchema, TResult = void>(\n config: CliCommandConfig<TSchema, TResult>\n): CliCommand<TSchema, TResult> {\n return createCommand(config);\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { PipelineError } from "../core/pipeline-types.js";
|
|
2
|
+
/** Stable shell exit codes for the workbench command family. */
|
|
3
|
+
export declare const TUBELESS_WORKBENCH_EXIT_CODE: {
|
|
4
|
+
readonly success: 0;
|
|
5
|
+
readonly usage: 1;
|
|
6
|
+
readonly load: 2;
|
|
7
|
+
readonly definition: 3;
|
|
8
|
+
readonly validation: 4;
|
|
9
|
+
readonly planning: 5;
|
|
10
|
+
readonly execution: 6;
|
|
11
|
+
readonly cancellation: 7;
|
|
12
|
+
};
|
|
13
|
+
export declare function isCliHelpRequested(error: unknown): error is {
|
|
14
|
+
helpText: string;
|
|
15
|
+
};
|
|
16
|
+
export declare function isCliValidationError(error: unknown): error is {
|
|
17
|
+
errors: readonly string[];
|
|
18
|
+
helpText: string;
|
|
19
|
+
};
|
|
20
|
+
export declare function isPipelineExecutionError(error: unknown): error is {
|
|
21
|
+
result: {
|
|
22
|
+
errors: PipelineError[];
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/** Map a thrown CLI or pipeline error onto the workbench exit-code family. */
|
|
26
|
+
export declare function toExitCode(error: unknown): number;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { tubelessErrorKind } from "../utilities/tubeless-error.js";
|
|
2
|
+
/** Stable shell exit codes for the workbench command family. */
|
|
3
|
+
export const TUBELESS_WORKBENCH_EXIT_CODE = {
|
|
4
|
+
success: 0,
|
|
5
|
+
usage: 1,
|
|
6
|
+
load: 2,
|
|
7
|
+
definition: 3,
|
|
8
|
+
validation: 4,
|
|
9
|
+
planning: 5,
|
|
10
|
+
execution: 6,
|
|
11
|
+
cancellation: 7,
|
|
12
|
+
};
|
|
13
|
+
function errorName(error) {
|
|
14
|
+
return typeof error === "object" && error !== null && "name" in error
|
|
15
|
+
? String(error.name)
|
|
16
|
+
: undefined;
|
|
17
|
+
}
|
|
18
|
+
export function isCliHelpRequested(error) {
|
|
19
|
+
// Dual library copies under dynamic import break instanceof. Key on the
|
|
20
|
+
// brand, then the pre-brand name-and-shape used by older loaded copies.
|
|
21
|
+
return ((tubelessErrorKind(error) === "cli-help" || errorName(error) === "CliHelpRequested") &&
|
|
22
|
+
typeof error === "object" &&
|
|
23
|
+
error !== null &&
|
|
24
|
+
"helpText" in error &&
|
|
25
|
+
typeof error.helpText === "string");
|
|
26
|
+
}
|
|
27
|
+
export function isCliValidationError(error) {
|
|
28
|
+
// Dual library copies under dynamic import break instanceof. Key on the
|
|
29
|
+
// brand, then the pre-brand name-and-shape used by older loaded copies.
|
|
30
|
+
return ((tubelessErrorKind(error) === "cli-validation" || errorName(error) === "CliValidationError") &&
|
|
31
|
+
typeof error === "object" &&
|
|
32
|
+
error !== null &&
|
|
33
|
+
"errors" in error &&
|
|
34
|
+
Array.isArray(error.errors) &&
|
|
35
|
+
"helpText" in error &&
|
|
36
|
+
typeof error.helpText === "string");
|
|
37
|
+
}
|
|
38
|
+
export function isPipelineExecutionError(error) {
|
|
39
|
+
// Dual library copies under dynamic import break instanceof. Key on the
|
|
40
|
+
// brand, then the pre-brand name-and-shape used by older loaded copies.
|
|
41
|
+
return ((tubelessErrorKind(error) === "pipeline-execution" ||
|
|
42
|
+
errorName(error) === "PipelineExecutionError") &&
|
|
43
|
+
typeof error === "object" &&
|
|
44
|
+
error !== null &&
|
|
45
|
+
"result" in error &&
|
|
46
|
+
typeof error.result === "object" &&
|
|
47
|
+
error.result !== null &&
|
|
48
|
+
"errors" in error.result &&
|
|
49
|
+
Array.isArray(error.result.errors));
|
|
50
|
+
}
|
|
51
|
+
/** Map a thrown CLI or pipeline error onto the workbench exit-code family. */
|
|
52
|
+
export function toExitCode(error) {
|
|
53
|
+
if (isCliHelpRequested(error))
|
|
54
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.success;
|
|
55
|
+
if (isCliValidationError(error))
|
|
56
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.validation;
|
|
57
|
+
if (isPipelineExecutionError(error)) {
|
|
58
|
+
const errors = error.result.errors;
|
|
59
|
+
if (errors.length > 0 && errors.every(({ kind }) => kind === "cancellation")) {
|
|
60
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.cancellation;
|
|
61
|
+
}
|
|
62
|
+
if (errors.some(({ phase }) => phase === "planning")) {
|
|
63
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.planning;
|
|
64
|
+
}
|
|
65
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.execution;
|
|
66
|
+
}
|
|
67
|
+
return TUBELESS_WORKBENCH_EXIT_CODE.execution;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=cli-exit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-exit.js","sourceRoot":"","sources":["../../src/cli/cli-exit.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineError } from \"../core/pipeline-types.js\";\nimport { tubelessErrorKind } from \"../utilities/tubeless-error.js\";\n\n/** Stable shell exit codes for the workbench command family. */\nexport const TUBELESS_WORKBENCH_EXIT_CODE = {\n success: 0,\n usage: 1,\n load: 2,\n definition: 3,\n validation: 4,\n planning: 5,\n execution: 6,\n cancellation: 7,\n} as const;\n\nfunction errorName(error: unknown): string | undefined {\n return typeof error === \"object\" && error !== null && \"name\" in error\n ? String(error.name)\n : undefined;\n}\n\nexport function isCliHelpRequested(error: unknown): error is { helpText: string } {\n // Dual library copies under dynamic import break instanceof. Key on the\n // brand, then the pre-brand name-and-shape used by older loaded copies.\n return (\n (tubelessErrorKind(error) === \"cli-help\" || errorName(error) === \"CliHelpRequested\") &&\n typeof error === \"object\" &&\n error !== null &&\n \"helpText\" in error &&\n typeof error.helpText === \"string\"\n );\n}\n\nexport function isCliValidationError(\n error: unknown\n): error is { errors: readonly string[]; helpText: string } {\n // Dual library copies under dynamic import break instanceof. Key on the\n // brand, then the pre-brand name-and-shape used by older loaded copies.\n return (\n (tubelessErrorKind(error) === \"cli-validation\" || errorName(error) === \"CliValidationError\") &&\n typeof error === \"object\" &&\n error !== null &&\n \"errors\" in error &&\n Array.isArray(error.errors) &&\n \"helpText\" in error &&\n typeof error.helpText === \"string\"\n );\n}\n\nexport function isPipelineExecutionError(\n error: unknown\n): error is { result: { errors: PipelineError[] } } {\n // Dual library copies under dynamic import break instanceof. Key on the\n // brand, then the pre-brand name-and-shape used by older loaded copies.\n return (\n (tubelessErrorKind(error) === \"pipeline-execution\" ||\n errorName(error) === \"PipelineExecutionError\") &&\n typeof error === \"object\" &&\n error !== null &&\n \"result\" in error &&\n typeof error.result === \"object\" &&\n error.result !== null &&\n \"errors\" in error.result &&\n Array.isArray(error.result.errors)\n );\n}\n\n/** Map a thrown CLI or pipeline error onto the workbench exit-code family. */\nexport function toExitCode(error: unknown): number {\n if (isCliHelpRequested(error)) return TUBELESS_WORKBENCH_EXIT_CODE.success;\n if (isCliValidationError(error)) return TUBELESS_WORKBENCH_EXIT_CODE.validation;\n if (isPipelineExecutionError(error)) {\n const errors = error.result.errors;\n if (errors.length > 0 && errors.every(({ kind }) => kind === \"cancellation\")) {\n return TUBELESS_WORKBENCH_EXIT_CODE.cancellation;\n }\n if (errors.some(({ phase }) => phase === \"planning\")) {\n return TUBELESS_WORKBENCH_EXIT_CODE.planning;\n }\n return TUBELESS_WORKBENCH_EXIT_CODE.execution;\n }\n return TUBELESS_WORKBENCH_EXIT_CODE.execution;\n}\n"]}
|
|
@@ -25,4 +25,3 @@ export declare function assertNoDuplicateFlags(schema: CliParamsSchema): void;
|
|
|
25
25
|
export declare function assertValidMultipleParams(schema: CliParamsSchema): void;
|
|
26
26
|
export declare function assertValidPositionals(positionals: readonly string[], schema: CliParamsSchema): void;
|
|
27
27
|
export declare function assertValidEnvironmentFallbacks(schema: CliParamsSchema): void;
|
|
28
|
-
//# sourceMappingURL=cli-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-parser.js","sourceRoot":"","sources":["../../src/cli/cli-parser.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from \"fs\";\nimport * as path from \"path\";\nimport type {\n CliBooleanParam,\n CliCheckpointConfig,\n CliCommandConfig,\n CliCommandDescriptor,\n CliNumberParam,\n CliParam,\n CliParameterDescriptor,\n CliParamsSchema,\n CliStringParam,\n} from \"./cli-types.js\";\n\n/**\n * Every command gets `-h`/`--help`, `--dry-run`, and `--resume`/`--no-resume` for free, the\n * same way every pipeline step gets `context.dryRun` — that's the point: a command's\n * `dryRun` value is forwarded through executor controls when the command runs a pipeline.\n * `resume` is useful even\n * without `config.checkpoint` set — a script can implement its own \"is this done\" check\n * (a DB query, re-reading an output artifact) and just read `values.resume` directly.\n * Schemas can't redeclare any of these names; `defineCommand` throws immediately if one\n * tries, instead of silently shadowing the built-in.\n */\nconst DRY_RUN_KEY = \"dryRun\";\nconst DRY_RUN_PARAM: CliBooleanParam = {\n type: \"boolean\",\n description: \"Preview without making changes.\",\n group: \"execution\",\n};\nconst RESUME_KEY = \"resume\";\nconst RESERVED_FLAG_NAMES: ReadonlySet<string> = new Set([\n \"help\",\n \"dry-run\",\n \"resume\",\n \"no-resume\",\n]);\n\nexport function buildEffectiveSchema(\n params: CliParamsSchema,\n checkpoint: CliCheckpointConfig | undefined\n): CliParamsSchema {\n if (Object.prototype.hasOwnProperty.call(params, DRY_RUN_KEY)) {\n throw new Error(\n `\"${DRY_RUN_KEY}\" is a reserved parameter provided automatically by every command; remove it from params.`\n );\n }\n if (Object.prototype.hasOwnProperty.call(params, RESUME_KEY)) {\n throw new Error(\n `\"${RESUME_KEY}\" is a reserved parameter provided automatically by every command; remove it from params.`\n );\n }\n const resumeParam: CliBooleanParam = {\n type: \"boolean\",\n description: \"Resume: skip work that's already done instead of starting fresh.\",\n default: checkpoint?.defaultResume ?? false,\n group: \"execution\",\n };\n return {\n [DRY_RUN_KEY]: DRY_RUN_PARAM,\n [RESUME_KEY]: resumeParam,\n ...params,\n };\n}\n\nfunction defaultCommandName(): string {\n const entry = process.argv[1];\n if (!entry) {\n return \"command\";\n }\n return path.basename(entry).replace(/\\.[^./]+$/, \"\");\n}\n\nexport function flagName(key: string, param: CliParam): string {\n return param.flag ?? key.replace(/([a-z0-9])([A-Z])/g, \"$1-$2\").toLowerCase();\n}\n\n/** True for a string/number param declared `multiple: true` — the only types that support it. */\nfunction isMultipleParam(\n param: CliParam\n): param is (CliStringParam | CliNumberParam) & { multiple: true } {\n return (param.type === \"string\" || param.type === \"number\") && param.multiple === true;\n}\n\nexport function commandDescriptor(\n config: Pick<CliCommandConfig<CliParamsSchema, unknown>, \"description\" | \"name\">,\n params: CliParamsSchema,\n positionals: readonly string[]\n): CliCommandDescriptor {\n const parameters = Object.entries(params).map(([key, param]): CliParameterDescriptor => {\n const defaultValue = param.type === \"boolean\" ? (param.default ?? false) : param.default;\n const required =\n param.type !== \"boolean\" &&\n !isMultipleParam(param) &&\n !param.optional &&\n param.default === undefined &&\n param.env === undefined;\n const descriptor: MutableCliParameterDescriptor = {\n flag: flagName(key, param),\n key,\n multiple: isMultipleParam(param),\n positional: positionals.includes(key),\n required,\n type: param.type,\n };\n if (param.group !== undefined) {\n descriptor.group = param.group;\n }\n if (param.exclusive === true) {\n descriptor.exclusive = true;\n }\n if (param.type === \"string\" && param.choices) {\n descriptor.choices = Object.freeze([...param.choices]);\n }\n if (defaultValue !== undefined) {\n descriptor.default = defaultValue;\n }\n if (param.description !== undefined) {\n descriptor.description = param.description;\n }\n if (param.env !== undefined) {\n descriptor.environment = param.env;\n }\n if (param.type === \"number\" && param.integer) {\n descriptor.integer = true;\n }\n if (param.type === \"number\" && param.max !== undefined) {\n descriptor.max = param.max;\n }\n if (param.type === \"number\" && param.min !== undefined) {\n descriptor.min = param.min;\n }\n if (param.type === \"path\" && param.mustExist) {\n descriptor.mustExist = true;\n }\n if (param.type === \"path\" && param.kind) {\n descriptor.pathKind = param.kind;\n }\n if (param.short !== undefined) {\n descriptor.short = param.short;\n }\n return Object.freeze(descriptor);\n });\n const command: MutableCliCommandDescriptor = {\n name: config.name ?? defaultCommandName(),\n parameters: Object.freeze(parameters),\n };\n if (config.description !== undefined) {\n command.description = config.description;\n }\n return Object.freeze(command);\n}\n\nfunction usageToken(flag: string, param: CliParam): string {\n if (param.type === \"boolean\") return `--${flag}`;\n return isMultipleParam(param) ? `--${flag} <${param.type}...>` : `--${flag} <${param.type}>`;\n}\n\nfunction positionalUsageToken(key: string, param: CliParam): string {\n const name = isMultipleParam(param) ? `<${key}...>` : `<${key}>`;\n const optional =\n param.type !== \"boolean\" &&\n (param.optional || param.default !== undefined || isMultipleParam(param));\n return optional ? `[${name}]` : name;\n}\n\nfunction describeParam(param: CliParam): string {\n const parts: string[] = [];\n if (param.description) {\n parts.push(param.description);\n }\n if (param.type === \"string\" && param.choices) {\n parts.push(`one of: ${param.choices.join(\", \")}`);\n }\n if (param.type === \"number\") {\n if (param.integer) parts.push(\"integer\");\n if (param.min !== undefined) parts.push(`min: ${param.min}`);\n if (param.max !== undefined) parts.push(`max: ${param.max}`);\n }\n if (param.type === \"path\" && param.kind && param.mustExist) {\n parts.push(`must be a ${param.kind}`);\n }\n if (isMultipleParam(param)) {\n parts.push(\"repeatable; default: []\");\n } else if (param.type === \"boolean\") {\n parts.push(`default: ${param.default ?? false}`);\n } else if (param.default !== undefined) {\n parts.push(`default: ${JSON.stringify(param.default)}`);\n } else if (!param.optional) {\n parts.push(\"required\");\n }\n return parts.join(\"; \");\n}\n\nexport function renderHelp(\n name: string,\n description: string | undefined,\n schema: CliParamsSchema,\n positionals: readonly string[]\n): string {\n const rows = Object.entries(schema).map(([key, param]) => {\n const flag = flagName(key, param);\n const longUsage = usageToken(flag, param);\n const usage = param.short ? `-${param.short}, ${longUsage}` : longUsage;\n const env = param.env ? `env: ${param.env}` : undefined;\n return [usage, [describeParam(param), env].filter(Boolean).join(\"; \")] as const;\n });\n const width = Math.max(10, ...rows.map(([usage]) => usage.length));\n const positionalUsage = positionals\n .map((key) => positionalUsageToken(key, schema[key]!))\n .join(\" \");\n const lines = [`Usage: ${name} [options]${positionalUsage ? ` ${positionalUsage}` : \"\"}`];\n if (description) {\n lines.push(\"\", description);\n }\n lines.push(\"\", \"Options:\");\n for (const [usage, summary] of rows) {\n lines.push(summary ? ` ${usage.padEnd(width)} ${summary}` : ` ${usage}`);\n }\n lines.push(` ${\"-h, --help\".padEnd(width)} Show this help message.`);\n return lines.join(\"\\n\");\n}\n\nexport interface TokenizeResult {\n values: Map<string, string | boolean | string[]>;\n errors: string[];\n help: boolean;\n}\n\ninterface CliParamEntry {\n flag: string;\n key: string;\n param: CliParam;\n}\n\nfunction buildParamEntries(schema: CliParamsSchema): CliParamEntry[] {\n return Object.entries(schema).map(([key, param]) => ({ key, param, flag: flagName(key, param) }));\n}\n\nexport function tokenize(\n argv: readonly string[],\n schema: CliParamsSchema,\n positionals: readonly string[]\n): TokenizeResult {\n const entries = buildParamEntries(schema);\n const paramByFlag = new Map<string, CliParamEntry>();\n const paramByShort = new Map<string, CliParamEntry>();\n const positionalEntries = positionals.map(\n // SAFETY: `assertValidPositionals` (run by callers before `tokenize`) rejects any\n // positional key absent from the schema, so every positional is present in `entries`.\n (key) => entries.find((entry) => entry.key === key) as CliParamEntry\n );\n for (const entry of entries) {\n paramByFlag.set(entry.flag, entry);\n if (entry.param.short) {\n paramByShort.set(entry.param.short, entry);\n }\n }\n\n const values = new Map<string, string | boolean | string[]>();\n const errors: string[] = [];\n let help = false;\n let positionalIndex = 0;\n let afterOptions = false;\n\n const assignValue = (entry: CliParamEntry, value: string | boolean): void => {\n if (isMultipleParam(entry.param)) {\n const collected = values.get(entry.key);\n const array = Array.isArray(collected) ? collected : [];\n // SAFETY: only string/number params support `multiple`, and `assignValue` is only\n // reached with boolean values for boolean params, so `value` here is always a string.\n array.push(value as string);\n values.set(entry.key, array);\n return;\n }\n values.set(entry.key, value);\n };\n\n const nextPositionalEntry = (): CliParamEntry | undefined => {\n while (\n positionalIndex < positionalEntries.length &&\n values.has(positionalEntries[positionalIndex]!.key) &&\n !isMultipleParam(positionalEntries[positionalIndex]!.param)\n ) {\n positionalIndex++;\n }\n return positionalEntries[positionalIndex];\n };\n\n const assignPositional = (token: string): void => {\n const entry = nextPositionalEntry();\n if (!entry) {\n errors.push(`Unexpected argument: ${token}`);\n return;\n }\n assignValue(entry, token);\n if (!isMultipleParam(entry.param)) {\n positionalIndex++;\n }\n };\n\n const nextValue = (index: number, name: string): string | undefined => {\n const next = argv[index + 1];\n // A known short option must not be consumed as a value, but negative numeric\n // values and ordinary dash-prefixed paths remain valid option values.\n if (\n next === undefined ||\n next.startsWith(\"--\") ||\n next === \"-h\" ||\n (next.length === 2 && next.startsWith(\"-\") && paramByShort.has(next[1]!))\n ) {\n errors.push(`Missing value for --${name}`);\n return undefined;\n }\n return next;\n };\n\n for (let index = 0; index < argv.length; index++) {\n const token = argv[index];\n if (!afterOptions && token === \"--\") {\n afterOptions = true;\n continue;\n }\n if (!afterOptions && (token === \"--help\" || token === \"-h\")) {\n help = true;\n continue;\n }\n if (afterOptions || !token.startsWith(\"-\")) {\n assignPositional(token);\n continue;\n }\n\n if (!token.startsWith(\"--\")) {\n if (nextPositionalEntry()?.param.type === \"number\" && /^-\\d/.test(token)) {\n assignPositional(token);\n continue;\n }\n if (token.length !== 2) {\n errors.push(`Unknown option: ${token}`);\n continue;\n }\n const entry = paramByShort.get(token[1]!);\n if (!entry) {\n errors.push(`Unknown option: ${token}`);\n continue;\n }\n if (entry.param.type === \"boolean\") {\n assignValue(entry, true);\n continue;\n }\n const value = nextValue(index, entry.flag);\n if (value !== undefined) {\n assignValue(entry, value);\n index++;\n }\n continue;\n }\n\n const body = token.slice(2);\n const bodyEqualsIndex = body.indexOf(\"=\");\n const bodyName = bodyEqualsIndex === -1 ? body : body.slice(0, bodyEqualsIndex);\n\n // A registered flag is matched exactly first, so a real flag that happens to start\n // with \"no-\" (e.g. a `noCache` param, or an explicit `flag: \"no-dry-run\"`) is never\n // misread as a negation of some other flag; negation is only inferred as a fallback\n // when the literal name isn't registered.\n const negated = !paramByFlag.has(bodyName) && bodyName.startsWith(\"no-\");\n const withoutNegation = negated ? body.slice(3) : body;\n const equalsIndex = withoutNegation.indexOf(\"=\");\n const name = equalsIndex === -1 ? withoutNegation : withoutNegation.slice(0, equalsIndex);\n const inlineValue = equalsIndex === -1 ? undefined : withoutNegation.slice(equalsIndex + 1);\n\n const entry = paramByFlag.get(name);\n if (!entry) {\n errors.push(`Unknown option: --${body}`);\n continue;\n }\n\n if (entry.param.type !== \"boolean\") {\n if (negated) {\n errors.push(`--no-${name} is only valid for boolean options`);\n continue;\n }\n let value: string;\n if (inlineValue !== undefined) {\n value = inlineValue;\n } else {\n const next = nextValue(index, name);\n if (next === undefined) continue;\n value = next;\n index++;\n }\n assignValue(entry, value);\n continue;\n }\n\n if (negated && inlineValue !== undefined) {\n errors.push(`--no-${name} cannot be combined with a value`);\n } else if (inlineValue === undefined) {\n values.set(entry.key, !negated);\n } else if (inlineValue === \"true\") {\n values.set(entry.key, true);\n } else if (inlineValue === \"false\") {\n values.set(entry.key, false);\n } else {\n errors.push(`--${name} must be true or false, got \"${inlineValue}\"`);\n }\n }\n\n return { values, errors, help };\n}\n\n/** A single resolved parameter value after CLI/environment/default decoding. */\nexport type ResolvedParamValue = string | number | boolean | (string | number)[] | undefined;\n\n/** Mutable build-time views of the public descriptors, frozen before return. */\ntype Mutable<T> = { -readonly [K in keyof T]: T[K] };\ntype MutableCliParameterDescriptor = Mutable<CliParameterDescriptor>;\ntype MutableCliCommandDescriptor = Mutable<CliCommandDescriptor>;\n\nfunction isBooleanValue(value: string | boolean | string[] | undefined): value is boolean {\n return typeof value === \"boolean\";\n}\n\nfunction isStringValue(value: string | boolean | string[] | undefined): value is string {\n return typeof value === \"string\";\n}\n\nfunction isNumberValue(value: string | number): value is number {\n return typeof value === \"number\";\n}\n\nexport function resolveParam(\n key: string,\n param: CliParam,\n raw: string | boolean | string[] | undefined,\n cwd: string,\n errors: string[],\n source: \"argv\" | \"env\" | \"default\" = \"argv\"\n): ResolvedParamValue {\n const flag = flagName(key, param);\n const sourceLabel = source === \"env\" ? `environment variable ${param.env}` : `--${flag}`;\n const showRawValue = source !== \"env\";\n\n if (param.type === \"boolean\") {\n if (isBooleanValue(raw)) return raw;\n if (isStringValue(raw)) {\n if (raw === \"true\") return true;\n if (raw === \"false\") return false;\n errors.push(\n showRawValue\n ? `${sourceLabel} must be true or false, got \"${raw}\"`\n : `${sourceLabel} must be true or false`\n );\n }\n return param.default ?? false;\n }\n\n if (isMultipleParam(param)) {\n const rawValues = Array.isArray(raw) ? raw : [];\n const resolved: (string | number)[] = [];\n for (const item of rawValues) {\n if (param.type === \"string\") {\n if (param.choices && !param.choices.includes(item)) {\n errors.push(\n showRawValue\n ? `${sourceLabel} must be one of: ${param.choices.join(\", \")} (got \"${item}\")`\n : `${sourceLabel} must be one of: ${param.choices.join(\", \")}`\n );\n continue;\n }\n resolved.push(item);\n continue;\n }\n const value = validateNumberValue(flag, param, item, errors, source, param.env);\n if (value !== undefined) resolved.push(value);\n }\n return resolved;\n }\n\n if (param.type === \"string\") {\n const value = isStringValue(raw) ? raw : param.default;\n if (value === undefined) {\n if (param.optional) return undefined;\n errors.push(`Missing required option --${flag}`);\n return undefined;\n }\n if (param.choices && !param.choices.includes(value)) {\n errors.push(\n showRawValue\n ? `${sourceLabel} must be one of: ${param.choices.join(\", \")} (got \"${value}\")`\n : `${sourceLabel} must be one of: ${param.choices.join(\", \")}`\n );\n }\n return value;\n }\n\n if (param.type === \"number\") {\n const rawValue = isStringValue(raw) ? raw : param.default;\n if (rawValue === undefined) {\n if (param.optional) return undefined;\n errors.push(`Missing required option --${flag}`);\n return undefined;\n }\n return validateNumberValue(flag, param, rawValue, errors, source, param.env);\n }\n\n const rawString = isStringValue(raw) ? raw : param.default;\n if (rawString === undefined) {\n if (param.optional) return undefined;\n errors.push(`Missing required option --${flag}`);\n return undefined;\n }\n const resolved = path.isAbsolute(rawString) ? rawString : path.join(cwd, rawString);\n if (param.mustExist) {\n if (!fs.existsSync(resolved)) {\n errors.push(\n showRawValue\n ? `${sourceLabel} path does not exist: ${resolved}`\n : `${sourceLabel} path does not exist`\n );\n return undefined;\n }\n if (param.kind) {\n const stats = fs.statSync(resolved);\n const matches = param.kind === \"directory\" ? stats.isDirectory() : stats.isFile();\n if (!matches) {\n errors.push(\n showRawValue\n ? `${sourceLabel} must be a ${param.kind}: ${resolved}`\n : `${sourceLabel} must be a ${param.kind}`\n );\n return undefined;\n }\n }\n }\n return resolved;\n}\n\nfunction validateNumberValue(\n flag: string,\n param: CliNumberParam,\n rawValue: string | number,\n errors: string[],\n source: \"argv\" | \"env\" | \"default\" = \"argv\",\n envName?: string\n): number | undefined {\n const value = isNumberValue(rawValue) ? rawValue : Number(rawValue);\n const displayValue = String(rawValue);\n const label = source === \"env\" ? `environment variable ${envName}` : `--${flag}`;\n const received = source === \"env\" ? \"\" : `, got \"${displayValue}\"`;\n if (!Number.isFinite(value)) {\n errors.push(`${label} must be a number${received}`);\n return undefined;\n }\n if (param.integer && !Number.isInteger(value)) {\n errors.push(`${label} must be an integer${received}`);\n return undefined;\n }\n if (param.min !== undefined && value < param.min) {\n errors.push(\n source === \"env\"\n ? `${label} must be >= ${param.min}`\n : `${label} must be >= ${param.min}, got ${value}`\n );\n return undefined;\n }\n if (param.max !== undefined && value > param.max) {\n errors.push(\n source === \"env\"\n ? `${label} must be <= ${param.max}`\n : `${label} must be <= ${param.max}, got ${value}`\n );\n return undefined;\n }\n return value;\n}\n\nexport function assertNoDuplicateFlags(schema: CliParamsSchema): void {\n const keyByFlag = new Map<string, string>();\n const keyByShort = new Map<string, string>();\n for (const [key, param] of Object.entries(schema)) {\n const flag = flagName(key, param);\n // \"no-resume\" is reserved alongside \"resume\" (see RESERVED_FLAG_NAMES): the tokenizer\n // exact-matches a registered flag before falling back to \"no-\" negation, so a schema\n // that claims \"no-resume\" for itself (derived or via an explicit `flag:` override)\n // would silently intercept it, breaking the --no-resume opt-out for every command.\n const isBuiltInKey = key === DRY_RUN_KEY || key === RESUME_KEY;\n if (!isBuiltInKey && RESERVED_FLAG_NAMES.has(flag)) {\n throw new Error(\n `--${flag} is a reserved flag provided automatically by every command; remove \"${key}\" from params or give it a different flag name.`\n );\n }\n const existingKey = keyByFlag.get(flag);\n if (existingKey) {\n throw new Error(`Duplicate --${flag} flag: both \"${existingKey}\" and \"${key}\" resolve to it`);\n }\n keyByFlag.set(flag, key);\n\n if (param.short === undefined) continue;\n if (!/^[A-Za-z]$/.test(param.short) || param.short === \"h\") {\n throw new Error(\n `\"${key}\" has invalid short alias \"${param.short}\"; aliases must be one letter other than \"h\".`\n );\n }\n const existingShortKey = keyByShort.get(param.short);\n if (existingShortKey) {\n throw new Error(\n `Duplicate -${param.short} alias: both \"${existingShortKey}\" and \"${key}\" resolve to it`\n );\n }\n keyByShort.set(param.short, key);\n }\n}\n\n/**\n * `default` or `optional` on a `multiple` param would be silently ignored at runtime:\n * `resolveParam`'s `multiple` branch always resolves absent to `[]`, never consulting\n * `param.default`, and `CliParamIsOptional` always resolves `multiple` params as\n * non-optional regardless of `param.optional`. Unlike `default`+`optional` on a scalar\n * param (a harmless, merely-wider type — see the doc comment above\n * `CliParamIsOptional`), these are dead, misleading configuration on a `multiple` param,\n * so they're rejected the same way duplicate/reserved flags are.\n */\nexport function assertValidMultipleParams(schema: CliParamsSchema): void {\n for (const [key, param] of Object.entries(schema)) {\n if (!isMultipleParam(param)) {\n continue;\n }\n if (param.default !== undefined) {\n throw new Error(\n `\"${key}\" combines multiple: true with a default; multiple params always resolve to [] when absent and cannot declare a default.`\n );\n }\n if (param.optional) {\n throw new Error(\n `\"${key}\" combines multiple: true with optional; multiple params always resolve to [] when absent and are never undefined.`\n );\n }\n }\n}\n\nexport function assertValidPositionals(\n positionals: readonly string[],\n schema: CliParamsSchema\n): void {\n const seen = new Set<string>();\n let sawOptional = false;\n for (let index = 0; index < positionals.length; index++) {\n const key = positionals[index]!;\n const param = schema[key];\n if (!param) {\n throw new Error(`Unknown positional parameter \"${key}\"; it must be declared in params.`);\n }\n if (seen.has(key)) {\n throw new Error(`Duplicate positional parameter \"${key}\".`);\n }\n seen.add(key);\n if (param.type === \"boolean\") {\n throw new Error(`\"${key}\" is boolean and cannot be used as a positional parameter.`);\n }\n if (isMultipleParam(param) && index !== positionals.length - 1) {\n throw new Error(`Repeatable positional parameter \"${key}\" must be last.`);\n }\n const optional = param.optional || param.default !== undefined || isMultipleParam(param);\n if (sawOptional && !optional) {\n throw new Error(\n `Required positional parameter \"${key}\" cannot follow an optional positional parameter.`\n );\n }\n sawOptional ||= optional;\n }\n}\n\nexport function assertValidEnvironmentFallbacks(schema: CliParamsSchema): void {\n for (const [key, param] of Object.entries(schema)) {\n if (param.env === undefined) continue;\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(param.env)) {\n throw new Error(`\"${key}\" has invalid environment variable name \"${param.env}\".`);\n }\n if (isMultipleParam(param)) {\n throw new Error(\n `\"${key}\" combines multiple: true with env; repeatable environment values are ambiguous, so pass repeated flags instead.`\n );\n }\n }\n}\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CliBooleanParam, CliCheckpointConfig, CliCommandDescriptor, CliContext, CliParams, CliParamsSchema, CliStringParam } from "./cli-types.js";
|
|
2
|
-
import { type Pipeline, type PipelineHooks, type PipelineMermaidOptions, type PipelinePlan, type PipelineRunControls
|
|
3
|
-
import { type PipelineReporterConfig } from "
|
|
2
|
+
import { type Pipeline, type PipelineHooks, type PipelineMermaidOptions, type PipelinePlan, type PipelineRunControls } from "../core/pipeline.js";
|
|
3
|
+
import { type PipelineReporterConfig } from "../reporter/reporter-entry.js";
|
|
4
4
|
export type PipelineCliBuiltins = {
|
|
5
5
|
stepIds: CliStringParam & {
|
|
6
6
|
multiple: true;
|
|
@@ -52,7 +52,7 @@ export interface PipelineCommandHookContext<TSchema extends CliParamsSchema> {
|
|
|
52
52
|
}
|
|
53
53
|
export type PipelineCommandHookSets<TResult> = PipelineHooks<TResult> | readonly PipelineHooks<TResult>[];
|
|
54
54
|
export type PipelineCommandHookConfig<TResult, TSchema extends CliParamsSchema> = PipelineCommandHookSets<TResult> | ((input: PipelineCommandHookContext<TSchema>) => PipelineCommandHookSets<TResult> | undefined);
|
|
55
|
-
type PipelineCommandMapOptions<TOptions extends object, TSchema extends CliParamsSchema> = (values: PipelineCliValues<TSchema>, context: CliContext) =>
|
|
55
|
+
type PipelineCommandMapOptions<TOptions extends object, TSchema extends CliParamsSchema> = (values: PipelineCliValues<TSchema>, context: CliContext) => TOptions | Promise<TOptions>;
|
|
56
56
|
type DefaultPipelineCommandOptions<TSchema extends CliParamsSchema> = Omit<PipelineCliValues<TSchema>, "continueOnError" | "dryRun" | "resume" | "stepIds" | "targets">;
|
|
57
57
|
type CanDefaultPipelineCommandOptions<TOptions extends object, TSchema extends CliParamsSchema> = DefaultPipelineCommandOptions<TSchema> extends TOptions ? Exclude<keyof TSchema, keyof TOptions> extends never ? true : false : false;
|
|
58
58
|
interface DefinePipelineCommandConfigBase<TResult, TSchema extends CliParamsSchema> {
|
|
@@ -83,4 +83,3 @@ export type DefinePipelineCommandConfig<TOptions extends object, TResult, TSchem
|
|
|
83
83
|
/** Turn a typed pipeline into a command with selection, plan, and reporting defaults. */
|
|
84
84
|
export declare function definePipelineCommand<TOptions extends object, TResult, const TSchema extends CliParamsSchema = {}>(pipeline: Pipeline<TOptions, TResult>, config: DefinePipelineCommandConfig<NoInfer<TOptions>, TResult, TSchema>): PipelineCommand<TSchema, TResult>;
|
|
85
85
|
export {};
|
|
86
|
-
//# sourceMappingURL=cli-pipeline-command.d.ts.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createCommand } from "./cli-command.js";
|
|
2
2
|
import { flagName } from "./cli-parser.js";
|
|
3
3
|
import { markPipelineCommand } from "./pipeline-command-marker.js";
|
|
4
|
-
import {} from "
|
|
5
|
-
import { createPipelineReporter } from "
|
|
6
|
-
import { TUBELESS_WORKBENCH_EXIT_CODE } from "./
|
|
4
|
+
import {} from "../core/pipeline.js";
|
|
5
|
+
import { createPipelineReporter } from "../reporter/reporter-entry.js";
|
|
6
|
+
import { TUBELESS_WORKBENCH_EXIT_CODE } from "./cli-exit.js";
|
|
7
7
|
const PIPELINE_COMMAND_KEYS = new Set(["continueOnError", "stepIds", "targets"]);
|
|
8
8
|
const PIPELINE_COMMAND_FLAGS = new Set(["continue-on-error", "step", "target"]);
|
|
9
9
|
function assertNoPipelineCommandConflicts(params) {
|
|
@@ -51,7 +51,7 @@ function isHookConfigFunction(config) {
|
|
|
51
51
|
return typeof config === "function";
|
|
52
52
|
}
|
|
53
53
|
function defaultPipelineCommandOptions(values) {
|
|
54
|
-
const { continueOnError, dryRun, resume, stepIds, targets, ...domainValues } = values;
|
|
54
|
+
const { continueOnError: _continueOnError, dryRun: _dryRun, resume: _resume, stepIds: _stepIds, targets: _targets, ...domainValues } = values;
|
|
55
55
|
return domainValues;
|
|
56
56
|
}
|
|
57
57
|
/** Turn a typed pipeline into a command with selection, plan, and reporting defaults. */
|
|
@@ -136,10 +136,7 @@ export function definePipelineCommand(pipeline, config) {
|
|
|
136
136
|
...(reporter ? [reporter.hooks] : []),
|
|
137
137
|
...normalizePipelineHookSets(configuredHooks),
|
|
138
138
|
];
|
|
139
|
-
|
|
140
|
-
// merged object satisfies `PipelineRunOptions<TOptions>`.
|
|
141
|
-
const options = { ...mapped, ...controls };
|
|
142
|
-
result = await pipeline.runOrThrow(options, {
|
|
139
|
+
result = await pipeline.runOrThrow(mapped, controls, {
|
|
143
140
|
...cliContext.pipelineContext,
|
|
144
141
|
cwd: runtimeContext.cwd,
|
|
145
142
|
log: runtimeContext.log,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-pipeline-command.js","sourceRoot":"","sources":["../../src/cli/cli-pipeline-command.ts"],"names":[],"mappings":"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","sourcesContent":["import { createCommand } from \"./cli-command.js\";\nimport { flagName } from \"./cli-parser.js\";\nimport type {\n CliBooleanParam,\n CliCheckpointConfig,\n CliCommandConfig,\n CliCommandDescriptor,\n CliContext,\n CliParams,\n CliParamsSchema,\n CliStringParam,\n} from \"./cli-types.js\";\nimport { markPipelineCommand } from \"./pipeline-command-marker.js\";\nimport {\n type Pipeline,\n type PipelineHooks,\n type PipelineMermaidOptions,\n type PipelinePlan,\n type PipelineRunControls,\n} from \"../core/pipeline.js\";\nimport { createPipelineReporter, type PipelineReporterConfig } from \"../reporter/reporter-entry.js\";\nimport { TUBELESS_WORKBENCH_EXIT_CODE } from \"./cli-exit.js\";\n\nexport type PipelineCliBuiltins = {\n stepIds: CliStringParam & { multiple: true };\n targets: CliStringParam & { multiple: true };\n continueOnError: CliBooleanParam;\n};\n\nexport type PipelineCliValues<TSchema extends CliParamsSchema> = CliParams<TSchema> & {\n stepIds: readonly string[];\n targets: readonly string[];\n continueOnError: boolean;\n};\n\nexport type PipelineCliParseResult<TSchema extends CliParamsSchema> =\n | { kind: \"values\"; values: PipelineCliValues<TSchema> }\n | { kind: \"help\"; helpText: string }\n | { kind: \"error\"; errors: readonly string[]; helpText: string };\n\nexport interface PipelineCommand<TSchema extends CliParamsSchema, TResult> {\n readonly descriptor: CliCommandDescriptor;\n /** Stable identity of the wrapped pipeline. */\n readonly id: string;\n /** Stable definition-order step ids for discovery surfaces such as CLI help. */\n readonly stepIds: readonly string[];\n /** Stable declared goal ids that support dependency-aware target execution. */\n readonly targetIds: readonly string[];\n /** Plan without parsing or requiring domain parameters. */\n plan(controls?: PipelineRunControls): PipelinePlan;\n /** Generate a static Mermaid flowchart without running or planning the pipeline. */\n toMermaid(options?: PipelineMermaidOptions): string;\n parse(argv?: readonly string[], context?: Partial<CliContext>): PipelineCliParseResult<TSchema>;\n /** Validate structured form values without tokenizing argv. */\n parseValues(\n values: Record<string, unknown>,\n context?: Partial<CliContext>\n ): PipelineCliParseResult<TSchema>;\n /** Execute already validated form values. */\n execute(values: PipelineCliValues<TSchema>, context?: Partial<CliContext>): Promise<TResult>;\n run(argv?: readonly string[], context?: Partial<CliContext>): Promise<TResult>;\n main(argv?: readonly string[], context?: Partial<CliContext>): Promise<void>;\n}\n\nexport interface PipelineCommandHookContext<TSchema extends CliParamsSchema> {\n context: CliContext;\n values: PipelineCliValues<TSchema>;\n}\n\nexport type PipelineCommandHookSets<TResult> =\n | PipelineHooks<TResult>\n | readonly PipelineHooks<TResult>[];\n\nexport type PipelineCommandHookConfig<TResult, TSchema extends CliParamsSchema> =\n | PipelineCommandHookSets<TResult>\n | ((input: PipelineCommandHookContext<TSchema>) => PipelineCommandHookSets<TResult> | undefined);\n\ntype PipelineCommandMapOptions<TOptions extends object, TSchema extends CliParamsSchema> = (\n values: PipelineCliValues<TSchema>,\n context: CliContext\n) => TOptions | Promise<TOptions>;\n\ntype DefaultPipelineCommandOptions<TSchema extends CliParamsSchema> = Omit<\n PipelineCliValues<TSchema>,\n \"continueOnError\" | \"dryRun\" | \"resume\" | \"stepIds\" | \"targets\"\n>;\n\ntype CanDefaultPipelineCommandOptions<TOptions extends object, TSchema extends CliParamsSchema> =\n DefaultPipelineCommandOptions<TSchema> extends TOptions\n ? Exclude<keyof TSchema, keyof TOptions> extends never\n ? true\n : false\n : false;\n\ninterface DefinePipelineCommandConfigBase<TResult, TSchema extends CliParamsSchema> {\n /** Defaults to pipeline.id. */\n name?: string;\n description?: string;\n /** Extra flags beyond the command and pipeline built-ins. */\n params?: TSchema;\n /** Extra parameter keys accepted in positional order. */\n positionals?: readonly (keyof TSchema & string)[];\n checkpoint?: CliCheckpointConfig;\n /** Additional lifecycle hooks, or a factory resolved from parsed values and CLI context. */\n hooks?: PipelineCommandHookConfig<TResult, TSchema>;\n /** Configure plain/interactive reporting, or disable it. Defaults to automatic mode. */\n reporter?: false | PipelineReporterConfig;\n /** Print domain-specific result lines after a successful run. */\n summarize?(\n result: TResult,\n values: PipelineCliValues<TSchema>,\n context: CliContext\n ): readonly string[] | void;\n validate?(values: PipelineCliValues<TSchema>, context: CliContext): string[] | void;\n}\n\n/** Configuration for a typed pipeline command. Mapping is optional only for compatible flags. */\nexport type DefinePipelineCommandConfig<\n TOptions extends object,\n TResult,\n TSchema extends CliParamsSchema,\n> = DefinePipelineCommandConfigBase<TResult, TSchema> &\n (CanDefaultPipelineCommandOptions<TOptions, TSchema> extends true\n ? {\n /** Override the default same-name flag-to-option mapping. */\n mapOptions?: PipelineCommandMapOptions<TOptions, TSchema>;\n }\n : {\n /** Required when parsed flags do not already satisfy the pipeline's domain options. */\n mapOptions: PipelineCommandMapOptions<TOptions, TSchema>;\n });\n\nconst PIPELINE_COMMAND_KEYS = new Set([\"continueOnError\", \"stepIds\", \"targets\"]);\nconst PIPELINE_COMMAND_FLAGS = new Set([\"continue-on-error\", \"step\", \"target\"]);\n\nfunction assertNoPipelineCommandConflicts(params: CliParamsSchema): void {\n for (const [key, param] of Object.entries(params)) {\n if (PIPELINE_COMMAND_KEYS.has(key)) {\n throw new Error(\n `\"${key}\" is a reserved parameter provided automatically by pipeline commands; remove it from params.`\n );\n }\n const flag = flagName(key, param);\n if (PIPELINE_COMMAND_FLAGS.has(flag)) {\n throw new Error(\n `--${flag} is a reserved flag provided automatically by pipeline commands; remove \"${key}\" from params or give it a different flag name.`\n );\n }\n }\n}\n\nfunction normalizePipelineCliValues<TSchema extends CliParamsSchema>(\n values: CliParams<PipelineCliBuiltins & TSchema>\n): PipelineCliValues<TSchema> {\n // SAFETY: `PipelineCliValues<TSchema>` is `CliParams<TSchema>` plus the builtin\n // `stepIds`/`targets`/`continueOnError` keys, all of which `CliParams<PipelineCliBuiltins & TSchema>`\n // already provides, so the runtime shape matches the target type.\n const pipelineValues = values as PipelineCliValues<TSchema>;\n const { continueOnError, stepIds, targets } = pipelineValues;\n return {\n ...pipelineValues,\n continueOnError,\n stepIds,\n targets: targets ?? [],\n };\n}\n\nfunction pipelineRunControlsFromCliValues(values: {\n continueOnError: boolean;\n dryRun: boolean;\n stepIds: readonly string[];\n targets: readonly string[];\n}): PipelineRunControls {\n const controls: PipelineRunControls = {\n dryRun: values.dryRun,\n continueOnError: values.continueOnError,\n };\n if (values.stepIds.length > 0) controls.stepIds = values.stepIds;\n if (values.targets.length > 0) controls.targets = values.targets;\n return controls;\n}\n\nfunction normalizePipelineHookSets<TResult>(\n hooks: PipelineCommandHookSets<TResult> | undefined\n): PipelineHooks<TResult>[] {\n if (!hooks) return [];\n // SAFETY: a non-array `PipelineCommandHookSets` is always a single `PipelineHooks`.\n return Array.isArray(hooks) ? [...hooks] : [hooks as PipelineHooks<TResult>];\n}\n\nfunction isHookConfigFunction<TResult, TSchema extends CliParamsSchema>(\n config: PipelineCommandHookConfig<TResult, TSchema> | undefined\n): config is (\n input: PipelineCommandHookContext<TSchema>\n) => PipelineCommandHookSets<TResult> | undefined {\n return typeof config === \"function\";\n}\n\nfunction defaultPipelineCommandOptions<TSchema extends CliParamsSchema>(\n values: PipelineCliValues<TSchema>\n): DefaultPipelineCommandOptions<TSchema> {\n const {\n continueOnError: _continueOnError,\n dryRun: _dryRun,\n resume: _resume,\n stepIds: _stepIds,\n targets: _targets,\n ...domainValues\n } = values;\n return domainValues;\n}\n\n/** Turn a typed pipeline into a command with selection, plan, and reporting defaults. */\nexport function definePipelineCommand<\n TOptions extends object,\n TResult,\n const TSchema extends CliParamsSchema = {},\n>(\n pipeline: Pipeline<TOptions, TResult>,\n config: DefinePipelineCommandConfig<NoInfer<TOptions>, TResult, TSchema>\n): PipelineCommand<TSchema, TResult> {\n // SAFETY: `config.params` is declared as `TSchema`; the empty-object fallback is only\n // reached when the caller omits `params`, which is exactly the `{}` schema case.\n const userParams = config.params ?? ({} as TSchema);\n assertNoPipelineCommandConflicts(userParams);\n\n const targetFlagEnabled = pipeline.targetIds.length > 0;\n const bridgeParams: CliParamsSchema = {\n stepIds: {\n type: \"string\",\n multiple: true,\n flag: \"step\",\n group: \"execution\",\n exclusive: true,\n choices: pipeline.stepIds,\n description: `Run exactly this step. Steps: ${pipeline.stepIds.join(\", \")}`,\n },\n continueOnError: {\n type: \"boolean\",\n group: \"execution\",\n description: \"Continue independent work after a step fails.\",\n },\n };\n if (targetFlagEnabled) {\n bridgeParams.targets = {\n type: \"string\",\n multiple: true,\n flag: \"target\",\n group: \"execution\",\n exclusive: true,\n choices: pipeline.targetIds,\n description: `Run this declared target and its prerequisites. Targets: ${pipeline.targetIds.join(\", \")}`,\n };\n }\n\n // SAFETY: `bridgeParams` supplies the `PipelineCliBuiltins` keys and `userParams` is\n // `TSchema`, so the merged object satisfies `PipelineCliBuiltins & TSchema`.\n const params = { ...bridgeParams, ...userParams } as PipelineCliBuiltins & TSchema;\n\n const commandConfig = {\n name: config.name ?? pipeline.id,\n description: config.description,\n params,\n positionals: config.positionals,\n checkpoint: config.checkpoint,\n validate: (values, context) => {\n const pipelineValues = normalizePipelineCliValues<TSchema>(values);\n const errors = config.validate?.(pipelineValues, context) ?? [];\n if (pipelineValues.stepIds.length > 0 && pipelineValues.targets.length > 0) {\n return [\"--step and --target cannot be used together.\", ...errors];\n }\n return errors.length > 0 ? errors : undefined;\n },\n run: async (values, cliContext) => {\n const pipelineValues = normalizePipelineCliValues<TSchema>(values);\n let mapped: TOptions;\n if (config.mapOptions) {\n mapped = await config.mapOptions(pipelineValues, cliContext);\n } else {\n // SAFETY: `defaultPipelineCommandOptions` returns exactly the domain options the\n // `CanDefaultPipelineCommandOptions` constraint guarantees map to `TOptions`.\n mapped = defaultPipelineCommandOptions(pipelineValues) as TOptions;\n }\n const controls = pipelineRunControlsFromCliValues({\n dryRun: values.dryRun,\n continueOnError: pipelineValues.continueOnError,\n stepIds: pipelineValues.stepIds,\n targets: targetFlagEnabled ? pipelineValues.targets : [],\n });\n\n const reporter =\n config.reporter === false\n ? undefined\n : createPipelineReporter<TResult>({ log: cliContext.log, ...(config.reporter ?? {}) });\n const runtimeContext = reporter ? { ...cliContext, log: reporter.log } : cliContext;\n let result: TResult;\n try {\n const configuredHooks = isHookConfigFunction(config.hooks)\n ? config.hooks({ context: runtimeContext, values: pipelineValues })\n : config.hooks;\n const hooks: PipelineHooks<TResult>[] = [\n ...normalizePipelineHookSets(cliContext.pipelineContext?.hooks),\n ...(reporter ? [reporter.hooks] : []),\n ...normalizePipelineHookSets(configuredHooks),\n ];\n\n result = await pipeline.runOrThrow(mapped, controls, {\n ...cliContext.pipelineContext,\n cwd: runtimeContext.cwd,\n log: runtimeContext.log,\n hooks: hooks.length > 0 ? hooks : undefined,\n signal: runtimeContext.signal,\n });\n } finally {\n reporter?.dispose();\n }\n for (const line of config.summarize?.(result, pipelineValues, cliContext) ?? []) {\n cliContext.log.log(line);\n }\n return result;\n },\n } satisfies CliCommandConfig<PipelineCliBuiltins & TSchema, TResult>;\n\n const command = createCommand(commandConfig, undefined, {\n validation: TUBELESS_WORKBENCH_EXIT_CODE.validation,\n });\n\n function parse(\n argv: readonly string[] = process.argv.slice(2),\n contextOverrides?: Partial<CliContext>\n ): PipelineCliParseResult<TSchema> {\n const result = command.parse(argv, contextOverrides);\n return result.kind === \"values\"\n ? { kind: \"values\", values: normalizePipelineCliValues<TSchema>(result.values) }\n : result;\n }\n\n function plan(controls: PipelineRunControls = {}): PipelinePlan {\n return pipeline.plan(controls);\n }\n\n function parseValues(\n values: Record<string, unknown>,\n contextOverrides?: Partial<CliContext>\n ): PipelineCliParseResult<TSchema> {\n const result = command.parseValues(values, contextOverrides);\n return result.kind === \"values\"\n ? { kind: \"values\", values: normalizePipelineCliValues<TSchema>(result.values) }\n : result;\n }\n\n return markPipelineCommand({\n descriptor: command.descriptor,\n id: pipeline.id,\n stepIds: pipeline.stepIds,\n targetIds: pipeline.targetIds,\n execute: (values, contextOverrides) =>\n // SAFETY: `execute` receives `PipelineCliValues<TSchema>` from the public interface,\n // which is a subtype of `CliParams<PipelineCliBuiltins & TSchema>`.\n command.execute(values as CliParams<PipelineCliBuiltins & TSchema>, contextOverrides),\n parse,\n parseValues,\n plan,\n toMermaid: (options) => pipeline.toMermaid(options),\n run: command.run,\n main: command.main,\n });\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { CheckpointStore } from "
|
|
2
|
-
import type { PipelineContext, PipelineLogger } from "
|
|
1
|
+
import type { CheckpointStore } from "../node/checkpoint.js";
|
|
2
|
+
import type { PipelineContext, PipelineLogger } from "../core/pipeline.js";
|
|
3
3
|
/**
|
|
4
4
|
* Typed command-line entry points for scripts, mirroring how `definePipeline` turns a
|
|
5
5
|
* declarative step list into a runnable pipeline: declare a flag schema once and get a
|
|
@@ -223,4 +223,3 @@ export interface CliCommand<TSchema extends CliParamsSchema, TResult> {
|
|
|
223
223
|
main(argv?: readonly string[], context?: Partial<CliContext>): Promise<void>;
|
|
224
224
|
}
|
|
225
225
|
export {};
|
|
226
|
-
//# sourceMappingURL=cli-types.d.ts.map
|