tools-plugin/skills/cli-smoke-recipes/SKILL.md
CLI smoke recipes: expose pure-function modules via subcommands with a bulk-smoke justfile recipe. Use when designing data-transform modules or authoring smoke tests.
npx skillsauth add laurigates/claude-plugins cli-smoke-recipesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Every pure-function module that transforms data should be reachable from the shell plus a bulk-smoke recipe that iterates every shipped input. Applies to decoders, codecs, parsers, validators, formatters, compilers, transpilers, linters.
| Use this skill when… | Skip when… | |---------------------|------------| | Designing a new module with a clear input → output contract | Internal helper with no stable interface | | Adding CLI exposure to an existing library | Code whose only consumer is another in-process module | | Authoring justfile recipes for bulk verification | One-off scripts | | Deciding if a feature is complete | Implementation is purely experimental |
Each transforming module is callable via <bin> <module> <subcmd>:
| Operation | Pattern | Required? |
|-----------|---------|-----------|
| info | Pure reader; prints headers / metadata | Yes |
| decode / parse | Source → output format | Yes if the module consumes |
| encode / render | Output → source format | Yes if the module produces |
| identify / validate | Classify / verify without full parse | Optional but cheap |
The subcommand is a shell entry point, not a new abstraction. It uses the module's existing functions — never a re-implementation.
Reader subcommands default to streaming to stdout when the destination argument is omitted. This makes them pipe-friendly:
mytool codec info foo.bin | head -20
mytool codec decode foo.bin | jq .header
mytool codec decode foo.bin | cmp - expected.raw
Errors go to stderr, so stdout stays a clean data stream. Exit codes follow standard conventions (0 success, non-zero failure). Do not print decorative banners to stdout in reader commands.
CLI paths keep module dependencies minimal. In practice: a codec module's CLI entrypoint should not import the application's UI / framework layer. The test:
Can the CLI run in a headless, framework-free environment (CI sandbox, bare container, a naked shell)?
If yes, the module is pure enough. If no, the module has a UI dependency that belongs somewhere else. Prune the import.
One recipe per subcommand, names: <module>-<subcmd>:
codec-info path:
@just build
./build/mytool codec info {{path}}
codec-decode path:
@just build
./build/mytool codec decode {{path}}
The recipe declares build as a prerequisite so stale binaries never
hide bugs. Paths resolve against a workspace variable like
GAME_ROOT / DATA_DIR / FIXTURE_DIR so they work across machines
and in CI.
Per module, one <module>-smoke recipe that iterates every shipped
instance of the input format and prints a one-line summary per input:
codec-smoke:
@just build
for f in $(fd -e bin . "$DATA_DIR/codec"); do \
printf "%-40s " "$(basename $f)"; \
./build/mytool codec info "$f" | head -1; \
done
The bulk recipe catches correctness properties that per-file runs miss:
CLI, justfile recipe, and module code ship in one commit. If the
CLI or recipe is deferred to a follow-up, the feature tracker does not
advance past "in progress." This is the same discipline as
.claude/rules/docs-currency.md applied to the manual-verification
surface instead of the docs.
Before applying the pattern, confirm the module qualifies:
| Signal | Indicates | |--------|-----------| | Module has a pure transformation function | Pattern applies | | Input / output are serialisable (bytes, text, JSON) | Pattern applies | | Module needs UI / framework context to run | Pattern does not apply — refactor first | | Module is a one-off migration script | Pattern does not apply |
info subcommand exposeddecode / parse streams to stdout by defaultbuild prerequisite declared<module>-smoke iterates every shipped input| Mistake | Correct Approach | |---------|-----------------| | Decorative banners on stdout | Stderr only; stdout is data | | Running bulk smoke on "representative" inputs | Bulk smoke iterates every shipped input | | CLI imports the UI layer | Refactor; keep CLI path headless | | Deferring the smoke recipe to a follow-up | Same-commit or tracker does not advance | | Hard-coded absolute paths in recipes | Resolve against a workspace variable |
tools-plugin:justfile-expert — recipe-authoring mechanics.claude/rules/docs-currency.md — the same-commit principle this skill mirrorsblueprint-plugin:blueprint-docs-currency — the docs-side counterpartagent-patterns-plugin:parallel-agent-dispatch — smoke recipes are the gate between waves in multi-wave dispatchesEvidence: the manual-verification surface is the last line of defence before gameplay / real traffic / integration tests exist. Smoke recipes shipped in the same commit as a decoder module caught encoding consistency and round-trip byte-identity on first run — manual exercise had never caught either.
tools
Scaffold a new ComfyUI custom-node repo (pyproject, CI, release-please, vitest+pytest, JS extension skeleton) in the picker/gesture vein. Use when bootstrapping or init-ing a comfyui node pack.
tools
Orchestrate a ComfyUI node pack from idea to registry: scaffold, create + seed the repo, open the gitops adoption PR. Use when releasing or spinning up a new comfyui node pack.
testing
macOS EndpointSecurity/EDR high CPU & battery drain. Use when Kandji ESF / XProtect pegs a core; trace the exec storm via powermetrics + eslogger.
development
odiff pixel-by-pixel image diffing. Use when comparing screenshots, detecting visual regressions, diffing before/after PNGs, asserting golden images.