-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Summary
The cli-dev plugin provides scaffolding and conventions for building CLI applications across multiple languages, with a preference for zx (scripted shell via JavaScript) over raw bash. This is valuable because CLI app setup involves many boilerplate decisions (argument parsing library, output formatting, error handling, distribution) that the plugin standardizes.
Original Intent
Guidelines for CLI development. Conventions, npm and Python libs, and use zx npm instead of bash where possible.
Commands
/cli-dev:init
Purpose: Initialize a new CLI application project with appropriate scaffolding.
Behavior:
-
Ask user for:
- CLI name
- Language/runtime: TypeScript/Bun (default), TypeScript/Node, Python, Go
- CLI type: single-command tool, multi-command CLI, interactive REPL
-
Generate project based on language choice:
TypeScript/Bun (default):
<name>/ ├── src/ │ ├── index.ts # Entry point with shebang │ ├── commands/ │ │ └── example.ts # Example command │ └── utils/ │ ├── cli.ts # Argument parsing setup │ └── output.ts # Colored output helpers ├── tests/ │ └── example.test.ts ├── package.json ├── tsconfig.json ├── biome.json └── README.md- Arg parser:
commander(most popular, well-typed) oryargs(if complex subcommands) - Shell commands:
zxfor anything that would otherwise be a bash script - Output formatting:
chalkfor colors,cli-table3for tables,orafor spinners
Python:
<name>/ ├── src/<name>/ │ ├── __init__.py │ ├── __main__.py # Entry point │ ├── cli.py # Typer app definition │ └── commands/ │ └── example.py ├── tests/ │ └── test_example.py ├── pyproject.toml # With [project.scripts] entry └── README.md- Arg parser:
typer(type-based CLI, click under the hood) - Output:
richfor colors/tables/progress
Go:
<name>/ ├── cmd/ │ ├── root.go # Cobra root command │ └── example.go # Example subcommand ├── internal/ │ └── output.go # Output helpers ├── main.go ├── go.mod └── README.md- Arg parser:
cobra(industry standard) - Output:
lipglossfor styling,bubblesfor TUI components
- Arg parser:
-
Install dependencies for chosen language
-
Set up entry point with:
- Help text (
--help) - Version flag (
--version) - Verbose/quiet flags
- Color/no-color support
- Help text (
-
Make entry point executable (chmod +x, shebang line)
-
Output summary of created files
Edge cases:
- Directory not empty → warn and offer to scaffold into existing project
- Name conflicts with existing system commands → warn
/cli-dev:command
Purpose: Add a new subcommand to an existing CLI application.
Behavior:
-
Detect language from existing project structure
-
Ask user for:
- Command name
- Description
- Arguments (positional)
- Options/flags (with types and defaults)
-
Generate command file based on language:
TypeScript (commander):
import { Command } from "commander"; export const greetCommand = new Command("greet") .description("Greet a user by name") .argument("<name>", "Name to greet") .option("-l, --loud", "Use uppercase", false) .action((name: string, options: { loud: boolean }) => { const greeting = `Hello, ${name}!`; console.log(options.loud ? greeting.toUpperCase() : greeting); });
Python (typer):
import typer from rich.console import Console console = Console() def greet( name: str = typer.Argument(help="Name to greet"), loud: bool = typer.Option(False, "--loud", "-l", help="Use uppercase"), ) -> None: """Greet a user by name.""" greeting = f"Hello, {name}!" console.print(greeting.upper() if loud else greeting)
Go (cobra):
var greetCmd = &cobra.Command{ Use: "greet [name]", Short: "Greet a user by name", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { // ... }, }
-
Register the command in the main CLI entry point
-
Generate a test file for the command
-
Output: created files + example usage
Edge cases:
- Command name already exists → warn
- No CLI framework detected → suggest running
/cli-dev:initfirst
/cli-dev:release (new)
Purpose: Prepare the CLI for distribution.
Behavior:
-
Detect language and determine distribution strategy:
Language Strategy Command TypeScript/Bun Compile to binary bun build --compileTypeScript/Node npm publish npm publishPython PyPI publish uv build && uv publishGo Cross-compile GOOS=linux GOARCH=amd64 go build -
For Bun compiled binaries:
- Cross-compile for targets:
bun-linux-x64,bun-darwin-arm64,bun-linux-arm64 - Package into dist/ directory
- Cross-compile for targets:
-
Update version in manifest
-
Generate/update CHANGELOG.md entry
-
Create git tag (but don't push — defer to gitflow plugin)
-
Output distribution artifacts and next steps
Edge cases:
- No version in manifest → ask user
- Existing release workflow (GitHub Actions) → suggest using it instead
Hooks
PostToolUse: zx_suggestion
Trigger: Write tool, when creating/editing a .sh or .bash file with more than 20 lines
Behavior:
- Output:
💡 Consider using zx (JavaScript) instead of bash for complex scripts. See: https://google.github.io/zx/ - Do NOT block — informational only
- Only trigger once per file
File Manifest
| File | Est. Lines | Purpose |
|---|---|---|
commands/init.md |
110-130 | Initialize CLI project |
commands/command.md |
80-100 | Add new subcommand |
commands/release.md |
70-90 | Prepare for distribution |
hooks/zx_suggestion.md |
20-30 | Suggest zx over bash |
README.md |
150-180 | Full plugin documentation |
.claude-plugin/plugin.json |
15-20 | Plugin manifest |
README Outline
-
Overview — CLI development across languages, zx-first for scripts
-
Quick Start — Installation +
/cli-dev:init -
Commands — Table with all 3 commands
-
Language Comparison
Feature Bun/TS Python Go Arg parser commander typer cobra Output chalk + cli-table3 rich lipgloss Shell ops zx subprocess os/exec Binary bun --compile pyinstaller/shiv go build Startup ~30ms ~100ms ~5ms -
Project Templates — Directory layout per language
-
zx Guide — When and how to use zx instead of bash
-
Distribution — Publishing and cross-compilation
-
Recommended Libraries — Per-language table of CLI utilities
Prerequisites
- Language-specific runtime (Bun, Python, Go)
zx(installed automatically viabun add google/zxorbunx zx)
Quality Checklist
- Each command .md is 60+ lines with concrete steps
- README is 100+ lines with examples and reference tables
- Multi-language support is concrete (not just "detect language")
- zx preference over bash is documented with rationale
- Plugin provides clear value (scaffolding + consistent structure)