███████╗██╗ ██╗ ██╗██╗ ██╗
██╔════╝██║ ██║ ██║╚██╗██╔╝ ██╗
█████╗ ██║ ██║ ██║ ╚███╔╝ ╚═╝
██╔══╝ ██║ ██║ ██║ ██╔██╗ ██╗
██║ ███████╗╚██████╔╝██╔╝ ██╗ ╚═╝
╚═╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═╝
da ideia ao merge, sem trocar de ferramenta
Família de comandos globais e context-agnósticos que cobre o ciclo inteiro de trabalho num repo: da issue ao código, do código ao review, do review ao merge, do merge à comunicação.
/plugin marketplace add grippado/flux
/plugin install flux@flux
Pronto: /flux:peek, /flux:review, /flux:iterate e os demais ficam disponíveis em qualquer repo Git, sem configuração nenhuma.
Para somar specialists, persistência no vault e integrações do seu time, declare um manifesto de contexto. Exemplos prontos em examples/.
flux: é um ciclo, não um conjunto de utilitários. Cada comando é um elo com fronteira nítida, e o elo seguinte assume onde o anterior parou. Você nunca sai da família para completar uma entrega.
Dois princípios sustentam isso:
- Os comandos são globais e não sabem nada do seu time. Eles vivem na raiz da instalação (
${FLUX_ROOT}/commands/flux/) e funcionam em qualquer repo Git. O que é específico de um time (quais reviewers, qual vault, quais repos) vem de um manifesto de contexto —flux-context.json—, nunca hardcoded no comando. - Cada elo delega o trabalho especializado. Review vai para agents reviewers; execução vai para o motor nativo do repo; prospecção de codebase vai para specialists. Os comandos orquestram, não reimplementam.
ideia / thread / bug relatado
│
▼
┌───────────────────────┐
│ flux:issue │ fonte livre → issue embasada em código real
└───────────┬───────────┘
▼
┌───────────────────────┐
│ flux:build │ issue → código + PR draft
└───────────┬───────────┘ (despacha ao motor nativo do repo)
▼
┌───────────────────────┐ ┌───────────────────────┐
│ flux:peek │ │ flux:review │
│ relance read-only │◀──ou──▶│ review formal │
│ não posta, não grava│ │ persiste no vault │
└───────────┬───────────┘ └───────────┬───────────┘
└──────────┬─────────────────────┘
▼
┌───────────────────────┐
│ flux:iterate │ threads → correções → push → CI verde
└───────────┬───────────┘ ↻ fica vivo até a PR assentar
▼
┌───────────────────────┐
│ flux:land │ N PRs → toposort → merge-ready → go/no-go
└───────────┬───────────┘ (não mergeia: humano decide)
▼
┌───────────────────────┐
│ flux:reply │ comunica, embasado no que de fato mudou
└───────────────────────┘
Nenhum elo é obrigatório e nenhum chama o próximo sozinho. Cada um termina apontando o elo seguinte e devolvendo o volante para você.
| Comando | Entrada | Saída | Escreve? |
|---|---|---|---|
flux:issue |
thread do Slack, texto livre, PR | issue de alta qualidade, embasada via specialists | rascunho no vault; cria no Linear só após aprovação |
flux:build |
ticket Linear ou descrição + repo | código + PR draft | sim, via motor do repo |
flux:peek |
working tree, branch, range, PR, doc, path | parecer com badges no chat | não (exceto --save) |
flux:review |
PR ou doc | review formal (holístico + specialists reconciliados) | vault; posta quando você manda |
flux:iterate |
PR | correções aplicadas, réplicas postadas, threads resolvidas, CI vigiado | sim (--dry rascunha read-only) |
flux:land |
issue/feature multi-PR | ordem de merge, validação de regressão, go/no-go | mantém PRs merge-ready; nunca mergeia |
flux:reply |
permalink de thread | rascunho Slack-safe + ata no vault | salva rascunho; nunca posta sozinho |
reviewvsiterate—reviewproduz o parecer.iterateconsome pareceres (inclusive de bots e humanos), verifica cada alegação contra o código real, aplica o que procede e defende o que não procede.buildvs/workflowdo repo —buildé o dispatcher: resolve repo e motor. O/workflowdo repo é o motor: conhece os próprios testes, gates e padrão de PR.buildnunca reimplementa motor.iteratevsland—iteratefecha uma PR.landorquestra N PRs de uma entrega e delega o merge-ready de cada uma aoiterate.
flux/
├── README.md ← este arquivo (doc da família)
├── LICENSE MIT
├── examples/ manifestos prontos: solo / time / pessoal
├── .claude-plugin/marketplace.json o marketplace (é o que o /plugin add lê)
└── plugins/flux/ ← ${FLUX_ROOT} quando instalado
├── .claude-plugin/plugin.json
├── agents/pr-reviewer.md o holístico genérico (default universal)
├── skills/ ← os verbos (globais, context-agnósticos)
│ ├── issue/ build/ peek/
│ └── review/ iterate/ land/ reply/
└── shared/ contratos compartilhados (fonte única, não duplicar nos verbos)
├── preflight.md verificação de pré-requisitos, níveis de capacidade, banner
├── flux-context.md resolução de contexto via manifesto
├── review-agents.md descoberta + reconciliação de specialists
├── review-legend.md badges canônicos dos findings
├── review-artifact-template.md formato do artefato de review no vault
├── review-body-template.md formato do corpo da review postada no GitHub
├── issue-template.md formato da issue do flux:issue
├── board-template.md formato do board vivo (execução / iterate / delivery / conversa)
├── worktree-discipline.md todo fluxo que escreve opera em worktree dedicado
├── fanout-discipline.md todo trabalho pesado vai para subagente, em paralelo
├── context-budget.md leitura sob demanda, um root por sessão, delegação
└── quality-gate-api.md diagnóstico de gates Sonar via API (consultar em vez de deduzir)
O plugin resolve skills/<verbo>/SKILL.md como /flux:<verbo>. Adicionar um diretório em skills/ publica um verbo novo, sem tocar em instalação.
${FLUX_ROOT} é resolvido pelo preflight na ordem: ${CLAUDE_PLUGIN_ROOT} (instalação via marketplace) → dois níveis acima do verbo em execução (checkout direto) → ${FLUX_HOME} do ambiente. Por isso os mesmos arquivos funcionam instalados como plugin ou clonados na mão.
Um flux-context.json num .claude/ de workspace ou repo. O comando procura o mais próximo subindo a árvore a partir do cwd — mesma disciplina do .claude/ do Claude Code. Achou → perfil declarado. Não achou → perfil genérico.
{
"name": "acme",
"holistic_reviewer": "acme-pr-reviewer",
"doc_reviewer": "acme-doc-reviewer",
"answerer": "acme-pr-answerer",
"slack_prospector": "acme-slack-prospector",
"slack_answerer": "acme-slack-answerer",
"specialists_root": "~/agents/acme/{repo}/repo-owner.md",
"vault_root": "~/notes",
"vault_context": "acme",
"workspace_root": "~/code/acme",
"linear_org": "acme",
"repos": ["backoffice", "rf-monorepo", "communication-api", "..."],
"exec_command": "workflow",
"exec_fallback": "acme:implement",
"no_emdash": true
}Contrato completo dos campos: shared/flux-context.md.
A família funciona sem configuração nenhuma. Sem manifesto, cada comando cai num default universal:
| Aspecto | Default sem manifesto |
|---|---|
| Reviewer holístico | pr-reviewer (agente global, detecta a stack dinamicamente) |
| Specialists | override local do repo: <repo>/.claude/agents/reviewer.md; sem isso, só holístico |
| Persistência | não persiste; imprime no chat (--save <dir> no flux:review) |
| Motor de execução | /workflow do repo; sem ele, o exec_fallback do perfil; sem ele, modo autônomo (worktree + CLAUDE.md + checks + PR draft) |
| Travessão | permitido (no_emdash: false) |
Quem instala a família já tem review holístico e execução funcionando em qualquer repo GitHub. Declarar um flux-context.json é o que soma specialists, persistência no vault e integrações do time.
- Falhar bem em vez de rodar mal — todo elo abre pelo
preflight.md: verifica osrequiresdeclarados no frontmatter, resolve e confere a existência do agente holístico, e classifica o nível de capacidade (FULL/REDUCED/THIN/UNAVAILABLE). Faltou requisitohard→ aborta sem efeito colateral. Faltousoft→ roda e declara a perda no banner de perfil, que abre todo output. Um elo nunca improvisa um reviewer inline nem produz artefato fora do contrato de saída. - Badges canônicos — todo finding usa o vocabulário de
review-legend.md:request-change,breaking-change,question,suggestion,praise,note. Cada um ancorado emarquivo:linha(código) ou§seção + trecho verbatim(doc). - Verificar antes de aceitar — nenhuma alegação de review (de bot ou de humano) é aplicada sem ser conferida contra o código real. Defender uma decisão correta é resultado válido.
- Worktree sempre — todo fluxo que escreve código opera em git worktree dedicado à branch, nunca na árvore principal. Ver
worktree-discipline.md. - Fan-out sempre — o contexto principal de um elo orquestra; investigar código, tocar repo, aplicar correção ou rodar outro
flux:*vai para subagente, e unidades independentes vão em paralelo num único bloco. Na main ficam só parse, metadados baratos, HITL, board e watch. Regra pétrea, par simétrico do worktree: verfanout-discipline.md. - Humano no volante nas fronteiras externas — nada é postado no GitHub, no Linear ou no Slack, nem mergeado, sem aprovação explícita.
- pt-BR com acentuação correta no output; EN no código.
no_emdash— quandotrue, nada que possa acabar publicado (título/corpo de PR, comentário, mensagem de Slack) usa travessão ou en-dash.
A maioria dos elos quer workspace mode (cd <workspace_root> && claude), porque precisa navegar cross-repo. O flux:build funciona nos dois: em workspace mode você passa o repo como primeiro argumento; em repo mode ele infere do cwd.
Um verbo novo entra assim:
- Crie
plugins/flux/skills/<verbo>/SKILL.mdcom frontmattername/description/user-invocable: true. - Abra com um Step 0-context que resolve o perfil via
flux-context.md— nada de path ou agente de time hardcoded. - Declare Out of scope explicitamente. A fronteira de cada elo é o que mantém o ciclo legível.
- Aponte os shared que se aplicam em vez de reescrever a lógica deles.
- Termine com handoff: qual elo vem depois, e por que.
- Registre o verbo na tabela Os comandos e, se ele mudar o ciclo, no diagrama.
Antes de abrir PR, valide os manifests. Este comando pega uma classe de erro que leitura não pega:
claude plugin validate . # marketplace
claude plugin validate ./plugins/flux # plugin + frontmatter de cada skill
Sempre use aspas na
descriptiondo frontmatter. Um:(dois-pontos seguido de espaço) num valor YAML sem aspas quebra o parse, e o skill carrega com metadata vazia, silenciosamente: semname, semdescription, semuser-invocable. O sintoma é um1 error during loadgenérico no/reload-plugins, sem dizer qual arquivo. Ovalidatediz.
Duas regras que valem para qualquer contribuição:
- Nada de contexto de time hardcoded. Se o seu time precisa de algo, isso vira campo do manifesto, nunca literal dentro de um verbo. O contrato está em
shared/flux-context.md. - Degradar bem em vez de rodar mal. Toda capacidade nova entra com o caminho de ausência definido e declarado no banner de perfil.
MIT.