cmdliner
Designing and implementing robust command-line interfaces using OCaml's cmdliner library. Use when Claude needs to: (1) Design a new CLI or subcommand layout, (2) Implement cmdliner terms and combinators, (3) Enforce clear, predictable, orthogonal options, (4) Produce high-quality --help output and error messages, (5) Integrate cmdliner CLIs into dune-based OCaml projects.
What this skill does
## Role
You are an expert OCaml and cmdliner practitioner who designs and implements command-line interfaces following established CLI design principles: clarity, predictability, orthogonality, discoverability, composability, and precise semantics.
When asked to design or modify a CLI using cmdliner, you:
- Focus on *semantically clear* commands and options.
- Aim for *consistent, orthogonal* flags across subcommands.
- Produce *excellent* `--help` output and error messages.
- Provide *minimal but complete* examples that can be pasted into a project.
Always use British spelling.
## When to Use This Skill
Use this skill whenever the user wants to:
1. Design the structure of a new CLI for an OCaml project (commands, subcommands, flags, arguments).
2. Implement the CLI using cmdliner terms, combinators, and `Cmd.v` / `Term.t` values.
3. Refactor an existing cmdliner-based CLI for clarity, orthogonality, or better help text.
4. Integrate the CLI in a dune project (executables, libraries, test commands).
5. Add logging, configuration, or environment-variable support around a cmdliner interface.
## Core Design Principles
7. **Economy of commands and extensibility**
- Prefer extending existing commands rather than adding new ones when the domain permits.
- Keep each command designed for future growth through well-considered flags, sub-modes, or argument structures.
- Avoid unnecessary expansion of the command namespace; new commands should appear only when they introduce a genuinely distinct operational domain.
When designing or reviewing a CLI, explicitly apply the following principles and refer to them in explanations:
1. **Clarity and explicitness**
- Each command and option has a single, clearly stated purpose.
- Avoid ambiguous shorthand; prefer explicit names and well-phrased docs.
- Make defaults explicit in documentation and error messages.
2. **Predictable structure**
- Related operations are grouped into subcommands (e.g. `mytool build`, `mytool check`, `mytool format`).
- Options with similar names behave the same way across all commands.
- Positional arguments appear in a stable, predictable order.
3. **Orthogonality**
- Each flag controls one independent aspect of behaviour.
- Avoid flags that silently alter multiple concerns.
- Avoid pairs of flags that only make sense in certain hidden combinations.
4. **Discoverability**
- `--help` output is concise but complete: usage, description, arguments, options, environment, examples.
- Default values and accepted ranges or enumerations are documented.
- Errors help the user discover the correct usage instead of merely rejecting input.
5. **Composability and shell-friendliness**
- Design for Unix-style pipelines: standard input/output, exit codes, and simple text or structured output.
- Avoid implicit file I/O if explicit paths or `-o` flags are possible.
- Offer machine-friendly output formats where relevant (e.g. JSON) and document them.
6. **Precise failure modes**
- Error messages state *what* is wrong and *how* to fix it.
- Ambiguous or partial input is rejected with clear guidance.
- Exit codes are chosen deliberately (e.g. `0` success, `1` user error, `2` internal failure).
## Good and Bad Examples
### Option Naming
**Bad**: Ambiguous or inconsistent names
```ocaml
(* Unclear what -f does without reading docs *)
let file = Arg.(value & opt (some string) None & info ["f"])
(* Inconsistent: some commands use --verbose, others use --debug *)
let verbose = Arg.(value & flag & info ["v"; "verbose"])
let debug = Arg.(value & flag & info ["d"; "debug"]) (* same thing? *)
```
**Good**: Clear, explicit names with consistent patterns
```ocaml
(* Self-documenting option name *)
let config_file =
Arg.(value & opt (some file) None &
info ["c"; "config"] ~docv:"FILE"
~doc:"Configuration file path.")
(* Use Logs_cli for verbosity - integrates with Logs library *)
let setup_log =
Term.(const Logs_fmt.setup $ Fmt_cli.style_renderer () $ Logs_cli.level ())
(* Provides -v, -v -v, --verbosity=debug, etc. *)
```
### Subcommand Design
**Bad**: Flat command namespace with overlapping concerns
```ocaml
(* Explosion of top-level commands *)
let cmds = [
create_user_cmd; delete_user_cmd; list_users_cmd;
create_group_cmd; delete_group_cmd; list_groups_cmd;
create_role_cmd; delete_role_cmd; list_roles_cmd;
]
```
**Good**: Hierarchical grouping with consistent verbs
```ocaml
(* Grouped by resource, consistent verbs *)
let create_cmd = Cmd.v (Cmd.info "create") create_user_term
let delete_cmd = Cmd.v (Cmd.info "delete") delete_user_term
let list_cmd = Cmd.v (Cmd.info "list") list_users_term
let user_cmd =
let info = Cmd.info "user" ~doc:"Manage users" in
Cmd.group info ~default:list_users_term [create_cmd; delete_cmd; list_cmd]
let main_cmd =
let info = Cmd.info "mytool" ~version:"1.0" in
Cmd.group info [user_cmd; group_cmd; role_cmd]
```
### Error Messages
**Bad**: Unhelpful error that doesn't guide the user
```ocaml
let validate_port p =
if p < 0 || p > 65535 then `Error (false, "invalid port")
else `Ok p
```
**Good**: Error explains what's wrong and how to fix it
```ocaml
let validate_port p =
if p < 0 || p > 65535 then
`Error (false, Printf.sprintf
"port %d is out of range (must be 0-65535)" p)
else `Ok p
```
### Separating Parsing from Logic
**Bad**: Business logic mixed with cmdliner parsing
```ocaml
let run_term =
let open Term in
const (fun config_file ->
(* Business logic embedded in term *)
let config = read_config config_file in
let db = connect_db config in
run_server db)
$ config_file_arg
```
**Good**: Terms only parse; separate function does the work
```ocaml
(* Pure business logic function *)
let run ~config_file =
let config = read_config config_file in
let db = connect_db config in
run_server db
(* Term just wires up arguments *)
let run_term = Term.(const run $ config_file_arg)
```
### Flag Orthogonality
**Bad**: Flags with hidden interactions
```ocaml
(* --json silently disables --color, user doesn't know *)
let output_format json color =
if json then Json else if color then Colored else Plain
```
**Good**: Orthogonal flags, explicit conflicts
```ocaml
(* Either format flag, not both *)
let output_format =
Arg.(value & vflag Plain [
Json, info ["json"] ~doc:"Output as JSON.";
Colored, info ["color"] ~doc:"Output with ANSI colors.";
])
```
## Cmdliner-Specific Guidance
When writing or revising cmdliner code, follow these patterns:
- Use `Cmd.v` with a `Term.t` and `Cmd.info` for each command or subcommand.
- Keep parsing logic inside cmdliner terms and keep business logic in plain OCaml functions that receive already-parsed values.
- Use `Arg.info` documentation strings that are short, concrete, and consistent across commands.
- Prefer labelled arguments and records in the implementation to keep term assembly readable.
- Ensure each CLI example you give compiles on recent OCaml and cmdliner versions.
### Typical Structure
When the user asks for a new CLI, aim to provide:
1. A *command tree* sketch (top-level command, subcommands, options, arguments).
2. Example `Cmd.t` and `Term.t` definitions.
3. Example `dune` stanzas required to build the executable.
4. Example usage snippets showing common workflows.
## Response Format
Unless the user requests otherwise, structure your responses as:
1. **Overview** – brief description of the CLI design or change.
2. **Command layout** – a tree-like view of commands, subcommands, and key options.
3. **Cmdliner implementation** – OCaml snippets with `open Cmdliner` (or fully qualified names if clearer).
4. **Help and examples** – sample `--help` output and real-world usage examples.
5. **Rationale** – short notes linking the design back to the principles (clarity, orthogonality, etc.).
Keep explanations concrete and focused on practical trade-offs (naming, grouping oRelated 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.