Skip to content

Native CLI: rebuild deka_cli on the deka-cli-core registry - #1205

Merged
samifouad merged 3 commits into
mainfrom
kimi/cli-core-1204
Oct 2, 2026
Merged

samifouad merged 3 commits into
mainfrom
kimi/cli-core-1204

Conversation

@samifouad

@samifouad samifouad commented Oct 2, 2026 •

Copy link
Copy Markdown
Member

What changed

The native deka binary hand-parsed std::env::args() with an if-chain and decided exit codes inline. This PR rebuilds it on the deka-cli-core registry (dcore, no V8 link — the legacy cli crate is untouched and not a dependency):

  • One registry (deka_cli/src/cli.rs): all seven commands (run/start, dev, check, build/compile, test, init) registered with owner/category/summary; flags --entry/--outfile/--exercise registered per command; global --help/--version.
  • One dispatcher: dispatch(registry, argv) -> i32 — argv in, exit code out, so tests drive every command without spawning a process. Usage errors (unknown command/flag, missing value, extra positionals) exit 2 with did-you-mean suggestions; runtime failures exit 1. main is the single exit point.
  • Outcome shim: deka-cli-core 0.5.0 handlers are fn(&Context) with no return, so each handler stores its Result in one Outcome slot in the context extensions and the dispatcher maps it to the exit code. Registry: handlers return an exit status, flags carry typed values cli-core#22 (0.6.0, status-returning handlers + typed flags) replaces exactly this shim — adoption is deleting it.
  • Truthful help: dcore::help::render_command_help is bypassed for command help because its curated copy describes the legacy V8 CLI (build --bundle --minify emitting JavaScript); native command help renders from the registry instead. Global help still uses the dcore renderer.

Behavior preserved

Same commands, aliases and flags; bare .ds/.dsx still means run; embedded-payload apps and --exercise unchanged — the existing integration suite (crates/deka_cli/tests/native_cli.rs: script runs, deka test counts, build + codesign + relocated app, desktop --exercise 3 → Count: 3, cycles, init) passes unmodified. Deliberate tightenings: unknown command/flag and --outfile on run now exit 2 (GNU usage convention, matching the legacy CLI) instead of 1.

Evidence

  • cargo check --locked --workspace --all-targets → 0

  • cargo clippy --locked --workspace --all-targets --all-features → 0, no warnings in deka_cli

  • cargo test --locked -p deka_cli → 11 lib + 7 integration passed, 0 failed

  • Revert proof: stubbing dispatch to the pre-registry "everything succeeds" behavior makes 7 of the 9 new lib tests fail (unknown_command_and_bad_flags_are_usage_errors, run_rejects_usage_mistakes, run_executes_script_and_maps_failures, check_accepts_valid_source_and_rejects_invalid, init_scaffolds_once, test_reports_counts, build_produces_an_executable_with_an_embedded_payload)

  • Manual transcript (debug binary):

    $ deka --version   → deka 0.60.1 (Rust VM)
    $ deka frobnicate  → deka: unknown argument `frobnicate`     (exit 2)
    $ deka --outfile   → deka: missing value for `--outfile`     (exit 2)
    $ deka hello.ds    → hello from registry cli                 (exit 0, bare path = run)
    $ deka build --help → Usage + --entry/--outfile flags
    $ deka run --help   → Usage + --entry/--exercise flags
    $ deka --help       → registry-rendered global help, Getting Started block filtered to native commands
    

Docs: docs/dekascript/native-cli.mdx gains a Command line section (registry, deka <command> --help, exit-code convention).

closes #1204
-kimi

Update: now on deka-cli-core 0.6.0 (bd672282)

The first commit built the registry on 0.5.0 with an Outcome slot shim. deka-cli-core 0.6.0 (dekaruntime/cli-core#26, published as v0.6.0) has since shipped, and the second commit adopts it:

  • Handlers return Result<ExitStatus, CommandError> — the shim is deleted. Registry::run_argv is the single place that prints errors and maps them to exit codes.
  • Flag values go through typed accessors (ctx.param::<usize>("--exercise")?) — bad values are usage errors in the registry's one format.
  • dcore is dropped (it stays on 0.5.0 for the legacy CLI; its curated help also describes that CLI) — help renders locally from the registry; tests()/build() write through the context output sinks, so tests assert 1 passed, 0 failed and the OK line in-process via run_captured.
  • Transcript: deka frobnicate → unknown argument \frobnicate`(2);deka run x.ds --exercise NaN→invalid value for `--exercise`: invalid digit found in string(2);deka check x.ds→OK x.ds` (0).
  • Gates re-run: cargo check --locked --workspace --all-targets → 0; cargo clippy --locked --workspace --all-targets --all-features → 0 (no deka_cli warnings); cargo test --locked -p deka_cli → 11 lib + 7 integration green. Revert proof: making handlers unable to report failure fails init_scaffolds_once and test_reports_counts.

deka_cli hand-parsed std::env::args() with an if-chain and decided exit
codes inline. Command registration, parsing and dispatch now go through
dcore (deka-cli-core 0.5.0): one registry, argv-in/exit-code-out dispatch,
a single exit point in main, usage errors exit 2 with did-you-mean
suggestions, and per-command help rendered from the registry (dcore's
curated copy describes the legacy V8 CLI and is bypassed).

Handlers keep today's fn(&Context) signature; their results reach the
dispatcher through one Outcome slot, the isolated shim that deka-cli-core
0.6.0 (dekaruntime/cli-core#22) replaces with status-returning handlers.

Behavior preserved: same seven commands and aliases, bare .ds/.dsx means
run, embedded-payload apps and --exercise work as before (integration
suite passes unchanged).
Handlers now return Result<ExitStatus, CommandError> directly; the 0.5.0
Outcome-slot shim is deleted. Registry::run_argv is the single place that
prints errors and maps them to process exit codes. Flag values go through
the typed accessors (ctx.param::<usize>("--exercise")?), so a bad value
is a usage error in the registry's one format.

deka_cli depends on deka-cli-core 0.6.0 from crates.io and drops dcore
(which stays on 0.5.0 for the legacy CLI, and whose curated help describes
that CLI); global and per-command help render locally from the registry.
tests() and build() write through Context output sinks, so run_captured
asserts PASS/FAIL counts and the OK line in-process.
@samifouad
samifouad merged commit 8fa77ab into main Oct 2, 2026
11 checks passed
@samifouad
samifouad deleted the kimi/cli-core-1204 branch October 2, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Native CLI: rebuild deka_cli on the deka-cli-core registry

1 participant