cli: harden argument parsing, validation, and exit codes (#528)#529
Conversation
Fixes the CLI parsing/status/exit-code regressions reported in #528. - read -L: reject malformed / non-numeric / zero / reversed ranges with a clear error instead of silently defaulting (`abc-10` -> 1) or printing empty exit-0 output (`20-1`); parse `-L`/`--compact` before OR after the path, and reject unknown flags + extra args (items 3, 4, 7, 8) - runCliTool: return exit 1 when a bridged handler emits an `error:` line (context / glob / file / symbol / deps were exit 0 on failure), keying off the same `error:` marker MCP uses; zero-result wording keeps exit 0 (item 6) - deps: parse flags in any order, resolve the first non-flag token as the path, reject unknown flags, require a positive `--max-depth` (items 2, 11) - search: reject unknown `--flags` instead of searching for the flag text, support `--max-results N`, reject empty query, and let `--` end flag parsing so a literal `--foo` can still be searched (item 9) - regex: surface error.InvalidRegex instead of swallowing it and reporting "no results" (item 10) - --no-telemetry: strip/honor it globally (was only parsed after `mcp`), matching its documented "global option" status (item 12) - status: add a read-only `codedb status` CLI command mirroring codedb_status (item 1) - docs: document zero-result = exit 0 semantics in `--help` (item 5) New pure helpers parseLineRange / parseSearchArgs / parseDepsArgs replace the ad-hoc positional parsing and are unit-tested in test_mcp.zig; the invalid-regex path is tested in test_explore.zig. zig build test is green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Benchmark Regression ReportThresholds: 10.00% and 50,000 ns absolute delta
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1cba0f601a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| } else if (std.mem.eql(u8, a, "--no-telemetry")) { | ||
| // #528 item 12: --no-telemetry is documented as a global option, | ||
| // so strip it before positional parsing (like --config-file) | ||
| // instead of only honoring it after `mcp`. Telemetry.init also | ||
| // honors CODEDB_NO_TELEMETRY. | ||
| no_telemetry = true; | ||
| continue; |
There was a problem hiding this comment.
Preserve literal --no-telemetry command arguments
Because --no-telemetry is stripped before positional parsing regardless of command context, users can no longer pass it as data to commands that explicitly support -- for literals. For example, codedb search -- --no-telemetry is filtered down to search -- and then fails with MissingQuery, even though parseSearchArgs documents and tests -- as the escape for searching ---prefixed strings; this also prevents searching for this flag in the codebase itself. Consider only treating it as global before the command/root boundary or otherwise preserving it after a command's -- sentinel.
Useful? React with 👍 / 👎.
…, CLI hardening, ReScript - release_info.semver 0.2.5823 -> 0.2.5824 (the version codedb reports and update.zig compares against; build.zig.zon was already 0.2.5824). - CHANGELOG: document the warm CLI daemon (#525), faster fuzzy find (#526), CLI hardening (#529), ReScript .res/.resi (#532), and audit fixes (#530) alongside the existing code-graph / snapshot-load sections. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Fixes the CLI parsing / status / exit-code regressions reported in #528. Closes #528.
The root cause across most findings was ad-hoc, per-command positional parsing. This PR introduces small pure, unit-tested argument parsers (
parseLineRange,parseSearchArgs,parseDepsArgs) and routes the bridged commands through a shared exit-code helper.Findings addressed
codedb statusCLI commandstatusrenderer mirroringcodedb_status(version, root, files, seq, outlines, index)deps --depends-on <path>misparsed flag as pathparseDepsArgs: flags any order, first non-flag = pathread -L nopetreated as a pathparseLineRange→ clearinvalid line rangeerror, exit 1read -L 20-1exited 0 with no outputReversed, exit 1--helperror:but exited 0finishClireturns 1 when the handler's output starts witherror:(same marker MCP uses forisError); zero-result wording keeps exit 0read -L 0-3/abc-10/10-abcsilently defaultedparseLineRangerejects zero/non-numeric ends, exit 1read <path> -L 1-3ignored trailing flagssearch --max-results 1 foosearched literal--max-resultsparseSearchArgs: reject unknown flags, support--max-results N, reject empty query,--ends flagssearchContentRegex[WithScope]pre-compiles and returnserror.InvalidRegex; CLI/MCP reportinvalid regexdepsignored unknown flags / coerced bad--max-depthto 1--no-telemetrydocumented global but only parsed aftermcp--config-file)Tests
src/test_mcp.zig—parseLineRange,parseSearchArgs,parseDepsArgs, andfinishCli(exit-code mapping incl. zero-result = exit 0).src/test_explore.zig—searchContentRegexsurfaceserror.InvalidRegex.zig build testis green.End-to-end verification
Ran the binary against the issue's repro cases:
🤖 Generated with Claude Code