cli-smoke-recipes

v2026.09.24

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.

GitHub
安装命令
npx skhub add laurigates/cli-smoke-recipes
Markdown
SKILL.md

CLI Smoke Recipes

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.

When to Use This Skill

Use this skill when…Skip when…
Designing a new module with a clear input → output contractInternal helper with no stable interface
Adding CLI exposure to an existing libraryCode whose only consumer is another in-process module
Authoring justfile recipes for bulk verificationOne-off scripts, or recipe syntax generally — use justfile-expert
Deciding if a feature is completeImplementation is purely experimental

The Pattern

1. CLI exposure

Each transforming module is callable via <bin> <module> <subcmd>:

OperationPatternRequired?
infoPure reader; prints headers / metadataYes
decode / parseSource → output formatYes if the module consumes
encode / renderOutput → source formatYes if the module produces
identify / validateClassify / verify without full parseOptional but cheap

The subcommand is a shell entry point, not a new abstraction. It uses the module's existing functions — never a re-implementation.

2. Stdout-first

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.

3. Module purity

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.

4. Justfile wrapper per subcommand

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.

5. Bulk smoke recipe

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:

  • "All N shipped inputs identify as the expected format" — catches format drift.
  • "Round-trip against input X is byte-identical" — catches encode-vs-decode asymmetry.
  • "Parser never crashes on any shipped input" — catches the most embarrassing class of bug.

6. Same-commit landing

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.

Detection Heuristic

Before applying the pattern, confirm the module qualifies:

SignalIndicates
Module has a pure transformation functionPattern applies
Input / output are serialisable (bytes, text, JSON)Pattern applies
Module needs UI / framework context to runPattern does not apply — refactor first
Module is a one-off migration scriptPattern does not apply

Quick Reference

Checklist for new transforming module

  • info subcommand exposed
  • decode / parse streams to stdout by default
  • Errors go to stderr
  • Module import graph excludes UI / framework layer
  • One justfile recipe per subcommand, build prerequisite declared
  • <module>-smoke iterates every shipped input
  • CLI + recipes + module land in the same commit

Common Mistakes

MistakeCorrect Approach
Decorative banners on stdoutStderr only; stdout is data
Running bulk smoke on "representative" inputsBulk smoke iterates every shipped input
CLI imports the UI layerRefactor; keep CLI path headless
Deferring the smoke recipe to a follow-upSame-commit or tracker does not advance
Hard-coded absolute paths in recipesResolve against a workspace variable

Related

  • tools-plugin:justfile-expert — recipe-authoring mechanics
  • .claude/rules/docs-currency.md — the same-commit principle this skill mirrors
  • blueprint-plugin:blueprint-docs-currency — the docs-side counterpart
  • agent-patterns-plugin:parallel-agent-dispatch — smoke recipes are the gate between waves in multi-wave dispatches

Evidence: 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.

发现
标签

此技能尚未发布标签。

版本
最新版本元数据

版本

v2026.09.24

发布时间

2026年9月24日

分类

未分类

许可证

MIT

源路径

tools-plugin/skills/cli-smoke-recipes

默认分支

main

最新提交

1668324

Tree SHA

b2d4cc3