tubeless 0.2.8 → 0.2.10
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 +21 -21
- package/dist/cli/cli-command.d.ts +1 -0
- package/dist/cli/cli-command.js +10 -3
- package/dist/cli/cli-command.js.map +1 -1
- package/dist/cli/cli-parser.d.ts +1 -1
- package/dist/cli/cli-parser.js +27 -21
- package/dist/cli/cli-parser.js.map +1 -1
- package/dist/cli/cli-pipeline-command.d.ts +36 -13
- package/dist/cli/cli-pipeline-command.js +44 -16
- package/dist/cli/cli-pipeline-command.js.map +1 -1
- package/dist/cli/cli-schema.d.ts +25 -0
- package/dist/cli/cli-schema.js +129 -0
- package/dist/cli/cli-schema.js.map +1 -0
- package/dist/cli/cli-types.d.ts +27 -4
- package/dist/cli/cli-types.js +2 -0
- package/dist/cli/cli-types.js.map +1 -1
- package/dist/cli/cli.d.ts +2 -2
- package/dist/cli/cli.js.map +1 -1
- package/dist/core/child-execution.d.ts +8 -10
- package/dist/core/child-execution.js +61 -255
- package/dist/core/child-execution.js.map +1 -1
- package/dist/core/child-progress.d.ts +15 -5
- package/dist/core/child-progress.js +252 -9
- package/dist/core/child-progress.js.map +1 -1
- package/dist/core/mapped-child-progress.d.ts +4 -20
- package/dist/core/mapped-child-progress.js +2 -34
- package/dist/core/mapped-child-progress.js.map +1 -1
- package/dist/core/pipeline-compiler.d.ts +3 -2
- package/dist/core/pipeline-compiler.js +22 -5
- package/dist/core/pipeline-compiler.js.map +1 -1
- package/dist/core/pipeline-definition-identity.d.ts +14 -0
- package/dist/core/pipeline-definition-identity.js +141 -0
- package/dist/core/pipeline-definition-identity.js.map +1 -0
- package/dist/core/pipeline-definition-validation.js +21 -5
- package/dist/core/pipeline-definition-validation.js.map +1 -1
- package/dist/core/pipeline-definition.d.ts +30 -4
- package/dist/core/pipeline-definition.js.map +1 -1
- package/dist/core/pipeline-execute.d.ts +1 -2
- package/dist/core/pipeline-execute.js +80 -73
- package/dist/core/pipeline-execute.js.map +1 -1
- package/dist/core/pipeline-finalizer.d.ts +1 -1
- package/dist/core/pipeline-finalizer.js +1 -1
- package/dist/core/pipeline-finalizer.js.map +1 -1
- package/dist/core/pipeline-ids.js +1 -6
- package/dist/core/pipeline-ids.js.map +1 -1
- package/dist/core/pipeline-plan.js +2 -0
- package/dist/core/pipeline-plan.js.map +1 -1
- package/dist/core/pipeline-run-state.js +25 -10
- package/dist/core/pipeline-run-state.js.map +1 -1
- package/dist/core/pipeline-scheduler.d.ts +10 -0
- package/dist/core/pipeline-scheduler.js +54 -0
- package/dist/core/pipeline-scheduler.js.map +1 -0
- package/dist/core/pipeline-steps.d.ts +53 -39
- package/dist/core/pipeline-steps.js +5 -9
- package/dist/core/pipeline-steps.js.map +1 -1
- package/dist/core/pipeline-types.d.ts +94 -19
- package/dist/core/pipeline-types.js.map +1 -1
- package/dist/core/pipeline.d.ts +17 -6
- package/dist/core/pipeline.js +16 -3
- package/dist/core/pipeline.js.map +1 -1
- package/dist/node/checkpoint.d.ts +2 -0
- package/dist/node/checkpoint.js +1 -0
- package/dist/node/checkpoint.js.map +1 -1
- package/dist/node/env.d.ts +1 -0
- package/dist/node/env.js +1 -0
- package/dist/node/env.js.map +1 -1
- package/dist/node/file-utils.d.ts +3 -0
- package/dist/node/file-utils.js +3 -0
- package/dist/node/file-utils.js.map +1 -1
- package/dist/node/node.d.ts +2 -0
- package/dist/node/node.js +1 -0
- package/dist/node/node.js.map +1 -1
- package/dist/node/paths.d.ts +2 -1
- package/dist/node/paths.js +2 -1
- package/dist/node/paths.js.map +1 -1
- package/dist/node/worker-thread-adapter.d.ts +19 -0
- package/dist/node/worker-thread-adapter.js +194 -0
- package/dist/node/worker-thread-adapter.js.map +1 -0
- package/dist/node/worker-thread-protocol.d.ts +57 -0
- package/dist/node/worker-thread-protocol.js +26 -0
- package/dist/node/worker-thread-protocol.js.map +1 -0
- package/dist/node/worker-thread-runtime.d.ts +1 -0
- package/dist/node/worker-thread-runtime.js +53 -0
- package/dist/node/worker-thread-runtime.js.map +1 -0
- package/dist/project/pipeline-project.d.ts +40 -0
- package/dist/project/pipeline-project.js +83 -0
- package/dist/project/pipeline-project.js.map +1 -0
- package/dist/project/project-compiler.d.ts +15 -6
- package/dist/project/project-compiler.js +42 -4
- package/dist/project/project-compiler.js.map +1 -1
- package/dist/project/project-document.d.ts +6 -4
- package/dist/project/project-document.js +4 -0
- package/dist/project/project-document.js.map +1 -1
- package/dist/project/project.d.ts +3 -3
- package/dist/project/project.js +1 -2
- package/dist/project/project.js.map +1 -1
- package/dist/render/render.d.ts +3 -7
- package/dist/render/render.js +5 -2
- package/dist/render/render.js.map +1 -1
- package/dist/reporter/interactive-reporter.d.ts +5 -0
- package/dist/reporter/interactive-reporter.js +39 -32
- package/dist/reporter/interactive-reporter.js.map +1 -1
- package/dist/reporter/live-ticker-worker.js +17 -14
- package/dist/reporter/live-ticker-worker.js.map +1 -1
- package/dist/reporter/live-ticker.d.ts +6 -6
- package/dist/reporter/live-ticker.js +117 -44
- package/dist/reporter/live-ticker.js.map +1 -1
- package/dist/reporter/reporter.d.ts +5 -0
- package/dist/reporter/reporter.js +27 -17
- package/dist/reporter/reporter.js.map +1 -1
- package/dist/reporter/terminal-text.d.ts +2 -0
- package/dist/reporter/terminal-text.js +20 -0
- package/dist/reporter/terminal-text.js.map +1 -0
- package/dist/run-store/definition-diff.d.ts +9 -0
- package/dist/run-store/definition-diff.js +39 -0
- package/dist/run-store/definition-diff.js.map +1 -0
- package/dist/run-store/run-store-codec.d.ts +2 -2
- package/dist/run-store/run-store-codec.js +14 -14
- package/dist/run-store/run-store-codec.js.map +1 -1
- package/dist/run-store/run-store-event-decoder.d.ts +3 -0
- package/dist/run-store/run-store-event-decoder.js +18 -0
- package/dist/run-store/run-store-event-decoder.js.map +1 -0
- package/dist/run-store/run-store-ndjson.js +2 -2
- package/dist/run-store/run-store-ndjson.js.map +1 -1
- package/dist/run-store/run-store-sqlite.js +3 -3
- package/dist/run-store/run-store-sqlite.js.map +1 -1
- package/dist/run-store/run-store.d.ts +4 -1
- package/dist/run-store/run-store.js +23 -9
- package/dist/run-store/run-store.js.map +1 -1
- package/dist/studio/run-store-ui-client-browser.js +2 -2
- package/dist/studio/run-store-ui-client-transport.d.ts +7 -1
- package/dist/studio/run-store-ui-client-transport.js +9 -6
- package/dist/studio/run-store-ui-client-transport.js.map +1 -1
- package/dist/studio/run-store-ui-client.d.ts +68 -1
- package/dist/studio/run-store-ui-client.js +764 -3
- package/dist/studio/run-store-ui-client.js.map +1 -1
- package/dist/studio/run-store-ui-data-controller.d.ts +24 -0
- package/dist/studio/run-store-ui-data-controller.js +238 -0
- package/dist/studio/run-store-ui-data-controller.js.map +1 -0
- package/dist/studio/run-store-ui-definitions.d.ts +6 -0
- package/dist/studio/run-store-ui-definitions.js +29 -0
- package/dist/studio/run-store-ui-definitions.js.map +1 -0
- package/dist/studio/run-store-ui-page.d.ts +1 -1
- package/dist/studio/run-store-ui-page.js +6 -1
- package/dist/studio/run-store-ui-page.js.map +1 -1
- package/dist/studio/run-store-ui.js +1 -1
- package/dist/studio/run-store-ui.js.map +1 -1
- package/dist/testing/testing.d.ts +2 -0
- package/dist/testing/testing.js.map +1 -1
- package/dist/tracing/tracing-internal.js +18 -3
- package/dist/tracing/tracing-internal.js.map +1 -1
- package/dist/tracing/tracing-schema.d.ts +167 -12
- package/dist/tracing/tracing-schema.js +60 -2
- package/dist/tracing/tracing-schema.js.map +1 -1
- package/dist/utilities/batch.d.ts +22 -10
- package/dist/utilities/batch.js +21 -14
- package/dist/utilities/batch.js.map +1 -1
- package/dist/utilities/pipeline-command-marker.d.ts +4 -0
- package/dist/utilities/pipeline-command-marker.js +16 -0
- package/dist/utilities/pipeline-command-marker.js.map +1 -0
- package/dist/utilities/rate-limit.d.ts +1 -0
- package/dist/utilities/rate-limit.js +1 -0
- package/dist/utilities/rate-limit.js.map +1 -1
- package/dist/utilities/retry.d.ts +3 -1
- package/dist/utilities/retry.js +1 -0
- package/dist/utilities/retry.js.map +1 -1
- package/dist/workbench/pipeline-module.d.ts +4 -6
- package/dist/workbench/pipeline-module.js +5 -10
- package/dist/workbench/pipeline-module.js.map +1 -1
- package/dist/workbench/workbench-commands.d.ts +6 -0
- package/dist/workbench/workbench-commands.js +288 -0
- package/dist/workbench/workbench-commands.js.map +1 -0
- package/dist/workbench/workbench-history.js +1 -1
- package/dist/workbench/workbench-history.js.map +1 -1
- package/dist/workbench/workbench-launch-session.d.ts +25 -0
- package/dist/workbench/workbench-launch-session.js +91 -0
- package/dist/workbench/workbench-launch-session.js.map +1 -0
- package/dist/workbench/workbench-project-loader.d.ts +28 -26
- package/dist/workbench/workbench-project-loader.js +112 -86
- package/dist/workbench/workbench-project-loader.js.map +1 -1
- package/dist/workbench/workbench-run.js +11 -7
- package/dist/workbench/workbench-run.js.map +1 -1
- package/dist/workbench/workbench-shared.d.ts +2 -5
- package/dist/workbench/workbench-shared.js +3 -5
- package/dist/workbench/workbench-shared.js.map +1 -1
- package/dist/workbench/workbench-ui.js +46 -146
- package/dist/workbench/workbench-ui.js.map +1 -1
- package/dist/workbench/workbench.d.ts +1 -1
- package/dist/workbench/workbench.js +4 -8
- package/dist/workbench/workbench.js.map +1 -1
- package/docs/README.md +12 -11
- package/docs/agent-guide.md +144 -38
- package/docs/agent-skills.md +1 -1
- package/docs/api-reference.md +160 -145
- package/docs/api-report.json +26 -31
- package/docs/assets/social.svg +192 -56
- package/docs/child-pipeline-composition.md +45 -23
- package/docs/cli.md +257 -80
- package/docs/comparison.md +21 -29
- package/docs/concepts.md +148 -26
- package/docs/declarative-pipelines.md +85 -34
- package/docs/getting-started.md +100 -19
- package/docs/llms.txt +10 -5
- package/docs/pipeline-document.schema.json +5 -0
- package/docs/recipes.md +91 -38
- package/docs/remote-step-composition.md +84 -3
- package/docs/studio.md +120 -34
- package/examples/automatic-cli.ts +12 -0
- package/examples/best-effort.ts +1 -1
- package/examples/child-pipeline.ts +1 -9
- package/examples/cli-job.ts +2 -14
- package/examples/conditional-step.ts +2 -6
- package/examples/declarative/handlers.ts +2 -2
- package/examples/declarative/peloton-handlers.ts +2 -2
- package/examples/declarative/peloton.yaml +2 -0
- package/examples/declarative/pipelines.yaml +8 -0
- package/examples/live-tui.ts +4 -1
- package/examples/minimal-pipeline.ts +27 -0
- package/examples/parallel-dag.ts +46 -0
- package/examples/prime-worker.ts +22 -0
- package/examples/{catalog → project}/pipelines/enrich.ts +2 -2
- package/examples/{catalog → project}/scripts/enrich.ts +1 -0
- package/examples/{catalog → project}/scripts/import.ts +1 -0
- package/examples/{catalog → project}/scripts/publish.ts +1 -0
- package/examples/project/tubeless.project.ts +33 -0
- package/examples/tracing.ts +3 -0
- package/examples/tubeless.project.ts +10 -0
- package/examples/typed-import.ts +0 -10
- package/examples/validated-boundaries.ts +10 -12
- package/examples/worker-threads.ts +50 -0
- package/examples/yaml-peloton.ts +2 -5
- package/examples/yaml-pipelines.ts +5 -5
- package/package.json +8 -10
- package/skills/tubeless/SKILL.md +92 -18
- package/skills/tubeless-make-pipeline/SKILL.md +1 -1
- package/dist/cli/pipeline-command-marker.d.ts +0 -4
- package/dist/cli/pipeline-command-marker.js +0 -21
- package/dist/cli/pipeline-command-marker.js.map +0 -1
- package/dist/project/project-manifest.d.ts +0 -27
- package/dist/project/project-manifest.js +0 -66
- package/dist/project/project-manifest.js.map +0 -1
- package/dist/studio/run-store-ui-client-app.d.ts +0 -12
- package/dist/studio/run-store-ui-client-app.js +0 -224
- package/dist/studio/run-store-ui-client-app.js.map +0 -1
- package/dist/studio/run-store-ui-client-commands.d.ts +0 -18
- package/dist/studio/run-store-ui-client-commands.js +0 -98
- package/dist/studio/run-store-ui-client-commands.js.map +0 -1
- package/dist/studio/run-store-ui-client-form.d.ts +0 -11
- package/dist/studio/run-store-ui-client-form.js +0 -54
- package/dist/studio/run-store-ui-client-form.js.map +0 -1
- package/dist/studio/run-store-ui-client-modals.d.ts +0 -20
- package/dist/studio/run-store-ui-client-modals.js +0 -154
- package/dist/studio/run-store-ui-client-modals.js.map +0 -1
- package/dist/studio/run-store-ui-client-model.d.ts +0 -19
- package/dist/studio/run-store-ui-client-model.js +0 -189
- package/dist/studio/run-store-ui-client-model.js.map +0 -1
- package/dist/studio/run-store-ui-client-runs.d.ts +0 -24
- package/dist/studio/run-store-ui-client-runs.js +0 -78
- package/dist/studio/run-store-ui-client-runs.js.map +0 -1
- package/dist/studio/run-store-ui-client-shared.d.ts +0 -22
- package/dist/studio/run-store-ui-client-shared.js +0 -63
- package/dist/studio/run-store-ui-client-shared.js.map +0 -1
- package/dist/workbench/workbench-graph.d.ts +0 -2
- package/dist/workbench/workbench-graph.js +0 -64
- package/dist/workbench/workbench-graph.js.map +0 -1
- package/dist/workbench/workbench-inspect.d.ts +0 -2
- package/dist/workbench/workbench-inspect.js +0 -70
- package/dist/workbench/workbench-inspect.js.map +0 -1
- package/dist/workbench/workbench-list.d.ts +0 -2
- package/dist/workbench/workbench-list.js +0 -53
- package/dist/workbench/workbench-list.js.map +0 -1
- package/dist/workbench/workbench-plan.d.ts +0 -2
- package/dist/workbench/workbench-plan.js +0 -67
- package/dist/workbench/workbench-plan.js.map +0 -1
- package/dist/workbench/workbench-validate.d.ts +0 -2
- package/dist/workbench/workbench-validate.js +0 -76
- package/dist/workbench/workbench-validate.js.map +0 -1
- package/examples/catalog/tubeless.project.ts +0 -76
- /package/examples/{catalog → project}/pipelines/import.ts +0 -0
- /package/examples/{catalog → project}/pipelines/normalize.ts +0 -0
- /package/examples/{catalog → project}/pipelines/publish.ts +0 -0
package/README.md
CHANGED
|
@@ -11,11 +11,13 @@
|
|
|
11
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
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
13
|
<a href="./LICENSE"><img alt="MIT" src="https://img.shields.io/npm/l/tubeless?style=flat-square&labelColor=121212&color=c4c0b4"></a>
|
|
14
|
+
<a href="./docs/getting-started.md#install"><img alt="Node" src="https://img.shields.io/node/v/tubeless?style=flat-square&labelColor=121212&color=c4c0b4"></a> <a href="https://www.npmjs.com/package/tubeless"><img alt="provenance" src="https://img.shields.io/badge/provenance-npm-2f6f4a?style=flat-square&labelColor=121212"></a>
|
|
14
15
|
</p>
|
|
15
16
|
|
|
16
17
|
Tubeless is a TypeScript toolkit for work that unfolds in steps. It fits data
|
|
17
18
|
pipelines, multi-step application workflows, and AI workloads—anywhere you want
|
|
18
|
-
explicit dependencies, typed handoffs, and inspectable execution.
|
|
19
|
+
explicit dependencies, typed handoffs, and inspectable execution. The name is the
|
|
20
|
+
cycling kind of tubeless: no inner tube, and no extra runtime to keep the work rolling.
|
|
19
21
|
|
|
20
22
|
Pipelines run in your process with no runtime dependencies. You can preview
|
|
21
23
|
execution, select a target and its dependencies, compose child pipelines, and
|
|
@@ -28,7 +30,7 @@ For scheduling or crash recovery, pair it with a [queue or workflow engine](./do
|
|
|
28
30
|
npm install tubeless
|
|
29
31
|
```
|
|
30
32
|
|
|
31
|
-
The library uses ESM and requires Node.js 22 or later. The CLI also requires
|
|
33
|
+
The library uses ESM and requires Node.js 22.6 or later. The CLI also requires
|
|
32
34
|
Bun 1.3.14 or later. Linux and macOS are supported; Windows is untested.
|
|
33
35
|
See [installation and runtime support](./docs/getting-started.md#install).
|
|
34
36
|
|
|
@@ -36,11 +38,10 @@ Tubeless is pre-1.0, so the public API may change between releases.
|
|
|
36
38
|
|
|
37
39
|
## Quick start
|
|
38
40
|
|
|
39
|
-
This pipeline loads and normalizes strings. `step` creates a step; dependencies give typed
|
|
40
|
-
inputs. Adding `skip` makes it skippable and widens its output to include `undefined`.
|
|
41
|
+
This pipeline loads and normalizes strings. `step` creates a step; dependencies give typed inputs.
|
|
41
42
|
|
|
42
43
|
```ts
|
|
43
|
-
import { createSteps, definePipeline
|
|
44
|
+
import { createSteps, definePipeline } from "tubeless";
|
|
44
45
|
|
|
45
46
|
interface ImportOptions {
|
|
46
47
|
lines: readonly string[];
|
|
@@ -60,33 +61,33 @@ const normalize = step("normalize", {
|
|
|
60
61
|
export const ImportPipeline = definePipeline({
|
|
61
62
|
id: "import",
|
|
62
63
|
steps: [load, normalize],
|
|
63
|
-
targets: [normalize],
|
|
64
|
-
finalize: requireOutputs([normalize], ({ normalize }) => normalize),
|
|
65
64
|
});
|
|
66
65
|
|
|
67
66
|
const rows = await ImportPipeline.runOrThrow({ lines: [" Alpha ", "", "Beta"] });
|
|
68
67
|
// ["alpha", "beta"]
|
|
69
68
|
```
|
|
70
69
|
|
|
71
|
-
`
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
Omitted `targets` and `finalize` use the last step in execution order: `normalize`.
|
|
71
|
+
Missing output returns `undefined`; use `requireOutputs` when absence should fail.
|
|
72
|
+
|
|
73
|
+
`runOrThrow` returns the result or throws on failure. Use `run` for reports, `plan`
|
|
74
|
+
for previews, and `toMermaid` for diagrams. See [getting started](./docs/getting-started.md).
|
|
74
75
|
|
|
75
76
|
## Use the CLI
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
78
|
+
Projects made with `defineProject(id, [pipeline, command])` register each pipeline once and are directly usable by the CLI;
|
|
79
|
+
schema-backed pipelines get inferred flags automatically. See the [CLI guide](./docs/cli.md)
|
|
80
|
+
for direct project usage and advanced custom command adapters. From this repository:
|
|
80
81
|
|
|
81
82
|
```sh
|
|
82
|
-
bunx tubeless list
|
|
83
|
-
bunx tubeless inspect import
|
|
84
|
-
bunx tubeless run import
|
|
83
|
+
bunx tubeless list --project examples/tubeless.project.ts
|
|
84
|
+
bunx tubeless inspect --project examples/tubeless.project.ts validated-import
|
|
85
|
+
bunx tubeless run --project examples/tubeless.project.ts validated-import -- --source rows.txt
|
|
85
86
|
```
|
|
86
87
|
|
|
87
|
-
|
|
88
|
-
Record runs with `--store` or
|
|
89
|
-
|
|
88
|
+
In your app, add `tubeless.project.ts` and omit `--project`. Pass application
|
|
89
|
+
flags after `--`. Record runs with `--store` or `--trace`, then inspect them with
|
|
90
|
+
`tubeless history` or the [local studio](./docs/studio.md).
|
|
90
91
|
|
|
91
92
|
## Find your route
|
|
92
93
|
|
|
@@ -94,8 +95,7 @@ them with `tubeless history` or the [local studio](./docs/studio.md).
|
|
|
94
95
|
[dry runs and write gates](./examples/publish-with-gates.ts) to a publishing job.
|
|
95
96
|
- Build a larger workflow with [child pipelines](./examples/child-pipeline.ts)
|
|
96
97
|
and [fan-out](./examples/fan-out-progress.ts).
|
|
97
|
-
-
|
|
98
|
-
workflow that brings several pipeline features together.
|
|
98
|
+
- Optional: the [peloton example](./examples/peloton.ts) is a cycling-themed kitchen sink for the live TUI.
|
|
99
99
|
|
|
100
100
|
The [recipe index](./docs/recipes.md) covers validation, retries, tracing, testing,
|
|
101
101
|
and more. For help authoring pipelines with a coding agent, install the
|
|
@@ -2,4 +2,5 @@ import { type CliCommand, type CliCommandConfig, type CliParamsSchema } from "./
|
|
|
2
2
|
export declare function createCommand<const TSchema extends CliParamsSchema, TResult = void>(config: CliCommandConfig<TSchema, TResult>, mainExits?: {
|
|
3
3
|
validation?: number;
|
|
4
4
|
}): CliCommand<TSchema, TResult>;
|
|
5
|
+
/** Create a typed command from a declarative parameter schema and run handler. */
|
|
5
6
|
export declare function defineCommand<const TSchema extends CliParamsSchema, TResult = void>(config: CliCommandConfig<TSchema, TResult>): CliCommand<TSchema, TResult>;
|
package/dist/cli/cli-command.js
CHANGED
|
@@ -8,6 +8,7 @@ function resolveContext(overrides) {
|
|
|
8
8
|
cwd: overrides?.cwd ?? process.cwd(),
|
|
9
9
|
env: overrides?.env ?? process.env,
|
|
10
10
|
log: overrides?.log ?? console,
|
|
11
|
+
reporterOutput: overrides?.reporterOutput,
|
|
11
12
|
pipelineContext: overrides?.pipelineContext,
|
|
12
13
|
signal: overrides?.signal,
|
|
13
14
|
checkpoint: overrides?.checkpoint,
|
|
@@ -60,7 +61,7 @@ function inMemoryCheckpointView(seed) {
|
|
|
60
61
|
};
|
|
61
62
|
}
|
|
62
63
|
export function createCommand(config, mainExits) {
|
|
63
|
-
const effectiveParams = buildEffectiveSchema(config.params, config.checkpoint);
|
|
64
|
+
const effectiveParams = buildEffectiveSchema(config.params, config.checkpoint, config.resume);
|
|
64
65
|
assertNoDuplicateFlags(effectiveParams);
|
|
65
66
|
assertValidMultipleParams(effectiveParams);
|
|
66
67
|
assertValidEnvironmentFallbacks(effectiveParams);
|
|
@@ -68,14 +69,19 @@ export function createCommand(config, mainExits) {
|
|
|
68
69
|
assertValidPositionals(positionals, effectiveParams);
|
|
69
70
|
const descriptor = commandDescriptor(config, effectiveParams, positionals);
|
|
70
71
|
function resolveValues(readValue, context, errors, helpText) {
|
|
71
|
-
const values = {};
|
|
72
|
+
const values = { resume: false };
|
|
72
73
|
for (const [key, param] of Object.entries(effectiveParams)) {
|
|
73
74
|
const errorCount = errors.length;
|
|
74
75
|
const raw = readValue(key, param);
|
|
75
76
|
if (errors.length > errorCount)
|
|
76
77
|
continue;
|
|
77
78
|
const envValue = raw === undefined && param.env ? context.env?.[param.env] : undefined;
|
|
78
|
-
values
|
|
79
|
+
Object.defineProperty(values, key, {
|
|
80
|
+
value: resolveParam(key, param, raw ?? envValue, context.cwd, errors, raw !== undefined ? "argv" : envValue !== undefined ? "env" : "default"),
|
|
81
|
+
enumerable: true,
|
|
82
|
+
configurable: true,
|
|
83
|
+
writable: true,
|
|
84
|
+
});
|
|
79
85
|
}
|
|
80
86
|
if (errors.length > 0)
|
|
81
87
|
return { kind: "error", errors, helpText };
|
|
@@ -291,6 +297,7 @@ function normalizeStructuredValue(key, param, value, errors) {
|
|
|
291
297
|
}
|
|
292
298
|
return value;
|
|
293
299
|
}
|
|
300
|
+
/** Create a typed command from a declarative parameter schema and run handler. */
|
|
294
301
|
export function defineCommand(config) {
|
|
295
302
|
return createCommand(config);
|
|
296
303
|
}
|
|
@@ -1 +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 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 resolveValues(\n readValue: (\n key: string,\n param: CliParamsSchema[string]\n ) => string | boolean | string[] | undefined,\n context: CliContext,\n errors: string[],\n helpText: string\n ): CliParseResult<TSchema> {\n const values: Record<string, ResolvedParamValue> = {};\n for (const [key, param] of Object.entries(effectiveParams)) {\n const errorCount = errors.length;\n const raw = readValue(key, param);\n if (errors.length > errorCount) continue;\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: resolveParam populated every effective schema key and all input checks passed.\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 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 const tokenized = tokenize(argv, effectiveParams, positionals);\n if (tokenized.help) return { kind: \"help\", helpText };\n return resolveValues(\n (key) => tokenized.values.get(key),\n context,\n [...tokenized.errors],\n helpText\n );\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 for (const key of Object.keys(structuredValues)) {\n if (!Object.prototype.hasOwnProperty.call(effectiveParams, key)) {\n errors.push(`Unknown parameter: ${key}`);\n }\n }\n return resolveValues(\n (key, param) => normalizeStructuredValue(key, param, structuredValues[key], errors),\n context,\n errors,\n helpText\n );\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 /**\n * No-op unless `config.checkpoint` is set, a store is attached, and the run completed\n * without a dry run or caller cancellation.\n */\n function finalizeCheckpoint(context: CliContext, values: CliParams<TSchema>): void {\n const checkpointConfig = config.checkpoint;\n if (!checkpointConfig || !context.checkpoint || values.dryRun || context.signal?.aborted) {\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 runContext = attachCheckpoint(context, 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 runContext = attachCheckpoint(managedSignal.context, 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"]}
|
|
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 reporterOutput: overrides?.reporterOutput,\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 mainExits?: { validation?: number }\n): CliCommand<TSchema, TResult> {\n const effectiveParams = buildEffectiveSchema(config.params, config.checkpoint, config.resume);\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 resolveValues(\n readValue: (\n key: string,\n param: CliParamsSchema[string]\n ) => string | boolean | string[] | undefined,\n context: CliContext,\n errors: string[],\n helpText: string\n ): CliParseResult<TSchema> {\n const values: Record<string, ResolvedParamValue> = { resume: false };\n for (const [key, param] of Object.entries(effectiveParams)) {\n const errorCount = errors.length;\n const raw = readValue(key, param);\n if (errors.length > errorCount) continue;\n const envValue = raw === undefined && param.env ? context.env?.[param.env] : undefined;\n Object.defineProperty(values, key, {\n value: resolveParam(\n key,\n param,\n raw ?? envValue,\n context.cwd,\n errors,\n raw !== undefined ? \"argv\" : envValue !== undefined ? \"env\" : \"default\"\n ),\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n if (errors.length > 0) return { kind: \"error\", errors, helpText };\n // SAFETY: resolveParam populated every effective schema key and all input checks passed.\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 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 const tokenized = tokenize(argv, effectiveParams, positionals);\n if (tokenized.help) return { kind: \"help\", helpText };\n return resolveValues(\n (key) => tokenized.values.get(key),\n context,\n [...tokenized.errors],\n helpText\n );\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 for (const key of Object.keys(structuredValues)) {\n if (!Object.prototype.hasOwnProperty.call(effectiveParams, key)) {\n errors.push(`Unknown parameter: ${key}`);\n }\n }\n return resolveValues(\n (key, param) => normalizeStructuredValue(key, param, structuredValues[key], errors),\n context,\n errors,\n helpText\n );\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 /**\n * No-op unless `config.checkpoint` is set, a store is attached, and the run completed\n * without a dry run or caller cancellation.\n */\n function finalizeCheckpoint(context: CliContext, values: CliParams<TSchema>): void {\n const checkpointConfig = config.checkpoint;\n if (!checkpointConfig || !context.checkpoint || values.dryRun || context.signal?.aborted) {\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 runContext = attachCheckpoint(context, 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 runContext = attachCheckpoint(managedSignal.context, 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\n/** Create a typed command from a declarative parameter schema and run handler. */\nexport function defineCommand<const TSchema extends CliParamsSchema, TResult = void>(\n config: CliCommandConfig<TSchema, TResult>\n): CliCommand<TSchema, TResult> {\n return createCommand(config);\n}\n"]}
|
package/dist/cli/cli-parser.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CliCheckpointConfig, CliCommandConfig, CliCommandDescriptor, CliParam, CliParamsSchema } from "./cli-types.js";
|
|
2
|
-
export declare function buildEffectiveSchema(params: CliParamsSchema, checkpoint: CliCheckpointConfig | undefined): CliParamsSchema;
|
|
2
|
+
export declare function buildEffectiveSchema(params: CliParamsSchema, checkpoint: CliCheckpointConfig | undefined, resume: true | undefined): CliParamsSchema;
|
|
3
3
|
export declare function flagName(key: string, param: CliParam): string;
|
|
4
4
|
export declare function commandDescriptor(config: Pick<CliCommandConfig<CliParamsSchema, unknown>, "description" | "name">, params: CliParamsSchema, positionals: readonly string[]): CliCommandDescriptor;
|
|
5
5
|
export declare function renderHelp(name: string, description: string | undefined, schema: CliParamsSchema, positionals: readonly string[]): string;
|
package/dist/cli/cli-parser.js
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
/**
|
|
4
|
-
* Every command gets `-h`/`--help
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `
|
|
8
|
-
*
|
|
9
|
-
* (a DB query, re-reading an output artifact) and just read `values.resume` directly.
|
|
10
|
-
* Schemas can't redeclare any of these names; `defineCommand` throws immediately if one
|
|
11
|
-
* tries, instead of silently shadowing the built-in.
|
|
4
|
+
* Every command gets `-h`/`--help` and `--dry-run` for free, the same way every pipeline
|
|
5
|
+
* step gets `context.dryRun`. `--resume`/`--no-resume` is added only for managed
|
|
6
|
+
* checkpointing or an explicit application-owned resume capability. Schemas can't
|
|
7
|
+
* redeclare any of these names; `defineCommand` throws immediately if one tries, instead
|
|
8
|
+
* of silently shadowing the built-in.
|
|
12
9
|
*/
|
|
13
10
|
const DRY_RUN_KEY = "dryRun";
|
|
14
11
|
const DRY_RUN_PARAM = {
|
|
@@ -23,24 +20,33 @@ const RESERVED_FLAG_NAMES = new Set([
|
|
|
23
20
|
"resume",
|
|
24
21
|
"no-resume",
|
|
25
22
|
]);
|
|
26
|
-
export function buildEffectiveSchema(params, checkpoint) {
|
|
23
|
+
export function buildEffectiveSchema(params, checkpoint, resume) {
|
|
27
24
|
if (Object.prototype.hasOwnProperty.call(params, DRY_RUN_KEY)) {
|
|
28
25
|
throw new Error(`"${DRY_RUN_KEY}" is a reserved parameter provided automatically by every command; remove it from params.`);
|
|
29
26
|
}
|
|
30
27
|
if (Object.prototype.hasOwnProperty.call(params, RESUME_KEY)) {
|
|
31
|
-
throw new Error(`"${RESUME_KEY}" is a reserved parameter
|
|
28
|
+
throw new Error(`"${RESUME_KEY}" is a reserved parameter; set resume: true on the command instead of declaring it in params.`);
|
|
32
29
|
}
|
|
33
|
-
const
|
|
34
|
-
type: "boolean",
|
|
35
|
-
description: "Resume: skip work that's already done instead of starting fresh.",
|
|
36
|
-
default: checkpoint?.defaultResume ?? false,
|
|
37
|
-
group: "execution",
|
|
38
|
-
};
|
|
39
|
-
return {
|
|
30
|
+
const effectiveParams = {
|
|
40
31
|
[DRY_RUN_KEY]: DRY_RUN_PARAM,
|
|
41
|
-
[RESUME_KEY]: resumeParam,
|
|
42
|
-
...params,
|
|
43
32
|
};
|
|
33
|
+
if (checkpoint || resume === true) {
|
|
34
|
+
effectiveParams[RESUME_KEY] = {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Resume: skip work that's already done instead of starting fresh.",
|
|
37
|
+
default: checkpoint?.defaultResume ?? false,
|
|
38
|
+
group: "execution",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
for (const [key, param] of Object.entries(params)) {
|
|
42
|
+
Object.defineProperty(effectiveParams, key, {
|
|
43
|
+
value: param,
|
|
44
|
+
enumerable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
writable: true,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return effectiveParams;
|
|
44
50
|
}
|
|
45
51
|
function defaultCommandName() {
|
|
46
52
|
const entry = process.argv[1];
|
|
@@ -480,10 +486,10 @@ export function assertNoDuplicateFlags(schema) {
|
|
|
480
486
|
// "no-resume" is reserved alongside "resume" (see RESERVED_FLAG_NAMES): the tokenizer
|
|
481
487
|
// exact-matches a registered flag before falling back to "no-" negation, so a schema
|
|
482
488
|
// that claims "no-resume" for itself (derived or via an explicit `flag:` override)
|
|
483
|
-
// would silently intercept it
|
|
489
|
+
// would silently intercept it when resume support is enabled.
|
|
484
490
|
const isBuiltInKey = key === DRY_RUN_KEY || key === RESUME_KEY;
|
|
485
491
|
if (!isBuiltInKey && RESERVED_FLAG_NAMES.has(flag)) {
|
|
486
|
-
throw new Error(`--${flag} is a reserved flag
|
|
492
|
+
throw new Error(`--${flag} is a reserved flag; remove "${key}" from params or give it a different flag name.`);
|
|
487
493
|
}
|
|
488
494
|
const existingKey = keyByFlag.get(flag);
|
|
489
495
|
if (existingKey) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-parser.js","sourceRoot":"","sources":["../../src/cli/cli-parser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAa7B;;;;;;;;;GASG;AACH,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,aAAa,GAAoB;IACrC,IAAI,EAAE,SAAS;IACf,WAAW,EAAE,iCAAiC;IAC9C,KAAK,EAAE,WAAW;CACnB,CAAC;AACF,MAAM,UAAU,GAAG,QAAQ,CAAC;AAC5B,MAAM,mBAAmB,GAAwB,IAAI,GAAG,CAAC;IACvD,MAAM;IACN,SAAS;IACT,QAAQ;IACR,WAAW;CACZ,CAAC,CAAC;AAEH,MAAM,UAAU,oBAAoB,CAClC,MAAuB,EACvB,UAA2C;IAE3C,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,CAAC;QAC9D,MAAM,IAAI,KAAK,CACb,IAAI,WAAW,2FAA2F,CAC3G,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,KAAK,CACb,IAAI,UAAU,2FAA2F,CAC1G,CAAC;IACJ,CAAC;IACD,MAAM,WAAW,GAAoB;QACnC,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,kEAAkE;QAC/E,OAAO,EAAE,UAAU,EAAE,aAAa,IAAI,KAAK;QAC3C,KAAK,EAAE,WAAW;KACnB,CAAC;IACF,OAAO;QACL,CAAC,WAAW,CAAC,EAAE,aAAa;QAC5B,CAAC,UAAU,CAAC,EAAE,WAAW;QACzB,GAAG,MAAM;KACV,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,KAAe;IACnD,OAAO,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;AAChF,CAAC;AAED,iGAAiG;AACjG,SAAS,eAAe,CACtB,KAAe;IAEf,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,MAAgF,EAChF,MAAuB,EACvB,WAA8B;IAE9B,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAA0B,EAAE;QACrF,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QACzF,MAAM,QAAQ,GACZ,KAAK,CAAC,IAAI,KAAK,SAAS;YACxB,CAAC,eAAe,CAAC,KAAK,CAAC;YACvB,CAAC,KAAK,CAAC,QAAQ;YACf,KAAK,CAAC,OAAO,KAAK,SAAS;YAC3B,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC;QAC1B,MAAM,UAAU,GAAkC;YAChD,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC;YAC1B,GAAG;YACH,QAAQ,EAAE,eAAe,CAAC,KAAK,CAAC;YAChC,UAAU,EAAE,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC;YACrC,QAAQ;YACR,IAAI,EAAE,KAAK,CAAC,IAAI;SACjB,CAAC;QACF,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7B,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7C,UAAU,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC;QACD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAC/B,UAAU,CAAC,OAAO,GAAG,YAAY,CAAC;QACpC,CAAC;QACD,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACpC,UAAU,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QAC7C,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YAC5B,UAAU,CAAC,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC;QACrC,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;YAC7C,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC;QAC5B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACvD,UAAU,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAC7B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;YACvD,UAAU,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;QAC7B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAC7C,UAAU,CAAC,SAAS,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACxC,UAAU,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC;QACnC,CAAC;QACD,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC9B,UAAU,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;QACjC,CAAC;QACD,OAAO,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,GAAgC;QAC3C,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,kBAAkB,EAAE;QACzC,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC;KACtC,CAAC;IACF,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC;IAC3C,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,UAAU,CAAC,IAAY,EAAE,KAAe;IAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,KAAK,IAAI,EAAE,CAAC;IACjD,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,KAAK,IAAI,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC;AAC/F,CAAC;AAED,SAAS,oBAAoB,CAAC,GAAW,EAAE,KAAe;IACxD,MAAM,IAAI,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC;IACjE,MAAM,QAAQ,GACZ,KAAK,CAAC,IAAI,KAAK,SAAS;QACxB,CAAC,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAC5E,OAAO,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED,SAAS,aAAa,CAAC,KAAe;IACpC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,WAAW,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAC7D,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,QAAQ,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,KAAK,CAAC,IAAI,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QAC3D,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,YAAY,KAAK,CAAC,OAAO,IAAI,KAAK,EAAE,CAAC,CAAC;IACnD,CAAC;SAAM,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACvC,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC;SAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACzB,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,WAA+B,EAC/B,MAAuB,EACvB,WAA8B;IAE9B,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QACvD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxE,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACxD,OAAO,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAU,CAAC;IAClF,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnE,MAAM,eAAe,GAAG,WAAW;SAChC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,oBAAoB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAE,CAAC,CAAC;SACrD,IAAI,CAAC,GAAG,CAAC,CAAC;IACb,MAAM,KAAK,GAAG,CAAC,UAAU,IAAI,aAAa,eAAe,CAAC,CAAC,CAAC,IAAI,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IAC9B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IAC3B,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC;QACpC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,KAAK,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;IACvE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAcD,SAAS,iBAAiB,CAAC,MAAuB;IAChD,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,IAAuB,EACvB,MAAuB,EACvB,WAA8B;IAE9B,MAAM,OAAO,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAyB,CAAC;IACrD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAyB,CAAC;IACtD,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG;IACvC,kFAAkF;IAClF,sFAAsF;IACtF,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAkB,CACrE,CAAC;IACF,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACtB,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,GAAG,EAAuC,CAAC;IAC9D,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,eAAe,GAAG,CAAC,CAAC;IACxB,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,MAAM,WAAW,GAAG,CAAC,KAAoB,EAAE,KAAuB,EAAQ,EAAE;QAC1E,IAAI,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACjC,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;YACxD,kFAAkF;YAClF,sFAAsF;YACtF,KAAK,CAAC,IAAI,CAAC,KAAe,CAAC,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAC7B,OAAO;QACT,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,mBAAmB,GAAG,GAA8B,EAAE;QAC1D,OACE,eAAe,GAAG,iBAAiB,CAAC,MAAM;YAC1C,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,eAAe,CAAE,CAAC,GAAG,CAAC;YACnD,CAAC,eAAe,CAAC,iBAAiB,CAAC,eAAe,CAAE,CAAC,KAAK,CAAC,EAC3D,CAAC;YACD,eAAe,EAAE,CAAC;QACpB,CAAC;QACD,OAAO,iBAAiB,CAAC,eAAe,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,gBAAgB,GAAG,CAAC,KAAa,EAAQ,EAAE;QAC/C,MAAM,KAAK,GAAG,mBAAmB,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QACD,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,eAAe,EAAE,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,CAAC,KAAa,EAAE,IAAY,EAAsB,EAAE;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAC7B,6EAA6E;QAC7E,sEAAsE;QACtE,IACE,IAAI,KAAK,SAAS;YAClB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YACrB,IAAI,KAAK,IAAI;YACb,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,CAAC,EACzE,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;YAC3C,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACjD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,CAAC,YAAY,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACpC,YAAY,GAAG,IAAI,CAAC;YACpB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,YAAY,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,EAAE,CAAC;YAC5D,IAAI,GAAG,IAAI,CAAC;YACZ,SAAS;QACX,CAAC;QACD,IAAI,YAAY,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3C,gBAAgB,CAAC,KAAK,CAAC,CAAC;YACxB,SAAS;QACX,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,IAAI,mBAAmB,EAAE,EAAE,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzE,gBAAgB,CAAC,KAAK,CAAC,CAAC;gBACxB,SAAS;YACX,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,mBAAmB,KAAK,EAAE,CAAC,CAAC;gBACxC,SAAS;YACX,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBACnC,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBACzB,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3C,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;gBACxB,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC1B,KAAK,EAAE,CAAC;YACV,CAAC;YACD,SAAS;QACX,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAG,eAAe,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;QAEhF,mFAAmF;QACnF,oFAAoF;QACpF,oFAAoF;QACpF,0CAA0C;QAC1C,MAAM,OAAO,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACzE,MAAM,eAAe,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACjD,MAAM,IAAI,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;QAC1F,MAAM,WAAW,GAAG,WAAW,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC;QAE5F,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,CAAC,qBAAqB,IAAI,EAAE,CAAC,CAAC;YACzC,SAAS;QACX,CAAC;QAED,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,oCAAoC,CAAC,CAAC;gBAC9D,SAAS;YACX,CAAC;YACD,IAAI,KAAa,CAAC;YAClB,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;gBAC9B,KAAK,GAAG,WAAW,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;gBACpC,IAAI,IAAI,KAAK,SAAS;oBAAE,SAAS;gBACjC,KAAK,GAAG,IAAI,CAAC;gBACb,KAAK,EAAE,CAAC;YACV,CAAC;YACD,WAAW,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAC1B,SAAS;QACX,CAAC;QAED,IAAI,OAAO,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACzC,MAAM,CAAC,IAAI,CAAC,QAAQ,IAAI,kCAAkC,CAAC,CAAC;QAC9D,CAAC;aAAM,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;YACrC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;aAAM,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;YAClC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,WAAW,KAAK,OAAO,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,KAAK,IAAI,gCAAgC,WAAW,GAAG,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AAClC,CAAC;AAUD,SAAS,cAAc,CAAC,KAA8C;IACpE,OAAO,OAAO,KAAK,KAAK,SAAS,CAAC;AACpC,CAAC;AAED,SAAS,aAAa,CAAC,KAA8C;IACnE,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACnC,CAAC;AAED,SAAS,aAAa,CAAC,KAAsB;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,YAAY,CAC1B,GAAW,EACX,KAAe,EACf,GAA4C,EAC5C,GAAW,EACX,MAAgB,EAChB,MAAM,GAA+B,MAAM;IAE3C,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAClC,MAAM,WAAW,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,wBAAwB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IACzF,MAAM,YAAY,GAAG,MAAM,KAAK,KAAK,CAAC;IAEtC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC7B,IAAI,cAAc,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QACpC,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,GAAG,KAAK,MAAM;gBAAE,OAAO,IAAI,CAAC;YAChC,IAAI,GAAG,KAAK,OAAO;gBAAE,OAAO,KAAK,CAAC;YAClC,MAAM,CAAC,IAAI,CACT,YAAY;gBACV,CAAC,CAAC,GAAG,WAAW,gCAAgC,GAAG,GAAG;gBACtD,CAAC,CAAC,GAAG,WAAW,wBAAwB,CAC3C,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,QAAQ,GAAwB,EAAE,CAAC;QACzC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC5B,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;oBACnD,MAAM,CAAC,IAAI,CACT,YAAY;wBACV,CAAC,CAAC,GAAG,WAAW,oBAAoB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,IAAI,IAAI;wBAC9E,CAAC,CAAC,GAAG,WAAW,oBAAoB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjE,CAAC;oBACF,SAAS;gBACX,CAAC;gBACD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpB,SAAS;YACX,CAAC;YACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;YAChF,IAAI,KAAK,KAAK,SAAS;gBAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QACvD,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,IAAI,KAAK,CAAC,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;YACjD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpD,MAAM,CAAC,IAAI,CACT,YAAY;gBACV,CAAC,CAAC,GAAG,WAAW,oBAAoB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,KAAK,IAAI;gBAC/E,CAAC,CAAC,GAAG,WAAW,oBAAoB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACjE,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;QAC1D,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,IAAI,KAAK,CAAC,QAAQ;gBAAE,OAAO,SAAS,CAAC;YACrC,MAAM,CAAC,IAAI,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;YACjD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC;IAC3D,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,QAAQ;YAAE,OAAO,SAAS,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;QACjD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpF,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;QACpB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CACT,YAAY;gBACV,CAAC,CAAC,GAAG,WAAW,yBAAyB,QAAQ,EAAE;gBACnD,CAAC,CAAC,GAAG,WAAW,sBAAsB,CACzC,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;YAClF,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CACT,YAAY;oBACV,CAAC,CAAC,GAAG,WAAW,cAAc,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE;oBACvD,CAAC,CAAC,GAAG,WAAW,cAAc,KAAK,CAAC,IAAI,EAAE,CAC7C,CAAC;gBACF,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,mBAAmB,CAC1B,IAAY,EACZ,KAAqB,EACrB,QAAyB,EACzB,MAAgB,EAChB,MAAM,GAA+B,MAAM,EAC3C,OAAgB;IAEhB,MAAM,KAAK,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACpE,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;IACjF,MAAM,QAAQ,GAAG,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,YAAY,GAAG,CAAC;IACnE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,oBAAoB,QAAQ,EAAE,CAAC,CAAC;QACpD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,sBAAsB,QAAQ,EAAE,CAAC,CAAC;QACtD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CACT,MAAM,KAAK,KAAK;YACd,CAAC,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,GAAG,EAAE;YACpC,CAAC,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,GAAG,SAAS,KAAK,EAAE,CACrD,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC;QACjD,MAAM,CAAC,IAAI,CACT,MAAM,KAAK,KAAK;YACd,CAAC,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,GAAG,EAAE;YACpC,CAAC,CAAC,GAAG,KAAK,eAAe,KAAK,CAAC,GAAG,SAAS,KAAK,EAAE,CACrD,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,MAAuB;IAC5D,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC5C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAClC,sFAAsF;QACtF,qFAAqF;QACrF,mFAAmF;QACnF,mFAAmF;QACnF,MAAM,YAAY,GAAG,GAAG,KAAK,WAAW,IAAI,GAAG,KAAK,UAAU,CAAC;QAC/D,IAAI,CAAC,YAAY,IAAI,mBAAmB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACnD,MAAM,IAAI,KAAK,CACb,KAAK,IAAI,wEAAwE,GAAG,iDAAiD,CACtI,CAAC;QACJ,CAAC;QACD,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACxC,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,eAAe,IAAI,gBAAgB,WAAW,UAAU,GAAG,iBAAiB,CAAC,CAAC;QAChG,CAAC;QACD,SAAS,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEzB,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS;QACxC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,KAAK,GAAG,EAAE,CAAC;YAC3D,MAAM,IAAI,KAAK,CACb,IAAI,GAAG,8BAA8B,KAAK,CAAC,KAAK,+CAA+C,CAChG,CAAC;QACJ,CAAC;QACD,MAAM,gBAAgB,GAAG,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrD,IAAI,gBAAgB,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,cAAc,KAAK,CAAC,KAAK,iBAAiB,gBAAgB,UAAU,GAAG,iBAAiB,CACzF,CAAC;QACJ,CAAC;QACD,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACnC,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,yBAAyB,CAAC,MAAuB;IAC/D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,IAAI,GAAG,0HAA0H,CAClI,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CACb,IAAI,GAAG,oHAAoH,CAC5H,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,WAA8B,EAC9B,MAAuB;IAEvB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,IAAI,WAAW,GAAG,KAAK,CAAC;IACxB,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,MAAM,GAAG,GAAG,WAAW,CAAC,KAAK,CAAE,CAAC;QAChC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,mCAAmC,CAAC,CAAC;QAC3F,CAAC;QACD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,mCAAmC,GAAG,IAAI,CAAC,CAAC;QAC9D,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,4DAA4D,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,KAAK,KAAK,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/D,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,iBAAiB,CAAC,CAAC;QAC5E,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;QACzF,IAAI,WAAW,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CACb,kCAAkC,GAAG,mDAAmD,CACzF,CAAC;QACJ,CAAC;QACD,WAAW,KAAK,QAAQ,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,+BAA+B,CAAC,MAAuB;IACrE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS;YAAE,SAAS;QACtC,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,4CAA4C,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,IAAI,GAAG,kHAAkH,CAC1H,CAAC;QACJ,CAAC;IACH,CAAC;AACH,CAAC","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
|
+
{"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` and `--dry-run` for free, the same way every pipeline\n * step gets `context.dryRun`. `--resume`/`--no-resume` is added only for managed\n * checkpointing or an explicit application-owned resume capability. Schemas can't\n * redeclare any of these names; `defineCommand` throws immediately if one tries, instead\n * 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 resume: true | 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; set resume: true on the command instead of declaring it in params.`\n );\n }\n const effectiveParams: CliParamsSchema = {\n [DRY_RUN_KEY]: DRY_RUN_PARAM,\n };\n if (checkpoint || resume === true) {\n effectiveParams[RESUME_KEY] = {\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 }\n for (const [key, param] of Object.entries(params)) {\n Object.defineProperty(effectiveParams, key, {\n value: param,\n enumerable: true,\n configurable: true,\n writable: true,\n });\n }\n return effectiveParams;\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 when resume support is enabled.\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; 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"]}
|