wizz-method 2.17.0 → 2.17.1

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "wizz-method",
4
- "version": "2.17.0",
4
+ "version": "2.17.1",
5
5
  "description": "Wizz Method: método de agência orientado por IA em PT-BR",
6
6
  "keywords": [
7
7
  "agile",
@@ -4,7 +4,7 @@ The names `wizz-exec-mechanical`/`wizz-exec-standard`/`wizz-exec-strong`/`wizz-e
4
4
 
5
5
  ## The recommended session (the boss)
6
6
 
7
- The recommended session model is the Standard tier (Sonnet / gpt-5.6-terra / claude-sonnet-5-5 / gemini-3.5-flash). The boss does common work itself — commands, questions, implementation with a spec — dispatches subagents for isolation or parallel work, arbitrates conflict between executor and reviewer, and takes architecture/product decisions WITH the user.
7
+ The recommended session model is the Standard tier (Sonnet / gpt-6-sol / claude-sonnet-5-5 / gemini-3.5-flash). The boss does common work itself — commands, questions, implementation with a spec — dispatches subagents for isolation or parallel work, arbitrates conflict between executor and reviewer, and takes architecture/product decisions WITH the user.
8
8
 
9
9
  A session running above Standard (Opus, Fable, Mythos...) absorbs every tier at or below its own model: an Opus session does Strong work itself, and dispatches `wizz-exec-ultra` only after that attempt returns `ESCALAR` per the escalation signals below. A session on the Ultra model (Fable) absorbs Ultra too: it takes strong's `ESCALAR` itself and never dispatches `wizz-exec-ultra`. Review is the exception — it's NEVER absorbed: it always runs on `wizz-exec-review`, pinned to the Strong tier, so in a Fable session review moves off the boss and onto Opus.
10
10
 
@@ -14,11 +14,13 @@ How to know who the boss is in Claude Code: the system prompt states the session
14
14
 
15
15
  | Tier | Subagent | Use | Claude Code | Codex | OpenCode | Gemini CLI |
16
16
  |---|---|---|---|---|---|---|
17
- | Mechanical | `wizz-exec-mechanical` | scanning, rename, repetitive diff, 100% specified change | haiku (maxTurns 50, no effort field) | gpt-5.6-luna, effort low | anthropic/claude-haiku-4-5 | gemini-3.1-flash-lite (max_turns 50, no effort field) |
18
- | Standard | `wizz-exec-standard` | small/medium defined feature, bug with known cause, tests | sonnet, effort medium (maxTurns 80) | gpt-5.6-terra, effort medium | anthropic/claude-sonnet-5-5 | gemini-3.5-flash (max_turns 80) |
19
- | Strong | `wizz-exec-strong` | bug with unclear cause after one investigation cycle, refactor spanning modules, schema/auth/payment changes, local technical decision | opus, effort high (maxTurns 120) | gpt-5.6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 120) |
17
+ | Mechanical | `wizz-exec-mechanical` | scanning, rename, repetitive diff, 100% specified change | haiku (maxTurns 50, no effort field) | gpt-6-luna, effort low | anthropic/claude-haiku-4-5 | gemini-3.1-flash-lite (max_turns 50, no effort field) |
18
+ | Standard | `wizz-exec-standard` | small/medium defined feature, bug with known cause, tests | sonnet, effort medium (maxTurns 80) | gpt-6-sol, effort medium | anthropic/claude-sonnet-5-5 | gemini-3.5-flash (max_turns 80) |
19
+ | Strong | `wizz-exec-strong` | bug with unclear cause after one investigation cycle, refactor spanning modules, schema/auth/payment changes, local technical decision | opus, effort high (maxTurns 120) | gpt-6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 120) |
20
20
  | Ultra | `wizz-exec-ultra` | ultra-hard work the Strong tier returned `ESCALAR` on, plus its findings | fable, effort xhigh (maxTurns 150) | gpt-6-astra, effort xhigh | anthropic/claude-fable-5-1 | no ultra tier on this platform |
21
- | Review | `wizz-exec-review` | review of a diff produced by any tier; pinned to Strong, never inherits the session | opus, effort high (maxTurns 60) | gpt-5.6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 60) |
21
+ | Review | `wizz-exec-review` | review of a diff produced by any tier; pinned to Strong, never inherits the session | opus, effort high (maxTurns 60) | gpt-6-sol, effort high | anthropic/claude-opus-5-5 | gemini-3.1-pro-preview (max_turns 60) |
22
+
23
+ Staying current: Claude Code tiers are aliases that Claude Code points at the newest model, so they never need a bump. Codex has no such alias: on install and on every `wizz update`, the installer reads the machine's Codex models cache (`~/.codex/models_cache.json`) and swaps each pinned Codex model for the newest current model of the same class (fast, workhorse, frontier). The table's Codex column is the fallback, used when the cache is missing, older than the spec, or the newer model lacks the tier's effort. OpenCode and Gemini CLI stay pinned to the table.
22
24
 
23
25
  OpenCode gets the model only: its per-agent effort field isn't documented, and it has no per-agent turn cap field either. Claude Code and Gemini CLI enforce turn caps natively (`maxTurns` / `max_turns`); Codex and OpenCode have no per-agent turn cap field, so briefs to them should always carry `max_calls`.
24
26
 
@@ -1,9 +1,9 @@
1
1
  # Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
2
2
  name = "wizz-exec-mechanical"
3
3
  description = """
4
- Mechanical Wizz Method executor, the cheapest tier. File sweeps, lookups, renames, repetitive diffs, and applying already 100%-specified changes. Dispatch 1 instance when the work fits in 3 files or fewer; parallel instances only when partitioned by file/module (never two on the same file), up to 4 at once. Model on this platform: gpt-5.6-luna, effort low.
4
+ Mechanical Wizz Method executor, the cheapest tier. File sweeps, lookups, renames, repetitive diffs, and applying already 100%-specified changes. Dispatch 1 instance when the work fits in 3 files or fewer; parallel instances only when partitioned by file/module (never two on the same file), up to 4 at once. Model on this platform: gpt-6-luna, effort low.
5
5
  """
6
- model = "gpt-5.6-luna"
6
+ model = "gpt-6-luna"
7
7
  model_reasoning_effort = "low"
8
8
  developer_instructions = """
9
9
  You are a mechanical executor for the Wizz Method. You receive a closed brief and execute it to the letter.
@@ -1,9 +1,9 @@
1
1
  # Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
2
2
  name = "wizz-exec-review"
3
3
  description = """
4
- Wizz Method reviewer pinned to the Strong tier (gpt-5.6-sol, effort high), never to the session's model. Receives a diff or an executor's result and reviews correctness, security, regressions, and scope adherence. Doesn't implement: returns a verdict and a list of issues with file:line.
4
+ Wizz Method reviewer pinned to the Strong tier (gpt-6-sol, effort high), never to the session's model. Receives a diff or an executor's result and reviews correctness, security, regressions, and scope adherence. Doesn't implement: returns a verdict and a list of issues with file:line.
5
5
  """
6
- model = "gpt-5.6-sol"
6
+ model = "gpt-6-sol"
7
7
  model_reasoning_effort = "high"
8
8
  sandbox_mode = "read-only"
9
9
  developer_instructions = """
@@ -1,9 +1,9 @@
1
1
  # Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
2
2
  name = "wizz-exec-standard"
3
3
  description = """
4
- Standard Wizz Method executor for day-to-day implementation. Well-defined small/medium features, bug fixes with a known cause, multi-file edits, tests. Same tier as the recommended session model: dispatch it for isolation or parallel work (1 per file/module, up to 4 at once), not to escalate. Model on this platform: gpt-5.6-terra, effort medium.
4
+ Standard Wizz Method executor for day-to-day implementation. Well-defined small/medium features, bug fixes with a known cause, multi-file edits, tests. Same tier as the recommended session model: dispatch it for isolation or parallel work (1 per file/module, up to 4 at once), not to escalate. Model on this platform: gpt-6-sol, effort medium.
5
5
  """
6
- model = "gpt-5.6-terra"
6
+ model = "gpt-6-sol"
7
7
  model_reasoning_effort = "medium"
8
8
  developer_instructions = """
9
9
  You are an implementation executor for the Wizz Method. You receive a brief with a goal and context, and you implement it.
@@ -1,9 +1,9 @@
1
1
  # Gerado por tools/generate-subagents.mjs a partir de src/modules/wizz/subagents/spec.yaml. Não edite este arquivo direto: edite o spec.yaml e rode `npm run generate:subagents`.
2
2
  name = "wizz-exec-strong"
3
3
  description = """
4
- Strong Wizz Method executor for hard work. Bugs with no known cause after one investigation cycle, cross-module refactors, schema/auth/payment changes, local technical decisions. The session dispatches it when the work is too hard for the session's own tier. If the work turns out to be ultra hard, it returns ESCALAR with its findings; it never dispatches anything itself. Model on this platform: gpt-5.6-sol, effort high.
4
+ Strong Wizz Method executor for hard work. Bugs with no known cause after one investigation cycle, cross-module refactors, schema/auth/payment changes, local technical decisions. The session dispatches it when the work is too hard for the session's own tier. If the work turns out to be ultra hard, it returns ESCALAR with its findings; it never dispatches anything itself. Model on this platform: gpt-6-sol, effort high.
5
5
  """
6
- model = "gpt-5.6-sol"
6
+ model = "gpt-6-sol"
7
7
  model_reasoning_effort = "high"
8
8
  developer_instructions = """
9
9
  You are a senior executor for the Wizz Method. You receive a brief with a goal and context for hard work, where the root cause or the path forward isn't clear yet.
@@ -169,12 +169,15 @@ models:
169
169
  strong: anthropic/claude-opus-5-5
170
170
  ultra: anthropic/claude-fable-5-1
171
171
  review: anthropic/claude-opus-5-5
172
+ # GPT-6 has three models for five tiers (2026-10-05, Codex models cache):
173
+ # luna = fast/cheap, sol = workhorse, astra = frontier. Strong/review
174
+ # reuse sol at higher effort; ultra stays on astra.
172
175
  codex:
173
- mechanical: gpt-5.6-luna
174
- standard: gpt-5.6-terra
175
- strong: gpt-5.6-sol
176
+ mechanical: gpt-6-luna
177
+ standard: gpt-6-sol
178
+ strong: gpt-6-sol
176
179
  ultra: gpt-6-astra
177
- review: gpt-5.6-sol
180
+ review: gpt-6-sol
178
181
 
179
182
  # Codex `model_reasoning_effort`.
180
183
  codex_effort:
@@ -22,8 +22,9 @@ const INSTRUCTION_FILES = ['CLAUDE.md', 'AGENTS.md'];
22
22
  // claude-haiku-4-5 continua atual (não há Haiku mais novo em 2026-09-30).
23
23
  // `claude-(opus|sonnet)-5` sem sufixo foi trocado por 5-5; o lookahead evita
24
24
  // casar o próprio `-5-5`.
25
+ // A família GPT 5.x (Codex) saiu da escada em 2026-10-05: a família GPT-6 assumiu.
25
26
  const RETIRED_MODEL_RE =
26
- /\bclaude-(?:instant|2|3|3-5|3-7)(?:-[a-z0-9]+)*\b|\bclaude-(?:opus|sonnet)-4(?:-\d+)?\b|\bclaude-(?:opus|sonnet)-5\b(?!-)/gi;
27
+ /\bclaude-(?:instant|2|3|3-5|3-7)(?:-[a-z0-9]+)*\b|\bclaude-(?:opus|sonnet)-4(?:-\d+)?\b|\bclaude-(?:opus|sonnet)-5\b(?!-)|\bgpt-5(?:\.\d+)?(?:-[a-z]+)*\b/gi;
27
28
 
28
29
  const LEGACY_RULES = [
29
30
  { id: 'gsd', re: /\bGSD\b|get-shit-done|\/gsd[:-]/, why: 'GSD foi substituído pelas fases e checkpoints do Wizz Method' },
@@ -0,0 +1,112 @@
1
+ // Modelo dos subagentes resolvido na instalação (2026-10-05).
2
+ //
3
+ // O spec.yaml pina um modelo por tier e plataforma. No Claude Code isso é um
4
+ // apelido (haiku/sonnet/opus/fable) que o próprio Claude Code aponta para a
5
+ // versão mais nova, então o arquivo passa intacto. O Codex não tem apelido de
6
+ // "mais novo": aqui o installer lê o cache de modelos do Codex desta máquina
7
+ // (~/.codex/models_cache.json) e troca o modelo pinado pelo mais novo da mesma
8
+ // classe (barato / do dia a dia / fronteira). Qualquer dúvida mantém o pinado:
9
+ // sem cache, cache mais velho que o spec (o pinado nem aparece nele), esforço
10
+ // que o modelo novo não suporta, ou JSON em formato inesperado.
11
+ //
12
+ // OpenCode e Gemini seguem pinados: falta uma fonte local confiável da lista
13
+ // de modelos deles.
14
+
15
+ const fs = require('node:fs');
16
+ const os = require('node:os');
17
+ const path = require('node:path');
18
+
19
+ const CLASS_PATTERNS = {
20
+ fast: /\b(fast|affordable|efficient|lightweight|cheap|mini|nano)\b/i,
21
+ frontier: /\b(frontier|most capable|most demanding|most intelligent)\b/i,
22
+ };
23
+ const OUTDATED = /\b(older|legacy|deprecated)\b/i;
24
+
25
+ function defaultCodexCachePath() {
26
+ return process.env.CODEX_MODELS_CACHE || path.join(os.homedir(), '.codex', 'models_cache.json');
27
+ }
28
+
29
+ function loadCodexCache(cachePath = defaultCodexCachePath()) {
30
+ try {
31
+ return JSON.parse(fs.readFileSync(cachePath, 'utf8'));
32
+ } catch {
33
+ return null;
34
+ }
35
+ }
36
+
37
+ // Classe pela descrição; um modelo antigo ("Older fast and efficient model")
38
+ // ainda casa a classe certa porque o padrão ignora o "Older".
39
+ function classOf(entry) {
40
+ const text = `${entry.slug} ${entry.description || ''}`;
41
+ if (CLASS_PATTERNS.frontier.test(text)) return 'frontier';
42
+ if (CLASS_PATTERNS.fast.test(text)) return 'fast';
43
+ return 'workhorse';
44
+ }
45
+
46
+ function isCurrent(entry) {
47
+ return entry.visibility === 'list' && !entry.upgrade && !OUTDATED.test(entry.description || '');
48
+ }
49
+
50
+ function supportsEffort(entry, effort) {
51
+ if (!effort) return true;
52
+ const levels = Array.isArray(entry.supported_reasoning_levels) ? entry.supported_reasoning_levels : [];
53
+ return levels.some((level) => level && level.effort === effort);
54
+ }
55
+
56
+ /**
57
+ * Modelo Codex mais novo da mesma classe do pinado, ou o próprio pinado.
58
+ * @param {string} pinned - modelo do spec
59
+ * @param {string|undefined} effort - model_reasoning_effort do arquivo
60
+ * @param {Object|null} cache - conteúdo de models_cache.json
61
+ */
62
+ function resolveCodexModel(pinned, effort, cache) {
63
+ const models = cache && Array.isArray(cache.models) ? cache.models.filter((m) => m && typeof m.slug === 'string') : null;
64
+ if (!models) return pinned;
65
+ const pinnedEntry = models.find((m) => m.slug === pinned);
66
+ // O pinado fora do cache = cache mais velho que o spec: nunca rebaixar.
67
+ if (!pinnedEntry) return pinned;
68
+ const wanted = classOf(pinnedEntry);
69
+ const newest = models
70
+ .filter((m) => isCurrent(m) && classOf(m) === wanted)
71
+ .sort((a, b) => (a.priority ?? Infinity) - (b.priority ?? Infinity))[0];
72
+ if (!newest || !supportsEffort(newest, effort)) return pinned;
73
+ return newest.slug;
74
+ }
75
+
76
+ function readModel(content) {
77
+ const match = content.match(/^model = "([^"]+)"$/m) || content.match(/^model: (\S+)$/m);
78
+ return match ? match[1] : null;
79
+ }
80
+
81
+ function replaceModel(content, from, to) {
82
+ return from && to && from !== to ? content.split(from).join(to) : content;
83
+ }
84
+
85
+ /**
86
+ * Conteúdo do subagente com o modelo resolvido para esta máquina.
87
+ * @param {string} content - arquivo gerado a partir do spec
88
+ * @param {string|undefined} platform - agents_source_subdir (codex, gemini...)
89
+ * @param {Object} [opts] - codexCache (objeto) ou codexCachePath
90
+ */
91
+ function renderSubagent(content, platform, opts = {}) {
92
+ if (platform !== 'codex') return content;
93
+ const pinned = readModel(content);
94
+ if (!pinned) return content;
95
+ const effort = (content.match(/^model_reasoning_effort = "([^"]+)"$/m) || [])[1];
96
+ const cache = opts.codexCache === undefined ? loadCodexCache(opts.codexCachePath) : opts.codexCache;
97
+ return replaceModel(content, pinned, resolveCodexModel(pinned, effort, cache));
98
+ }
99
+
100
+ /**
101
+ * Dois arquivos iguais a menos do modelo: um arquivo instalado com outro
102
+ * modelo resolvido continua sendo do Wizz (não precisa de backup).
103
+ */
104
+ function sameExceptModel(a, b) {
105
+ if (a === b) return true;
106
+ const modelA = readModel(a);
107
+ const modelB = readModel(b);
108
+ if (!modelA || !modelB) return false;
109
+ return a.split(modelA).join('<wizz-model>') === b.split(modelB).join('<wizz-model>');
110
+ }
111
+
112
+ module.exports = { renderSubagent, resolveCodexModel, sameExceptModel, loadCodexCache };
@@ -6,6 +6,7 @@ const prompts = require('../prompts');
6
6
  const { loadCsvCached } = require('../core/yaml-cache');
7
7
  const { WIZZ_FOLDER_NAME } = require('./shared/path-utils');
8
8
  const { findExistingWizzDir } = require('../core/wizz-dir');
9
+ const { renderSubagent, sameExceptModel } = require('../core/subagent-models');
9
10
  const { getInstalledCanonicalIds, isWizzOwnedEntry } = require('./shared/installed-skills');
10
11
 
11
12
  // Reserved OpenCode slash commands. A skill whose canonicalId collides with
@@ -567,7 +568,8 @@ class ConfigDrivenIdeSetup {
567
568
  }
568
569
  const existing = await fs.readFile(targetFile, 'utf8');
569
570
  const source = await fs.readFile(sourcePath, 'utf8');
570
- if (existing !== source) {
571
+ // Same file with another resolved model is still Wizz-generated.
572
+ if (!sameExceptModel(existing, source)) {
571
573
  const backupPath = await this._backupSubagentFile(targetFile, options, report);
572
574
  if (!backupPath) {
573
575
  report.preserved++;
@@ -576,7 +578,10 @@ class ConfigDrivenIdeSetup {
576
578
  report.backups++;
577
579
  }
578
580
  }
579
- await fs.copy(sourcePath, targetFile, { overwrite: true });
581
+ const rendered = renderSubagent(await fs.readFile(sourcePath, 'utf8'), config.agents_source_subdir, {
582
+ codexCachePath: options.codexModelsCachePath,
583
+ });
584
+ await fs.writeFile(targetFile, rendered);
580
585
  count++;
581
586
  report.installed++;
582
587
  } catch (error) {
@@ -930,7 +935,7 @@ class ConfigDrivenIdeSetup {
930
935
  // Exact source equality is the only proof that a source-backed file is
931
936
  // unchanged. Without a matching source, both current and legacy tiers
932
937
  // may contain customizations and must be backed up before removal.
933
- const generated = sourceContent !== undefined && content === sourceContent;
938
+ const generated = sourceContent !== undefined && sameExceptModel(content, sourceContent);
934
939
  if (!generated) {
935
940
  const backupPath = await this._backupSubagentFile(filePath, options, report);
936
941
  if (!backupPath) {