wizz-method 1.16.1 → 1.18.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.
Files changed (148) hide show
  1. package/README.md +1 -1
  2. package/package.json +7 -2
  3. package/removals.txt +9 -0
  4. package/skills-registry.yaml +119 -36
  5. package/src/bmm-skills/1-analysis/wizz-agent-analyst/customize.toml +1 -1
  6. package/src/bmm-skills/1-analysis/wizz-set-feature/SKILL.md +41 -37
  7. package/src/bmm-skills/2-plan-workflows/wizz-agent-pm/customize.toml +1 -1
  8. package/src/bmm-skills/2-plan-workflows/wizz-agent-ux-designer/customize.toml +1 -1
  9. package/src/bmm-skills/3-solutioning/wizz-agent-architect/customize.toml +1 -1
  10. package/src/bmm-skills/3-solutioning/wizz-generate-project-context/project-context-template.md +5 -0
  11. package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-01-discover.md +16 -5
  12. package/src/bmm-skills/3-solutioning/wizz-generate-project-context/steps/step-03-complete.md +5 -0
  13. package/src/bmm-skills/4-implementation/wizz-agent-dev/customize.toml +1 -1
  14. package/src/bmm-skills/4-implementation/wizz-retrospective/customize.toml +3 -1
  15. package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/__pycache__/sprint_status.cpython-313.pyc +0 -0
  16. package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_git_evidence.cpython-313-pytest-9.1.1.pyc +0 -0
  17. package/src/bmm-skills/4-implementation/wizz-retrospective/scripts/tests/__pycache__/test_sprint_status.cpython-313-pytest-9.1.1.pyc +0 -0
  18. package/src/bmm-skills/4-implementation/wizz-sprint-planning/customize.toml +3 -1
  19. package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/__pycache__/sprint_plan.cpython-313.pyc +0 -0
  20. package/src/bmm-skills/4-implementation/wizz-sprint-planning/scripts/tests/__pycache__/test_sprint_plan.cpython-313-pytest-9.1.1.pyc +0 -0
  21. package/src/core-skills/wizz-advanced-elicitation/scripts/__pycache__/pick_methods.cpython-313.pyc +0 -0
  22. package/src/core-skills/wizz-advanced-elicitation/scripts/tests/__pycache__/test_pick_methods.cpython-313-pytest-9.1.1.pyc +0 -0
  23. package/src/core-skills/wizz-brainstorming/scripts/__pycache__/brain.cpython-313.pyc +0 -0
  24. package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-313-pytest-9.1.1.pyc +0 -0
  25. package/src/core-skills/wizz-brainstorming/scripts/tests/__pycache__/test_brain.cpython-314.pyc +0 -0
  26. package/src/core-skills/wizz-forge-idea/scripts/__pycache__/resolve_personas.cpython-314.pyc +0 -0
  27. package/src/core-skills/wizz-forge-idea/scripts/tests/__pycache__/test_resolve_personas.cpython-314.pyc +0 -0
  28. package/src/core-skills/wizz-party-mode/scripts/__pycache__/resolve_party.cpython-314.pyc +0 -0
  29. package/src/core-skills/wizz-party-mode/scripts/tests/__pycache__/test_resolve_party.cpython-314.pyc +0 -0
  30. package/src/modules/lowticket/README.md +55 -0
  31. package/src/modules/lowticket/module.yaml +31 -0
  32. package/src/modules/lowticket/skills/lowticket-funil/SKILL.md +112 -0
  33. package/src/modules/lowticket/skills/lowticket-funil/references/copy-das-paginas.md +75 -0
  34. package/src/modules/lowticket/skills/lowticket-funil/references/mapa-do-funil.md +71 -0
  35. package/src/modules/lowticket/skills/lowticket-metodologia/CATALOGO.md +352 -0
  36. package/src/modules/lowticket/skills/lowticket-metodologia/SKILL.md +62 -0
  37. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/01-principios.md +12 -0
  38. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/02-diagnostico-funil.md +83 -0
  39. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/03-campanha-bidcap.md +95 -0
  40. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/04-criativos.md +66 -0
  41. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/04a-criativos-ia.md +79 -0
  42. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/04b-criativos-formatos.md +152 -0
  43. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/05-oferta.md +51 -0
  44. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/06-pagina-vendas.md +175 -0
  45. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/06a-instagram.md +138 -0
  46. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/07-funil-upsell.md +73 -0
  47. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/08-pesquisa-publico.md +14 -0
  48. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/09-especialista-coproducao.md +41 -0
  49. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/10-levantar-caixa.md +49 -0
  50. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/11-checklist-roi.md +36 -0
  51. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/12-mineracao-ofertas.md +63 -0
  52. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/12a-mineracao-veredito.md +78 -0
  53. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/12b-fabrica-de-ofertas.md +178 -0
  54. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/13-benchmarks-vsl.md +10 -0
  55. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/14-vocabulario.md +55 -0
  56. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/15-como-estender.md +35 -0
  57. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/INDEX.md +45 -0
  58. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/guardrails.md +33 -0
  59. package/src/modules/lowticket/skills/lowticket-metodologia/knowledge/pontos-em-aberto.md +42 -0
  60. package/src/modules/lowticket/skills/lowticket-metodologia/references/swipe-file.md +38 -0
  61. package/src/modules/lowticket/skills/lowticket-minerador/SKILL.md +115 -0
  62. package/src/modules/lowticket/skills/lowticket-minerador/references/rubrica.md +75 -0
  63. package/src/modules/lowticket/skills/lowticket-pagina/SKILL.md +106 -0
  64. package/src/modules/lowticket/skills/lowticket-pagina/references/metas-e-medicao.md +70 -0
  65. package/src/modules/lowticket/skills/lowticket-pagina/references/padroes-de-codigo.md +148 -0
  66. package/src/modules/lowticket/skills/lowticket-trafego/SKILL.md +88 -0
  67. package/src/modules/lowticket/skills/lowticket-trafego/references/formato-do-diagnostico.md +56 -0
  68. package/src/modules/lowticket/skills/lowticket-trafego/references/reguas.md +72 -0
  69. package/src/modules/wizz/README.md +1 -1
  70. package/src/modules/wizz/_shared/cerebro.md +35 -1
  71. package/src/modules/wizz/_shared/communication-rules.md +8 -1
  72. package/src/modules/wizz/_shared/encerramento.md +22 -0
  73. package/src/modules/wizz/_shared/token-economy.md +7 -10
  74. package/src/modules/wizz/agents/wizz-ads/customize.toml +1 -1
  75. package/src/modules/wizz/agents/wizz-copy/customize.toml +1 -1
  76. package/src/modules/wizz/agents/wizz-designer/SKILL.md +1 -1
  77. package/src/modules/wizz/agents/wizz-designer/customize.toml +1 -1
  78. package/src/modules/wizz/agents/wizz-growth/customize.toml +1 -1
  79. package/src/modules/wizz/agents/wizz-maestro/SKILL.md +5 -1
  80. package/src/modules/wizz/agents/wizz-maestro/customize.toml +1 -1
  81. package/src/modules/wizz/agents/wizz-memoria/SKILL.md +1 -1
  82. package/src/modules/wizz/agents/wizz-qa/SKILL.md +6 -0
  83. package/src/modules/wizz/agents/wizz-qa/customize.toml +1 -1
  84. package/src/modules/wizz/agents/wizz-seo/customize.toml +1 -1
  85. package/src/modules/wizz/agents/wizz-social/SKILL.md +1 -0
  86. package/src/modules/wizz/agents/wizz-social/customize.toml +1 -1
  87. package/src/modules/wizz/overrides/wizz-agent-analyst.toml +2 -2
  88. package/src/modules/wizz/overrides/wizz-agent-architect.toml +2 -2
  89. package/src/modules/wizz/overrides/wizz-agent-dev.toml +1 -1
  90. package/src/modules/wizz/overrides/wizz-agent-pm.toml +1 -1
  91. package/src/modules/wizz/overrides/wizz-agent-tech-writer.toml +1 -1
  92. package/src/modules/wizz/overrides/wizz-agent-ux-designer.toml +1 -1
  93. package/src/modules/wizz/subagents/codex/wizz-exec-haiku.toml +12 -0
  94. package/src/modules/wizz/subagents/codex/wizz-exec-opus.toml +12 -0
  95. package/src/modules/wizz/subagents/codex/wizz-exec-review.toml +11 -0
  96. package/src/modules/wizz/subagents/codex/wizz-exec-sonnet.toml +12 -0
  97. package/src/modules/wizz/subagents/gemini/wizz-exec-haiku.md +12 -0
  98. package/src/modules/wizz/subagents/gemini/wizz-exec-opus.md +12 -0
  99. package/src/modules/wizz/subagents/gemini/wizz-exec-review.md +11 -0
  100. package/src/modules/wizz/subagents/gemini/wizz-exec-sonnet.md +12 -0
  101. package/src/modules/wizz/subagents/opencode/wizz-exec-haiku.md +12 -0
  102. package/src/modules/wizz/subagents/opencode/wizz-exec-opus.md +12 -0
  103. package/src/modules/wizz/subagents/opencode/wizz-exec-review.md +11 -0
  104. package/src/modules/wizz/subagents/opencode/wizz-exec-sonnet.md +12 -0
  105. package/src/modules/wizz/subagents/wizz-exec-haiku.md +12 -0
  106. package/src/modules/wizz/subagents/wizz-exec-opus.md +12 -0
  107. package/src/modules/wizz/subagents/wizz-exec-review.md +11 -0
  108. package/src/modules/wizz/subagents/wizz-exec-sonnet.md +12 -0
  109. package/src/skills-lib/analytics-tracking/SKILL.md +2 -0
  110. package/src/skills-lib/analytics-tracking/references/utm-taxonomy.md +92 -0
  111. package/src/skills-lib/cerebro/SKILL.md +20 -17
  112. package/src/skills-lib/cerebro/references/comandos-pesquisa-e-memoria.md +96 -0
  113. package/src/skills-lib/cerebro/references/comandos-rotina-e-captura.md +25 -6
  114. package/src/skills-lib/cerebro/references/comandos-sessao.md +61 -37
  115. package/src/skills-lib/launch-readiness/SKILL.md +94 -0
  116. package/src/skills-lib/launch-readiness/references/01-tecnico-build.md +26 -0
  117. package/src/skills-lib/launch-readiness/references/02-seguranca.md +26 -0
  118. package/src/skills-lib/launch-readiness/references/03-seo-descoberta.md +27 -0
  119. package/src/skills-lib/launch-readiness/references/04-analytics-medicao.md +25 -0
  120. package/src/skills-lib/launch-readiness/references/05-conteudo-prova-social.md +25 -0
  121. package/src/skills-lib/launch-readiness/references/06-legal-lgpd.md +25 -0
  122. package/src/skills-lib/launch-readiness/references/07-infra-deploy-rollback.md +26 -0
  123. package/src/skills-lib/launch-readiness/references/08-fusao-priorizacao.md +33 -0
  124. package/src/skills-lib/launch-readiness/references/09-persistencia-project-context.md +48 -0
  125. package/src/skills-lib/premium-landing-ui-researcher/references/source-first-protocol.md +1 -1
  126. package/src/skills-lib/site-launch-kit/SKILL.md +1 -1
  127. package/src/skills-lib/taste-skill/SKILL.md +4 -2
  128. package/src/skills-lib/{taste-redesign → taste-skill}/references/design-audit.md +30 -41
  129. package/src/skills-lib/taste-skill/references/redesign-protocol.md +2 -2
  130. package/src/skills-lib/taste-skill/references/upgrade-techniques.md +33 -0
  131. package/src/skills-lib/tracking-audit/SKILL.md +78 -0
  132. package/src/skills-lib/tracking-audit/references/modo-diagnostico.md +72 -0
  133. package/src/skills-lib/tracking-audit/references/modo-implantacao.md +89 -0
  134. package/src/skills-lib/tracking-audit/references/utm-e-atribuicao.md +75 -0
  135. package/src/skills-lib/wizz-offer-forge/SKILL.md +30 -4
  136. package/src/skills-lib/wizz-offer-forge/references/plano-de-medicao.md +74 -0
  137. package/src/skills-lib/wizz-router/SKILL.md +8 -2
  138. package/src/skills-lib/wizz-router/references/routing-table-flat.md +4 -3
  139. package/tools/fetch-assets.mjs +3 -2
  140. package/tools/installer/commands/trace-report.js +248 -4
  141. package/tools/installer/modules/official-modules.js +5 -0
  142. package/tools/installer/modules/skills-lib.js +7 -1
  143. package/wizz-modules.yaml +20 -3
  144. package/src/skills-lib/cerebro/references/comandos-pesquisa-e-sync.md +0 -44
  145. package/src/skills-lib/graphify/.graphify_version +0 -1
  146. package/src/skills-lib/graphify/SKILL.md +0 -1199
  147. package/src/skills-lib/taste-redesign/SKILL.md +0 -42
  148. package/src/skills-lib/taste-redesign/references/upgrade-techniques.md +0 -31
@@ -11,13 +11,137 @@
11
11
 
12
12
  const os = require('node:os');
13
13
  const path = require('node:path');
14
+ const yaml = require('yaml');
14
15
  const fs = require('../fs-native');
15
16
  const prompts = require('../prompts');
17
+ const { getProjectRoot } = require('../project-root');
16
18
 
17
19
  function getTraceFile() {
18
20
  return process.env.WIZZ_TRACE_FILE || path.join(os.homedir(), '.claude', 'wizz-trace.jsonl');
19
21
  }
20
22
 
23
+ // `--coverage` (P2 da auditoria 360°, "evals de descoberta"): cruza o
24
+ // catálogo de skills do skills-registry.yaml (fonte única, lido em runtime
25
+ // e nunca hardcoded aqui) contra os marcadores de decisão (`type:
26
+ // "decision"`, escritos por tools/hooks/wizz-decision-trace.js) já
27
+ // agregados no mesmo JSONL. Mede subutilização de roteamento: uma skill
28
+ // pode estar SELECIONADA (`sel`), DESCARTADA COM MOTIVO (`desc`, correto:
29
+ // foi considerada e explicitamente preterida) ou NUNCA CONSIDERADA (não
30
+ // aparece em nenhum dos dois arrays de nenhum trace): esta última é a
31
+ // falha de roteamento silenciosa que o item da auditoria pede pra medir.
32
+ function getRegistryFile() {
33
+ return path.join(getProjectRoot(), 'skills-registry.yaml');
34
+ }
35
+
36
+ // Lê e parseia skills-registry.yaml, devolvendo o catálogo de ids de
37
+ // skills em ordem alfabética estável (mesma lista independente da ordem em
38
+ // que as áreas/skills aparecem no YAML). Escopo deliberado: só as skills
39
+ // `areas.*.skills[]` e as cross-cutting `utility[]` (find-skills,
40
+ // enhance-prompt, wizz-router; também são skills de verdade em
41
+ // src/skills-lib/). CLIs/MCPs/squads ficam de fora: `sel`/`desc` no
42
+ // marcador de decisão podem citar agentes ou skills (ver encerramento.md),
43
+ // mas este comando mede especificamente subutilização de SKILL, não de
44
+ // ferramenta/squad. Lança em vez de devolver `null` em erro: quem chama
45
+ // decide como reportar (fail-clear, não fail-silent: ao contrário do
46
+ // trace, o catálogo é a fonte de verdade e um erro aqui é um bug real).
47
+ function collectSkillCatalog(registryFile) {
48
+ const raw = fs.readFileSync(registryFile, 'utf8');
49
+ const registry = yaml.parse(raw);
50
+ const ids = new Set();
51
+ for (const area of Object.values(registry.areas || {})) {
52
+ for (const skill of area.skills || []) {
53
+ if (skill && typeof skill.id === 'string') ids.add(skill.id);
54
+ }
55
+ }
56
+ for (const item of registry.utility || []) {
57
+ if (item && typeof item.id === 'string') ids.add(item.id);
58
+ }
59
+ return [...ids].sort();
60
+ }
61
+
62
+ // Agrega os traces `type: "decision"` já parseados contra o catálogo.
63
+ // Função pura (mesmo espírito de `aggregate`/`aggregateLadder`), testável
64
+ // sem tocar em disco. `catalogIds` já deve vir ordenado (saída de
65
+ // `collectSkillCatalog`): a ordem de `neverConsidered` deriva dela, então
66
+ // a saída é estável entre execuções.
67
+ //
68
+ // Ids de `sel`/`desc` que não pertencem ao catálogo (ex.: agente
69
+ // "wizz-designer" em vez de skill) são ignorados aqui, não contados como
70
+ // erro: o marcador aceita os dois tipos (encerramento.md), este comando só
71
+ // mede a fatia de skills.
72
+ //
73
+ // Categorização mutuamente exclusiva por skill (soma sempre = catalogTotal):
74
+ // selecionada (apareceu em algum `sel`) > descartada-só (apareceu só em
75
+ // `desc`, nunca em `sel`) > nunca considerada (nenhum dos dois). Se uma
76
+ // skill foi selecionada numa decisão e descartada noutra, conta como
77
+ // selecionada: "foi de fato usada ao menos uma vez" pesa mais que "também
78
+ // foi preterida uma vez" para o proposito de subutilização.
79
+ function aggregateCoverage(entries, catalogIds) {
80
+ const catalogSet = new Set(catalogIds);
81
+ const selected = new Set();
82
+ const discarded = new Set();
83
+ let decisionCount = 0;
84
+
85
+ for (const entry of entries) {
86
+ if (!entry || entry.type !== 'decision') continue;
87
+ const decision = entry.decision;
88
+ if (!decision || typeof decision !== 'object') continue;
89
+ decisionCount++;
90
+
91
+ if (Array.isArray(decision.sel)) {
92
+ for (const id of decision.sel) {
93
+ if (typeof id === 'string' && catalogSet.has(id)) selected.add(id);
94
+ }
95
+ }
96
+ if (Array.isArray(decision.desc)) {
97
+ for (const pair of decision.desc) {
98
+ if (Array.isArray(pair) && typeof pair[0] === 'string' && catalogSet.has(pair[0])) {
99
+ discarded.add(pair[0]);
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ const discardedOnly = [];
106
+ const neverConsidered = [];
107
+ for (const id of catalogIds) {
108
+ if (selected.has(id)) continue;
109
+ if (discarded.has(id)) discardedOnly.push(id);
110
+ else neverConsidered.push(id);
111
+ }
112
+
113
+ return {
114
+ catalogTotal: catalogIds.length,
115
+ decisionCount,
116
+ selectedCount: selected.size,
117
+ discardedOnlyCount: discardedOnly.length,
118
+ neverConsidered,
119
+ };
120
+ }
121
+
122
+ function formatCoverageSummary(stats, registryFile) {
123
+ const consideredCount = stats.catalogTotal - stats.neverConsidered.length;
124
+ const lines = [
125
+ `Catálogo: ${stats.catalogTotal} skills (${registryFile})`,
126
+ `Traces de decisão: ${stats.decisionCount}`,
127
+ `Selecionadas (sel): ${stats.selectedCount} (${pct(stats.selectedCount, stats.catalogTotal)})`,
128
+ `Descartadas c/ motivo: ${stats.discardedOnlyCount} (${pct(stats.discardedOnlyCount, stats.catalogTotal)})`,
129
+ `Nunca consideradas: ${stats.neverConsidered.length} (${pct(stats.neverConsidered.length, stats.catalogTotal)})`,
130
+ `Cobertura do catálogo: ${pct(consideredCount, stats.catalogTotal)}`,
131
+ ];
132
+
133
+ if (stats.decisionCount === 0) {
134
+ lines.push('', '(nenhum trace de decisão encontrado; rode com WIZZ_TRACE=1 e feche pedidos roteados pra gerar dados)');
135
+ } else if (stats.neverConsidered.length === 0) {
136
+ lines.push('', 'Nunca consideradas: nenhuma, catálogo 100% coberto.');
137
+ } else {
138
+ lines.push('', 'Nunca consideradas:');
139
+ for (const id of stats.neverConsidered) lines.push(` ${id}`);
140
+ }
141
+
142
+ return lines.join('\n');
143
+ }
144
+
21
145
  // Faz o parse de 1 linha JSONL. Retorna `null` (em vez de lançar) para
22
146
  // linhas corrompidas — fail-open, mesmo espírito do resto do framework: o
23
147
  // trace nunca pode quebrar quem o lê.
@@ -31,14 +155,24 @@ function parseLine(line) {
31
155
 
32
156
  // Agrega as entradas já parseadas em contadores/período. Função pura, sem
33
157
  // I/O, para ser testável isoladamente do disco.
158
+ //
159
+ // Linhas tipadas (`type: "decision"` do marcador 🧭 e `type: "ladder"` da
160
+ // escada de modelos, ambas escritas por tools/hooks/wizz-decision-trace.js)
161
+ // são IGNORADAS aqui: são outra granularidade de evento (o fecho de um
162
+ // pedido, não o roteamento em si) e contá-las junto de trivial/mode poluiria
163
+ // as contagens. `type: "ladder"` alimenta só `aggregateLadder`, abaixo.
34
164
  function aggregate(entries) {
35
165
  const byMode = { wizz: 0, flat: 0, null: 0 };
166
+ let total = 0;
36
167
  let trivialCount = 0;
37
168
  let warningsCount = 0;
38
169
  let firstTs = null;
39
170
  let lastTs = null;
40
171
 
41
172
  for (const entry of entries) {
173
+ if (entry.type === 'decision' || entry.type === 'ladder') continue;
174
+ total++;
175
+
42
176
  if (entry.isTrivial) {
43
177
  trivialCount++;
44
178
  } else {
@@ -54,9 +188,9 @@ function aggregate(entries) {
54
188
  }
55
189
 
56
190
  return {
57
- total: entries.length,
191
+ total,
58
192
  trivialCount,
59
- routedCount: entries.length - trivialCount,
193
+ routedCount: total - trivialCount,
60
194
  byMode,
61
195
  warningsCount,
62
196
  firstTs,
@@ -64,6 +198,53 @@ function aggregate(entries) {
64
198
  };
65
199
  }
66
200
 
201
+ // Bucket de rota pra agregação da escada de modelos: agrupa qualquer
202
+ // "agent:*" (designer, copy, seo, etc.) numa única chave — o que importa
203
+ // pra aderência é "foi delegado a um agente de área", não qual área
204
+ // especificamente. `maestro` e `flat` ficam como buckets próprios; qualquer
205
+ // outro valor (ou ausência) cai em `outro`.
206
+ function ladderBucket(rota) {
207
+ if (typeof rota !== 'string' || rota.length === 0) return 'outro';
208
+ if (rota.startsWith('agent:')) return 'agent:*';
209
+ if (rota === 'maestro') return 'maestro';
210
+ if (rota === 'flat') return 'flat';
211
+ return 'outro';
212
+ }
213
+
214
+ // Agrega as linhas `type: "ladder"` (uma por pedido roteado que fechou com
215
+ // marcador de decisão — ver wizz-decision-trace.js) em aderência à escada
216
+ // de modelos: quantos pedidos invocaram algum subagente wizz-exec-*,
217
+ // quebrado por rota. Função pura, mesmo espírito de `aggregate`.
218
+ function aggregateLadder(entries) {
219
+ const byRoute = {};
220
+
221
+ const bump = (bucket, invoked) => {
222
+ if (!byRoute[bucket]) byRoute[bucket] = { total: 0, withExec: 0 };
223
+ byRoute[bucket].total++;
224
+ if (invoked) byRoute[bucket].withExec++;
225
+ };
226
+
227
+ let total = 0;
228
+ let withExec = 0;
229
+
230
+ for (const entry of entries) {
231
+ if (!entry || entry.type !== 'ladder') continue;
232
+ total++;
233
+ const invoked = Array.isArray(entry.execs) && entry.execs.length > 0;
234
+ if (invoked) withExec++;
235
+ bump(ladderBucket(entry.rota), invoked);
236
+ }
237
+
238
+ return { total, withExec, byRoute };
239
+ }
240
+
241
+ // Percentual formatado, protegido contra divisão por zero (mostra "—" em
242
+ // vez de NaN%/Infinity% quando o denominador é 0).
243
+ function pct(part, total) {
244
+ if (!total) return '—';
245
+ return `${Math.round((part / total) * 100)}%`;
246
+ }
247
+
67
248
  function formatSummary(stats, traceFile) {
68
249
  const lines = [
69
250
  `Arquivo: ${traceFile}`,
@@ -82,10 +263,34 @@ function formatSummary(stats, traceFile) {
82
263
  return lines.join('\n');
83
264
  }
84
265
 
266
+ // Ordem de exibição fixa das rotas na segunda caixa — independente da ordem
267
+ // em que apareceram no arquivo, pra saída estável entre execuções.
268
+ const ROUTE_DISPLAY_ORDER = ['agent:*', 'maestro', 'flat', 'outro'];
269
+
270
+ function formatLadderSummary(ladderStats) {
271
+ const lines = [
272
+ `Pedidos roteados com dado de escada: ${ladderStats.total}`,
273
+ `Invocaram algum wizz-exec-*: ${ladderStats.withExec} (${pct(ladderStats.withExec, ladderStats.total)})`,
274
+ 'Por rota:',
275
+ ];
276
+
277
+ const routes = ROUTE_DISPLAY_ORDER.filter((route) => ladderStats.byRoute[route]);
278
+ if (routes.length === 0) {
279
+ lines.push(' (sem dados)');
280
+ } else {
281
+ for (const route of routes) {
282
+ const bucket = ladderStats.byRoute[route];
283
+ lines.push(` ${route.padEnd(8)} ${bucket.withExec}/${bucket.total} (${pct(bucket.withExec, bucket.total)})`);
284
+ }
285
+ }
286
+
287
+ return lines.join('\n');
288
+ }
289
+
85
290
  module.exports = {
86
291
  command: 'trace-report',
87
292
  description: 'Resume o arquivo local de trace do roteamento (WIZZ_TRACE)',
88
- options: [],
293
+ options: [['--coverage', 'Cruza o catálogo de skills do registry contra os traces: mede skills nunca consideradas no roteamento']],
89
294
  action: async (options) => {
90
295
  try {
91
296
  const traceFile = getTraceFile();
@@ -112,10 +317,37 @@ module.exports = {
112
317
  }
113
318
  }
114
319
 
320
+ // `--coverage` é um modo alternativo, não aditivo: troca as 2 caixas
321
+ // base (contagem trivial/mode e escada de modelos) por 1 caixa focada
322
+ // em subutilização de skills. Motivo: são leituras diferentes do mesmo
323
+ // JSONL (roteamento agregado vs catálogo x descoberta): misturar as
324
+ // 3 caixas por padrão poluiria a saída sem ganho pro caso de uso de
325
+ // cada flag.
326
+ if (options.coverage) {
327
+ const registryFile = getRegistryFile();
328
+ let catalogIds;
329
+ try {
330
+ catalogIds = collectSkillCatalog(registryFile);
331
+ } catch (error) {
332
+ await prompts.log.error(`Não foi possível ler o catálogo de skills: ${error.message}`);
333
+ await prompts.log.message(`Esperado em: ${registryFile}`);
334
+ process.exit(1);
335
+ return;
336
+ }
337
+
338
+ const coverageStats = aggregateCoverage(entries, catalogIds);
339
+ await prompts.box(formatCoverageSummary(coverageStats, registryFile), 'Cobertura do Catálogo de Skills');
340
+ process.exit(0);
341
+ return;
342
+ }
343
+
115
344
  const stats = { ...aggregate(entries), corruptedCount };
116
345
 
117
346
  await prompts.box(formatSummary(stats, traceFile), 'Wizz Trace Report');
118
347
 
348
+ const ladderStats = aggregateLadder(entries);
349
+ await prompts.box(formatLadderSummary(ladderStats), 'Aderência à Escada de Modelos');
350
+
119
351
  process.exit(0);
120
352
  } catch (error) {
121
353
  await prompts.log.error(`Trace report failed: ${error.message}`);
@@ -127,5 +359,17 @@ module.exports = {
127
359
  },
128
360
  // Exportado só para teste unitário direto da agregação, sem precisar
129
361
  // spawnar o processo pra cada caso de borda.
130
- _internal: { aggregate, parseLine, formatSummary },
362
+ _internal: {
363
+ aggregate,
364
+ parseLine,
365
+ formatSummary,
366
+ aggregateLadder,
367
+ ladderBucket,
368
+ formatLadderSummary,
369
+ pct,
370
+ collectSkillCatalog,
371
+ aggregateCoverage,
372
+ formatCoverageSummary,
373
+ getRegistryFile,
374
+ },
131
375
  };
@@ -292,6 +292,11 @@ class OfficialModules {
292
292
  * @param {Object} options.logger - Logger instance for output
293
293
  */
294
294
  async install(moduleName, wizzDir, fileTrackingCallback = null, options = {}) {
295
+ // Aliases (ex.: bauto → bmad-loop) chegam crus via --modules e via
296
+ // moduleIds de instalações antigas; sem normalizar aqui, o cache de
297
+ // getPluginResolution, o targetPath e o manifest usariam o código legado.
298
+ moduleName = await this.externalModuleManager.resolveCanonicalCode(moduleName);
299
+
295
300
  // Check if this module has a plugin resolution (custom marketplace install)
296
301
  const { CustomModuleManager } = require('./custom-module-manager');
297
302
  const customMgr = new CustomModuleManager();
@@ -29,7 +29,7 @@ const { resolveAreaEntries } = require('./registry-resolve');
29
29
  /**
30
30
  * Resolve which skill ids to install from the registry for the chosen areas.
31
31
  * Empty / undefined / containing 'all' means every area. Utility skills
32
- * (graphify, find-skills, ...) are cross-cutting and always included.
32
+ * (find-skills, wizz-router, ...) are cross-cutting and always included.
33
33
  *
34
34
  * Wrapper fino sobre `resolveAreaEntries` (A16): a resolução por área vive em
35
35
  * `registry-resolve.js`; aqui só sobra reduzir as entradas resolvidas ao
@@ -43,6 +43,12 @@ function resolveSkillIds(registry, selectedAreas) {
43
43
  const entries = resolveAreaEntries(registry, selectedAreas, {
44
44
  listKey: 'skills',
45
45
  utilityKey: 'utility',
46
+ // Uma entrada com `module:` vem de src/modules/<module>/skills/, não de
47
+ // src/skills-lib/ — ela é instalada junto do módulo. Sem este gate o
48
+ // installer procuraria src/skills-lib/<id>/SKILL.md, não acharia, e
49
+ // reportaria a skill como "skipped" em toda instalação. Ela continua no
50
+ // registry porque o router/maestro precisa enxergá-la para rotear.
51
+ isActionable: (raw) => !raw.module,
46
52
  });
47
53
  return entries.map((entry) => entry.id);
48
54
  }
package/wizz-modules.yaml CHANGED
@@ -40,6 +40,23 @@
40
40
  # aliases (optional) — prior `code` values this module was registered under.
41
41
  # An existing install recorded under an alias resolves to this entry instead of
42
42
  # being orphaned as "no source available" when the code changes.
43
+ #
44
+ # ─────────────────────────────────────────────────────────────────────────────
45
+ # NOT LISTED HERE: bundled local modules.
46
+ # ─────────────────────────────────────────────────────────────────────────────
47
+ # This file registers modules that live in ANOTHER repository and are fetched
48
+ # at install time. Modules that ship inside this repo under src/modules/<code>/
49
+ # are auto-discovered by the installer (OfficialModules.listAvailable scans
50
+ # src/modules/ for a module.yaml) and must NOT get an entry here — an entry
51
+ # without a real upstream `url` would break resolution.
52
+ #
53
+ # Bundled local modules today:
54
+ # wizz src/modules/wizz/ default_selected: true
55
+ # lowticket src/modules/lowticket/ default_selected: false
56
+ #
57
+ # Their installable skills are declared in skills-registry.yaml with a
58
+ # `module:` field, which keeps the router aware of them while telling the
59
+ # skills-lib copier to leave them alone (see tools/installer/modules/skills-lib.js).
43
60
 
44
61
  modules:
45
62
  bmad-method-test-architecture-enterprise:
@@ -81,12 +98,12 @@ modules:
81
98
  # .claude-plugin/marketplace.json via plugin resolver (ver external-manager).
82
99
  marketplace-plugin: true
83
100
  post-install-message: |
84
- Wizz Loop installed. To finish setup, run the bmad-loop-setup skill
85
- from your agent:
101
+ Wizz Loop installed. To finish setup, ask your agent to run the setup
102
+ skill (the command keeps the upstream name):
86
103
 
87
104
  > use the bmad-loop-setup skill
88
105
 
89
- It installs the bmad-loop orchestrator tool and wires up the per-project
106
+ It installs the Wizz Loop orchestrator tool and wires up the per-project
90
107
  hooks and policy. The automation skills don't run until setup completes.
91
108
 
92
109
  bmad-creative-intelligence-suite:
@@ -1,44 +0,0 @@
1
- # Comandos de Pesquisa e Sync: /prospect, /sync
2
-
3
- Carregue este arquivo ao executar `/prospect` ou `/sync`. Antes de tudo, releia a REGRA DE OURO e a seção Vault no SKILL.md principal — esses comandos dependem delas.
4
-
5
- ## /prospect
6
-
7
- **Objetivo:** pesquisar e registrar prospect.
8
-
9
- **Passos:**
10
- 1. Receber nome/empresa + objetivo (tudo de uma vez)
11
- 2. Pesquisar via web search (setor, presença digital, dores, oportunidades)
12
- 3. Write direto em `_prospects/YYYY-MM-DD-[slug].md`
13
- 4. Resumo executivo para o usuário (não precisa estar no arquivo)
14
-
15
- **Template `_prospects/YYYY-MM-DD-[slug].md`:**
16
- ```markdown
17
- # [Nome / Empresa]
18
- > Data: [data] | Objetivo: [tipo] | Status: pesquisado
19
-
20
- ## Perfil
21
- - Setor / Tamanho / Produto / Público-alvo
22
-
23
- ## Presença digital
24
- - Site / Redes / Ads ativos
25
-
26
- ## Oportunidade e ângulo de abordagem
27
- [o que oferecer e como entrar]
28
-
29
- ## Próximo passo
30
- - [ ] [ação]
31
- ```
32
-
33
- ## /sync
34
-
35
- **Objetivo:** espelhar CONTEXT.md → vault após sessão no Codex.
36
-
37
- **Passos:**
38
- 1. Read `CONTEXT.md` no diretório atual (arquivo pequeno — OK ler completo)
39
- 2. `wc -l "$VAULT/projetos/$PROJ.md"` → tail Read das últimas 60 linhas
40
- 3. Identificar diferenças em: estado atual, pendências, decisões
41
- 4. Edit cirúrgico em `projetos/[nome].md` (só seções alteradas)
42
- 5. `grep -n "Última sessão\|Pendente" "$VAULT/CEREBRO.md" | grep -i "$PROJ"` → Edit linha
43
- 6. Append linha em `_index/sessions.md`
44
- 7. Confirmar em 2 linhas
@@ -1 +0,0 @@
1
- 0.3.19