CLI quality gates and plan (stages 3-4)
quality/cli.md: gates for parsing/defaults, guard/scan/auth, remote commands, assets, and error/secret handling. plan/cli.md: ordered implementation checklist. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e215dd8b87
commit
c4abadc8e4
|
|
@ -0,0 +1,70 @@
|
|||
# Plan: the CLI
|
||||
|
||||
Ordered, dependency-first tasks for `architecture/cli.md`, each mapped to the
|
||||
gate(s)/test(s) it satisfies.
|
||||
|
||||
## Foundations
|
||||
|
||||
- [x] Add `clap_complete` + `clap_mangen` workspace deps; create the `cbd-cli`
|
||||
crate (clap defs default; `client` feature adds the gRPC executor).
|
||||
- [x] `cbd-cli`: `Role`, `RemoteArgs`, `Connection`, the command enums, the
|
||||
three top-level `Cli`s, `generate_assets`, `print_completions`, and a
|
||||
`run_remote` stub. Compiles with and without `client`.
|
||||
|
||||
## Remote executor (`cbd-cli` `client` feature)
|
||||
|
||||
- [ ] Implement `run_remote`: dispatch every `LibraryCmd`/`QueueCmd`/`GlobalCmd`
|
||||
to its RPC via the generated client; pretty-print listings and the queue;
|
||||
concise messages for mutations. Add the missing `Stop` call. _(Gates: remote
|
||||
commands. Tests: a request-mapping unit test per group against a fake tonic
|
||||
server, or at least argument-parse tests for the clap tree.)_
|
||||
- [ ] Map gRPC `Status`/transport errors to a short `color-eyre`/`eyre` report
|
||||
(no chain dump for "unreachable"). _(Gate: remote errors.)_
|
||||
|
||||
## Config writers
|
||||
|
||||
- [ ] Server: `ServerSettings::store(config_dir)` round-trips `[auth]`
|
||||
(preserve other roles, flat shape). _(Gate: guard config write. Test:
|
||||
set one role, reload, other roles intact.)_
|
||||
- [ ] Client: a `Config` writer (load/modify/save `cbd-tui.toml`/`cbd.toml`).
|
||||
_(Gate: auth. Test: round-trip user/password/address.)_
|
||||
|
||||
## Server binary (`crabidy-server`)
|
||||
|
||||
- [ ] Replace the `Cli`/`HashPassword` with `cbd_cli::ServerCli`. No subcommand
|
||||
→ `serve()` (unchanged). _(Gate: no-subcommand default.)_
|
||||
- [ ] `guard`: hash (stdin fallback), print PHC, write config unless
|
||||
`--no-config`. Remove `hash-password`. _(Gate: guard.)_
|
||||
- [ ] `scan`: walk + write tomls; `--capture`/`--move` via a new
|
||||
`CrabidyStore::ingest_file(path, move) -> StoreName` (factor the local-source
|
||||
half of the D4 capture flow). _(Gate: scan. Tests: toml written; capture
|
||||
dedups; move removes source; existing toml skipped.)_
|
||||
- [ ] `library`/`queue`/`global` → `cbd_cli::run_remote` (enable `cbd-cli`
|
||||
`client`). `completions` → `print_completions`.
|
||||
|
||||
## Client binary (`cbd-tui`) and `cbd`
|
||||
|
||||
- [ ] Replace ClapSerde parsing: parse `cbd_cli::TuiCli`; load the TOML config
|
||||
and apply `remote`/`spectrum` overrides; no subcommand → `run(config)`.
|
||||
_(Gate: parsing/defaults. Tests: flag overrides file; first-run writes file.)_
|
||||
- [ ] `auth` writes the client config; `library`/`queue`/`global` →
|
||||
`run_remote`; `completions` prints.
|
||||
- [ ] `cbd`: parse `cbd_cli::CbdCli`; no subcommand → server + TUI (unchanged);
|
||||
subcommands dispatch to the server (guard/scan), client (auth), or remote
|
||||
(library/queue/global) paths. _(Gate: cbd union.)_
|
||||
|
||||
## Assets + build
|
||||
|
||||
- [ ] `build.rs` in each binary: build-dep `cbd-cli` (default features), call
|
||||
`generate_assets` for its `Command` into `OUT_DIR` and, when `CBD_ASSET_DIR`
|
||||
is set, into that dir. _(Gate: assets.)_
|
||||
- [ ] devenv `gen-cli-assets` script: `CBD_ASSET_DIR=$PWD/dist cargo build`.
|
||||
_(Gate: assets.)_
|
||||
|
||||
## Docs + verification
|
||||
|
||||
- [ ] README: a CLI section (subcommands per binary, completions/man, the
|
||||
password-in-argv note); update the config section for `auth`/`guard`.
|
||||
- [ ] `plan/summary.md`: what was built + deviations.
|
||||
- [ ] `cargo test --workspace` green; clippy `-D warnings`, fmt, markdownlint
|
||||
clean (via `devenv shell`).
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
# Quality gates: the CLI
|
||||
|
||||
Criteria beyond the automatic tests (`cbd-cli`, `crabidy-server`, `cbd-tui`).
|
||||
Each gate is pass/fail by reading the code. See `architecture/cli.md`. Boxes are
|
||||
checked as the implement stage verifies them; deviations noted inline.
|
||||
|
||||
## Parsing and defaults
|
||||
|
||||
- [ ] Every binary (`crabidy-server`, `cbd-tui`, `cbd`) parses with clap-derive;
|
||||
`--help`, `--version`, and per-subcommand `--help` work.
|
||||
- [ ] **No subcommand preserves today's behavior**: `crabidy-server` runs the
|
||||
server, `cbd-tui` runs the TUI, `cbd` runs the in-process server + TUI. No
|
||||
extra output, no behavior change on the default path.
|
||||
- [ ] The client config still writes a defaults file on first run, and a
|
||||
provided `--address/--user/--password/--spectrum` overrides the file value;
|
||||
omitted flags fall back to the file. The `cbd-tui.toml`/`cbd.toml` schema is
|
||||
unchanged (same keys).
|
||||
|
||||
## `guard` (server)
|
||||
|
||||
- [ ] Prints the argon2id PHC hash to stdout and nothing else on the hash line
|
||||
(pipe-friendly); the password is never logged.
|
||||
- [ ] Without `--no-config`, writes the hash into the correct `[auth]` field
|
||||
(`owner`/`queue_owner`/`queue_appender`) of `crabidy-server.toml`, creating the
|
||||
file if missing and **preserving the other roles** and the flat shape
|
||||
(`deny_unknown_fields` still parses the result).
|
||||
- [ ] `--no-config` only prints (the exact replacement for the old
|
||||
`hash-password`).
|
||||
- [ ] A missing password argument reads one line from stdin.
|
||||
|
||||
## `scan` (server)
|
||||
|
||||
- [ ] Walks the path (bounded, skips hidden), selects files by audio extension,
|
||||
and writes a `<stem>.cbd-track.toml` beside each with a `Playable::File`
|
||||
pointing at the file's own name; an existing toml is left untouched (warned).
|
||||
- [ ] `--capture` ingests each file into the content store (hash + de-dup +
|
||||
sidecar) and writes a `Playable::Store` toml instead; re-scanning de-dups.
|
||||
- [ ] `--move` moves the source into the store instead of copying; the original
|
||||
location keeps only the toml. `--capture`/`--move` require a store dir.
|
||||
- [ ] No panic on unreadable files/dirs; each defect is a warning, the walk
|
||||
continues.
|
||||
|
||||
## `auth` (client)
|
||||
|
||||
- [ ] Writes `user` (role name) and `password` (cleartext), and `address` when
|
||||
given, into the client config, preserving other fields; creates the file if
|
||||
missing. The help text says the password is stored in plaintext.
|
||||
|
||||
## `library` / `queue` / `global` (remote)
|
||||
|
||||
- [ ] Each subcommand maps to the documented RPC (including a new `Stop`
|
||||
wrapper); `library list` prints child nodes and tracks (captured rows marked).
|
||||
- [ ] Connects with basic-auth from `--user/--password` (config fallback); an
|
||||
empty user talks to an open server with no header.
|
||||
- [ ] A server/RPC error exits non-zero with a readable message; no internal
|
||||
report (color-eyre chain) is dumped for an ordinary "server unreachable" or a
|
||||
gRPC status — those map to a concise message.
|
||||
- [ ] The commands are available on `crabidy-server`, `cbd-tui`, and `cbd`
|
||||
(cbd = union of server + client commands).
|
||||
|
||||
## Assets
|
||||
|
||||
- [ ] `clap_complete` + `clap_mangen` generate bash/zsh/fish completions and a
|
||||
man page for each binary from its top-level `Command` in `build.rs`
|
||||
(`OUT_DIR`), and into `$CBD_ASSET_DIR` when set.
|
||||
- [ ] `build.rs` build-depends on `cbd-cli` with **default features only** (no
|
||||
tonic on ordinary builds).
|
||||
- [ ] A `completions <shell>` subcommand prints a script to stdout.
|
||||
- [ ] A devenv `gen-cli-assets` script produces `dist/completions/**` and
|
||||
`dist/man/*.1`.
|
||||
|
||||
## Errors and safety
|
||||
|
||||
- [ ] Library errors are `thiserror`; CLI reports use `color-eyre`; no panics on
|
||||
bad input, missing config, or an unreachable server.
|
||||
- [ ] Passwords never appear in logs or error messages; the argv-exposure of a
|
||||
password argument is documented and a stdin path is offered.
|
||||
Loading…
Reference in New Issue