Skip to content

release/0.2.5824: CLI parsing/status/exit-code regressions #528

@justrach

Description

@justrach

Summary

On the release/0.2.5824 branch/local build, several CLI behaviors are either unsupported, confusing, or inconsistent with the documented CLI surface. These were found while smoke-testing the installed local binary:

$ codedb --version
codedb 0.2.5824

The release branch currently needed a local embedded semver correction in src/release_info.zig to report 0.2.5824; upstream origin/release/0.2.5824 still showed 0.2.5823 when tested.

Environment

  • Branch: release/0.2.5824
  • Binary path: /opt/homebrew/bin/codedb
  • Platform: macOS arm64
  • Zig: 0.16.0

Confirmed CLI issues

1. codedb status is unsupported

MCP exposes status-style functionality, but CLI does not support a matching status command.

$ codedb status
# exits 1 and prints general usage

Relevant code:

  • CLI usage list: src/main.zig:1981-2055
  • command recognition list excludes status: src/main.zig:1728-1734

Potential fix:

  • Add status to the CLI command list and implement a read-only status renderer, or explicitly document that status is MCP-only.
  • A minimal CLI status could print indexed file count, store sequence, and scan/snapshot state, mirroring codedb_status.

2. deps flags before the path are misparsed

This form is documented naturally by usage as deps <path> [--depends-on] ..., but many CLI users place flags before positional arguments. Currently that misparses the flag as the path:

$ codedb deps --depends-on src/main.zig
--depends-on is imported by:
  (none)

did you mean:
  ...

The working form is:

$ codedb deps src/main.zig --depends-on

Relevant code:

  • runCliTool stores the first post-command arg as path before scanning flags: src/mcp.zig:3883-3920

Potential fix:

  • Parse deps args in any order: consume known flags first, identify the first non-flag as path, and validate unknown flags.
  • Ensure --max-depth consumes its numeric argument regardless of flag position.

3. Malformed read -L range is treated as a file path

$ codedb read -L nope src/main.zig
✗ not indexed and disk read failed: -L

Expected: a clear range validation error such as invalid line range: nope.

Relevant code:

  • read option parsing breaks on malformed -L, then falls through with -L as the path: src/main.zig:364-394

Potential fix:

  • When -L/--lines is present, require the next token and validate FROM-TO immediately.
  • On parse failure, return exit 1 with a specific usage/error message.

4. Reversed read -L range exits 0 with empty content

$ codedb read -L 20-1 src/main.zig
✓ src/main.zig  zig  L20-1  ...
# no content, exit 0

Expected: reject reversed ranges or normalize intentionally.

Relevant code:

  • read range parsing/output: src/main.zig:364-488

Potential fix:

  • After parsing, validate start <= end unless end is EOF/std.math.maxInt(u32).
  • Return exit 1 with invalid line range: start must be <= end.

5. No-result commands often exit 0

The following no-result cases exit successfully even though they report no match/entry:

codedb find __DefinitelyMissingSymbol__
codedb symbol __DefinitelyMissingSymbol__
codedb word __DefinitelyMissingIdentifier__
codedb file zzzzzzzzzzzzzzzz
codedb glob 'no/such/**/*.zig'
codedb ls no/such/dir
codedb outline does-not-exist.zig

This may be intentional for search-like commands, but it is inconsistent with missing required args exiting 1. It also makes shell scripting less reliable.

Potential fix:

  • Decide and document CLI exit-code semantics. Suggested split:
    • Usage/invalid input: exit 2 or 1
    • Operational errors/security blocked paths: exit 1
    • Valid query with zero results: either exit 0 consistently and document it, or exit 1 consistently for commands whose purpose is to find a single required entity (find, outline, read).

Safety checks that passed

These worked as expected:

codedb read /etc/passwd      # blocked
codedb read ../README.md     # blocked
codedb read .env             # blocked
codedb / search buildSnapshot # rejected as unsafe root

Relevant safety implementation for read: src/main.zig:395-411.

Suggested implementation plan

  1. Add argument-parsing helpers for command options instead of ad hoc positional parsing.
  2. Fix deps to support flags before/after path and reject unknown flags.
  3. Fix read -L validation for malformed, missing, zero, and reversed ranges.
  4. Add or explicitly document status CLI behavior.
  5. Define exit-code semantics and add tests for missing args, invalid args, zero results, and blocked reads.
  6. Add release regression tests around the above cases.

Tested working examples

codedb tree
codedb outline src/main.zig
codedb find buildSnapshot
codedb search buildSnapshot
codedb search --regex 'buildSnapshot|codesign'
codedb search --paths-only buildSnapshot
codedb word Explorer
codedb read src/release_info.zig
codedb read -L 1-3 src/release_info.zig
codedb hot
codedb symbol main
codedb callers buildSnapshot
codedb deps src/main.zig
codedb deps src/main.zig --depends-on
codedb glob 'src/*.zig'
codedb ls src
codedb file releasinfo
codedb context 'check CLI search and outline commands'

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions