Agentes¶
Três mecanismos conectam assistentes de IA (Cursor, Antigravity, híbridos) ao projeto DARE de forma determinística e auditável: hooks (automações por evento), steering files (contexto/regras resolvidos por arquivo) e o servidor MCP (API local de leitura do projeto e do grafo).
Paridade terminal ↔ chat¶
Cada comando semântico do DARE tem dois gatilhos equivalentes:
| Caminho | Exemplo |
|---|---|
| Terminal | dare reverse --ai |
| Chat da IDE | /dare-reverse |
O contrato está codificado em PARITY_CONTRACTS (packages/cli/src/ai/parity.ts):
mesmo schema JSON, mesmos artefatos mesclados, mesma validação Zod (RS-01).
Providers suportados (v3.12+)¶
| Provider | Enrichment (--ai) |
Execução (execute --agent) |
CLI default |
|---|---|---|---|
codex |
✓ | ✓ (--driver codex) |
codex |
claude-code |
✓ | ✓ (--driver claude) |
claude |
cursor-cli |
✓ | ✓ (--driver cursor) |
cursor-agent |
antigravity-cli |
✓ | ✓ (--driver antigravity) |
antigravity |
mock |
✓ (testes) | ✓ (--dry-run) |
— |
Resolução de provider: --provider > ai.defaultProvider no config > codex.
# Diagnóstico de CLIs instalados + capacidade enrichment/execução
dare ai doctor
dare ai doctor --json
# Saída estruturada após heurística determinística
dare reverse --ai --json
dare review task-001 --ai --json
Skills /dare-* nas três IDEs incluem a linha Equivalente no terminal apontando
para o comando dare <cmd> --ai correspondente — o chat continua caminho de primeira
classe; o terminal ganha o mesmo poder.
Hooks¶
Automações disparadas por eventos do ciclo de desenvolvimento. São
determinísticas (nenhum LLM decide o que roda) e opt-in: a ausência do
bloco hooks no dare.config.json significa zero hooks.
Eventos¶
Conjunto fechado na v1 (hooks/types.ts). Eventos fora desta lista são
rejeitados:
| Evento | Quando dispara | Payload |
|---|---|---|
on-save |
Ao salvar um arquivo | file (relativo, validado) |
on-file-create |
Ao criar um arquivo | file (relativo, validado) |
on-task-complete |
Ao concluir uma task | taskId (/^task-[0-9a-z-]+$/) |
pre-commit |
Antes de um commit | — |
Allowlist de ações¶
O bloco on mapeia evento → lista de ações. Cada ação é uma chave de um
conjunto fechado (hooks/allowlist.ts) — nunca uma string de shell:
| Ação | Comando resolvido | Tipo |
|---|---|---|
dare-validate |
dare validate --strict |
spawn |
dare-review |
dare review <taskId> --strict --format json |
spawn (exige taskId) |
graph-register |
— (interno, não spawna) | interno |
lint |
comando de lint da stack (resolvido do config) | spawn |
test |
comando de teste da stack (resolvido do config) | spawn |
As ações dare-validate, dare-review, lint e test produzem um veredito
pass/fail a partir do exit code (0 = pass). graph-register é uma ação
interna que apenas registra o gatilho no grafo.
Trust gate¶
{
"hooks": {
"on": {
"on-task-complete": [{ "action": "dare-review" }],
"pre-commit": [{ "action": "dare-validate" }, { "action": "test" }]
},
"trusted": false
}
}
Enquanto hooks.trusted for false, os hooks não auto-executam:
dispatchHook lança TrustRequiredError e dare hooks run falha com
TRUST_REQUIRED (exit 2). Para rodar mesmo assim, use --trust (override por
execução) ou defina trusted: true no config.
Comandos¶
# Listar hooks configurados
dare hooks list
dare hooks list --json # { "hooks": {...}, "trusted": false }
# Rodar os hooks de um evento
dare hooks run on-save --file src/app.ts
dare hooks run on-task-complete --task task-001
dare hooks run pre-commit --trust # override do trust gate
dare hooks run on-save --file src/app.ts --json
# Validar schema + allowlist do bloco hooks
dare hooks validate
dare hooks validate --json # { "valid": true, "errors": [] }
Flags por subcomando:
| Subcomando | Flags | Notas |
|---|---|---|
list |
--json |
Lista o mapa on e trusted. |
run <event> |
--file <path>, --task <taskId>, --trust, --json |
Exit 0 = ok, 1 = alguma ação falhou, 2 = config inválida / untrusted. |
validate |
--json |
Exit 0 = válido, 1 = erros. |
Segurança¶
Por que os hooks são seguros por construção
- Allowlist fechada: só as 5 chaves canônicas são aceitas; editável apenas via diff versionado. Strings de shell arbitrárias são impossíveis.
shell: false: tudo roda viasafeSpawncomspawn(cmd, argv, { shell: false }). Args entram como elementos de argv, nunca interpolados em shell — sem injeção via;,&&, backticks etc.- Confinamento de caminho:
payload.filee args com cara de caminho passam porassertRelativeSafe; escapes lançamPathEscapeError. - Env saneado: variáveis que casam com
SECRET|TOKEN|KEY|PASSWORD|CREDENTIAL|API_KEY|AUTH|PRIVATEsão removidas antes do spawn (allowlist de env emsafe-spawn.ts). - Trust explícito: sem
trusted:true/--trust, nada executa. - Timeout e saída limitada: cada spawn tem timeout (600s no dispatcher) e saída capada.
Steering files¶
Arquivos Markdown que fornecem contexto e regras à IA, resolvidos por
arquivo-alvo de forma determinística (steering/loader.ts + resolver.ts).
Não vivem no dare.config.json.
O que são e de onde vêm¶
A loader descobre três origens:
| Origem | isBase |
Front-matter |
|---|---|---|
DARE/PROJECT-DNA.md |
true |
base canônica (reuso do DNA do projeto) |
DARE/PATTERNS.md |
true |
base canônica (padrões do projeto) |
.dare/steering/*.md |
false |
front-matter YAML validado por Zod |
Arquivos .env* nunca são elegíveis
Qualquer arquivo cujo nome case com ^\.env(\..*)?$ é descartado como
fonte de steering (proteção contra vazamento de segredos).
Front-matter de um steering file em .dare/steering/ (Zod .strict()):
| Campo | Tipo | Default | Descrição |
|---|---|---|---|
scope |
'project' \| 'glob' |
— (obrigatório) | project aplica a tudo; glob aplica conforme o padrão. |
glob |
string |
— | Obrigatório quando scope: glob. Precisa ser relativo, sem ... |
priority |
number (int) |
0 |
Desempate dentro do mesmo bucket. |
title |
string |
— | Título opcional. |
---
scope: glob
glob: src/api/**
priority: 10
title: Regras da camada de API
---
Sempre validar entrada com Zod antes de tocar no banco.
Precedência / resolução¶
resolveSteeringForFile filtra os blocos aplicáveis ao arquivo-alvo e ordena
do menos para o mais específico — o consumidor concatena nessa ordem
(blocos mais específicos sobrescrevem os mais gerais). A ordenação
(sortSteeringByPrecedence) usa:
- Bucket (do mais geral ao mais específico):
base(0) →project(1) →glob(2); priority(menor primeiro);path(ordem alfabética) como desempate final.
Blocos base (PROJECT-DNA / PATTERNS) e de escopo project sempre se aplicam;
blocos glob só quando o padrão casa com o arquivo-alvo.
Comandos¶
# Listar steering files descobertos, em ordem de precedência
dare steering list
dare steering list --json
# Resolver o steering aplicável a um arquivo (na ordem de aplicação)
dare steering show src/api/users.ts
dare steering show src/api/users.ts --json
steering show lança erro de caminho (PathEscapeError, exit 1) se o arquivo
não for relativo e contido no projeto.
MCP server¶
Servidor HTTP local que expõe leitura de contexto do projeto e do knowledge
graph para as IDEs. Implementado em mcp-server/server.ts, iniciado pelo
binário dare-mcp-server (mcp-server/bin/server.ts).
Como sobe¶
# binário publicado no package
dare-mcp-server
# ou apontando para outro projeto / porta / token
DARE_PROJECT_PATH=/caminho/do/projeto \
DARE_MCP_PORT=3000 \
DARE_MCP_TOKEN="um-token-forte" \
dare-mcp-server
Defaults de boot (boot-config.ts): bind 127.0.0.1, porta 3000,
DARE_PROJECT_PATH = cwd, e token = randomUUID() se DARE_MCP_TOKEN não for
definido. Ver a tabela completa em
Configuração › Variáveis do MCP.
Bind em loopback e auth Bearer
O servidor faz bind em 127.0.0.1 por padrão. Em loopback, requisições sem
token são aceitas (allowLoopbackWithoutToken, ligado por default); para
qualquer outra origem é obrigatório Authorization: Bearer <token>. Com
DARE_MCP_BIND=0.0.0.0 o servidor avisa que está exposto à LAN — só use em
redes confiáveis e com um DARE_MCP_TOKEN forte. O CORS aceita apenas
http://127.0.0.1:* e http://localhost:*. O token nunca é logado por
inteiro (redactToken).
Endpoints¶
| Método | Rota | Descrição |
|---|---|---|
GET |
/health |
Status, versão e basename do projeto. |
GET |
/tools |
Lista as ferramentas MCP disponíveis. |
POST |
/context/query |
Busca contexto por type (file/task/dependency/architecture/schema/endpoint) e query. |
GET |
/blueprint |
Conteúdo de DARE/BLUEPRINT.md. |
GET |
/dag |
Conteúdo de DARE/dare-dag.yaml. |
GET |
/tasks/:taskId |
Status de uma task (lido de TASKS.md). |
PUT |
/tasks/:taskId |
Atualiza o status de uma task em TASKS.md. |
GET |
/project |
Conteúdo de dare.config.json. |
GET |
/steering?file=<rel> |
Steering resolvido para um arquivo. |
POST |
/graph/locate |
Localiza símbolos a partir de um seed. |
POST |
/graph/map-requirement |
Mapeia um reqId (RF-…/O-…/task-…) para símbolos e tasks. |
POST |
/graph/traverse |
Percorre o grafo a partir de seedNodeIds. |
As rotas de grafo (graph/*) abrem o backend via loadGraphConfig +
createGraph conforme o dare-graph.yml do projeto, clampando hops/limit
(1–5 / 1–50) e validando seeds com aparência de caminho. As rotas que leem
arquivos resolvem caminhos com resolveSafePath; tentativas de escape retornam
403 Forbidden.
Como as 3 IDEs consomem¶
As IDEs configuradas em ide (cursor, antigravity, hybrid) apontam um
cliente MCP para http://127.0.0.1:3000 e usam o token Bearer (DARE_MCP_TOKEN)
para acessar as ferramentas listadas em /tools. O fluxo típico:
get_project_context(GET /project) eget_blueprint/get_dagdão à IDE o contexto estrutural do projeto;query_context(POST /context/query) busca trechos relevantes de BLUEPRINT/TASKS/DAG por palavra-chave;get_task_status/update_task_status(GET/PUT /tasks/:id) sincronizam o progresso das tasks;graph_locate/graph_map_requirement/graph_traverse(POST /graph/*) navegam o knowledge graph para ancorar mudanças em requisitos e símbolos;get_steering(GET /steering) entrega à IDE as regras aplicáveis ao arquivo aberto, já resolvidas por precedência.