claudebox help is a sed of its own header, and the flags it advertises are not real #8

Closed
opened 2026-07-13 20:23:24 +00:00 by dan-claude-bot · 0 comments
dan-claude-bot commented 2026-07-13 20:23:24 +00:00 (Migrated from github.com)

Problem

claudebox help is eight lines of comment scraped out of the script's own
header, and the CLI around it doesn't honor the conventions every other
command-line tool does. A first-time user (my co-founder, this week) can't find
out what the tool does, and — worse — several things the CLI appears to offer
don't exist.

The help itself

It is a sed of its own source. bin/claudebox:89:

help|*)   sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//' ;;

Hard-coded line numbers against the header comment. Add a line to the top of the
file and the help silently truncates or starts printing set -euo pipefail.

It has no structure. No NAME / SYNOPSIS / COMMANDS / OPTIONS /
EXAMPLES sections. Commands are smashed together as shell|down|start|status|rm <box>, so nothing says what down does (stop, keeping state) or how it differs
from rm (irreversible). The flags are the worst of it: --remote, --vm,
--container and --force appear only inside a synopsis line, and are never
explained anywhere — not in the help, not in the README.

There is no -h/--help. claudebox --help works only by accident (it
falls through the catch-all). Per-command help doesn't exist at all:

$ claudebox new --help
claudebox: usage: claudebox new --name <box> [--from <src>[/<snap>]]
$ echo $?
1

--help gets swallowed as a positional arg and you get an error, not help.

There is no --version. The installer says "re-run any time to upgrade" and
gives you no way to tell what you're on.

The CLI contract around it

These are the things that actually cost my co-founder time — the help is only
half the problem, because parts of the interface it would be documenting
aren't real.

Typos exit 0. Any unknown command hits help|*), prints help, and returns
success. claudebox lst, claudebox delete work, claudebox list — all
"succeed". A script can't detect it and a human reads a wall of help as though it
were output.

Unknown flags are swallowed as positional args. The parser's *) arm pushes
anything it doesn't recognize into args, so a typo'd flag becomes data:

$ claudebox snapshot work --labl mysnap    # label is now literally "--labl"

No "unknown flag" error anywhere.

--force is dead — and rm force-deletes regardless. The flag is parsed and
never read; shellcheck flags it (SC2034: force appears unused):

--force) force=1; shift ;;          # line 23 — the only mention of it
rm) need_name; incus delete -f ...  # line 87 — always -f, force or not

So claudebox rm work immediately destroys a running box, with no
confirmation
— while offering a --force flag that implies the bare form is
the careful one. The README calls rm "irreversible; snapshot first". This is
the one that loses work.

Proposal

Rewrite the help to the standard shape, and make the interface it describes true.

  1. Structured help from a real usage() function (no self-sed): NAME,
    SYNOPSIS, COMMANDS (one line each, describing behavior), OPTIONS (every
    flag, explained), EXAMPLES (the fresh-box and snapshot→clone flows),
    EXIT STATUS, and a pointer to the isolation/creds-free model.
  2. Per-command help: claudebox help <cmd> and claudebox <cmd> --help
    print a focused page — description, flags that apply, examples.
  3. -h / --help accepted anywhere; --version / -V prints the version.
  4. Usage errors exit 2, on stderr, with a "did you mean …?" suggestion for a
    near-miss command. Unknown flags are rejected instead of silently becoming
    arguments (-- still passes everything through for exec).
  5. Make --force real⚠️ behavior change: rm confirms before deleting
    (y/N) when attached to a TTY; --force/-f skips the prompt; with no TTY
    and no --force it refuses and exits 2 rather than destroying a box in a
    script. Also fixes per-command usage strings (e.g. exec currently reports
    usage: claudebox exec <box>, omitting -- <cmd...>).
  6. Clean up the two standing shellcheck findings (SC2034, SC2015) so the
    script lints clean.
## Problem `claudebox help` is eight lines of comment scraped out of the script's own header, and the CLI around it doesn't honor the conventions every other command-line tool does. A first-time user (my co-founder, this week) can't find out what the tool does, and — worse — several things the CLI *appears* to offer don't exist. ### The help itself **It is a `sed` of its own source.** [`bin/claudebox:89`](../blob/main/bin/claudebox#L89): ```sh help|*) sed -n '2,9p' "$0" | sed 's/^# \{0,1\}//' ;; ``` Hard-coded line numbers against the header comment. Add a line to the top of the file and the help silently truncates or starts printing `set -euo pipefail`. **It has no structure.** No `NAME` / `SYNOPSIS` / `COMMANDS` / `OPTIONS` / `EXAMPLES` sections. Commands are smashed together as `shell|down|start|status|rm <box>`, so nothing says what `down` *does* (stop, keeping state) or how it differs from `rm` (irreversible). The flags are the worst of it: `--remote`, `--vm`, `--container` and `--force` appear only inside a synopsis line, and are never explained anywhere — not in the help, not in the README. **There is no `-h`/`--help`.** `claudebox --help` works only by accident (it falls through the catch-all). Per-command help doesn't exist at all: ```console $ claudebox new --help claudebox: usage: claudebox new --name <box> [--from <src>[/<snap>]] $ echo $? 1 ``` `--help` gets swallowed as a positional arg and you get an error, not help. **There is no `--version`.** The installer says "re-run any time to upgrade" and gives you no way to tell what you're on. ### The CLI contract around it These are the things that actually cost my co-founder time — the help is only half the problem, because parts of the interface it *would* be documenting aren't real. **Typos exit 0.** Any unknown command hits `help|*)`, prints help, and returns success. `claudebox lst`, `claudebox delete work`, `claudebox list` — all "succeed". A script can't detect it and a human reads a wall of help as though it were output. **Unknown flags are swallowed as positional args.** The parser's `*)` arm pushes anything it doesn't recognize into `args`, so a typo'd flag becomes data: ```console $ claudebox snapshot work --labl mysnap # label is now literally "--labl" ``` No "unknown flag" error anywhere. **`--force` is dead — and `rm` force-deletes regardless.** The flag is parsed and never read; shellcheck flags it (`SC2034: force appears unused`): ```sh --force) force=1; shift ;; # line 23 — the only mention of it rm) need_name; incus delete -f ... # line 87 — always -f, force or not ``` So `claudebox rm work` **immediately destroys a running box, with no confirmation** — while offering a `--force` flag that implies the bare form is the careful one. The README calls `rm` "irreversible; snapshot first". This is the one that loses work. ## Proposal Rewrite the help to the standard shape, and make the interface it describes true. 1. **Structured help** from a real `usage()` function (no self-`sed`): `NAME`, `SYNOPSIS`, `COMMANDS` (one line each, describing behavior), `OPTIONS` (every flag, explained), `EXAMPLES` (the fresh-box and snapshot→clone flows), `EXIT STATUS`, and a pointer to the isolation/creds-free model. 2. **Per-command help**: `claudebox help <cmd>` and `claudebox <cmd> --help` print a focused page — description, flags that apply, examples. 3. **`-h` / `--help` accepted anywhere**; `--version` / `-V` prints the version. 4. **Usage errors exit 2**, on stderr, with a "did you mean …?" suggestion for a near-miss command. Unknown flags are rejected instead of silently becoming arguments (`--` still passes everything through for `exec`). 5. **Make `--force` real** — ⚠️ *behavior change*: `rm` confirms before deleting (`y/N`) when attached to a TTY; `--force`/`-f` skips the prompt; with no TTY and no `--force` it refuses and exits 2 rather than destroying a box in a script. Also fixes per-command usage strings (e.g. `exec` currently reports `usage: claudebox exec <box>`, omitting `-- <cmd...>`). 6. Clean up the two standing shellcheck findings (`SC2034`, `SC2015`) so the script lints clean.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: heavy-duty/box#8
No description provided.