@luanpdd/kit-mcp 1.34.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,223 @@
1
+ ---
2
+ name: dynamic-workflow-authoring
3
+ description: Use ao gerar/criticar `.workflow.js` (Opus 4.8+). Codifica os 6 patterns canonicos (Classify-Act, Fanout-Synthesize, Adversarial-Verify, Generate-Filter, Tournament, Loop-Done) + API rules.
4
+ ---
5
+
6
+ # Dynamic Workflow Authoring
7
+
8
+ **Fonte canônica:** [A harness for every task — Anthropic blog](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code).
9
+
10
+ Esta skill existe para que workflows gerados pelo kit sigam um vocabulário comum e não reinventem padrões. Consulte-a SEMPRE antes de materializar um `.workflow.js`.
11
+
12
+ ## Os 6 patterns canônicos
13
+
14
+ A primeira decisão de design é qual pattern usar — ela determina a topologia do script. Todo workflow real ou é exatamente um destes ou uma composição limpa de dois.
15
+
16
+ ### 1. Classify-And-Act
17
+ **Quando:** tipos diferentes de entrada precisam de tratamentos diferentes.
18
+ **Tasks:** ticket triage (severity → agent específico), content moderation (violation type → handler), routing de PRs por área de código.
19
+ **API:**
20
+ ```js
21
+ phase('Classify')
22
+ const cls = await agent(`Classifique X em uma de: A, B, C.`, { schema: CLS_SCHEMA })
23
+ phase('Act')
24
+ const result = await agent(PROMPTS[cls.label], { schema: ACT_SCHEMA })
25
+ ```
26
+ **Anti-pitfall:** classifier vagaroso anula o ganho — mantenha-o pequeno e schema-estruturado. Se o classifier precisa do contexto completo, considere se isn't really Fanout disfarçado.
27
+
28
+ ### 2. Fanout-And-Synthesize
29
+ **Quando:** N itens similares onde isolation previne interferência cruzada.
30
+ **Tasks:** "renomeie User → Account em todos os arquivos", processar 80 currículos, auditar N Edge Functions, julgar N conversas.
31
+ **API:**
32
+ ```js
33
+ phase('Fanout')
34
+ const results = await pipeline(
35
+ items,
36
+ item => agent(`Process ${item.id}`, { phase: 'Fanout', schema: ITEM_SCHEMA })
37
+ )
38
+ phase('Synthesize')
39
+ const summary = await agent(`Synthesize: ${JSON.stringify(results)}`, { schema: REPORT_SCHEMA })
40
+ ```
41
+ **Default:** `pipeline()` sobre `parallel()` — barrier entre fanout e synthesize só se a síntese precisa de TODOS de uma vez.
42
+
43
+ ### 3. Adversarial-Verification
44
+ **Quando:** qualidade crítica, custo de falso-positivo > custo de revisão extra.
45
+ **Tasks:** code review, fact-checking, audit de findings de segurança, qualquer "X é real ou ilusão?".
46
+ **API:**
47
+ ```js
48
+ const finding = await agent(FIND_PROMPT, { phase: 'Find', schema: FINDING_SCHEMA })
49
+ const verdict = await agent(
50
+ `Você é cético. Tente REFUTAR: ${JSON.stringify(finding)}.
51
+ Default: refuted=true em caso de dúvida.`,
52
+ { phase: 'Verify', schema: VERDICT_SCHEMA }
53
+ )
54
+ if (verdict.confirmed) commit(finding)
55
+ ```
56
+ **Multi-voto:** quando o caso é cinza, spawne 3 verificadores independentes e exija majority:
57
+ ```js
58
+ const votes = await parallel(Array.from({length: 3}, () => () =>
59
+ agent(`Refute: ${claim}`, { schema: VERDICT_SCHEMA })))
60
+ const survives = votes.filter(Boolean).filter(v => !v.refuted).length >= 2
61
+ ```
62
+ **Perspective-diverse:** se o achado pode falhar de mais de uma forma, dê lentes DIFERENTES a cada verificador (correctness/security/perf) — diversidade pega o que redundância não pega.
63
+
64
+ ### 4. Generate-And-Filter
65
+ **Quando:** espaço de solução amplo, qualidade varia, descarte é barato.
66
+ **Tasks:** gerar nomes de CLI/produto, brainstormar abordagens de design, listar hipóteses de bug.
67
+ **API:**
68
+ ```js
69
+ phase('Generate')
70
+ const candidates = (await parallel(Array.from({length: N}, (_, i) => () =>
71
+ agent(GEN_PROMPT(i), { schema: GEN_SCHEMA })))).filter(Boolean)
72
+ phase('Filter')
73
+ const top = await agent(
74
+ `Avalie e dê top ${K} pela rubrica: ${RUBRIC}. Candidatos: ${JSON.stringify(candidates)}`,
75
+ { schema: TOP_SCHEMA }
76
+ )
77
+ ```
78
+ **Varie o prompt do generator por índice** (i no exemplo acima) — gera diversidade. Se todos os generators têm exatamente o mesmo prompt, você paga N tokens pra obter ~1 resposta.
79
+
80
+ ### 5. Tournament
81
+ **Quando:** ranking qualitativo, julgamento relativo > absoluto.
82
+ **Tasks:** ordenar 1000+ tickets por severidade, escolher melhor design entre N propostas, priorizar lista de bugs.
83
+ **API:**
84
+ ```js
85
+ let bracket = candidates
86
+ while (bracket.length > 1) {
87
+ bracket = await pipeline(
88
+ chunk(bracket, 2),
89
+ pair => agent(
90
+ `Compare A e B pela métrica X. Devolva winner.`,
91
+ { phase: `Round-${bracket.length}`, schema: COMPARE_SCHEMA }
92
+ ).then(r => r.winner)
93
+ )
94
+ }
95
+ return bracket[0]
96
+ ```
97
+ **Anti-pitfall:** se a métrica é absoluta (score 0–10 estável), use Generate-And-Filter — Tournament é caro em wall-clock e tokens (log₂N rounds).
98
+
99
+ ### 6. Loop-Until-Done
100
+ **Quando:** volume desconhecido, condição de parada > contador fixo.
101
+ **Tasks:** reproduzir flaky test até falhar, bug hunt até K rounds vazios, search com retry até confidence threshold.
102
+ **API (loop-until-dry):**
103
+ ```js
104
+ const seen = new Set()
105
+ let dry = 0
106
+ while (dry < 2) {
107
+ const fresh = (await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })).bugs
108
+ .filter(b => !seen.has(key(b)))
109
+ if (!fresh.length) { dry++; continue }
110
+ dry = 0
111
+ fresh.forEach(b => seen.add(key(b)))
112
+ // ... process fresh
113
+ }
114
+ ```
115
+ **Loop-until-budget:** scale automático ao `+500k` do usuário:
116
+ ```js
117
+ while (budget.total && budget.remaining() > 50_000) {
118
+ const r = await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })
119
+ if (!r.bugs.length) break
120
+ bugs.push(...r.bugs)
121
+ }
122
+ ```
123
+ **Guard sempre** em `budget.total` — `remaining()` é `Infinity` sem target e o loop bate o cap de 1000 agents.
124
+
125
+ ## Regras DURAS da API (violar = workflow quebra)
126
+
127
+ ### O `meta` é literal puro
128
+ ```js
129
+ // ✓ ok
130
+ export const meta = {
131
+ name: 'audit-pr-staleness',
132
+ description: 'List PRs open >7d without review and rank by impact.',
133
+ phases: [{ title: 'Discover' }, { title: 'Rank' }],
134
+ }
135
+
136
+ // ✗ quebra
137
+ export const meta = {
138
+ name: `audit-${type}-staleness`, // template literal
139
+ description: getDesc(), // function call
140
+ phases: [...DEFAULT_PHASES], // spread
141
+ }
142
+ ```
143
+
144
+ ### Date.now / Math.random / argless `new Date()` são banidos
145
+ Quebrariam o resume cache. Passe timestamps via `args` e varie randomness pelo `index` do pipeline/parallel.
146
+
147
+ ```js
148
+ // ✓ ok
149
+ const nowIso = args?.nowIso // caller produz e passa
150
+ const label = `gen-${i}` // i = índice do pipeline
151
+
152
+ // ✗ quebra
153
+ const ts = Date.now()
154
+ const id = Math.random().toString(36)
155
+ ```
156
+
157
+ ### Todo `agent()` com saída estruturada usa `schema`
158
+ Sem schema, o retorno é texto bruto e parsing fica frágil. Com schema (JSON Schema), o agent é forçado a chamar `StructuredOutput` e a validação acontece no tool-call layer (retry automático).
159
+
160
+ ```js
161
+ const SCHEMA = {
162
+ type: 'object', required: ['rank', 'reason'],
163
+ properties: { rank: { type: 'number' }, reason: { type: 'string' } }
164
+ }
165
+ const r = await agent(PROMPT, { schema: SCHEMA })
166
+ // r.rank e r.reason garantidos do tipo
167
+ ```
168
+
169
+ ### `pipeline()` é o default; `parallel()` é exceção
170
+ Use `parallel()` SÓ quando o próximo stage precisa de TODOS os resultados anteriores ao mesmo tempo. Caso contrário, `pipeline()` deixa o item rápido avançar enquanto o lento ainda processa.
171
+
172
+ **Smell test:** se você escreveu `const a = await parallel(...); const b = transform(a); const c = await parallel(b.map(...))` — quase certo que deveria ser `pipeline(items, stage1, transform-inline, stage2)`.
173
+
174
+ ### Concorrência tem cap real
175
+ `min(16, cores − 2)` por workflow. Em laptop de dev = ~14. Em CI/macOS pequeno = ~6. `parallel()`/`pipeline()` com 100 itens funciona — mas só ~10 rodam simultâneo.
176
+
177
+ ### O budget é hard ceiling
178
+ `budget.total` é o `+500k` do usuário. Quando `spent()` bate o `total`, próximas `agent()` calls **throw**. Sempre cheque antes de loops dinâmicos.
179
+
180
+ ### Composição via `workflow()` é 1 nível
181
+ `workflow('other-name', args)` pode chamar OUTRO workflow do registry. Mas o filho NÃO pode chamar outro `workflow()` — nesting > 1 throws. Use isto pra orquestrar fases grandes (Understand → Design → Implement → Review) cada uma como workflow separado.
182
+
183
+ ## Reusar agents canônicos do kit
184
+
185
+ Workflows gerados não precisam reinventar. Use `opts.agentType` pra delegar a um agent específico do kit:
186
+
187
+ ```js
188
+ const audit = await agent(
189
+ `Audite Edge Function ${fn.name} pelos 4 golden signals.`,
190
+ { agentType: 'observability-coverage-auditor', schema: AUDIT_SCHEMA }
191
+ )
192
+ ```
193
+
194
+ Mapa rápido de quando reusar (consulte [`kit/agents/`](../../agents/) pra lista completa):
195
+
196
+ | Sua necessidade | Agent canônico |
197
+ |---|---|
198
+ | Cobertura observability por Edge Fn | `observability-coverage-auditor` |
199
+ | Isolamento cross-tenant (RLS) | `multi-tenant-isolation-auditor` |
200
+ | Compliance LGPD | `lgpd-compliance-auditor` |
201
+ | Hipóteses de bug em produção | `incident-investigator` |
202
+ | Validar migration antes de aplicar | `schema-checker` |
203
+ | Verificar refactor antes do código | `refactor-safety-auditor` |
204
+ | Pesquisar fase / projeto | `phase-researcher` / `project-researcher` |
205
+ | Designer de UI seguindo MARCA.md | `designer-ui` |
206
+
207
+ ## Anti-pitfalls específicos
208
+
209
+ **1. Silent caps.** Se o workflow corta cobertura (top-N, no-retry, sampling), `log()` o que foi descartado. Truncar em silêncio lê como "cobri tudo" quando não cobriu.
210
+
211
+ **2. Synthesizer cego.** O último agent recebe `JSON.stringify(rows)` — se rows for 50MB de transcripts, ele estoura contexto. Pré-resuma cada item no stage anterior (campos só essenciais: id, score, top-3 evidence).
212
+
213
+ **3. Dedup vs `confirmed`.** Loop-until-dry deve dedupar contra TODOS os itens vistos (`seen`), NÃO só os confirmados. Senão findings judge-rejected reaparecem e o loop nunca converge.
214
+
215
+ **4. Schema sem `required`.** JSON Schema sem `required` deixa o agent retornar `{}` válido. Sempre liste `required: [...]`.
216
+
217
+ **5. Stage que mutate.** Stage 2 mutando o objeto vindo de stage 1 quebra resume cache. Crie objeto novo: `return { ...prev, extra: x }`.
218
+
219
+ ## Ver também
220
+
221
+ - [`kit/workflows/auditar-observabilidade-cobertura.workflow.js`](../../workflows/auditar-observabilidade-cobertura.workflow.js) — exemplo canônico do pattern Fanout-And-Synthesize + Adversarial-Verification combinados
222
+ - [`workflow-generator`](../../agents/workflow-generator.md) — agent que consulta esta skill ao gerar `.workflow.js`
223
+ - [`criar-workflow`](../../commands/criar-workflow.md) — slash-command entrypoint do gerador
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luanpdd/kit-mcp",
3
- "version": "1.34.0",
3
+ "version": "1.35.0",
4
4
  "description": "Generic infrastructure to ship YOUR personal kit of agents/commands/skills as an MCP server, with cross-IDE sync (Claude Code, Cursor, Codex, Gemini, Windsurf, Antigravity, Copilot, Trae).",
5
5
  "type": "module",
6
6
  "bin": {