Skip to content

feat(cli): headless CLI subcommands + parity table#52

Merged
sepehr-safari merged 1 commit into
mainfrom
feat/headless-cli
Jul 11, 2026
Merged

feat(cli): headless CLI subcommands + parity table#52
sepehr-safari merged 1 commit into
mainfrom
feat/headless-cli

Conversation

@sepehr-safari

Copy link
Copy Markdown
Member

What

feat(cli): the headless CLI (S4 #45) — the Studio binary's second face.
Closes #45 and completes S4.

Changes

  • src/cli.zigmaybeRun(init) dispatches on argv; a known subcommand runs
    and returns an exit code, and main exits before opening a window (a bare trace
    path opens the GUI). Subcommands mirror the toolkit CLI:
    • inspect <file> — counts + failures summary.
    • report <file> [-f markdown|html] — report to stdout.
    • diff <a> <b> [--format text|json] — trace diff.
    • anonymize <file> — anonymized JSON to stdout.
    • ci — run the vendored conformance scenarios; exit 0 (all pass) / 1.
    • scenario list / scenario run <name>.
  • Testable core. render*(bytes) → bytes are pure and unit-tested with
    fixtures; the argv / init.io / stdout shell is thin.
  • conformance/harness.zig refactored to expose runAll / runNamed /
    scenarioNames (shared by the conformance test and ci / scenario).
  • main.zigif (cli.maybeRun(init)) |code| std.process.exit(code); before
    any GUI setup.
  • docs/cli-parity.md — the parity table + intentional differences.

Intentional differences (documented)

  • stdout-only — no -o <file> yet (redirect: studio report t.json > out.md).
  • ci runs the embedded contract, not a user directory (Studio vendors the
    15 contract-v1 scenarios).

Verification

  • native test -Dplatform=null123/123; native check --strict clean;
    zig fmt clean.
  • native build (ReleaseFast) succeeds, and I ran the binary end-to-end:
    studio ci → 15× PASS, exit 0; inspect / report / diff (text + json) /
    anonymize / scenario list|run all correct; error paths exit 1 (bad file) /
    2 (bad usage). Both test and build pass — the full app path is analyzed,
    not just the Debug test build.

Note

Real wall-clock replay auto-play stays deferred to #33 (no runner timer effect) —
a replay-UI concern, not a CLI one.

Add src/cli.zig: the Studio binary's second face. maybeRun dispatches on argv
and, for a known subcommand, runs it and exits before any window opens (called
from main before runWithOptions — no runner eject needed, per the spike). A bare
trace path still opens the GUI.

Subcommands mirror the toolkit CLI: inspect, report (markdown/html), diff
(text/json), anonymize, ci (exit 0/1), and scenario (list / run) — thin glue over
the already-built pure engines. The render core is pure (bytes in, bytes out) and
unit-tested with fixtures; the argv / init.io / stdout shell is thin. Refactor
conformance/harness.zig to expose a callable runAll / runNamed / scenarioNames
(shared by the conformance test and the ci/scenario commands). Document parity and
the intentional differences (stdout-only, embedded-contract ci) in
docs/cli-parity.md.

Closes #45.
@sepehr-safari sepehr-safari merged commit d18523c into main Jul 11, 2026
3 checks passed
@sepehr-safari sepehr-safari deleted the feat/headless-cli branch July 11, 2026 22:05
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.

feat(cli): headless CLI subcommands + parity table

1 participant