npx-cli
Build and publish npx-executable CLI tools using Bun as the primary toolchain with npm-compatible output. Use when the user wants to create a new CLI tool, set up a command-line package for npx execution, configure argument parsing and terminal output, or publish a CLI to npm. Covers scaffolding, citty arg parsing, sub-commands, terminal UX, strict TypeScript, Biome + ESLint linting, Vitest testing, Bunup bundling, and publishing workflows. Keywords: npx, cli, command-line, binary, bin, tool, bun, citty, commander, terminal, publish, typescript, biome, vitest.
What this skill does
# npx CLI Tool Development (Bun-First)
Build and publish npx-executable command-line tools using Bun as the primary runtime and toolchain, producing binaries that work for all npm/npx users (Node.js runtime).
## When to Use This Skill
Use when:
- Creating a new CLI tool from scratch
- Building an npx-executable binary
- Setting up argument parsing, sub-commands, or terminal UX for a CLI
- Publishing a CLI tool to npm
- Adding a CLI to an existing library package
Do NOT use when:
- Building a library without a CLI (use the `npm-package` skill)
- Building an application (not a published package)
- Working in a monorepo (this skill targets single-package repos)
## Toolchain
| Concern | Tool | Why |
|---------|------|-----|
| Runtime / package manager | Bun | Fast install, run, transpile |
| Bundler | Bunup | Bun-native, dual entry (lib + cli), .d.ts |
| Argument parsing | citty | ~3KB, TypeScript-native, auto-help, `runMain()` |
| Terminal colors | picocolors | ~7KB, CJS+ESM, auto-detect |
| TypeScript | `module: "nodenext"`, `strict: true` + extras | Maximum correctness |
| Formatting + basic linting | Biome v2 | Fast, single tool |
| Type-aware linting | ESLint + typescript-eslint | Deep type safety |
| Testing | Vitest | Isolation, mocking, coverage |
| Versioning | Changesets | File-based, explicit |
| Publishing | `npm publish --provenance` | Trusted Publishing / OIDC |
## Scaffolding a New CLI
Run the scaffold script:
```bash
bun run <skill-path>/scripts/scaffold.ts ./my-cli \
--name my-cli \
--bin my-cli \
--description "What this CLI does" \
--author "Your Name" \
--license MIT
```
Options:
- `--bin <name>` — Binary name for npx (defaults to package name without scope)
- `--cli-only` — No library exports, CLI binary only
- `--no-eslint` — Skip ESLint, use Biome only
Then install dependencies:
```bash
cd my-cli
bun install
bun add -d bunup typescript vitest @vitest/coverage-v8 @biomejs/biome @changesets/cli
bun add citty picocolors
bun add -d eslint typescript-eslint # unless --no-eslint
```
## Project Structure
### Dual (Library + CLI) — Default
```
my-cli/
├── src/
│ ├── index.ts # Library exports (programmatic API)
│ ├── index.test.ts # Unit tests for library
│ ├── cli.ts # CLI entry point (imports from index.ts)
│ └── cli.test.ts # CLI integration tests
├── dist/
│ ├── index.js # Library bundle
│ ├── index.d.ts # Type declarations
│ └── cli.js # CLI binary (with shebang)
├── .changeset/
│ └── config.json
├── package.json
├── tsconfig.json
├── bunup.config.ts
├── biome.json
├── eslint.config.ts
├── vitest.config.ts
├── .gitignore
├── README.md
└── LICENSE
```
### CLI-Only (No Library Exports)
Same structure minus `src/index.ts` and `src/index.test.ts`. No `exports` field in package.json, only `bin`.
## Architecture Pattern
**Separate logic from CLI wiring.** The CLI entry (`cli.ts`) is a thin wrapper that:
1. Parses arguments with citty
2. Calls into the library/core modules
3. Formats output for the terminal
All business logic lives in importable modules (`index.ts` or internal modules). This makes logic unit-testable without spawning processes.
```
cli.ts → imports from → index.ts / core modules
↑
unit tests
```
## Key Rules (Non-Negotiable)
All rules from the npm-package skill apply here. These additional rules are specific to CLI packages:
### Binary Configuration
1. **Always use `#!/usr/bin/env node` in published bin files.** Never `#!/usr/bin/env bun`. The vast majority of npx users don't have Bun installed.
2. **Point `bin` at compiled JavaScript in `dist/`.** Never at TypeScript source. npx consumers won't have your build toolchain.
3. **Ensure the bin file is executable.** The build script includes `chmod +x dist/cli.js` after compilation.
4. **Build with Node.js as the target.** Bunup's output must run on Node.js, not require Bun runtime features.
### Package Configuration
5. **Always use `"type": "module"` in package.json.**
6. **`types` must be the first condition** in every exports block.
7. **Use `files: ["dist"]`.** Whitelist only.
8. **For dual packages (library + CLI):** The `exports` field exposes the library API. The `bin` field exposes the CLI. They are independent — `bin` is NOT part of `exports`.
### Code Quality
9. **`any` is banned.** Use `unknown` and narrow.
10. **Use `import type` for type-only imports.**
11. **Handle errors gracefully.** CLI users should never see raw stack traces. Use citty's `runMain()` which handles this automatically, plus `process.on('SIGINT', ...)` for cleanup.
12. **Exit with appropriate codes.** 0 for success, 1 for errors, 2 for bad arguments, 130 for SIGINT.
## Reference Documentation
Read these before modifying configuration:
- **[reference/cli-patterns.md](./reference/cli-patterns.md)** — bin setup, citty patterns, sub-commands, error handling, terminal UX, testing CLI binaries
- **[reference/esm-cjs-guide.md](./reference/esm-cjs-guide.md)** — `exports` map, dual package hazard, common mistakes
- **[reference/strict-typescript.md](./reference/strict-typescript.md)** — tsconfig, Biome rules, ESLint type-aware rules, Vitest config
- **[reference/publishing-workflow.md](./reference/publishing-workflow.md)** — Changesets, `files` field, Trusted Publishing, CI pipeline
## Argument Parsing with citty
### Single Command
```typescript
import { defineCommand, runMain } from 'citty';
const main = defineCommand({
meta: { name: 'my-cli', version: '1.0.0', description: '...' },
args: {
input: { type: 'positional', description: 'Input file', required: true },
output: { alias: 'o', type: 'string', description: 'Output path', default: './out' },
verbose: { alias: 'v', type: 'boolean', description: 'Verbose output', default: false },
},
run({ args }) {
// args is fully typed
},
});
void runMain(main);
```
### Sub-Commands
```typescript
import { defineCommand, runMain } from 'citty';
const init = defineCommand({ meta: { name: 'init' }, /* ... */ });
const build = defineCommand({ meta: { name: 'build' }, /* ... */ });
const main = defineCommand({
meta: { name: 'my-cli', version: '1.0.0' },
subCommands: { init, build },
});
void runMain(main);
```
See [reference/cli-patterns.md](./reference/cli-patterns.md) for complete examples including error handling, colors, and spinners.
## Testing Strategy
### Unit Tests — Test the Logic
```typescript
// src/index.test.ts
import { describe, it, expect } from 'vitest';
import { processInput } from './index.js';
describe('processInput', () => {
it('handles valid input', () => {
expect(processInput('test')).toBe('expected');
});
});
```
### Integration Tests — Test the Binary
Build first (`bun run build`), then spawn the compiled binary:
```typescript
// src/cli.test.ts
import { describe, it, expect } from 'vitest';
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
const exec = promisify(execFile);
describe('CLI', () => {
it('prints help', async () => {
const { stdout } = await exec('node', ['./dist/cli.js', '--help']);
expect(stdout).toContain('my-cli');
});
});
```
## Development Workflow
```bash
# Write code and tests
bun run test:watch # Vitest watch mode
# Check everything
bun run lint # Biome + ESLint
bun run typecheck # tsc --noEmit
bun run test # Vitest
# Build and try the CLI locally
bun run build
node ./dist/cli.js --help
node ./dist/cli.js some-input
# Prepare release
bunx changeset
bunx changeset version
# Publish
bun run release # Build + npm publish --provenance
```
## Adding Sub-Commands Later
1. Create a new file per sub-command: `src/commands/init.ts`, `src/commands/build.ts`
2. Each exports a `defineCommand()` result
3. Import and wire into the main command's `subCommands`
4. Keep logic in testable modules, commands aRelated in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.