design-cli-output
정보
이 스킬은 개발자가 CLI 도구의 터미널 출력을 설계할 때 색상 텍스트, 상태 표시기, 다양한 출력 형식(일반, 상세, 간소, JSON)과 같은 기능을 활용할 수 있도록 돕습니다. 아키텍처 구성, 다양한 터미널 간 호환성, 일관된 서술적 톤 유지에 대한 지침을 제공합니다. 새로운 CLI 보고자를 구축하거나, 기존 도구에 사용자 친화적인 출력을 추가하거나, 여러 명령어 간 출력을 표준화할 때 사용하세요.
빠른 설치
Claude Code
추천npx skills add pjt222/agent-almanac -a claude-code/plugin add https://github.com/pjt222/agent-almanacgit clone https://github.com/pjt222/agent-almanac.git ~/.claude/skills/design-cli-outputClaude Code에서 이 명령을 복사하여 붙여넣어 스킬을 설치하세요
문서
Design CLI Output
Diseñar salida de terminal consistente y de múltiples niveles para una herramienta de línea de comandos.
Cuándo Usar
- Construir un nuevo módulo reporter para una herramienta CLI
- Añadir salida cálida o narrativa junto con la salida transaccional estándar
- Estandarizar el formato de salida en múltiples comandos
- Diseñar salida JSON para máquina paralela a la salida legible para humanos
- Elegir colores, glyphs y niveles de verbosidad para una nueva herramienta de terminal
Entradas
- Requerido: Nombre de la herramienta CLI y audiencia primaria (desarrolladores, operadores, usuarios finales)
- Requerido: Comandos que necesitan formato de salida
- Opcional: Si se desea una variante de salida "ceremonial" o narrativa
- Opcional: Restricciones de marca (paleta de colores, tono)
Procedimiento
Paso 1: Definir la Paleta de Colores
Usar chalk para crear un objeto de paleta nombrado:
Paleta estándar (salida transaccional):
let chalk;
try { chalk = (await import('chalk')).default; }
catch { chalk = new Proxy({}, { get: () => (s) => s }); }
// Status colors
const ok = chalk.green; // success
const fail = chalk.red; // errors
const warn = chalk.yellow; // warnings
const info = chalk.cyan; // identifiers, names
const dim = chalk.dim; // secondary info, paths
const bold = chalk.bold; // headers
Paleta cálida (salida ceremonial/narrativa):
const C = {
flame: chalk.hex('#FF6B35'), // active elements, fire
amber: chalk.hex('#FFB347'), // arriving items, warm highlights
spark: chalk.hex('#FFF4E0'), // individual items (sparks/skills)
ember: chalk.hex('#8B4513'), // cold/dormant states
warm: chalk.hex('#D4A574'), // neutral warm text
dim: chalk.dim, // background, secondary
fail: chalk.red, // errors stay red (honest)
};
Reglas de diseño de paleta:
- Siempre proveer un respaldo sin color (el patrón Proxy de arriba)
- Usar colores hex para paletas personalizadas (
chalk.hex('#FF6B35')) - Mantener el color fail/error rojo independientemente del tema de la paleta
- Nombrar entradas de paleta por rol semántico, no por apariencia visual
Esperado: Un objeto de paleta con entradas nombradas y un respaldo sin color.
En caso de fallo: Si chalk no está disponible (salida con pipe, CI), el respaldo Proxy retorna strings sin cambios. Probar con la variable de entorno NO_COLOR=1.
Paso 2: Elegir Indicadores de Estado
Seleccionar glyphs Unicode o caracteres ASCII para comunicación de estado:
ASCII (compatibilidad máxima):
+ created/installed (green)
- removed/deleted (red)
= skipped/unchanged (dim)
! error/warning (red)
Unicode (más rico, necesita terminal UTF-8):
✦ item/skill/practice (spark)
◉ active/burning state
◎ cooling/embers state
○ cold/dormant state
◌ available/not installed
✗ failed item
✓ success (use sparingly — not all terminals render it well)
Criterios de selección:
- ASCII para herramientas que se ejecutan en CI o contextos con pipe
- Unicode para herramientas con usuarios de terminal interactivos
- Ofrecer ambos vía un flag
--asciio detección deNO_COLOR - Probar glyphs en: macOS Terminal, Windows Terminal, terminal de VS Code, sesiones SSH
Esperado: Un conjunto de glyphs que comunica el estado de un vistazo sin depender solo del color.
En caso de fallo: Si un glyph se renderiza como ? o un cuadro en pruebas, reemplazar con el equivalente ASCII. El conjunto +/-/=/! funciona en todas partes.
Paso 3: Diseñar Niveles de Verbosidad
Cada comando debe soportar cuatro niveles de salida:
| Nivel | Flag | Audiencia | Contenido |
|---|---|---|---|
| Default | (ninguno) | Humano en terminal | Formateado, coloreado, informativo |
| Verbose | --verbose o --ceremonial | Humano queriendo detalle | Desglose por item, secuencias de llegada |
| Quiet | --quiet | Scripts, CI | Líneas mínimas, iconos de estado, sin decoración |
| JSON | --json | Consumidores máquina | Estructurado, parseable, completo |
Patrón de implementación:
function output(data, options) {
if (options.json) {
console.log(JSON.stringify(data, null, 2));
return;
}
if (options.quiet) {
for (const item of data.items) {
const icon = item.ok ? '+' : '!';
console.log(`${icon} ${item.id}`);
}
return;
}
// Default (or verbose) human output
printFormatted(data, { verbose: options.verbose });
}
Reglas de salida JSON:
- Siempre JSON válido (sin mezclar con texto humano)
- Incluir todos los datos que muestra la salida humana, más campos útiles para máquina
- Usar nombres de claves consistentes en todos los comandos
- Código de salida 0 para éxito, 1 para errores (independientemente del modo de salida)
Esperado: Cuatro niveles de salida claros con comportamiento consistente entre comandos.
En caso de fallo: Si el modo verbose es demasiado ruidoso, hacerlo opt-in (--ceremonial) en lugar de un nivel de verbosidad gradual.
Paso 4: Establecer Reglas de Voz
Definir el tono y estilo que todas las funciones de salida siguen. Esto previene inconsistencia entre comandos.
Reglas de voz de ejemplo (del reporter campfire):
- Presente, voz activa: "mystic arrives" no "mystic has been installed"
- Sin signos de exclamación: Confianza tranquila. La herramienta no grita.
- La metáfora reemplaza la jerga: "practices" no "dependencies" (solo para modo ceremonia)
- Los fallos son honestos, no catastróficos: "A spark was lost" no "ERROR: installation failed with exit code 1"
- La línea de cierre refleja el estado: Cada operación termina con un resumen de estado
- Sin emoji: Los glyphs Unicode cargan peso visual sin ser decorativos
- Cada palabra carga información: Si una palabra no añade comprensión, eliminarla
Reglas de voz para salida estándar (no ceremonia):
- Líneas concisas y factuales
- Icono de estado + ID del item + contexto
- Línea de resumen con conteos
- Los mensajes de error sugieren acciones correctivas
Esperado: Un conjunto escrito de 3-7 reglas de voz que las funciones de salida deben seguir.
En caso de fallo: Si las reglas se sienten arbitrarias, probarlas: escribir la misma salida con y sin cada regla. Si quitar una regla no cambia la calidad de la salida, la regla no es necesaria.
Paso 5: Implementar Funciones Reporter
Organizar la salida en un módulo reporter con funciones enfocadas:
// reporter.js — standard output
export function printResults(results) { ... }
export function printItemTable(items) { ... }
export function printDetections(detections) { ... }
export function printAudit(auditResults) { ... }
export function printDryRun() { ... }
export function warn(msg) { ... }
export function error(msg) { ... }
export { chalk };
Cada función sigue la misma estructura:
- Manejar entrada vacía/null elegantemente
- Calcular layout (anchos de columna, padding)
- Salida con colores de paleta
- Línea de resumen al fondo
Para salida ceremonial, crear un módulo separado:
// campfire-reporter.js — warm narrative output
export function printArrival({ teamId, agents, results, ceremonial }) { ... }
export function printScatter({ teamId, agents, results }) { ... }
export function printTend(fires) { ... }
export function printCampfireList({ teams, state, reg }) { ... }
export function printFireSummary({ team, fireData, reg }) { ... }
export function printJson(data) { ... }
Esperado: Funciones reporter que son utilizables independientemente — cada una maneja su propio formato sin depender del estado del llamador.
En caso de fallo: Si las funciones crecen más allá de ~50 líneas, extraer helpers. Una función reporter debe ser fácil de revisar de forma aislada.
Paso 6: Probar Salida en Diferentes Entornos
Verificar que la salida se renderiza correctamente en diferentes contextos:
# With colors (interactive terminal)
node cli/index.js list --domains
# Without colors (piped)
node cli/index.js list --domains | cat
# With NO_COLOR environment variable
NO_COLOR=1 node cli/index.js list --domains
# JSON mode (parseable)
node cli/index.js campfire --json | jq .
# In CI (typically no TTY)
CI=true node cli/index.js audit
Verificar:
- Los colores se muestran correctamente en modo interactivo
- Ningún código de escape ANSI se filtra a la salida con pipe/redirigida
- El JSON es válido (pipe a
jq .para verificar) - Los glyphs Unicode se renderizan en los terminales objetivo
- La alineación de columnas se mantiene con anchos de contenido variables
Esperado: La salida es correcta en los cinco contextos.
En caso de fallo: Si los códigos ANSI se filtran, asegurar que chalk respeta NO_COLOR. Si Unicode se rompe, proveer un modo de respaldo ASCII.
Validación
- La paleta de colores tiene un respaldo sin color
- Los indicadores de estado funcionan en modos color y sin color
- Los cuatro niveles de verbosidad producen salida útil
- La salida JSON es válida y parseable por
jq - Las reglas de voz están documentadas y se siguen consistentemente
- Las funciones reporter manejan entrada vacía/null elegantemente
- Salida probada en: terminal, piped, NO_COLOR, CI
Errores Comunes
- Mezclar texto humano con JSON: En modo
--json, emitir solo JSON válido. Una sola línea perdida (como "DRY RUN") rompe los parseadores JSON. Si el comando debe mostrar ambos, separarlos claramente o suprimir el texto humano en modo JSON. - Anchos de columna hardcodeados: La longitud del contenido varía. Usar
Math.max(...items.map(i => i.id.length))para calcular el padding dinámicamente. - Color sin significado: Si el color es la única forma de distinguir éxito de fallo, los usuarios daltónicos y la salida con pipe pierden información. Siempre emparejar el color con un indicador de texto (
+,OK,ERR). - Ceremonia en el contexto incorrecto: La salida narrativa cálida es apropiada para sesiones interactivas de terminal. En CI, scripts o modo
--quiet, añade ruido. Limitar la salida ceremonial detrás de flags explícitos. - Olvidar la línea de resumen: Los usuarios escanean la última línea primero. Cada operación debe terminar con un resumen de una línea (conteos de éxito/fallo/saltado).
Habilidades Relacionadas
scaffold-cli-command— los comandos que usan esta salidatest-cli-application— probar que la salida coincide con las expectativasbuild-cli-plugin— los plugins reportan resultados a través de este sistema de salida
GitHub 저장소
연관 스킬
content-collections
메타이 스킬은 콘텐츠 콜렉션(Content Collections)을 위한 프로덕션 검증된 설정을 제공합니다. 콘텐츠 콜렉션은 Markdown/MDX 파일을 Zod 검증이 포함된 타입 안전한 데이터 콜렉션으로 변환해주는 TypeScript 최우선 도구입니다. 블로그, 문서 사이트 또는 콘텐츠 중심의 Vite + React 애플리케이션을 구축할 때 타입 안전성과 자동 콘텐츠 검증을 보장하기 위해 사용하세요. Vite 플러그인 구성과 MDX 컴파일부터 배포 최적화 및 스키마 검증에 이르기까지 모든 것을 다룹니다.
polymarket
메타이 스킬은 개발자들이 Polymarket 예측 시장 플랫폼을 활용한 애플리케이션을 구축할 수 있도록 지원하며, 거래 및 시장 데이터를 위한 API 통합 기능을 포함합니다. 또한 WebSocket을 통한 실시간 데이터 스트리밍을 제공하여 실시간 거래와 시장 활동을 모니터링할 수 있습니다. 이를 통해 거래 전략을 구현하거나 실시간 시장 업데이트를 처리하는 도구를 생성하는 데 활용할 수 있습니다.
creating-opencode-plugins
메타이 스킬은 개발자들이 명령어, 파일, LSP 작업 등 25개 이상의 이벤트 유형에 연결되는 OpenCode 플러그인을 만들 수 있도록 돕습니다. JavaScript/TypeScript 모듈을 위한 플러그인 구조, 이벤트 API 명세, 구현 패턴을 제공합니다. OpenCode AI 어시스턴트의 라이프사이클을 사용자 정의 이벤트 기반 로직으로 가로채거나, 모니터링하거나, 확장해야 할 때 사용하세요.
sglang
메타SGLang은 RadixAttention 프리픽스 캐싱을 활용하여 JSON, 정규식, 에이전트 워크플로우를 위한 고속 구조화 생성에 특화된 고성능 LLM 서빙 프레임워크입니다. 특히 반복되는 프리픽스가 있는 작업에서 상당히 빠른 추론 속도를 제공하여 복잡한 구조화 출력 및 다중 턴 대화에 이상적입니다. 제약 디코딩이 필요하거나 광범위한 프리픽스 공유가 있는 애플리케이션을 구축할 때는 vLLM과 같은 대안보다 SGLang을 선택하십시오.
