Design terminal output for a CLI tool with chalk colors, Unicode glyphs, multiple verbosity levels (human, verbose, quiet, JSON), and consistent voice rules. Covers color palette selection, status indicator design, reporter function architecture, ceremony/narrative output variants, and cross-terminal compatibility. Use when building a new CLI reporter module, adding warm narrative output to an existing tool, standardizing output across multiple commands, or designing machine-readable JSON alongside human-readable text.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
A direct command skips the review prompt. Inspect the source before running it.
Design terminal output for a CLI tool with chalk colors, Unicode glyphs, multiple verbosity levels (human, verbose, quiet, JSON), and consistent voice rules. Covers color palette selection, status indicator design, reporter function architecture, ceremony/narrative output variants, and cross-terminal compatibility. Use when building a new CLI reporter module, adding warm narrative output to an existing tool, standardizing output across multiple commands, or designing machine-readable JSON alongside human-readable text.
license
MIT
allowed-tools
Read Write Edit Bash Grep Glob
metadata
{"author":"Philipp Thoss","version":"1.0","domain":"cli","complexity":"basic","language":"TypeScript","tags":["cli","terminal","ux","chalk","unicode"],"locale":"ja","source_locale":"en","source_commit":"2630b6e9","translator":"Claude + human review","translation_date":"2026-07-30"}
// A factory returns a *function*; a direct style returns a string. Enumerate// this list against the installed chalk, not from memory — chalk 6 added the// three underline* variants, and a list that omits them is wrong for those names.constFACTORIES = newSet(['ansi256', 'bgAnsi256', 'bgHex', 'bgRgb', 'hex',
'rgb', 'underlineAnsi256', 'underlineHex', 'underlineRgb']);
functionmakeChalkStub() {
returnnewProxy((text) => text, {
get(target, prop) {
if (prop === 'then') returnundefined; // must not be a thenableif (prop === 'level') return0; // no color support, truthfullyif (typeof prop === 'symbol') returnReflect.get(target, prop);
returnFACTORIES.has(prop) ? () =>makeChalkStub() : makeChalkStub();
},
});
}
let chalk;
try { chalk = (awaitimport('chalk')).default; }
catch { chalk = makeChalkStub(); }
ファクトリは関数を返す: new Proxy({}, { get: () => (s) => s }) は直接スタイルを満たしつつファクトリを壊す。chalk.hex('#FF6B35') はそのとき 文字列'#FF6B35' であり、それを呼ぶと TypeError: ... is not a function を投げる。パレットはモジュールロード時に構築されるため、そのフォールバックはインポート時点でツールを落とす — プレーンテキストへの劣化こそが目的だったまさにその状況で。
✦ 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)
# 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
# The no-color fallback. A failed import cannot be provoked with an env var, so# assert on the stub itself in the suite rather than reaching it through the CLI.# Pass a glob, not a directory: `node --test <dir>` stopped expanding at Node 22.
node --test'cli/test/*.test.js'