☰ Categories

aa/cli taste

# Cli taste of AA - Use pnpm as the package manager for CLI projects.

CategoryDevelopment › Coding
TagsReviewingDeveloperCodeChecklist
Prompt
# Cli taste of AA
- Use pnpm as the package manager for CLI projects. Confidence: 1.00
- Use TypeScript for CLI projects. Confidence: 0.95
- Use tsup as the build tool for CLI projects. Confidence: 0.95
- Use vitest for testing CLI projects. Confidence: 0.95
- Use Commander.js for CLI command handling. Confidence: 0.95
- Use clack for interactive user input in CLI projects. Confidence: 0.95
- Check for existing CLI name conflicts before running npm link. Confidence: 0.95
- Organize CLI commands in a dedicated commands folder with each module separated. Confidence: 0.95
- Include a small 150px ASCII art welcome banner displaying the CLI name. Confidence: 0.95
- Use lowercase flags for version and help commands (-v, --version, -h, --help). Confidence: 0.85
- Start projects with version 0.0.1 instead of 1.0.0. Confidence: 0.85
- Version command should output only the version number with no ASCII art, banner, or additional information. Confidence: 0.90
- Read CLI version from package.json instead of hardcoding it in the source code. Confidence: 0.75
- Always use ora for loading spinners in CLI projects. Confidence: 0.95
- Use picocolors for terminal string coloring in CLI projects. Confidence: 0.90
- Use Ink for building interactive CLI UIs in CommandCode projects. Confidence: 0.80
- Use ink-spinner for loading animations in Ink-based CLIs. Confidence: 0.70
- Hide internal flags from help: .addOption(new Option('--local').hideHelp()). Confidence: 0.90
- Use pnpm.onlyBuiltDependencies in package.json to pre-approve native binary builds. Confidence: 0.60
- Use ANSI Shadow font for ASCII art at large terminal widths and ANSI Compact for small widths. Confidence: 0.85
- Use minimal white, gray, and black colors for ASCII art banners. Confidence: 0.85
- Check if package is publishable using `npx can-i-publish` before building or publishing. Confidence: 0.85

What this prompt does

A preference list for TypeScript CLI project setup and conventions. Each item includes a confidence value and recommends tools such as pnpm, tsup, vitest, and Commander.js.

Model comparison

Claude is the most complete and implementation-specific. Gemini contains behavioral inconsistencies and unsupported savings estimates, while ChatGPT leaves several requested conventions underspecified.

ClaudeTop overall
44/ 50

+ Best connects the requested stack to a concrete workflow.

- Name conflicts are checked but do not prevent linking.

ChatGPT
37/ 50

+ Presents the folder layout and conversion flow clearly.

- The short version flag and clack interaction remain underspecified.

Gemini
37/ 50

+ Clearly demonstrates package, banner, and hidden-option setup.

- Default banner behavior and documented options conflict with code.

CriterionChatGPTClaudeGeminiLeader
Instruction following798Claude +13%
Accuracy786Claude +14%
Specificity8108Claude +25%
Structure898Claude +13%
Right length787Claude +14%

Scored 1–10 by gpt-5.6-sol with model names hidden (2026-09-24). This is an AI review, not a measurement.

Read full answers

We gave three models the same input and copied their answers unedited. Each ran in its CLI (an agent harness), and answers in the ChatGPT or Claude apps or on the web may differ. Outputs are in Korean.

Input used
[Pasted material]
위 취향 기준 그대로, 여러 폴더에 흩어진 이미지 파일을 한 번에 WebP로 변환해주는 `imgshrink`라는 CLI 도구를 새로 설계해줘. package.json, 폴더 구조, 커맨드 목록(옵션 포함)까지 정리해줘.
gpt-5.6-luna (codex CLI · 에이전트 하네스) · Run on 2026-09-24

imgshrink CLI 설계안

여러 폴더의 이미지 파일을 재귀적으로 찾아 WebP로 변환하고, 원본 보존·덮어쓰기·품질·출력 디렉터리 등을 제어하는 CLI입니다.

기본 사용 예시

pnpm dlx imgshrink ./images
imgshrink ./public ./assets \
  --output ./dist \
  --quality 82 \
  --recursive \
  --keep

주요 커맨드

커맨드 설명
imgshrink convert <paths...> 이미지 검색 및 WebP 변환
imgshrink config 기본 설정 확인 및 변경
imgshrink doctor 이미지 처리 환경과 의존성 점검
imgshrink --version 버전만 출력
imgshrink --help 도움말 출력

기본 커맨드는 편의를 위해 convert로 동작하게 설계할 수 있습니다.

imgshrink ./images

옵션

convert

imgshrink convert <paths...> [options]
옵션 기본값 설명
-o, --output <dir> 입력 폴더 옆 변환 결과 출력 폴더
-q, --quality <number> 82 WebP 품질, 1~100
-r, --recursive true 하위 폴더 재귀 탐색
--no-recursive - 하위 폴더 탐색 안 함
--keep false 원본 파일 보존
--overwrite false 기존 WebP 덮어쓰기
--suffix <text> 없음 파일명 접미사 추가
--format <formats> jpg,jpeg,png 대상 확장자 목록
--dry-run false 실제 변환 없이 대상만 표시
--delete-originals false 변환 성공 후 원본 삭제
--concurrency <number> CPU 기반 동시 처리 개수
--silent false 진행 출력 최소화
--json false 결과를 JSON으로 출력
--local 숨김 내부 개발용 로컬 설정 사용

예시:

imgshrink convert ./src ./static \
  --output ./dist \
  --quality 85 \
  --keep \
  --overwrite
imgshrink ./images --dry-run

config

imgshrink config [options]
옵션 설명
--show 현재 설정 출력
--quality <number> 기본 품질 설정
--output <dir> 기본 출력 경로 설정
--reset 설정 초기화

doctor

imgshrink doctor

확인 항목:

  • Node.js 버전
  • Sharp 네이티브 바이너리 설치 여부
  • 입력 경로 접근 권한
  • 출력 경로 쓰기 권한
  • 지원 이미지 형식
  • 현재 imgshrink 버전

웰컴 배너

터미널 너비에 따라 ANSI Shadow 또는 ANSI Compact 스타일을 사용합니다.

 _                 _                 _       _               
(_)___ _ __   ___ | |__  _ __  _   _| |__   (_)___| |__  
| / __| '_ \ / __|| '_ \| '__|| | | | '_ \  | / __| '_ \ 
| \__ \ | | | (__ | | | | |   | |_| | | | | | \__ \ | | |
|_|___/_| |_|\___||_| |_|_|    \__,_|_| |_| |_|___/_| |_|
  • 대형 터미널: ANSI Shadow
  • 소형 터미널: ANSI Compact
  • 색상: 흰색, 회색, 검정색 계열만 사용
  • --version 실행 시 배너 없이 버전만 출력
$ imgshrink --version
0.0.1

폴더 구조

imgshrink/
├── .gitignore
├── README.md
├── package.json
├── pnpm-lock.yaml
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
├── src/
│   ├── index.ts
│   ├── cli.ts
│   ├── constants.ts
│   ├── banner/
│   │   ├── index.ts
│   │   ├── shadow.ts
│   │   └── compact.ts
│   ├── commands/
│   │   ├── convert.ts
│   │   ├── config.ts
│   │   └── doctor.ts
│   ├── core/
│   │   ├── discover-images.ts
│   │   ├── convert-image.ts
│   │   ├── convert-batch.ts
│   │   └── result.ts
│   ├── config/
│   │   ├── config-store.ts
│   │   └── config-schema.ts
│   ├── ui/
│   │   ├── logger.ts
│   │   ├── progress.ts
│   │   └── prompts.ts
│   └── utils/
│       ├── paths.ts
│       ├── file-size.ts
│       └── package-version.ts
└── tests/
    ├── discover-images.test.ts
    ├── convert-image.test.ts
    ├── config.test.ts
    └── cli.test.ts

package.json

{
  "name": "imgshrink",
  "version": "0.0.1",
  "description": "Batch-convert images from multiple folders to WebP",
  "type": "module",
  "bin": {
    "imgshrink": "./dist/index.js"
  },
  "files": [
    "dist",
    "README.md",
    "LICENSE"
  ],
  "scripts": {
    "dev": "tsx src/index.ts",
    "build": "tsup",
    "test": "vitest run",
    "test:watch": "vitest",
    "typecheck": "tsc --noEmit",
    "check:publish": "npx can-i-publish",
    "prepublishOnly": "pnpm check:publish && pnpm build"
  },
  "dependencies": {
    "@clack/prompts": "^0.10.0",
    "commander": "^14.0.0",
    "ora": "^8.2.0",
    "picocolors": "^1.1.1",
    "sharp": "^0.34.0"
  },
  "devDependencies": {
    "@types/node": "^22.0.0",
    "tsx": "^4.0.0",
    "tsup": "^8.0.0",
    "typescript": "^5.0.0",
    "vitest": "^3.0.0"
  },
  "engines": {
    "node": ">=20"
  },
  "pnpm": {
    "onlyBuiltDependencies": [
      "sharp"
    ]
  }
}

tsup.config.ts

import { defineConfig } from "tsup";

export default defineConfig({
  entry: ["src/index.ts"],
  format: ["esm"],
  dts: false,
  clean: true,
  sourcemap: true,
  banner: {
    js: "#!/usr/bin/env node"
  }
});

커맨드 구성 예시

// src/commands/convert.ts
import { Command, Option } from "commander";

export function createConvertCommand() {
  return new Command("convert")
    .argument("<paths...>", "이미지 또는 폴더 경로")
    .option("-o, --output <dir>", "출력 폴더")
    .option("-q, --quality <number>", "WebP 품질", "82")
    .option("-r, --recursive", "하위 폴더 재귀 탐색", true)
    .option("--no-recursive", "하위 폴더 탐색 안 함")
    .option("--keep", "원본 파일 보존")
    .option("--overwrite", "기존 WebP 덮어쓰기")
    .option("--dry-run", "실제 변환 없이 대상만 표시")
    .option("--json", "JSON 결과 출력")
    .addOption(
      new Option("--local", "내부 개발용 로컬 설정 사용").hideHelp()
    )
    .action(async (paths, options) => {
      // discover → validate → convert → report
    });
}

처리 흐름

입력 경로 수집
    ↓
지원 이미지 필터링
    ↓
중복 경로 제거
    ↓
출력 경로 계산
    ↓
변환 가능 여부 검증
    ↓
ora 스피너로 진행 상태 표시
    ↓
Sharp로 WebP 변환
    ↓
성공·실패·절감 용량 요약

완료 메시지 예시:

✓ 24개 이미지 변환 완료
✓ 18.4 MB → 7.2 MB
✓ 61% 용량 절감

구현 원칙

  • CLI는 TypeScript로 작성
  • 패키지 관리는 pnpm 사용
  • 빌드는 tsup 사용
  • 테스트는 vitest 사용
  • 커맨드 처리는 Commander.js 사용
  • 선택형 입력은 @clack/prompts 사용
  • 처리 중 상태는 ora 사용
  • 색상 출력은 picocolors 사용
  • 버전은 소스에 하드코딩하지 않고 package.json에서 읽음
  • --version은 버전 번호만 출력
  • 내부 옵션은 .hideHelp()로 숨김
  • 네이티브 의존성인 sharp는 pnpm.onlyBuiltDependencies로 사전 승인
  • 빌드 또는 배포 전에 npx can-i-publish 실행
  • npm link 전에는 기존 imgshrink 명령 충돌 여부 확인
command -v imgshrink || true
pnpm check:publish
pnpm build
pnpm link --global

More in this category

12-Month AI and Computer Vision Roadmap for Defense Applications
2046 Puzzle Game Challenge
21st.dev component prompt
3D FACTORY
3D FPS Game