MCP HubMCP Hub
스킬 목록으로 돌아가기

scaffold-cli-command

pjt222
업데이트됨 2 days ago
2 조회
17
2
17
GitHub에서 보기
테스팅testingdesign

정보

이 스킬은 Commander.js 애플리케이션을 위한 새로운 CLI 명령어를 구성하며, 옵션 구조, 액션 핸들러, 그리고 세 가지 출력 모드(가독성 높은 모드, 간소 모드, JSON 모드)를 생성합니다. 명령어 명명, 오류 처리, 일관성을 보장하기 위한 통합 테스트까지 포함합니다. 기존 CLI에 기능을 추가할 때, 새로운 도구를 처음부터 구축할 때, 또는 다중 명령어 CLI에서 명령어를 표준화할 때 사용하세요.

빠른 설치

Claude Code

추천
기본
npx skills add pjt222/agent-almanac -a claude-code
플러그인 명령대체
/plugin add https://github.com/pjt222/agent-almanac
Git 클론대체
git clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/scaffold-cli-command

Claude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요

문서

Scaffold a CLI Command

Add new command to Commander.js CLI app. Consistent option handling, three output modes, integration tests.

When Use

  • Add new command to existing Commander.js CLI
  • Design multi-command CLI tool from scratch
  • Standardize command structure so all follow same patterns
  • Add "ceremony" variant — replace machine output with warm narrative

Inputs

  • Required: Command name + verb (e.g., gather, audit, sync)
  • Required: What command does (one sentence)
  • Required: Path to CLI entry (e.g., cli/index.js)
  • Optional: Ceremony variant (warm narrative output)
  • Optional: Custom options beyond standard
  • Optional: Subcommand args (positional <name> or [names...])

Steps

Step 1: Choose Command Name and Category

Pick verb that says what command does. Group commands by category.

CategoryVerbsPattern
CRUDinstall, uninstall, list, searchOperates on content
Lifecycleinit, sync, auditManages project state
Ceremonygather, scatter, tend, campfireWarm narrative output

Naming.

  • Single verb (not install-skill — let options specify what)
  • Lowercase, no hyphens in command name itself
  • Positional args: <required> or [optional] or [variadic...]
program
  .command('gather <name>')
  .description('Gather a team around the campfire')

Got: Command name, description, positional args defined.

If fail: Verb overlaps existing? Compose (add option to existing) or differentiate clearly in description.

Step 2: Define Options

Every command should support standard shared options + command-specific.

Standard options (include as needed).

  .option('-n, --dry-run', 'Preview without making changes')
  .option('-q, --quiet', 'Suppress human-readable output')
  .option('--json', 'Output as JSON')
  .option('-f, --framework <id>', 'Target specific framework')
  .option('-g, --global', 'Use global scope')
  .option('--scope <scope>', 'Scope: project, workspace, global', 'project')
  .option('--source <path>', 'Path to tool root directory')

Command-specific options — add only what command needs.

  .option('--ceremonial', 'Show each item arriving individually')
  .option('--only <items>', 'Comma-separated subset to include')
  .option('-y, --yes', 'Skip confirmation prompts')

Design rules.

  • Short flags (-n) for frequent options
  • Long flags (--dry-run) for clarity
  • Defaults as third arg where appropriate
  • Boolean flags (no arg) for toggles

Got: Complete option chain — standard + custom.

If fail: Too many options (>8)? Split into subcommands or group related.

Step 3: Implement Action Handler

Action handler follows consistent pattern.

.action(async (name, options) => {
  // 1. Get shared context (registries, adapters, paths)
  const ctx = getContext(options);

  // 2. Resolve what to operate on
  const items = resolveItems(ctx, name, options);
  if (!items || items.length === 0) {
    reporter.error('Nothing found.');
    process.exit(1);
  }

  // 3. Preview if dry-run
  if (options.dryRun) reporter.printDryRun();

  // 4. Execute the operation
  const results = await executeOperation(items, ctx, options);

  // 5. Output results (3 modes)
  if (options.json) {
    console.log(JSON.stringify(results, null, 2));
  } else if (options.quiet) {
    reporter.printResults(results);
  } else {
    printHumanOutput(results, options);
  }
})

getContext() shared helper centralizes.

  • Root directory detection
  • Registry loading
  • Framework detection or explicit selection
  • Scope resolution

Got: Action handler follows 5-step pattern: context → resolve → preview → execute → output.

If fail: Command does not fit resolve-then-execute (purely informational like detect)? Simplify: context → compute → output.

Step 4: Add Three Output Modes

Every command should support three output modes.

Default (human-readable):

Installing 3 item(s) to Claude Code...

  + create-skill [claude-code] .claude/skills/create-skill
  + write-tests  [claude-code] .claude/skills/write-tests
  = commit-changes [claude-code] (skipped)

  2 installed, 1 skipped

Quiet (--quiet): Standard reporter output — concise lines with status icons (+, -, =, !), no ceremony, no decoration.

JSON (--json):

{
  "command": "install",
  "items": 3,
  "installed": 2,
  "skipped": 1,
  "failed": 0
}

Implementation.

if (options.json) {
  console.log(JSON.stringify(data, null, 2));
  return;
}
if (options.quiet) {
  reporter.printResults(results);
  return;
}
// Default: human-readable output
printHumanReadable(results, options);

Got: All three modes useful. JSON parseable. Quiet concise. Default informative.

If fail: Command no meaningful JSON (e.g., detect)? Skip JSON mode, document why.

Step 5: Add Ceremony Variant (Optional)

For commands that benefit from warm, narrative output instead of transactional.

if (options.json) {
  ceremonyReporter.printJson(data);
} else if (options.quiet) {
  reporter.printResults(results);
} else {
  ceremonyReporter.printArrival({
    teamId: name,
    agents,
    results: { installed, skipped, failed },
    ceremonial: options.ceremonial || false,
  });
}

Ceremony output voice rules.

  1. Present tense, active voice ("mystic arrives", not "mystic was installed")
  2. No exclamation marks
  3. Metaphor replaces jargon ("practices" not "dependencies")
  4. Failures honest, not catastrophic ("a spark was lost")
  5. Closing line reflects state ("The fire burns.")
  6. No emoji — use Unicode glyphs (✦ ◉ ◎ ○ ✗)
  7. Every word must carry information

See design-cli-output skill for detailed terminal output patterns.

Got: Ceremony output follows all voice rules, produces warm, informative narratives.

If fail: Ceremony feels forced or no info beyond standard? Skip. Not every command needs ceremony.

Step 6: Handle Errors and Edge Cases

// Unknown item
if (!item) {
  reporter.error(`Unknown: ${name}. Use 'tool list' to browse.`);
  process.exit(1);
}

// Confirmation for destructive actions
if (!options.yes && !options.quiet && !options.dryRun) {
  const answer = await askYesNo('Proceed?');
  if (!answer) {
    console.log('  Cancelled.');
    return;
  }
}

// State validation
if (!state.fires[name]) {
  reporter.error(`Not active. Nothing to remove.`);
  process.exit(1);
}

Error design.

  • Error msgs suggest corrective action
  • process.exit(1) for unrecoverable
  • Confirmation for destructive (bypass with --yes)
  • Dry-run always succeeds (never blocks on confirmation)

Got: All error paths give helpful msgs. Destructive ops require confirmation.

If fail: Confirmation interferes with scripting? Ensure --yes and --quiet both bypass.

Step 7: Write Integration Tests

import { describe, it, after } from 'node:test';
import assert from 'node:assert/strict';
import { execSync } from 'child_process';

const CLI = 'node cli/index.js';
function run(args) {
  return execSync(`${CLI} ${args}`, { encoding: 'utf8', timeout: 10000 });
}

describe('new-command', () => {
  after(() => { /* cleanup created files/state */ });

  it('dry-run shows preview', () => {
    const out = run('new-command arg --dry-run');
    assert.match(out, /DRY RUN/);
  });

  it('--json outputs valid JSON', () => {
    const out = run('new-command arg --json');
    const start = out.indexOf('{');
    const data = JSON.parse(out.slice(start));
    assert.equal(data.command, 'new-command');
  });

  it('rejects unknown input', () => {
    assert.throws(() => run('new-command nonexistent'), /Unknown/);
  });
});

See test-cli-application skill for full CLI testing patterns.

Got: At least 3 tests: dry-run, JSON output, error case. More for complex commands.

If fail: execSync times out? Up timeout or check for interactive prompts blocking command.

Checks

  • Command registered in CLI entry, appears in --help
  • Standard options (--dry-run, --quiet, --json) work
  • Default output human-readable, informative
  • JSON output valid, parseable
  • Error msgs suggest corrective actions
  • Destructive ops require confirmation (bypass --yes)
  • At least 3 integration tests pass
  • Command follows getContext → resolve → execute → output pattern

Pitfalls

  • Forget JSON mode: Machine consumers (scripts, CI) need structured output. Always implement --json even if seems interactive-only.
  • Confirmation prompts block scripts: Any command that prompts hangs in non-interactive contexts. Always provide --yes for destructive, ensure --quiet suppresses prompts.
  • Inconsistent error exit codes: Use process.exit(1) for all errors. Tools parsing CLI output check exit codes first.
  • Options without defaults: --scope should have sensible default so users do not specify every time.
  • Leak ceremony into quiet mode: --quiet = "minimal output for machines." Ceremony text leak = scripts break on unexpected output.

See Also

  • build-cli-plugin — build adapter/plugin commands operate on
  • test-cli-application — full CLI testing patterns beyond Step 7 basics
  • design-cli-output — terminal output design for all verbosity levels
  • install-almanac-content — example well-structured CLI command skill

GitHub 저장소

pjt222/agent-almanac
경로: i18n/caveman/skills/scaffold-cli-command
0
agentsagentskillsai-assisted-developmentclaude-codeskillsteams

연관 스킬

evaluating-llms-harness

테스팅

이 Claude Skill은 MMLU, GSM8K를 포함한 60개 이상의 표준화된 학술 과제에서 LLM 성능을 벤치마크하기 위해 lm-evaluation-harness를 실행합니다. 개발자들이 모델 품질을 비교하고, 학습 진행 상황을 추적하거나 학술 결과를 보고할 수 있도록 설계되었습니다. 이 도구는 HuggingFace와 vLLM 모델을 포함한 다양한 백엔드를 지원합니다.

스킬 보기

cloudflare-cron-triggers

테스팅

이 스킬은 cron 표현식을 사용하여 Worker를 스케줄링하기 위한 Cloudflare Cron Triggers 구현에 관한 포괄적인 지식을 제공합니다. 주기적 작업, 유지보수 작업, 자동화된 워크플로우 설정 방법을 다루며, 잘못된 cron 표현식이나 시간대 문제 같은 일반적인 이슈들을 해결하는 방법을 포함합니다. 개발자들은 이를 통해 스케줄된 핸들러 구성, cron 트리거 테스트, Workflows 및 Green Compute와의 연동 작업을 수행할 수 있습니다.

스킬 보기

webapp-testing

테스팅

이 Claude Skill은 Python 스크립트를 통해 로컬 웹 애플리케이션을 테스트하기 위한 Playwright 기반 툴킷을 제공합니다. 프론트엔드 검증, UI 디버깅, 스크린샷 캡처, 로그 확인 기능을 지원하며 서버 라이프사이클을 관리합니다. 브라우저 자동화 작업에 사용하되 컨텍스트 오염을 방지하기 위해 소스 코드를 읽지 않고 스크립트를 직접 실행하세요.

스킬 보기

finishing-a-development-branch

테스팅

이 스킬은 테스트 통과를 확인한 후 체계적인 통합 옵션을 제시하여 개발자가 완성된 작업을 마무리하도록 돕습니다. 구현이 완료된 후 머지, PR 생성, 브랜치 정리와 같은 워크플로우를 안내합니다. 코드가 준비되고 테스트가 완료되었을 때 개발 프로세스를 체계적으로 마무리하기 위해 사용하세요.

스킬 보기