Best for
- Use when reviewing CLI applications built with Commander.
agents-inc/skills/src/skills/meta-reviewing-cli-reviewing/SKILL.md
CLI code review patterns. Use when reviewing CLI applications built with Commander.js, @clack/prompts, picocolors. Covers exit codes, signal handling, error messages, user experience, testing adequacy.
Decision brief
Quick Guide: When reviewing CLI code, verify SIGINT handling, p.isCancel() checks, exit code constants, parseAsync() usage, and user feedback (spinners, clear errors). Check config hierarchy, help text quality, and dry-run support. Distinguish severity (Must Fix vs Should Fix vs…
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/agents-inc/skills --skill "src/skills/meta-reviewing-cli-reviewing"Inspect the Agent Skill "meta-reviewing-cli-reviewing" from https://github.com/agents-inc/skills/blob/81d43a51211aca12c85dcc16085fa99014ec548e/src/skills/meta-reviewing-cli-reviewing/SKILL.md at commit 81d43a51211aca12c85dcc16085fa99014ec548e. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
Use this comprehensive checklist for every CLI code review.
Review the “Entry Point Verification” section in the pinned source before continuing.
[ ] SIGINT handler exists in entry point
Verify all exit paths use named constants.
Review the “Exit Code Verification Checklist” section in the pinned source before continuing.
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 23 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Quick Guide: When reviewing CLI code, verify SIGINT handling, p.isCancel() checks, exit code constants, parseAsync() usage, and user feedback (spinners, clear errors). Check config hierarchy, help text quality, and dry-run support. Distinguish severity (Must Fix vs Should Fix vs Nice to Have) and explain WHY each issue matters.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST verify SIGINT (Ctrl+C) handling exists in CLI entry point)
(You MUST verify p.isCancel() is called after EVERY @clack/prompts call)
(You MUST verify exit codes use named constants - flag ANY magic numbers in process.exit())
(You MUST verify parseAsync() is used for async actions, not parse())
(You MUST verify spinners are stopped before any console output or error handling)
</critical_requirements>
Auto-detection: review CLI, check CLI code, CLI PR review, Commander.js review, @clack/prompts review, CLI quality, CLI error handling review, exit codes review
When to use:
When NOT to use:
Key patterns covered:
Detailed Resources:
CLI UX is critical. Unlike web apps with visual feedback, CLI tools communicate entirely through text. Poor error messages, missing progress indicators, or unexpected exits destroy user trust. Review with empathy for the end user.
When reviewing CLI code:
When NOT to be harsh:
Core principles:
Use this comprehensive checklist for every CLI code review.
## CLI Entry Point Review
**Signal Handling:**
- [ ] SIGINT handler exists in entry point
- [ ] SIGINT calls process.exit with EXIT_CODES.CANCELLED
- [ ] Other relevant signals handled (SIGTERM for containers)
**Command Registration:**
- [ ] Commands imported and registered cleanly
- [ ] parseAsync() used (not parse()) for async actions
- [ ] Global error handler with catch() on main()
- [ ] configureOutput() used for colored errors
- [ ] showHelpAfterError(true) enabled
**Global Options:**
- [ ] --dry-run supported for destructive operations
- [ ] --verbose supported for debug output
- [ ] --help generates useful output
- [ ] --version displays correct version
Why this matters: Entry point issues affect every command. Missing SIGINT handling leaves users unable to cancel, missing parseAsync swallows errors silently.
Verify all exit paths use named constants.
## Exit Codes Review
**Named Constants:**
- [ ] Exit codes defined as named constants (e.g., EXIT_CODES object)
- [ ] All exit codes have JSDoc descriptions
- [ ] Uses `as const` for type inference
**Usage Audit:**
- [ ] No magic numbers in process.exit() calls
- [ ] Correct exit code for each scenario:
- Success: EXIT_CODES.SUCCESS (0)
- General error: EXIT_CODES.ERROR (1)
- Invalid args: EXIT_CODES.INVALID_ARGS (2)
- User cancelled: EXIT_CODES.CANCELLED
- Validation failed: EXIT_CODES.VALIDATION_ERROR
// Must Fix: Magic number exit code
process.exit(1); // What does 1 mean?
// Good: Named constant
process.exit(EXIT_CODES.VALIDATION_ERROR);
Why this matters: Magic exit codes are unmaintainable. Scripts that depend on your CLI need predictable, documented exit codes.
Every @clack/prompts call must check for cancellation.
// Must Fix: Missing isCancel check
const name = await p.text({ message: "Name:" });
// User presses Ctrl+C - name is Symbol, code continues with garbage
// Good: Proper cancellation handling
const name = await p.text({ message: "Name:" });
if (p.isCancel(name)) {
p.cancel("Setup cancelled");
process.exit(EXIT_CODES.CANCELLED);
}
Review Checklist:
## Prompt Cancellation Review
For EACH @clack/prompts call (p.text, p.select, p.confirm, p.multiselect):
- [ ] p.isCancel() check immediately follows
- [ ] p.cancel() called with descriptive message
- [ ] process.exit() called with EXIT_CODES.CANCELLED
- [ ] No code executes after isCancel returns true
Why this matters: Missing isCancel checks cause undefined behavior when users press Ctrl+C. The code continues with a Symbol value instead of the expected string/boolean.
Verify spinners and error handling for all async work.
// Must Fix: No feedback for long operation
const data = await fetchRemoteConfig(); // User sees nothing
// Good: Spinner with descriptive messages
const s = p.spinner();
s.start("Fetching configuration...");
try {
const data = await fetchRemoteConfig();
s.stop(`Loaded ${data.items.length} items`);
} catch (error) {
s.stop("Failed to fetch configuration");
p.log.error(error.message);
process.exit(EXIT_CODES.NETWORK_ERROR);
}
Review Checklist:
## Async Operations Review
For EACH async operation (API calls, file operations, network):
- [ ] Spinner started with descriptive message
- [ ] Spinner stopped before any console output
- [ ] Spinner stopped before error logging
- [ ] Success message includes result info
- [ ] Error handling exists with appropriate exit code
Why this matters: Users need feedback that something is happening. Silent operations feel broken.
Evaluate error messages for actionability.
## Error Message Review
For EACH error path:
- [ ] Message explains WHAT failed (not just "Error")
- [ ] Message explains WHY it failed (permission, network, validation)
- [ ] Message suggests HOW to fix it (retry, check config, provide flag)
- [ ] Uses picocolors consistently (red for errors, yellow for warnings)
- [ ] Includes relevant context (file path, option name, command)
// Must Fix: Unhelpful error
p.log.error("Failed");
// Should Fix: Better but no resolution
p.log.error(`Config file not found: ${configPath}`);
// Good: Actionable error
p.log.error(`Config file not found: ${configPath}`);
p.log.info(`Run 'mycli init' to create one, or specify path with --config`);
Why this matters: Actionable errors reduce support burden and improve user experience. Users should never be stuck.
Verify config resolution follows correct precedence.
## Configuration Review
**Precedence Order (highest to lowest):**
1. [ ] CLI flags (--source, --config)
2. [ ] Environment variables (MYAPP_SOURCE)
3. [ ] Project config (.myapp/config.yaml in cwd)
4. [ ] Global config (~/.myapp/config.yaml)
5. [ ] Default values (hardcoded constants)
**Implementation:**
- [ ] resolveConfig function exists and follows precedence
- [ ] Empty flag values handled (--source "" should error or skip)
- [ ] Missing config files handled gracefully (no crash)
- [ ] Source/origin tracked for debugging (--verbose shows where value came from)
Why this matters: Incorrect config precedence confuses users. If env var overrides flag, that's a bug.
Evaluate command documentation quality.
## Help Text Review
**Command Documentation:**
- [ ] Description is clear and concise
- [ ] All options have descriptions
- [ ] Required vs optional options clear
- [ ] Default values documented in option descriptions
**Examples Section:**
- [ ] Common use cases shown
- [ ] Examples are copy-paste ready
- [ ] Complex options demonstrated
**Consistency:**
- [ ] Naming follows conventions (--dry-run not --dryRun)
- [ ] Short flags used for common options (-f for --force)
- [ ] Help shown after errors (showHelpAfterError enabled)
Verify CLI tests cover critical paths.
## Testing Review
**Command Testing:**
- [ ] Happy path tested for each command
- [ ] Invalid arguments tested (missing required, unknown options)
- [ ] --help output tested
- [ ] exitOverride() used to prevent process.exit in tests
**Prompt Testing:**
- [ ] @clack/prompts mocked properly
- [ ] Cancellation flow tested (isCancel returns true)
- [ ] Validation rejection tested
- [ ] Multiple selection paths tested
**File System Testing:**
- [ ] In-memory filesystem used for isolated tests
- [ ] Config loading tested (missing, invalid, valid)
- [ ] File write operations tested
**Exit Code Testing:**
- [ ] Success exits with 0
- [ ] Each error type returns correct non-zero code
- [ ] Cancellation exits with CANCELLED code
See examples/core.md for test code patterns to look for during review.
Verify command organization is logical.
## Command Structure Review
**Organization:**
- [ ] Related commands grouped as subcommands (config show, config set)
- [ ] Each command in separate file
- [ ] No god commands (> 200 lines)
- [ ] Shared utilities extracted to lib/
**Options:**
- [ ] Global options defined on parent (--verbose, --dry-run)
- [ ] optsWithGlobals() used to access parent options
- [ ] Option names consistent across commands
**Arguments:**
- [ ] Positional arguments have clear names
- [ ] Required vs optional arguments documented
- [ ] Argument validation happens early in action
Check for CLI-specific security concerns.
## CLI Security Review
**Input Validation:**
- [ ] No shell injection (user input not concatenated into shell commands)
- [ ] File paths validated before operations
- [ ] URLs validated before fetch
**Secrets Handling:**
- [ ] API keys/tokens not logged (even in verbose mode)
- [ ] Sensitive options not shown in help output
- [ ] Config files with secrets have appropriate permissions warning
**Dependency Injection:**
- [ ] Arguments not passed directly to child_process
- [ ] execa or similar used instead of exec when needed
<decision_framework>
Is this a safety/correctness issue?
├─ Missing SIGINT handler → MUST FIX
├─ Missing p.isCancel() check → MUST FIX
├─ Magic number exit code → MUST FIX
├─ parse() instead of parseAsync() → MUST FIX
├─ Missing error handling on async → MUST FIX
└─ NO → Is it a user experience issue?
├─ Missing spinner for >500ms operation → SHOULD FIX
├─ Unhelpful error message → SHOULD FIX
├─ Incorrect config precedence → SHOULD FIX
├─ Missing --help descriptions → SHOULD FIX
└─ NO → Is it an enhancement?
├─ Could add --json output → NICE TO HAVE
├─ Could add more examples in help → NICE TO HAVE
├─ Could improve verbose logging → NICE TO HAVE
└─ Style preference → DON'T MENTION
APPROVE when:
REQUEST CHANGES when:
MAJOR REVISIONS NEEDED when:
</decision_framework>
<red_flags>
High Priority Issues (Must Fix):
process.on("SIGINT", ...) in entry pointp.isCancel() after ANY prompt callprocess.exit(1) or process.exit(0) instead of named constantsprogram.parse() instead of program.parseAsync() with async actionsMedium Priority Issues (Should Fix):
--dry-run support for destructive operationsshowHelpAfterError(true) configuredCommon Mistakes:
Gotchas & Edge Cases:
--my-option to myOption in options object</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST verify SIGINT (Ctrl+C) handling exists in CLI entry point)
(You MUST verify p.isCancel() is called after EVERY @clack/prompts call)
(You MUST verify exit codes use named constants - flag ANY magic numbers in process.exit())
(You MUST verify parseAsync() is used for async actions, not parse())
(You MUST verify spinners are stopped before any console output or error handling)
Failure to catch these issues will result in CLIs that crash on Ctrl+C, have undocumented exit codes, and silently swallow errors.
</critical_reminders>
Frequently asked questions
Quick Guide: When reviewing CLI code, verify SIGINT handling, p.isCancel() checks, exit code constants, parseAsync() usage, and user feedback (spinners, clear errors). Check config hierarchy, help text quality, and dry-run support. Distinguish severity (Must Fix vs Should Fix vs…
The source record exposes this install command: npx skills add https://github.com/agents-inc/skills --skill "src/skills/meta-reviewing-cli-reviewing". Inspect the command and pinned source before running it.
Alternatives
Jamie-BitFlight/claude_skills
Shared Python 3.11+ development standards covering type safety (ty, native generics, Protocol, TypeIs), layered architecture, error handling, performance, identifier naming, UI/CLI patterns (Rich/Typer), testing requirements (pytest, 80% coverage, TDD), and quality gates. Activates when any Python skill or agent needs to apply shared standards for implementation, code review, refactoring, or test authoring.
VincentChuWaiChow/vanguard-frontier-agentic
Retrieves and analyzes Apex debug logs from a connected Salesforce org to identify governor-limit hits, SOQL N+1 patterns, unhandled exceptions, and async job failures. T1 read-only runtime — retrieves logs only, never executes code or mutates data. TRIGGER when: user asks to analyze an Apex log, debug a trigger failure, diagnose a governor limit hit, interpret a stack trace from a Salesforce org, or review a DEBUG log for performance issues. Trigger phrases: analyze apex log, debug this trigger
VincentChuWaiChow/vanguard-frontier-agentic
Executes Apex tests against a connected SANDBOX org via sf apex run test, parses results and coverage delta, identifies failures with stack traces, and suggests fixes. T1 read-only runtime (sandbox-only). Production org targets are HARD REFUSED before any API call. TRIGGER when: user wants to run Apex tests, execute a test class, check test coverage, diagnose test failures, or validate coverage before deployment. Trigger phrases: run apex tests, execute test class, test my changes, check test co
dotnet/skills
Grade specified test methods individually and produce a concise PR-ready table with each fully qualified test name, an A-F grade, score band, and one-line note. USE FOR per-test feedback on a curated list such as new or modified tests in a pull request, not a suite-wide audit. Polyglot: .NET, Python, TS/JS, Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, C++. Inputs may be test methods, method bodies, or file-and-line spans. DO NOT USE FOR: full suite audits (use test-quality-auditor agent or t