Commit 5e0bb31
committed
fix(cli): harden
An 8-angle adversarial review of this branch confirmed 10 defects (plus one
skill nit); this commit fixes all of them:
1. --write's overwrite decision (refusal AND interactive confirm) now runs
BEFORE minting — a declined overwrite previously discarded a live,
shown-exactly-once access key, contradicting the file's own contract.
2. Stdout is now actually pipe-clean: every clack call routes chrome to
stderr via { output: process.stderr }, so `stash env > prod.env` and
pipes into dotenv consumers capture only the block. (clack defaults
everything to stdout — the old comment's claim was wrong.)
3. This also fixes prompts rendering into redirected stdout (isInteractive
is stdin-only): prompts on stderr stay visible on the terminal.
4. `--write <path>` is now a feature, not a parse trap: parseArgs put the
path in values.write leaving flags.write undefined, silently printing
secrets to stdout. main.ts passes values.write ?? flags.write and the
command accepts a target path.
5. `--name` followed by another flag gets its own name_requires_value
diagnostic instead of a false missing_name.
6. `stash env <positional>` is rejected with did-you-mean --name guidance
instead of silently vanishing into the subcommand slot.
7. --json + --write now compose: the file is written and the JSON
confirmation ({ status: 'written' }) is deliberately secret-free.
8. 0600 is enforced on overwrite too (writeFileSync's mode only applies on
creation) via an explicit chmod.
9. All three API responses are zod-validated; non-base64 client_key is
refused before Node's lenient decoder can transcode garbage; a service
shape change can no longer print undefined into a credentials file.
10. The member role is pinned in the request (wire value verified lowercase
in cts-common) AND asserted on the response — a non-member key is
refused with revocation guidance, so the documented 'cannot mint admin
keys' invariant is enforced, not assumed.
11. All exits go through CliExit (never deep process.exit), so run()
records env outcomes for telemetry; cancel paths use CliExit(0). The
three divergent dead-code exit trailers are gone.
12. skills/stash-cli: the bare --env-file mention is attributed to
`supabase functions serve`, per the manifest-resolution rule.
Tests: 21 env unit tests (preflight-before-mint asserted via zero fetch
calls; chrome-on-stderr; role pinning; validation refusals; json+write
secret-free event; chmod-on-overwrite) and 4 e2e cases (all credential-free
pre-mint failures, including asserting error chrome lands on stderr, not
stdout). Full suite: 534 unit / 62 e2e green, code:check exit 0.
Claude-Session: https://claude.ai/code/session_01MxTTPaPP16m6br7Hoab94wstash env — all 10 findings from the branch review1 parent 3b83a37 commit 5e0bb31
8 files changed
Lines changed: 525 additions & 154 deletions
File tree
- .changeset
- packages/cli
- src
- bin
- cli
- commands/env
- __tests__
- tests/e2e
- skills/stash-cli
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
13 | 22 | | |
14 | 23 | | |
15 | 24 | | |
16 | 25 | | |
17 | | - | |
| 26 | + | |
18 | 27 | | |
19 | 28 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
533 | 533 | | |
534 | 534 | | |
535 | 535 | | |
536 | | - | |
| 536 | + | |
| 537 | + | |
| 538 | + | |
| 539 | + | |
537 | 540 | | |
538 | 541 | | |
| 542 | + | |
| 543 | + | |
| 544 | + | |
| 545 | + | |
| 546 | + | |
539 | 547 | | |
540 | 548 | | |
541 | 549 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
545 | 545 | | |
546 | 546 | | |
547 | 547 | | |
| 548 | + | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
548 | 552 | | |
549 | 553 | | |
550 | 554 | | |
551 | 555 | | |
| 556 | + | |
552 | 557 | | |
553 | 558 | | |
554 | 559 | | |
| |||
560 | 565 | | |
561 | 566 | | |
562 | 567 | | |
| 568 | + | |
563 | 569 | | |
564 | | - | |
| 570 | + | |
565 | 571 | | |
566 | 572 | | |
567 | 573 | | |
568 | 574 | | |
569 | | - | |
| 575 | + | |
570 | 576 | | |
571 | 577 | | |
572 | 578 | | |
| |||
0 commit comments