Repository navigation
fix(cli): scope destructive typo recovery to each command - #25699
kambarakun wants to merge 2 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📥 CommitsReviewing files that changed from the base of the PR and between 83858ef2dfca996f56af29dfc3591d85d49e54d9 and 26d65d1. 📒 Files selected for processing (1)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughDestructive command suggestions are now checked against each command’s own paths or aliases. The orchestration Priority: ⬇️ Low Severity of issue fixed: Low Merge Risk: ⚪ Minimal · up to No concrete merge-blocking risk is identified for the command-suggestion change. Merge after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The change suppresses misleading reset suggestions, but also makes some unrelated destructive commands eligible for recovery suggestions. Suggestions do not execute automatically, and command execution still requires a separate valid invocation. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
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 |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
This review covered both commits and all four changed files.
orchestration resetmarked destructive —src/cli/specs/orchestration.ts:295setsdestructive: true, so reset stops surfacing for unrelated verbs (resume,rerun,repl) whilerese/reststill recover it.- Destructive intent scoped per command —
src/cli/command-suggestion.ts:19replaces the registry-widedestructiveVerbs/intendsDestructionpair withintendsDestructiveCommand, so a near-miss unlocks only the candidate whose own path or alias it resembles.artifacts desetno longer unlocksartifacts delete. - Regression coverage — new
describe.eachblocks exercise both the isolated and full registries insrc/cli/command-suggestion.test.tsandsrc/cli/specs/orchestration.test.ts. - Import merge —
src/cli/specs/orchestration.ts:1folds the two../argsimports into one to stay under the 300-line cap.
The new guard is a strict subset of the old one (per-spec verbs ⊆ all destructive verbs), so it can only remove unlocks, never add them; the regression test for artifacts deset would fail against the pre-scoping code. pnpm test src/cli passes (141 files, 1658 tests).
ℹ️ Per-command scoping also narrows a few recovery paths
Binding the guard to each command's own verbs means a near-miss only recovers a candidate that shares its verb. environment remov no longer suggests environment rm (the spec's only verb is rm, with no remove alias), and a compound verb like project setup-del likewise falls outside the one-edit window. These were reachable before only through incidental cross-spec verb leakage, so this is a deliberate tradeoff the PR body already documents; noting it so the full set is on the record rather than only the one example given.
Technical details
# Recovery narrowing from per-command destructive scoping
## Affected sites
- `src/cli/command-suggestion.ts:53` — guard now binds the input token to the candidate spec's own `specPaths` final tokens.
- `src/cli/specs/environment.ts:55` — `environment rm` is the only verb; there is no `remove` alias.
- `src/cli/specs/project.ts:115` — `project setup-delete` is a compound verb; `setup-del` is more than one edit away.
## Required outcome
- None; informational. If that recovery is wanted back, registering `remove` as an alias on `environment rm` (matching `worktree rm` / `account rm`) restores it without weakening the guard.deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏
Use the existing suggestion guard for orchestration reset. Keep near-miss reset recovery and non-destructive command suggestions unchanged.
Match destructive intent against each candidate command and its aliases. Prevent a reset near-miss from unlocking unrelated deletion suggestions, while retaining close-typo and alias recovery.
83858ef to
26d65d1
Compare
|
Closing this PR as superseded by #26934, which has been merged and resolves #25571. The follow-up builds on the reset destructive marker and candidate-specific guard approach from this PR, while preserving alias recovery and extending the protection to additional destructive commands. Thanks for carrying this forward and for the attribution! |

ELI5
Mistyped commands should not steer users toward resetting or deleting saved state. This protects reset suggestions and keeps a typo near one destructive command from unlocking a different one. Close misspellings still recover.
What Changed
orchestration resetas destructive.artifacts desetcannot unlockartifacts deletemerely by resemblingreset.src/cli/command-suggestion.test.ts, covering suggestions, nextSteps, and near-miss recovery across isolated and real registries.Why
Reset was missing its destructive flag. The guard also treated destructive intent globally: classifying reset made an unrelated deletion eligible. Applying the existing one-edit rule to each command fixes both problems without a special-case blacklist. Ranking thresholds, reset execution, and scope validation stay unchanged.
restintentionally remains eligible because it is one edit fromreset; matching any alias still permits recovery of that same command. Verbs absent from a command's own paths and aliases intentionally no longer unlock it (for example,environment removno longer suggestsenvironment rm).Linked Issue
Fixes #25571
Visual Proof
Historical CLI captures are shown below with their original revisions. The rebuilt CLI at
26d65d1b0b61796e98d4bcced0d2528aeecfc4c0reproduces the same After results; no graphical UI is involved.node out/cli/index.js orchestration resume --json— baseline10bea3a8faefc7adf8771f5bfd57a37435ccede4to reviewed head83858ef2dfca996f56af29dfc3591d85d49e54d9:node out/cli/index.js artifacts deset --json— initial headfcc2fcca01bffa1fef3e6b31cbb15503b9679469to reviewed head83858ef2dfca996f56af29dfc3591d85d49e54d9:Both commands exit 1 with
invalid_argument/Unknown command.artifacts delet,orchestration rese/rest,worktree remov/delet, andorchestration chekretain recovery.reset --helpis byte-identical.Testing
Rebased onto
670c59d23a1d87f9ef3bd63b65f44673f16d28e2after #25791 removed the old spec-text test file. Moved this PR's 12 reset-recovery cases alongside its four cross-command cases; no retired spec-text tests were restored. Both production files are byte-identical to83858ef2dfca996f56af29dfc3591d85d49e54d9.Revalidated
26d65d1b0b61796e98d4bcced0d2528aeecfc4c0on macOS 26.5.2 arm64, Node 24.16.0, pnpm 12.8.1:pnpm test src/cli/command-suggestion.test.ts: 31 passed, including all 16 added cases with no skips.pnpm test src/cli: 133 files; 1,635 passed, 4 skipped.pnpm tc:cli, targetedoxlint/oxfmt --checkfor the three changed files, andpnpm run check:code-quality:changed -- 670c59d23a1d87f9ef3bd63b65f44673f16d28e2passed.pnpm exec tsc -p config/tsconfig.cli.json --outDir out --composite false --incremental falseandnode config/scripts/verify-cli-bin.mjs --fix-executable --fix-package-json; no global installation hook.reset --helppassed and matched the historical capture byte-for-byte. No reset or deletion was executed.Full repository lint/typecheck/unit suite, desktop build, Windows/Linux, and live SSH were not run.
AI Disclosure
OpenAI Codex implemented, tested, and rebased the change. Claude Opus 5.5 independently reviewed this conflict repair. The earlier CodeRabbit CLI 0.8.2 and Claude reviews apply to
83858ef2df, not the rebased head.Review
Claude Opus 5.5 independently reviewed this rebase repair and found no actionable issues: all 16 added cases and 15 existing suggestion cases remain, no retired spec-text checks were restored, and the production files match the old head. The review used source and recorded evidence; it did not execute tests.
Historical review of
83858ef2df: CodeRabbit CLI reported zero findings; Claude found no blocking issue and noted the documented narrowing of undeclared synonym recovery. These earlier results are not presented as new-head GitHub review or CI approval.The change affects suggestion policy, not execution authorization. It retains the length guard before edit-distance calculation. No execution handlers, platform branches, remote routing, agents, git-provider integration, mobile UI, persistence, or wire formats change.
Agent skill upstream boundary
Notes
CLI recovery runs before runtime lookup. Local, SSH, and folder execution paths are unchanged.
X: @kambarakun
Checklist
pnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)Original merge base:
10bea3a8faefc7adf8771f5bfd57a37435ccede4. Pre-rebase head:83858ef2dfca996f56af29dfc3591d85d49e54d9. Rebase base:670c59d23a1d87f9ef3bd63b65f44673f16d28e2. Revalidated head:26d65d1b0b61796e98d4bcced0d2528aeecfc4c0.