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, 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
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:
- Comandos safety-immune (
rm -rf,sudo, …) sempre exigem aprovação interativa — nunca auto-aprovados, nem pelo automode. - Suas regras de
/policyse aplicam (allow / ask / deny), e decisões de aprovação podem persistir regras novas (allow-always / deny-forever). - 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.
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
Gerenciando
✓/– de existência:
Exemplo: standup do time
@commands) agora tem /standup 2.