feat: add cli-builder skill — agent-friendly CLI design patterns #1

Merged
magnus merged 2 commits from feat/cli-builder-skill into main 2026-05-21 22:20:25 -04:00
Contributor

Summary

Adds the cli-builder skill: 10 universal design patterns for building CLI tools that AI agents can use reliably.

What is included

6 files, 1,169 lines, zero internal references.

cli-builder/
├── SKILL.md                   # 371 lines (<500, ~3,500 tokens)
├── templates/
│   └── bash-cli-scaffold.sh   # 242 lines — full scaffold template
└── references/
    ├── python-api-client.md   # 271 lines — lazy auth, pre-parsed flags
    ├── advanced-patterns.md   # 184 lines — edge case patterns
    ├── mcp-vs-cli.md          # 43 lines — discourse + decision framework
    └── improvement-cycle.md   # 58 lines — feedback + prioritization

Design Principles

  1. Non-Interactive by Default
  2. Progressive Help Discovery
  3. --json for Machine-Readable Output
  4. --dry-run for Destructive Operations
  5. Idempotent — Guard Before Act
  6. emit() — Single Dual-Output Helper
  7. Structured Logging with Levels
  8. --force / --yes for Automation
  9. Consistent Subcommand Structure
  10. Lazy Auth — Help Works Without Credentials

Validation

  • Frontmatter: all standard fields, no non-standard
  • Body: 353 lines (max 500), ~3,500 tokens (max 5,000)
  • Name matches directory
  • No internal paths, tool names, or self-referencing
  • MIT license, compatibility field
  • Progressive disclosure: references loaded on demand

Signed-off-by: Jasper magnus@groktop.us

## Summary Adds the `cli-builder` skill: 10 universal design patterns for building CLI tools that AI agents can use reliably. ## What is included **6 files, 1,169 lines, zero internal references.** ``` cli-builder/ ├── SKILL.md # 371 lines (<500, ~3,500 tokens) ├── templates/ │ └── bash-cli-scaffold.sh # 242 lines — full scaffold template └── references/ ├── python-api-client.md # 271 lines — lazy auth, pre-parsed flags ├── advanced-patterns.md # 184 lines — edge case patterns ├── mcp-vs-cli.md # 43 lines — discourse + decision framework └── improvement-cycle.md # 58 lines — feedback + prioritization ``` ## Design Principles 1. Non-Interactive by Default 2. Progressive Help Discovery 3. `--json` for Machine-Readable Output 4. `--dry-run` for Destructive Operations 5. Idempotent — Guard Before Act 6. `emit()` — Single Dual-Output Helper 7. Structured Logging with Levels 8. `--force` / `--yes` for Automation 9. Consistent Subcommand Structure 10. Lazy Auth — Help Works Without Credentials ## Validation - Frontmatter: all standard fields, no non-standard - Body: 353 lines (max 500), ~3,500 tokens (max 5,000) - Name matches directory - No internal paths, tool names, or self-referencing - MIT license, compatibility field - Progressive disclosure: references loaded on demand Signed-off-by: Jasper <magnus@groktop.us>
10 universal patterns for building CLI tools that AI agents can use
reliably: non-interactive, --json, --dry-run, idempotent, lazy auth,
progressive help, and more. Includes a bash scaffold template, Python
API client reference, advanced edge-case patterns, MCP-vs-CLI decision
framework, and an improvement cycle for iterating on shipped tools.

Principles grounded in real failures from building 15+ agent-facing
CLIs across multiple API services.

Signed-off-by: Jasper <magnus@groktop.us>
Adds a new Phase 4 section to the cli-builder skill that teaches how
to wrap a CLI tool in an agentskills.io-compliant SKILL.md wrapper,
creating the two-layer architecture: CLI as execution engine + skill
as trigger surface. Includes a complete worked example (weather-cli)
with frontmatter conventions, essential commands, gotchas, and auth
wiring documentation.

Signed-off-by: Jasper <magnus@groktop.us>
magnus merged commit f8085d9904 into main 2026-05-21 22:20:25 -04:00
jasper left a comment

First-Pass Code Review — Jasper (automated)

Overview

Well-structured contribution. The cli-builder skill covers a real need (agent-facing CLI design) with practical, experience-grounded patterns. 6 files, 1,169 lines, clean separation of concerns between the main SKILL.md, references/, and templates/.

What Works Well

  • Progressive disclosure is correctly implemented — SKILL.md is self-contained at ~3,500 tokens, references loaded on demand
  • 10 design patterns are concrete and well-motivated (each has a why this matters justification)
  • Phase 3 QA section is the strongest part — the test suite snippets and live-server verification steps address real failure modes
  • Gotchas section (#1-#8) captures hard-won lessons from actual agent-CLI failures
  • Agent-readiness checklist is a good summary artifact
  • mcp-vs-cli.md is concise with a practical decision framework backed by token-cost data
  • improvement-cycle.md has a clean feedback schema and HALO prioritization
  • advanced-patterns.md covers genuine edge cases (morphological matching, library init banners, robust JSON consumption)
  • Frontmatter is clean — no non-standard fields, no internal paths

Issues Found

Syntax error (medium) — python-api-client.md line 15
ENV_API_KEY=*** "") is not valid Python. Looks like a corrupted placeholder during template substitution. Should be os.getenv("MYTOOL_API_KEY", ""). Would cause SyntaxError on import.

Dead code (low) — python-api-client.md line 53
if not any("files" in k for k in ["_files"]) always evaluates to False because "files" is a substring of "_files". The Content-Type header is always set here. Harmless since _request() correctly handles the file upload case, but the guard is misleading.

Cross-language inconsistency (low) — SKILL.md line 263
Python code snippet in Pattern 10 (Lazy Auth) calls die() which is defined earlier as a bash function. Should use Python-native pattern like raise MyToolError(...) or sys.exit(1).

No Security Issues

  • No hardcoded credentials
  • Input sanitization covered in advanced-patterns.md
  • No shell injection vectors in the patterns
  • No internal paths or tool names exposed

Style / Nits

  • python-api-client.md could benefit from a if __name__ == "__main__": main() guard at the bottom of the example
  • The bash scaffold template uses cat <<'HELP' with single-quoted delimiter — correct, prevents expansion. Good.
  • Overall, the contribution is solid and addresses a real pain point. Recommend addressing the syntax error before merge.
## First-Pass Code Review — Jasper (automated) ### Overview Well-structured contribution. The cli-builder skill covers a real need (agent-facing CLI design) with practical, experience-grounded patterns. 6 files, 1,169 lines, clean separation of concerns between the main SKILL.md, references/, and templates/. ### What Works Well - **Progressive disclosure** is correctly implemented — SKILL.md is self-contained at ~3,500 tokens, references loaded on demand - **10 design patterns** are concrete and well-motivated (each has a why this matters justification) - **Phase 3 QA section** is the strongest part — the test suite snippets and live-server verification steps address real failure modes - **Gotchas section (#1-#8)** captures hard-won lessons from actual agent-CLI failures - **Agent-readiness checklist** is a good summary artifact - **mcp-vs-cli.md** is concise with a practical decision framework backed by token-cost data - **improvement-cycle.md** has a clean feedback schema and HALO prioritization - **advanced-patterns.md** covers genuine edge cases (morphological matching, library init banners, robust JSON consumption) - Frontmatter is clean — no non-standard fields, no internal paths ### Issues Found **Syntax error (medium) — python-api-client.md line 15** `ENV_API_KEY=*** "")` is not valid Python. Looks like a corrupted placeholder during template substitution. Should be `os.getenv("MYTOOL_API_KEY", "")`. Would cause SyntaxError on import. **Dead code (low) — python-api-client.md line 53** `if not any("files" in k for k in ["_files"])` always evaluates to False because `"files"` is a substring of `"_files"`. The Content-Type header is always set here. Harmless since `_request()` correctly handles the file upload case, but the guard is misleading. **Cross-language inconsistency (low) — SKILL.md line 263** Python code snippet in Pattern 10 (Lazy Auth) calls `die()` which is defined earlier as a bash function. Should use Python-native pattern like `raise MyToolError(...)` or `sys.exit(1)`. ### No Security Issues - No hardcoded credentials - Input sanitization covered in advanced-patterns.md - No shell injection vectors in the patterns - No internal paths or tool names exposed ### Style / Nits - python-api-client.md could benefit from a `if __name__ == "__main__": main()` guard at the bottom of the example - The bash scaffold template uses `cat <<'HELP'` with single-quoted delimiter — correct, prevents expansion. Good. - Overall, the contribution is solid and addresses a real pain point. Recommend addressing the syntax error before merge.
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
magnus/agent-skills!1
No description provided.