Skip to content

feat(cli)!: split the compiled execution graph out of CLISchema and seal it - #101

Merged
kjanat merged 2 commits into
v4-middleware-fieldfrom
v4-compiled-graph
Aug 12, 2026
Merged

kjanat merged 2 commits into
v4-middleware-fieldfrom
v4-compiled-graph

Conversation

@kjanat

@kjanat kjanat commented Aug 2, 2026 •

Copy link
Copy Markdown
Owner

Breaking, targets v4. Stacked on #100. Implements L3 of the approved v4 plan — the big one.

Compiled graph, minimal and private

  • CompiledCommand { schema, handler, steps, subcommands } / CompiledCLI { commands, defaultCommand, plugins } in internal cli/compiled.ts; compileCommand(builder) extracts once, retains no builder. Compiled state lives in a module-private WeakMap<CLIBuilder, CompiledCLI>; nothing reaches any d.mts on the package entry.
  • CLIBuilder is factory-only: private constructor + @internal static _from. All 14 rebuild sites plus the preflight rebuild carry compiled state (each traced in review — a missed site would silently drop handlers).
  • The schema-identity invariant (CompiledCommand.schema is the same object as the public schema-tree entry) is pinned by tests at root, default, nested level, and across builder rebuilds — review added the WeakMap-held-state assertions after finding the original tests only covered freshly-compiled nodes.

CLISchema descriptive + sealed

  • commands: readonly CommandSchema[], defaultCommand: CommandSchema | undefined, plugins gone; sealed with the 'cli' brand; ConfigSettings sealed as 'config' with the ConfigSettingsDefinition input rung; CLIDefinition + createCLISchema complete the ladder (one sanctioned cast, in sealCLISchema so builder-internal config rebuilds don't re-normalize the command tree and break identity).
  • ErasedCommand and the _command/_execute duality deleted; executeCommand takes { handler, steps }; planner/dispatch/preflight take { schema, compiled } as separate inputs (a mid-flight toExecutableView reconstitution of the mixed shape was caught and removed — it rebuilt exactly what this layer exists to split).
  • The five structural SchemaLike projections simplify; completion never actually read plugins, so nothing needed threading.

Behavioral note: cli('') now throws INVALID_SCHEMA (previously accepted). No call site existed; recorded in the changelog.

Fixture migration: ~160 wrapper call sites unwrapped; planner/dispatch fixtures build real command() trees + compileCommand; assertion-line diffs verified zero-delta across all four rewritten fixture files (identity assertions kept — planner/dispatch never execute, so recording actions would have been dead code).

Gates: typecheck exit 0, lint clean, fmt clean, 2981/2981 tests (93 files), build (attw+publint) clean, docs build clean, meta-descriptions up to date.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are limited based on label configuration.

🏷️ Required labels (at least one) (1)
  • cr:review
🚫 Excluded labels (none allowed) (2)
  • wip
  • cr:skip

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: 431d1382-5c31-4ef8-81a0-481bc3b023f6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

feat!: split compiled CLI state from public schemas

  • Add CompiledCommand and CompiledCLI execution graphs.
  • Preserve compiled state across CLIBuilder rebuilds with a private WeakMap.
  • Make CLISchema descriptive, sealed, and schema-only.
  • Add and export createCLISchema, CLIDefinition, and ConfigSettingsDefinition.
  • Remove ErasedCommand, schema command middleware, and _command/_execute duality.
  • Update planning, dispatch, preflight, execution, completion, and JSON Schema generation.
  • Reject empty CLI names with INVALID_SCHEMA.
  • Migrate fixtures to real command trees.
  • Add tests for schema identity, compiled graph retention, route conflicts, and rebuild behaviour.
  • Update documentation, changelog, and schema metadata.
  • Verify type checking, linting, formatting, tests, build, and metadata checks.

Walkthrough

The CLI now separates sealed public schemas from compiled execution state. createCLISchema() builds validated CLI and configuration schemas. compileCommand() builds route-indexed command graphs with handlers and execution steps. Dispatch, planning, runtime preflight, execution, completion, and JSON-schema generation now consume the new structures. ErasedCommand is removed. Public exports and tests now use direct CommandSchema values.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLIBuilder
  participant CompiledCLI
  participant Planner
  participant Dispatch
  participant Executor
  CLIBuilder->>CompiledCLI: retain compiled handlers and routes
  CompiledCLI->>Planner: provide compiled command graph
  Planner->>Dispatch: resolve command arguments
  Dispatch->>Planner: return matched CompiledCommand
  Planner->>Executor: pass handler, steps, and merged schema
Loading

Possibly related PRs

  • kjanat/dreamcli#1: Directly refactors the same command schema, dispatch, planner, completion, and execution structures.
  • kjanat/dreamcli#57: Updates the overlapping CLI schema, planner, dispatch, runtime preflight, completion, and JSON-schema paths.
  • kjanat/dreamcli#43: Uses the compiled-state and schema changes for completion flags and default-command behaviour.

Suggested labels: area: docs, area: completion

Poem

Sealed schemas gleam; compiled routes align,
Handlers and steps follow each command line.
Aliases resolve through the graph with care,
Direct schemas keep runtime state fair.
Tests pass brightly. Arrr, fixed with precision!


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 3 warnings)

Check name Status Explanation Resolution
Release Metadata Sync ❌ Error Both manifests declare 3.0.1 and CHANGELOG.md has a 3.0.1 heading, but [3.0.1] is missing and [Unreleased] still compares v3.0.0-rc.17 to HEAD. Add the [3.0.1] comparison link and update [Unreleased] to compare v3.0.1...HEAD.
Title check ⚠️ Warning The title describes the main change, but it is 77 characters, uses feat instead of a lowercase verb, and omits add for a new feature. Shorten the title and use a required verb-based prefix, such as add: split CLI graph from schema.‌
Semver Version Bump Validation ⚠️ Warning Source files changed and public APIs have breaking changes, but package.json stays at 3.0.1 on base and HEAD; no permitted version file changed. A major SemVer bump is missing. Update package.json to a valid 4.0.0 (or later 4.x) version and include that version-file change in the PR.
Agents.Md Documentation Updated ⚠️ Warning The PR changes completion and JSON-schema CLI contracts, but src/core/completion/AGENTS.md and src/core/json-schema/AGENTS.md are unchanged; only cli, schema, and testkit guidance was updated. Update the AGENTS.md files for every affected module, including completion and json-schema, to document the new schema and execution contracts.
✅ Passed checks (7 passed)
Check name Status Explanation
Description check ✅ Passed The description directly explains the compiled graph split, schema sealing, breaking changes, tests, and implementation scope.
Docstring Coverage ✅ Passed Docstring coverage is 72.50% which is sufficient. The required threshold is 30.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Runtime Support Sync ✅ Passed The PR does not change runtime minimums or support claims; all seven required support-truth surfaces are unchanged, and no runtime-support claim appears in added or removed lines.
No Generated Docs Artifacts ✅ Passed The PR diff contains no files under docs/.vitepress/dist/ or docs/.vitepress/cache/.
Changelog Update ✅ Passed Source files changed, and the same commit updates CHANGELOG.md under ## [Unreleased] with Added and Breaking Changed entries; package versions remain 3.0.1.

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
dreamcli 434a334 Commit Preview URL

Branch Preview URL
Aug 10 2026, 08:22 PM

@pkg-pr-new

pkg-pr-new Bot commented Aug 2, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

bun add https://pkg.pr.new/@kjanat/dreamcli@101
npm i https://pkg.pr.new/@kjanat/dreamcli@101

commit: 3772771

@kjanat kjanat self-assigned this Aug 2, 2026
@kjanat kjanat added the cr:review Allow CodeRabbit review label Aug 2, 2026
@kjanat

This comment was marked as resolved.

@coderabbitai coderabbitai Bot added area: cli CLI dispatch, planning, root UX, or plugins area: schema Schema builders, schema DSL, and JSON Schema export impact: breaking Introduces a breaking API, runtime, or packaging change kind: feature New capability or product enhancement labels Aug 2, 2026
@coderabbitai

This comment was marked as resolved.

@kjanat kjanat changed the title feat(cli)!: split the compiled execution graph out of CLISchema and seal it feat(cli)!: split the compiled execution graph out of CLISchema and seal it Aug 3, 2026
@kjanat kjanat added this to the v4 milestone Aug 3, 2026 — with ChatGPT Codex Connector
@kjanat
kjanat marked this pull request as ready for review August 3, 2026 23:38
@kjanat
kjanat force-pushed the v4-compiled-graph branch from 9b5cc06 to 17c1554 Compare August 10, 2026 17:54
coderabbitai[bot]

This comment was marked as resolved.

@kjanat
kjanat force-pushed the v4-compiled-graph branch from 17c1554 to 4b43249 Compare August 10, 2026 19:35
@coderabbitai coderabbitai Bot added area: completion Shell completion generation and parsing area: docs VitePress app, guides, reference pages, and docs UX labels Aug 10, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/core/schema/command.ts (1)

652-660: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Mark buildCommandSchema() as internal.

buildCommandSchema() is a module-private API. Its JSDoc must include @internal so generated documentation does not present it as supported API.

Proposed documentation change
  * `@throws` {`@link` CLIError} `INVALID_BUILDER_STATE` or `DUPLICATE_STDIN_ARG` when
  *   an arg breaks the ordering or stdin invariants.
+ * `@internal`
  */

As per coding guidelines, src/**/*.ts must use @internal to mark non-public APIs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/schema/command.ts` around lines 652 - 660, Update the JSDoc for
buildCommandSchema() to include the `@internal` tag, marking this module-private
API as unsupported for generated documentation while preserving the existing
documentation.

Source: Coding guidelines

src/core/schema/schema-sealing.test.ts (1)

248-257: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Rebuild the schema in this regression test.

The test name states that it verifies rebuilding and deep equality. It only checks the initial schema construction. A regression in createCommandSchema(built) can alter or remove nested interactive resolvers while this test still passes.

Proposed test change
 			const built = createCommandSchema({
 				name: 'deploy',
 				interactive: resolver,
 				commands: [{ name: 'status', interactive: resolver }],
 			});
+			const rebuilt = createCommandSchema(built);
 
-			expect(built.interactive).toBe(resolver);
-			expect(built.commands[0]?.interactive).toBe(resolver);
+			expect(rebuilt).toEqual(built);
+			expect(rebuilt.interactive).toBe(resolver);
+			expect(rebuilt.commands[0]?.interactive).toBe(resolver);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/schema/schema-sealing.test.ts` around lines 248 - 257, Update the
regression test around createCommandSchema to rebuild the initially created
schema by passing built back into createCommandSchema, then assert the rebuilt
schema retains deep equality with built and preserves the top-level and nested
interactive resolver references. Keep the existing nested-command setup and
resolver identity checks focused on the rebuilt result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/core/schema/command.ts`:
- Around line 652-660: Update the JSDoc for buildCommandSchema() to include the
`@internal` tag, marking this module-private API as unsupported for generated
documentation while preserving the existing documentation.

In `@src/core/schema/schema-sealing.test.ts`:
- Around line 248-257: Update the regression test around createCommandSchema to
rebuild the initially created schema by passing built back into
createCommandSchema, then assert the rebuilt schema retains deep equality with
built and preserves the top-level and nested interactive resolver references.
Keep the existing nested-command setup and resolver identity checks focused on
the rebuilt result.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: e5715ead-235f-4def-84c5-b998a16358f3

📥 Commits

Reviewing files that changed from the base of the PR and between 17c1554 and 4b43249.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • src/core/schema/command.ts
  • src/core/schema/schema-sealing.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (4)
  • GitHub Check: test (node latest, bun latest)
  • GitHub Check: test (node 22.22.2, bun latest)
  • GitHub Check: Workers Builds: dreamcli
  • GitHub Check: Analyze (javascript-typescript)
🧰 Additional context used
📓 Path-based instructions (5)
CHANGELOG.md

📄 CodeRabbit inference engine (Custom checks)

If a version bump is detected in CHANGELOG.md, the new section header MUST match the exact new version number in the format: '## [X.Y.Z] - YYYY-MM-DD'. If NO version bump is detected, changes MUST be added under the existing '## [Unreleased]' section with descriptive entries (e.g., Added, Changed, Fixed, Removed).

Files:

  • CHANGELOG.md
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Use tabs, single quotes, semicolons, and LF line endings in TypeScript files.
Use import type for type-only imports.
Include .ts extensions in all relative imports.
Use explicit named re-exports; do not use export *.
Do not add runtime dependencies.

Files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/**/*.ts: Add @module JSDoc at the top of source files and use @internal to mark non-public APIs.
Keep the public API factory-first, using factories such as cli(), command(), flag.*(), createOutput(), and createAdapter().

Files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.ts: Co-locate tests as *.test.ts; use describe() and it(), em dashes in suite titles, and // === and // --- section markers.
Do not use lifecycle hooks, snapshots, or module mocks in tests.
Include a trailing \n in output assertions.

Files:

  • src/core/schema/schema-sealing.test.ts
src/core/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

src/core/**/*.ts: Keep core code runtime-agnostic; route host I/O through RuntimeAdapter, WriteFn, or ReadFn.
Do not use process.* or other runtime-specific APIs in src/core/.

Files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
🧠 Learnings (11)
📚 Learning: 2026-02-10T16:25:08.867Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 1
File: AGENTS.md:12-12
Timestamp: 2026-02-10T16:25:08.867Z
Learning: In repository kjanat/dreamcli, prefer using the filename syntax (e.g., GOALS.md) when referencing files in Markdown documentation, and treat references that do not follow this style as non-issues. This pattern applies to all Markdown files across the project.

Applied to files:

  • CHANGELOG.md
📚 Learning: 2026-02-11T11:57:27.623Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 3
File: src/core/cli/cli-completion-e2e.test.ts:9-16
Timestamp: 2026-02-11T11:57:27.623Z
Learning: Enforce explicit .ts extensions in all relative imports for TypeScript source files (enabled by allowImportingTsExtensions and noEmit in tsconfig.json). This applies to both static and dynamic imports. For each TypeScript file, update relative import paths to end with .ts (e.g., './utils/helper' -> './utils/helper.ts'). Ensure tooling (linting/eslint rules or a codemod) flags missing extensions and provides a quick fix. This guideline should cover all TypeScript files in the repo, not just a single test or module.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-02-12T15:52:24.166Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 4
File: src/core/resolve/resolve-arg-env.test.ts:1-7
Timestamp: 2026-02-12T15:52:24.166Z
Learning: In test files, do not require the module JSDoc tag at the top. This rule applies to all test files, while non-test source files should still require the module tag. Use the pattern **/*.test.{ts,tsx} to cover all test TypeScript test files (adjust if your project uses only .ts tests).

Applied to files:

  • src/core/schema/schema-sealing.test.ts
📚 Learning: 2026-04-02T00:14:17.279Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 7
File: src/core/cli/cli.test.ts:14-14
Timestamp: 2026-04-02T00:14:17.279Z
Learning: In kjanat/dreamcli test files (src/**/*.test.ts), do not flag differences in section separator style between `// ---` and `// ===`. This style is intentionally used by the author for all section levels (including top-level sections) in tests, so separator casing/choice should not be treated as a guideline violation in code review.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
📚 Learning: 2026-04-06T11:25:57.444Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/spinner-progress.ts:2-12
Timestamp: 2026-04-06T11:25:57.444Z
Learning: In this repo, enforce that TypeScript source files under `src/` include the required `module` JSDoc tag (where the project’s lint/review rules expect it). Do not flag missing `module` tags in files under `examples/`, since those are documentation/example scripts (e.g., `examples/*.ts`).

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-04-06T11:26:11.173Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/json-mode.ts:2-15
Timestamp: 2026-04-06T11:26:11.173Z
Learning: In this repository, `module` JSDoc tags are required for TypeScript source files under `src/` (e.g., `src/**/*.ts`). Runnable demo/example scripts under `examples/` are not part of this requirement and should not be flagged for missing `module`.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-04-06T11:28:55.224Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/.vitepress/theme/index.ts:1-16
Timestamp: 2026-04-06T11:28:55.224Z
Learning: In the kjanat/dreamcli repo, enforce the `module` JSDoc tag requirement only for TypeScript source files under `src/` (i.e., `src/**/*.ts`). Do not require `module` for files under `docs/`, including anything in `docs/.vitepress/**`, since those are part of the VitePress docs pipeline.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-04-06T11:26:04.030Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: examples/middleware.ts:2-11
Timestamp: 2026-04-06T11:26:04.030Z
Learning: In the kjanat/dreamcli repository, require the `module` JSDoc tag only for library source files under `src/` (e.g., `src/**/*.ts`). Files outside `src/` such as runnable demo/example scripts under `examples/` are not considered source code for this rule and should not be required to include `module`.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-04-06T18:24:44.371Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/reference/api.md:8-8
Timestamp: 2026-04-06T18:24:44.371Z
Learning: In the kjanat/dreamcli repo, the explicit type annotation `Readonly<Record<string, string>>` applied to `const` object literals is an intentional documentation/intent pattern. Do not flag it as redundant or unnecessary (e.g., for being inferable) when reviewing TypeScript/TSX files; treat this explicitness as acceptable by design.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-04-06T18:40:01.263Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 9
File: docs/.vitepress/vite-plugins/source-artifacts.ts:62-83
Timestamp: 2026-04-06T18:40:01.263Z
Learning: For this repository, Windows is explicitly not a supported/targeted platform. During code review, do not raise issues about Windows-specific path separators or normalization differences (e.g., use of `path.sep`, handling forward-slash vs backslash, or `normalize()`-related concerns). These checks should be treated as out-of-scope because the project is intended for Linux/macOS only.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
  • src/core/schema/command.ts
📚 Learning: 2026-06-23T16:38:50.547Z
Learnt from: kjanat
Repo: kjanat/dreamcli PR: 37
File: src/core/output/output.test.ts:76-76
Timestamp: 2026-06-23T16:38:50.547Z
Learning: In this repository’s test files (`*.test.ts`), do not suggest or require em dashes (—) in `describe()` suite titles. When reviewing, treat the suite-title punctuation as a repo-specific convention: do not flag missing/absent em dashes or recommend adding them to `describe(...)` block names.

Applied to files:

  • src/core/schema/schema-sealing.test.ts
🔍 Remote MCP DeepWiki, GitHub Grep

Additional review context

  • The repository kjanat/dreamcli remains unavailable through DeepWiki, so its implementation and documentation could not be independently verified.

  • WeakMap-backed derived state is a demonstrated TypeScript pattern: Angular uses WeakMap to associate cached/internal state with object identity without mutating the object. This supports reviewing whether every CLIBuilder._from() path preserves the intended compiled-state association.

  • Immutable descriptor implementations commonly freeze nested structures, not just the outer object. Prisma examples clone and freeze records, arrays, nested fields, and execution steps. Review whether CLISchema sealing protects nested command/config structures against mutation.

  • Commander validates aliases against both the command’s own name and existing sibling commands, throwing on collisions. This supports checking that assertNoSiblingRouteConflict rejects every name/alias collision consistently and reports the conflicting route clearly.

🔇 Additional comments (3)
src/core/schema/schema-sealing.test.ts (1)

2-8: LGTM!

Also applies to: 22-29, 83-104, 159-224, 289-310, 328-411

CHANGELOG.md (1)

17-36: LGTM!

Also applies to: 40-60, 70-75

src/core/schema/command.ts (1)

529-529: LGTM!

Also applies to: 662-692, 710-733, 743-784, 950-959, 978-979, 1049-1059, 1544-1578, 1711-1711

@kjanat
kjanat force-pushed the v4-compiled-graph branch from 4b43249 to a0b6886 Compare August 10, 2026 20:06
@kjanat kjanat added cr:skip Skip CodeRabbit review and removed cr:review Allow CodeRabbit review labels Aug 10, 2026
@kjanat
kjanat force-pushed the v4-compiled-graph branch from a0b6886 to 434a334 Compare August 10, 2026 20:19
…eal it

CompiledCommand carries schema (by reference), handler, steps, and
subcommands; CompiledCLI holds the command graph and plugins in a
module-private WeakMap keyed by builder instance. CLISchema becomes a
descriptive tree (commands and defaultCommand are CommandSchema, plugins
gone) sealed with the cli brand alongside ConfigSettings; CLIDefinition,
ConfigSettingsDefinition, and createCLISchema complete the ladder.
CLIBuilder is factory-only: private constructor plus an internal _from
that seeds the compiled state. ErasedCommand and its _command/_execute
duality are deleted; executeCommand takes the executable handler/steps
pair and planner, dispatch, and preflight receive schema and compiled
graph as separate inputs. The compiled node's schema identity with the
public tree is pinned by tests, including across builder rebuilds.
@kjanat
kjanat force-pushed the v4-compiled-graph branch from 434a334 to ee281c9 Compare August 10, 2026 21:16
Validate routes created from plain CLI definitions, preserve default
commands in input schemas, and keep compiled state across every builder
rebuild path. Export the missing public configuration types and strip
internal declarations from published types.
@kjanat
kjanat merged commit 16b269c into master Aug 12, 2026
18 checks passed
@kjanat
kjanat deleted the v4-compiled-graph branch August 12, 2026 14:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: cli CLI dispatch, planning, root UX, or plugins area: completion Shell completion generation and parsing area: docs VitePress app, guides, reference pages, and docs UX area: schema Schema builders, schema DSL, and JSON Schema export cr:skip Skip CodeRabbit review impact: breaking Introduces a breaking API, runtime, or packaging change kind: feature New capability or product enhancement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant