Skip to main content
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

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. Subdiretórios viram namespaces: frontend/deploy.md → /frontend:deploy (o git/commit.toml do Gemini → /git:commit). Chaves de frontmatter alheias (agent, subtask, auto_execute_steps) são toleradas; o model do opencode mapeia pro hint de modelo do ChatCLI, e mode é uma chave first-class do ChatCLI (veja a seção de modo de execução abaixo). 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

Placeholders (a sintaxe de cada dialeto funciona em qualquer arquivo): $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 — e runs one-shot via pipe, onde o stdin não pode responder um prompt) 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. Uma regra allow explícita dispensa automode: roda headless (veja a seção de pipelines abaixo).
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. O matching é case-insensitive e o @ inicial é opcional (coder ≡ @coder). Os nomes são comparados exatamente contra os nomes de tool abaixo — um nome fora do catálogo nunca casa, o que significa que toda chamada de tool naquele run escala para ask. Em particular, os nomes de tool do Claude Code (Read, Write, Edit, Bash) não existem no ChatCLI — não os copie para o frontmatter de um comando.

Nomes de tool disponíveis

O engine do coder é uma única tool, @coder — read, write, patch, multipatch, search, tree, exec, git-status, git-diff, git-log, test, rollback e afins são subcomandos dela, não tools independentes. Permitir @coder permite todos eles (cada execução continua passando pelo /policy e pelo gate interativo). Plugins externos de ~/.chatcli/plugins participam com seus próprios nomes (ex. @docker-ps). @model só é registrado enquanto a tool de roteamento de modelo está habilitada (CHATCLI_AGENT_MODEL_TOOL).

Tools MCP

Tools de servidores MCP conectados aparecem como mcp_ + o nome da tool exatamente como o servidor declarou — sem prefixo de servidor. Um servidor chamado github que declara create_issue vira mcp_create_issue. Exemplo:
Qualquer outra tool MCP que o modelo tentar usar durante esse run escala para um ask interativo em vez de rodar silenciosamente.

Modo de execução e o auto-route do chat

O chat mode é sem tools por design — um comando cujo corpo usa tools seria simplesmente recusado ali. A chave mode: declara onde o comando deve rodar, e o dispatcher do chat honra isso:
  • mode: coder (ou inferido de um allowed-tools não-vazio): invocado no chat do REPL, o comando imprime um aviso (⚡ /deploy executa com tools…) e é auto-roteado por um run one-shot do coder — mesmo engine, gate de segurança e overlay de allowed-tools de um /coder manual, voltando ao prompt do chat quando o loop chega à resposta final. chatcli -p "/deploy prod" roteia do mesmo jeito (aviso no stderr).
  • mode: chat explícito veta a inferência — o comando continua um turno puramente conversacional mesmo declarando allowed-tools.
  • Valores ausentes ou não reconhecidos nunca invalidam o arquivo: a resolução cai na inferência e, por fim, em chat.
Arquivos interop do Claude Code e afins que trazem allowed-tools portanto rodam corretamente com zero edições. Comandos roteados ganham o marcador [coder] no completer, no /menu e em /config commands. Superfícies headless (gateway, ACP, MCP, scheduler) mantêm o comportamento existente — o auto-route só dispara no REPL interativo e no one-shot -p. Opt-out global com CHATCLI_COMMANDS_AUTOROUTE=off.

Superfícies


Pipelines & automação headless

Slash commands compõem com pipes do shell: o stdin do pipe é anexado ao prompt antes da resolução, então uma invocação bare funciona e o corpo inteiro do pipe cai em $ARGUMENTS:
Se o comando é mode: coder, o auto-route dispara aqui também — o modelo não só lê o pipe, ele pode agir sobre ele com o coder engine completo (editar arquivos, rodar testes) antes de a pipeline seguir.

Pre-execution sem prompts

Um run via pipe não tem terminal para responder um prompt de aprovação, então linhas ! resolvem só pela sua política de segurança. Para automatizar um comando headless — cron, CI, scripts — adicione uma regra allow explícita para exatamente o que ele executa em ~/.chatcli/coder_policy.json:
Com essa regra, o exemplo de standup abaixo roda de ponta a ponta numa pipeline com zero interação:
As garantias do gate não se dobram para automação: deny sempre vence allow, comandos safety-immune (rm -rf, sudo, …) continuam exigindo um humano interativo, e o que nenhuma regra casa cai em deny fail-safe. Escope os patterns com precisão — exec git log em vez de exec git — para a regra allow cobrir só o que o comando realmente precisa. /policy automode on é a alternativa mais grosseira (auto-aprova todo “ask” não-immune na sessão); prefira regras allow estreitas para pipelines unattended.

Gerenciando

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:
O catálogo é servido de um cache com fingerprint por stat: lookups são gratuitos até um arquivo realmente mudar.

Exemplo: standup do time

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