feat(cli): command-descriptor registry + stash manifest --json#572
Conversation
🦋 Changeset detectedLatest commit: d6c7a48 The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
…-3431)
Phase 1 of docs/plans/cli-help-and-manifest.md: a single source of truth for
command metadata so help/docs can't drift from the real command set.
- src/cli/registry.ts: Flag/CommandDescriptor/CommandGroup types + the full
command surface (groups, summaries, flags; long/examples for key commands),
populated from the existing HELP surface and per-command flag parsing.
- src/cli/manifest.ts: buildManifest(version) → { name, version, groups[] },
the exact contract the docs generator (cipherstash/docs#45) targets. version
comes from the CLI's package.json.
- `stash manifest --json` emits the structured surface; `stash manifest` prints
a grouped human-readable list. Pure metadata — no native binary required.
Additive and non-breaking; the top-level HELP string is untouched. Rendering
help from the registry (phases 2–4) is the documented follow-on.
Tests: unit coverage for buildManifest shape/version/hidden-exclusion; e2e for
`manifest --json`, `manifest`, and `--help` listing the command.
202dab5 to
715e489
Compare
coderdan
left a comment
There was a problem hiding this comment.
Test-coverage review — stash manifest / command-descriptor registry (PR #572)
Solid coverage overall: buildManifest version/name stamping, non-hidden command counts, the auth login worked example, the shared --database-url flag, JSON round-tripping, and both e2e output modes are all exercised. Two gaps worth closing, both in packages/cli/src/cli/manifest.ts:
- The hidden-command exclusion is only tested vacuously. No command in
registry.tssetshidden: true, so theexcludes hidden commandstest loops over an empty array and the.filter((cmd) => !cmd.hidden)branch's actual drop path is never executed. This is the classic "the negative case has no data to negate" anti-pattern — the guard could be inverted (filter(c => c.hidden)) and every test would still pass. BecausebuildManifestreads the module-levelregistry, closing this needs a small testability seam. - The
examplesoptional-field passthrough branch is untested.toManifestCommandhas three separateif (...!== undefined)copy branches forlong,examples, andflags;longandflagsare asserted present (viaauth login) and the all-undefined case is asserted absent (viawizard), but no test confirms a command'sexamplesarray actually survives into the manifest.
Inline sketches below. No out-of-scope security concerns noted.
Additional coverage gaps not posted inline
- The text-mode output of
manifestCommand(commands/manifest/index.ts) is exercised by the e2e only forauth login/--jsonsubstrings; the groupedtitle:headers and the trailingRun stash manifest --jsonhint line are not asserted. Low value — mentioning for completeness.
Registry-vs-reality fixes (the drift this PR exists to prevent): - encrypt status/plan: drop --table/--column — both dispatch to zero-arg commands (statusCommand()/planCommand()) that ignore them - eql install: add the real --name/--out flags (forwarded to the drizzle path) - db migrate: mark summary "(not yet implemented)" and drop the --database-url flag it never reads (dispatch only prints a not-implemented warning) Cleanup / correctness: - manifest: toManifestCommand now defensively copies examples/flags so the manifest can't alias the registry's shared flag singletons (mutation safety) - registry: extract TABLE/COLUMN/DRY_RUN/EXCLUDE_OPERATOR_FAMILY/SUPABASE_COMPAT shared flag consts (were copy-pasted 3-5x), matching the DATABASE_URL_FLAG pattern - manifest: drop the single-use `ManifestFlag = Flag` alias - soften the "single source of truth" claim (registry docstring + changeset): it's additive; HELP stays authoritative for --help until phase 2 Tests: - buildManifest gains a `groups` injection seam so the hidden-command filter is driven by a stub (was vacuously green against the real registry) - add positive assertions for examples passthrough and the defensive-copy fix
|
Addressed a code review + the test-gap review in Registry-vs-reality drift (the failure mode this PR exists to prevent — the manifest was hand-transcribed from
Correctness / cleanup:
Test gaps (both threads):
One finding I did not change: the Verification: 382 unit + manifest e2e green; typecheck adds no new errors; lint clean. |
stash manifest --json (CIP-3431)stash manifest --json
Registry-vs-reality fixes (the drift this PR exists to prevent): - encrypt status/plan: drop --table/--column — both dispatch to zero-arg commands (statusCommand()/planCommand()) that ignore them - eql install: add the real --name/--out flags (forwarded to the drizzle path) - db migrate: mark summary "(not yet implemented)" and drop the --database-url flag it never reads (dispatch only prints a not-implemented warning) Cleanup / correctness: - manifest: toManifestCommand now defensively copies examples/flags so the manifest can't alias the registry's shared flag singletons (mutation safety) - registry: extract TABLE/COLUMN/DRY_RUN/EXCLUDE_OPERATOR_FAMILY/SUPABASE_COMPAT shared flag consts (were copy-pasted 3-5x), matching the DATABASE_URL_FLAG pattern - manifest: drop the single-use `ManifestFlag = Flag` alias - soften the "single source of truth" claim (registry docstring + changeset): it's additive; HELP stays authoritative for --help until phase 2 Tests: - buildManifest gains a `groups` injection seam so the hidden-command filter is driven by a stub (was vacuously green against the real registry) - add positive assertions for examples passthrough and the defensive-copy fix
Implements phase 1 of the CLI help/manifest proposal (
docs/plans/cli-help-and-manifest.md), tracked by CIP-3431.Why
The docs V2 CLI reference is generated from the
stashCLI, but today it has to scrape--help— a hand-written string that drifts from the real command set (e.g. published--helpstill listeddb installafter it moved toeql install). This adds a structured, versioned source of truth.What
src/cli/registry.ts—Flag/CommandDescriptor/CommandGrouptypes plus the full command surface (groups, summaries, flags;long+examplesfor key commands), populated from the existingHELPand per-command flag parsing.src/cli/manifest.ts—buildManifest(version)→{ name, version, groups[] }, the exact contract the docs generator (cipherstash/docs#45) targets.versioncomes from the CLI'spackage.json, so a generated page always names the version it describes.stash manifest --jsonemits the structured surface;stash manifest(no flag) prints a grouped human-readable list. Pure metadata — no native binary required, so it runs anywhere.Scope / non-goals
Additive and non-breaking: the top-level
HELPstring is untouched in this PR. Rendering the top-level and per-command--helpfrom the same registry (and wiringrun) is the documented phase 2–4 follow-on — deliberately separate to keep this diff reviewable and to avoid disturbing the help text existing e2e tests pin.Tests
buildManifestshape, version stamping, hidden-command exclusion, clean JSON round-trip, theauth loginworked example, shared--database-urlflag.stash manifest --json(versioned/grouped, contains known commands),stash manifest(plain list),--helplistsmanifest.