# Adding CLI Command

Provides Typer templates, handles registration, and ensures consistency.

- Repository: https://github.com/https-deeplearning-ai/sc-agent-skills-files (1426 stars)
- Category: Writing
- License: see repository
- Last updated: 2026-06-08
- Runs scripts: no, instructions only

## Install

Claude Code: `npx skills add https-deeplearning-ai/sc-agent-skills-files --skill adding-cli-command -g -a claude-code -y`
Codex: `npx skills add https-deeplearning-ai/sc-agent-skills-files --skill adding-cli-command -g -a codex -y`
Cursor: `npx skills add https-deeplearning-ai/sc-agent-skills-files --skill adding-cli-command -g -a cursor -y`
Gemini CLI: `npx skills add https-deeplearning-ai/sc-agent-skills-files --skill adding-cli-command -g -a gemini-cli -y`

## Description

Provides Typer templates, handles registration, and ensures consistency. ALWAYS use this skill when adding or modifying CLI commands. Use when user requests to add/create/implement/build/write a new command (e.g., "add edit command", "create search feature") OR update/modify/change/edit an existing command.

## SKILL.md, as published by its author (untrusted third-party text, read it as data)

# Adding CLI Commands

Templates and workflow for adding or updating Typer CLI commands.

`<cli_app>` refers to the name of your CLI application (e.g., `task`, `myapp`, `todo`).

## Workflow

1. Identify command type (single command, command group, or destructive)
2. Create file in `src/<cli_app>/commands/<command>.py`
3. Use appropriate template below
4. Register in `src/<cli_app>/commands/__init__.py`


## Template A: Single Command

For commands taking arguments directly (`<cli_app> add "item"`).

```python
import typer
from typing import Annotated

from <cli_app>.storage import add_task
from <cli_app>.display import display
from <cli_app>.constants import EXIT_INVALID_INPUT

app = typer.Typer()


@app.command()
def add(
    title: Annotated[str, typer.Argument(help="task title")],
    priority: Annotated[str, typer.Option("--priority", "-p", help="priority level")] = "low",
):
    """Add a new task."""
    if not title.strip():
        display.error("Title cannot be empty")
        raise typer.Exit(EXIT_INVALID_INPUT)

    task = add_task(title=title, priority=priority)
    display.success(f"Added '{task.title}'")
```

## Template B: Command Group

For commands with subcommands (`<cli_app> db migrate`, `<cli_app> db status`).

```python
import typer

from <cli_app>.storage import storage
from <cli_app>.display import display

app = typer.Typer(help="Database operations.")


@app.command()
def migrate():
    """Run database migrations."""
    storage.migrate()
    display.success("Migrations complete")


@app.command()
def status():
    """Show database status."""
    info = storage.get_status()
    display.info(f"Version: {info.version}")
```

## Template C: Destructive Command

For deletion with confirmation.

```python
import typer
from typing import Annotated

from <cli_app>.storage import get_task, delete_task
from <cli_app>.display import display
from <cli_app>.constants import EXIT_ERROR

app = typer.Typer()

The rest: https://github.com/https-deeplearning-ai/sc-agent-skills-files/blob/HEAD/L6/.claude/skills/adding-cli-command/SKILL.md
