> ## Documentation Index
> Fetch the complete documentation index at: https://chatcli.edilsonfreitas.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Slash Commands

> Templates de prompt reutilizáveis e parametrizados em markdown — invocados como /nome em todas as superfícies, com interop de migração zero para 9 CLIs de agente: Claude Code, Devin, Windsurf, Cursor, opencode, Codex, Gemini CLI, Qwen Code e GitHub Copilot.

Slash commands transformam arquivos markdown em **templates de prompt reutilizáveis e parametrizados**: coloque `review-pr.md` em `.chatcli/commands/` e `/review-pr 1326 security` vira um prompt completo expandido — no REPL, dentro de uma sessão `/coder` em andamento, em scripts one-shot `-p`, pelo gateway de mensagens, e via ACP e MCP. A expansão acontece **antes** de o request ser montado, então os comandos funcionam de forma idêntica com todos os providers que o ChatCLI suporta. E se o seu time já mantém comandos para **Claude Code, Devin, Windsurf, Cursor, opencode, Codex, Gemini CLI, Qwen Code ou GitHub Copilot**, esses arquivos funcionam aqui sem mudanças — migração zero.

***

## Comandos vs. skills

|                | Skill                                  | Slash command                          |
| -------------- | -------------------------------------- | -------------------------------------- |
| O que é        | *Conhecimento* — "como fazemos X aqui" | *Ação* — "faça X agora com estes args" |
| Onde entra     | Bloco de guidance no system prompt     | Vira o próprio turno do usuário        |
| Ciclo de vida  | Persistente, envelhece, re-ativa       | One-shot, consumido                    |
| Parametrização | Args anexados ao lado                  | `$ARGUMENTS` / `$1`…`$9` interpolados  |

Ambos aparecem no completer e no palette `/menu`.

***

## Onde os comandos moram

Varridos em ordem de precedência — o primeiro nome encontrado vence. Os diretórios nativos do ChatCLI vêm primeiro, depois a **matriz de interop**: se o seu time já usa qualquer uma dessas CLIs de agente, os arquivos de comando delas funcionam no ChatCLI sem mudanças.

| Fonte              | Projeto                       | Global                             | Formato |
| ------------------ | ----------------------------- | ---------------------------------- | ------- |
| **ChatCLI**        | `.chatcli/commands/`          | `~/.chatcli/commands/`             | md      |
| **Claude Code**    | `.claude/commands/`           | —                                  | md      |
| **Devin**          | `.devin/workflows/`           | —                                  | md      |
| **Windsurf**       | `.windsurf/workflows/`        | —                                  | md      |
| **Cursor**         | `.cursor/commands/`           | `~/.cursor/commands/`              | md      |
| **opencode**       | `.opencode/commands/`         | `~/.config/opencode/commands/`     | md      |
| **Codex (OpenAI)** | —                             | `~/.codex/prompts/` (só top-level) | md      |
| **Gemini CLI**     | `.gemini/commands/`           | `~/.gemini/commands/`              | TOML    |
| **Qwen Code**      | `.qwen/commands/`             | `~/.qwen/commands/`                | TOML    |
| **GitHub Copilot** | `.github/prompts/*.prompt.md` | —                                  | md      |

Subdiretórios viram namespaces: `frontend/deploy.md` → `/frontend:deploy` (o `git/commit.toml` do Gemini → `/git:commit`). Chaves de frontmatter alheias (`agent`, `subtask`, `mode`, `auto_execute_steps`) são toleradas; o `model` do opencode mapeia pro hint de modelo do ChatCLI. Frontmatter que nem YAML válido é — como o formato `argument-hint: [FILES=<paths>]` documentado pelo próprio Codex — cai num parse linha a linha em vez de descartar o arquivo. Um comando nunca pode fazer shadow de um comando built-in — arquivos chamados `session.md`, `config.md` etc. são recusados e reportados em `/config commands`.

***

## Anatomia de um comando

```markdown theme={"system"}
---
description: Revisa um pull request com um foco específico
argument-hint: <numero-do-pr> [foco]
model: claude-sonnet-5
effort: high
allowed-tools: read, search
---
! gh pr view $1 --json title,body

Revise o PR $1 com foco em $ARGUMENTS.
Fundamente cada apontamento no diff acima.
```

| Frontmatter        | Efeito                                                                  |
| ------------------ | ----------------------------------------------------------------------- |
| `description`      | Aparece no completer, `/menu`, e nas listagens ACP e MCP                |
| `argument-hint`    | Dica de uso mostrada quando invocado sem args                           |
| `model` / `effort` | Roteiam o turno expandido (mesmo encanamento cross-provider das skills) |
| `allowed-tools`    | Restringe as tools durante o run iniciado pelo comando (veja abaixo)    |

**Placeholders** (a sintaxe de cada dialeto funciona em qualquer arquivo):

| Placeholder  | Significado                                                                            |
| ------------ | -------------------------------------------------------------------------------------- |
| `$ARGUMENTS` | String de argumentos crua, verbatim                                                    |
| `{{args}}`   | Alias Gemini/Qwen do mesmo                                                             |
| `$1`…`$9`    | Argumentos posicionais (tokens `KEY=value` ficam de fora)                              |
| `$KEY`       | Argumento nomeado estilo Codex: invoque com `/draftpr FILES="a b" PR_TITLE="Add hero"` |
| `$$`         | Um `$` literal                                                                         |

`$PALAVRAS` desconhecidas passam intactas.

***

## Linhas de pré-execução (`!`)

Uma linha começando com `!` executa um comando shell e embute o output no prompt expandido. Os dialetos inline também funcionam — o `!{cmd}` do Gemini e o `` !`cmd` `` do opencode substituem no meio da frase. Toda ocorrência, linha inteira ou inline, passa pelo **mesmo gate de segurança das tools do coder**:

1. Comandos safety-immune (`rm -rf`, `sudo`, …) sempre exigem aprovação interativa — nunca auto-aprovados, nem pelo automode.
2. Suas regras de `/policy` se aplicam (allow / ask / deny), e decisões de aprovação podem persistir regras novas (allow-always / deny-forever).
3. Em superfícies unattended (gateway, MCP, ACP, scheduler) um "ask" resolve via `/policy automode` — ou **cai em deny fail-safe**. Uma linha negada é substituída por um marcador explícito para o modelo saber que o output está faltando, nunca silenciosamente vazio.

Linhas dentro de code fences **nunca** são executadas — documentação continua documentação.

***

## `allowed-tools`

Quando definido, o run iniciado pelo comando ganha um overlay efêmero no gate de segurança: uma tool fora da lista escala de *allow* para **ask** — o humano (ou o policy automode) arbitra a exceção. Nunca amplia permissões silenciosamente e nunca nega silenciosamente.

***

## Superfícies

| Superfície       | Comportamento                                                                                                               |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- |
| REPL chat        | `/nome args` despacha como qualquer comando; completer + `/menu` listam o catálogo                                          |
| `/coder` mid-run | Follow-ups e type-ahead também expandem; `allowed-tools` re-arma o escopo, `model`/`effort` são ignorados mid-loop          |
| One-shot         | `chatcli -p "/review-pr 1326"` expande antes do roteamento                                                                  |
| Gateway          | Uma mensagem de canal `/deploy prod` expande antes de o coder engine ver o texto                                            |
| ACP (IDEs)       | Comandos são anunciados via `available_commands_update` com hints de input, e expandem no fluxo de prompt                   |
| MCP server       | Servidos pela primitive `prompts` — `prompts/list` traz o campo `arguments` do spec, `prompts/get` aceita `{"args": "..."}` |
| O próprio modelo | O builtin `@commands` deixa o agent descobrir (`list`) e expandir (`get`) os playbooks do time mid-task                     |

***

## Gerenciando

```bash theme={"system"}
/config commands          # painel de diagnóstico (abaixo)
/config commands reload   # força um re-scan (edições de arquivo também são detectadas automaticamente)
/reload                   # também re-escaneia o catálogo
```

O painel agrupa o catálogo por fonte com contagens e hints de argumento, depois os ledgers de falha — comandos **recusados** por shadow de built-in e arquivos **pulados** com o motivo do parse — e cada diretório varrido com marcador `✓`/`–` de existência:

```
⌘ Slash Commands ─────────────────────────
  9 comando(s) de 4 fonte(s)

  ▸ Projeto (.chatcli/commands) (2)
    /deploy       Deploy service          <env>
    /review-pr    Review a PR             <pr> [foco]

  ▸ Gemini CLI (1)
    /git:commit   Writes a conventional commit

  ⚠ Pulados (falha de parse — corrija o arquivo e ele carrega no próximo scan):
    ~/.gemini/commands/broken.toml
      unterminated """ string

  Diretórios varridos (ordem de precedência):
    ✓ ~/projeto/.chatcli/commands
    – ~/projeto/.claude/commands
```

O catálogo é servido de um cache com fingerprint por stat: lookups são gratuitos até um arquivo realmente mudar.

| Variável de ambiente | Default | Efeito                          |
| -------------------- | ------- | ------------------------------- |
| `CHATCLI_COMMANDS`   | `true`  | Chave mestra da feature inteira |

***

## Exemplo: standup do time

```bash theme={"system"}
mkdir -p .chatcli/commands
cat > .chatcli/commands/standup.md <<'EOF'
---
description: Resumo de standup a partir dos commits recentes
argument-hint: [dias]
---
! git log --oneline --since="$1 days ago" | head -20

Com base nos commits acima, escreva um resumo de standup em 3 bullets.
EOF
```

Commite — todo o time (e os agents, via `@commands`) agora tem `/standup 2`.
