Skip to main content

cli-printing-press-generator

Generate AI-agent-first CLIs from any API (OpenAPI, GraphQL, or browser-sniffed) with SQLite sync, compound commands, and MCP servers

Jump to install

Source facts

Repository
reason-machines/devtools-skills
Last source activity
May 16, 2026 at 23:22
Detected SKILL.md language
English
Stars
4
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
cli-printing-press-generator
description
Generate AI-agent-first CLIs from any API (OpenAPI, GraphQL, or browser-sniffed) with SQLite sync, compound commands, and MCP servers
triggers
["generate a CLI for an API","create an MCP server for this service","build a CLI with offline search","print a CLI from OpenAPI spec","reverse engineer an API and generate CLI","create agent-native CLI with SQLite","generate compound commands for API","build CLI with local data sync"]
# CLI Printing Press Generator > Skill by [ara.so](https://ara.so) — Devtools Skills collection. CLI Printing Press generates production-ready CLIs from any API — REST, GraphQL, or browser-sniffed traffic. Each generated CLI includes SQLite-backed local storage, offline full-text search, compound insight commands, and dual interfaces (Cobra CLI + MCP server). Designed for AI agents first with typed exit codes, auto-JSON output when piped, and token-efficient `--compact` mode. ## What It Does The Printing Press follows a 6-phase autonomous workflow: 1. **Research**: Discovers official docs, competing CLIs, MCP servers, and community patterns 2. **Non-Obvious Insight**: Identifies the API's secret identity (what it's *actually* useful for) 3. **Code Generation**: Builds Go CLI with domain-specific SQLite tables, FTS5 indexes, sync engine 4. **Verification**: Runs scorecard, dogfood tests, proof-of-behavior checks, live API smoke tests 5. **Polish**: Auto-fixes verify failures, removes dead code, cleans descriptions 6. **Publishing**: Packages for library, generates PR with quality score **Key differentiators:** - **Local-first**: High-gravity resources get domain tables (not JSON blobs) with incremental sync - **Compound commands**: Cross-resource queries (`stale`, `health`, `bottleneck`) impossible with stateless wrappers - **Dual output**: Every API generates both `<api>-pp-cli` (Cobra) and `<api>-pp-mcp` (MCP server) - **No spec required**: Point at a website, captures traffic, reverse-engineers the API - **Agent-native**: Auto-JSON when piped, typed exit codes, `--compact` flag, `--dry-run` ## Installation ### Prerequisites - Go 1.26.3+ ([install](https://go.dev/dl/)) - Claude Code or compatible AI agent harness - Git (for cloning skills repo) ### 1. Install Binary ```bash go install github.com/mvanhorn/cli-printing-press/v4/cmd/printing-press@latest ``` Verify: ```bash printing-press --version ``` ### 2. Install Skills (Recommended Method) Clone the repo to get skills and automatic updates via `git pull`: ```bash git clone https://github.com/mvanhorn/cli-printing-press.git cd cli-printing-press ``` ### 3. Start Printing Session From the cloned repo root: ```bash # Load skills directly from this repo claude --plugin-dir . # Or in a new git worktree (for parallel runs) claude --plugin-dir . -w ``` ## Core Commands ### Primary Generation Command Inside Claude Code session: ```text /printing-press <api-name> /printing-press <url> /printing-press <api-name> codex ``` **Examples:** ```text # Generate from API name (auto-discovers docs/specs) /printing-press Notion # Generate from website (browser-sniff traffic) /printing-press https://postman.com/explore # Use Codex for code generation (60% fewer Opus tokens) /printing-press HubSpot codex # Reprint existing CLI under latest machine /printing-press-reprint notion ``` ### Polish Existing CLI Runs diagnostics, fixes verify failures, removes dead code: ```text /printing-press-polish <api-name> ``` Example: ```text /printing-press-polish linear ``` ### Publish to Library Validates, packages, creates PR: ```text /printing-press-publish <api-name> ``` Example: ```text /printing-press-publish superhuman ``` ### Amend from Dogfood Session Turn session friction into PR (auto-detects target CLI): ```text /printing-press-amend /printing-press-amend <api-name> ``` ## Binary CLI Usage The `printing-press` binary is called by skills but can be used directly: ```bash # Research phase printing-press research <api-name> --output ./output # Generate full CLI printing-press generate notion --output ~/clis/notion-pp-cli # Verify generated CLI printing-press verify ~/clis/notion-pp-cli # Score quality printing-press scorecard ~/clis/notion-pp-cli # Dogfood test printing-press dogfood ~/clis/notion-pp-cli ``` ## Configuration ### Output Locations Default structure (auto-managed by skills): ``` ~/printing-press/ ├── .runstate/<scope>/runs/<run-id>/working/<api>-pp-cli/ # Active runs ├── library/<api>/ # Published CLIs └── manuscripts/<api>/<run-id>/ # Archived runs ├── research/ ├── proofs/ ├── discovery/ └── pipeline/ ``` `<scope>` derives from git checkout path (parallel worktrees don't conflict). ### Override Output ```bash printing-press generate stripe --output /custom/path/stripe-cli ``` ### Environment Variables Generated CLIs use these patterns: ```bash # API authentication export NOTION_API_KEY="secret_..." export LINEAR_API_KEY="lin_api_..." export GITHUB_TOKEN="ghp_..." # SQLite store location (override default) export NOTION_PP_STORE_PATH="/custom/notion.db" # Refresh settings for auto data-source export LINEAR_PP_REFRESH_TTL="5m" ``` ## Generated CLI Patterns Every generated CLI follows these conventions: ### Authentication Setup ```bash # Interactive auth setup (writes to ~/.config/<api>-pp-cli/config.yaml) notion-pp-cli auth login # Or set directly export NOTION_API_KEY="secret_abc123" ``` ### Data Source Modes ```bash # Auto mode: refresh if TTL expired (default) linear-pp-cli issues list --data-source auto # Force live API call linear-pp-cli issues list --data-source live # Local-only (offline) linear-pp-cli issues list --data-source local ``` ### Sync and Search ```bash # Initial sync notion-pp-cli sync # Incremental sync notion-pp-cli sync --incremental # Full-text search (FTS5) notion-pp-cli search "authentication flow" # Direct SQL query notion-pp-cli sql "SELECT title FROM pages WHERE updated_at > date('now', '-7 days')" ``` ### Agent-Native Features ```bash # Auto-JSON when piped linear-pp-cli issues list | jq '.[] | select(.priority == "urgent")' # Compact mode (60-80% fewer tokens) linear-pp-cli issues list --compact # Dry-run (safe exploration) linear-pp-cli issues create --title "Test" --dry-run # Typed exit codes linear-pp-cli issues get ISSUE-123 echo $? # 0=success, 2=not found, 3=auth, 4=validation, 5=server, 7=offline ``` ### Compound Commands Generated CLIs include domain-specific insight commands: ```bash # Linear example linear-pp-cli stale --threshold 7d # Issues blocked >7 days linear-pp-cli health --team backend # Team velocity metrics linear-pp-cli bottleneck # Most-blocking issues # Discord example discord-pp-cli knowledge --channel docs # Thread knowledge graph discord-pp-cli stale-threads --days 30 # Unanswered >30 days # Stripe example stripe-pp-cli churn-signals # Failed charges + cancellations stripe-pp-cli cohort-health --month 2026-04 ``` ## Code Examples ### Using a Generated CLI in Go ```go package main import ( "context" "fmt" "os" "os/exec" "encoding/json" ) // Call generated Linear CLI func getBlockedIssues() ([]Issue, error) { cmd := exec.Command("linear-pp-cli", "stale", "--threshold", "7d", "--output", "json") output, err := cmd.Output() if err != nil { return nil, fmt.Errorf("CLI error: %w", err) } var issues []Issue if err := json.Unmarshal(output, &issues); err != nil { return nil, err } return issues, nil } // Use MCP server programmatically func callMCPServer(ctx context.Context, method string, params map[string]interface{}) error { // MCP servers expose stdio interface cmd := exec.CommandContext(ctx, "linear-pp-mcp") stdin, _ := cmd.StdinPipe() stdout, _ := cmd.StdoutPipe() if err := cmd.Start(); err != nil { return err } req := map[string]interface{}{ "jsonrpc": "2.0", "method": method, "params": params, "id": 1, } json.NewEncoder(stdin).Encode(req) var resp map[string]interface{} json.NewDecoder(stdout).Decode(&resp) return cmd.Wait() } ``` ### Integrating Generated CLI into Scripts ```bash #!/bin/bash # Deploy blocker detection script # Sync latest data notion-pp-cli sync --incremental # Find stale blockers BLOCKERS=$(notion-pp-cli sql " SELECT b.id, b.title, i.title as blocked_issue FROM issues i JOIN issues b ON i.blocker_id = b.id WHERE b.state = 'in_progress' AND b.updated_at < date('now', '-7 days') " --output json) # Send to Slack if any found if [ "$(echo "$BLOCKERS" | jq 'length')" -gt 0 ]; then echo "$BLOCKERS" | jq -r '.[] | "⚠️ \(.blocked_issue) blocked by stale: \(.title)"' \ | slack-cli send --channel "#deploy-alerts" fi ``` ### Creating Custom Commands Generated CLIs support plugin architecture: ```go // Add to cmd/custom/reconcile.go in generated CLI package custom import ( "github.com/spf13/cobra" "github.com/mvanhorn/linear-pp-cli/internal/store" ) func NewReconcileCmd(st *store.Store) *cobra.Command { cmd := &cobra.Command{ Use: "reconcile", Short: "Find issues in API but missing from local store", RunE: func(cmd *cobra.Command, args []string) error { // Query local store localIDs := st.GetAllIssueIDs() // Query live API liveIDs := fetchLiveIssueIDs() // Diff missing := difference(liveIDs, localIDs) for _, id := range missing { fmt.Printf("Missing: %s\n", id) } return nil }, } return cmd } ``` ## Troubleshooting ### Generation Failures **Problem:** Research phase hangs or fails ```bash # Check if API has publicly accessible docs curl -I https://developers.notion.com # Try explicit spec URL /printing-press https://raw.githubusercontent.com/notion/openapi/main/spec.yaml # Use browser-sniff mode for private APIs /printing-press https://internal-tool.company.com ``` **Problem:** Codex mode fails repeatedly The press auto-falls back to local generation after 3 Codex failures. Check logs: ```bash tail -f ~/.printing-press/.runstate/<scope>/runs/<run-id>/logs/generation.log ``` ### Verification Errors **Problem:** Scorecard shows low score ```bash # Run polish to auto-fix /printing-press-polish <api-name> # Check specific failure printing-press verify ~/printing-press/library/<api> --verbose ``` **Problem:** Auth tests fail ```bash # Verify credentials work manually export API_KEY="your_key" curl -H "Authorization: Bearer $API_KEY" https://api.service.com/test # Check generated auth.go cat ~/printing-press/library/<api>-pp-cli/internal/auth/auth.go ``` ### Runtime Issues with Generated CLIs **Problem:** Sync fails with rate limit ```bash # Use incremental sync with backoff api-pp-cli sync --incremental --rate-limit 10/min # Check cursor tracking api-pp-cli sql "SELECT resource, cursor, updated_at FROM sync_cursors" ``` **Problem:** Search returns no results ```bash # Rebuild FTS5 index api-pp-cli sql "DELETE FROM pages_fts" api-pp-cli sync --rebuild-index # Verify FTS table api-pp-cli sql "SELECT * FROM sqlite_master WHERE type='table' AND name LIKE '%_fts'" ``` **Problem:** Compound command errors ```bash # Check if required tables exist api-pp-cli sql ".schema" | grep -A 5 "CREATE TABLE" # Run with debug output api-pp-cli stale --threshold 7d --log-level debug ``` ### MCP Server Issues **Problem:** MCP server not responding ```bash # Test stdio interface directly
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub