From cdfc2a5ac350c6ac4fa6329561d8b19cf03e2659 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 6 Apr 2026 21:55:20 +0200 Subject: [PATCH 01/20] feat: Local model override --- plugins/maestro/src/config/agent-modes.json | 74 ++++++++++++++++ scripts/setup-models.js | 97 +++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 plugins/maestro/src/config/agent-modes.json create mode 100755 scripts/setup-models.js diff --git a/plugins/maestro/src/config/agent-modes.json b/plugins/maestro/src/config/agent-modes.json new file mode 100644 index 00000000..0802437c --- /dev/null +++ b/plugins/maestro/src/config/agent-modes.json @@ -0,0 +1,74 @@ +{ + "quality": { + "accessibility_specialist": "gemini-3-flash-preview", + "analytics_engineer": "gemini-3-flash-preview", + "api_designer": "gemini-3-flash-preview", + "architect": "gemini-3-flash-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3-flash-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3-flash-preview", + "copywriter": "gemini-3-flash-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3-flash-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3-flash-preview", + "i18n_specialist": "gemini-3-flash-preview", + "performance_engineer": "gemini-3-flash-preview", + "product_manager": "gemini-3-flash-preview", + "refactor": "gemini-3-flash-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3-flash-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview" + }, + "balanced": { + "accessibility_specialist": "gemini-3-flash-preview", + "analytics_engineer": "gemini-3-flash-preview", + "api_designer": "gemini-3-flash-preview", + "architect": "gemini-3-flash-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3-flash-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3-flash-preview", + "copywriter": "gemini-3-flash-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3-flash-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3-flash-preview", + "i18n_specialist": "gemini-3-flash-preview", + "performance_engineer": "gemini-3-flash-preview", + "product_manager": "gemini-3-flash-preview", + "refactor": "gemini-3-flash-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3-flash-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview" + }, + "economic": { + "accessibility_specialist": "gemini-3-flash-preview", + "analytics_engineer": "gemini-3-flash-preview", + "api_designer": "gemini-3-flash-preview", + "architect": "gemini-3-flash-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3-flash-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3-flash-preview", + "copywriter": "gemini-3-flash-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3-flash-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3-flash-preview", + "i18n_specialist": "gemini-3-flash-preview", + "performance_engineer": "gemini-3-flash-preview", + "product_manager": "gemini-3-flash-preview", + "refactor": "gemini-3-flash-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3-flash-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview" + } +} diff --git a/scripts/setup-models.js b/scripts/setup-models.js new file mode 100755 index 00000000..90c54cf8 --- /dev/null +++ b/scripts/setup-models.js @@ -0,0 +1,97 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { atomicWriteSync } = require('../lib/core/atomic-write'); +const { resolveProjectRoot } = require('../lib/core/project-root-resolver'); + +/** + * Script to handle project-specific model selection for Maestro subagents. + * Checks for .gemini/settings.json and prompts for a choice of 3 modes if missing. + */ + +async function main() { + const projectRoot = resolveProjectRoot(); + const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); + + if (fs.existsSync(settingsPath)) { + // Already configured + return; + } + + const mode = process.argv[2]; + if (!mode) { + // If no mode is provided, we just exit. + // The orchestrator is responsible for providing the mode. + return; + } + + // Handle "skip" mode which only enables agents without overrides + if (mode === 'skip') { + const settings = { + experimental: { + enableAgents: true + } + }; + try { + atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); + console.log('Maestro initialized with default model inheritance.'); + console.log(`Settings saved to ${settingsPath}`); + } catch (err) { + console.error('Failed to write settings.json:', err.message); + process.exit(1); + } + return; + } + + if (!['quality', 'balanced', 'economic'].includes(mode)) { + console.error(`Invalid mode: ${mode}`); + process.exit(1); + } + + // Resolve the extension path to read the mode mapping + const extensionRoot = process.env.MAESTRO_EXTENSION_PATH || path.resolve(__dirname, '..'); + const modesPath = path.join(extensionRoot, 'lib', 'config', 'agent-modes.json'); + + let modes; + try { + modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); + } catch (err) { + console.error('Failed to read agent-modes.json:', err.message); + process.exit(1); + } + + const mapping = modes[mode]; + if (!mapping) { + console.error(`Unknown mode: ${mode}`); + process.exit(1); + } + + // Prepare the settings.json content + const settings = { + experimental: { + enableAgents: true + }, + agents: { + overrides: {} + } + }; + + for (const [agent, model] of Object.entries(mapping)) { + settings.agents.overrides[agent] = { + model: model + }; + } + + try { + atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); + console.log(`Successfully configured Maestro with "${mode}" mode.`); + console.log(`Settings saved to ${settingsPath}`); + } catch (err) { + console.error('Failed to write settings.json:', err.message); + process.exit(1); + } +} + +main(); From 3c2f62513188cf823a8dbead5d886bc6ea659391 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 6 Apr 2026 22:18:09 +0200 Subject: [PATCH 02/20] Introduce setup_models MCP --- .../src/references/orchestration-steps.md | 100 ++++++++++-------- scripts/setup-models.js | 97 ----------------- 2 files changed, 54 insertions(+), 143 deletions(-) delete mode 100755 scripts/setup-models.js diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index e6f79e3b..f81a1ac8 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -2,19 +2,27 @@ STARTUP (Turn 1 — tool calls only, no text output) 0. If get_runtime_context appears in your available tools, call it. Carry the returned mappings (tool names, agent dispatch syntax, MCP prefix, paths) through the entire session. If unavailable, use the fallback mappings in the entry-point skill preamble. 1. Call resolve_settings. 2. Call initialize_workspace with resolved state_dir. - 3. Call get_session_status — if active, present status and offer resume/archive. - 4. Call assess_task_complexity. - 5. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. - 6. STOP. Turn 1 is ONLY steps 1-5. No text, no design questions, no file reads. + 3. Local Settings Check: + - Check for the existence of `.gemini/settings.json` in the current working directory. + - If it's missing, use `ask_user` with `type: 'choice'` to prompt for operating mode: + - **Quality**: Higher accuracy, higher cost + - **Balanced**: Balanced performance and cost + - **Economic**: Lowest cost, lower performance + - After selection, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. + - Continue to Step 4. + 4. Call get_session_status — if active, present status and offer resume/archive. + 5. Call assess_task_complexity. + 6. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. + 7. STOP. Turn 1 is ONLY steps 1-6. No text, no design questions, no file reads. CLASSIFICATION (Turn 2) - 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 13, 15, 20). - 8. Classify task as simple/medium/complex. Present classification with rationale. - 9. Route: simple → Express (step 31). Medium/complex → continue to step 10. + 8. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 14, 16, 21). + 9. Classify task as simple/medium/complex. Present classification with rationale. +10. Route: simple → Express (step 32). Medium/complex → continue to step 11. DESIGN (Phase 1) -10. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. -11. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: +11. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. +12. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: - Design depth selector (first design question) - Repository grounding (for existing codebases, skip for greenfield) - One question at a time via user prompt @@ -31,51 +39,51 @@ DESIGN (Phase 1) WRONG: user requests "fan site" → options include React, Next.js, Astro CORRECT: user requests "fan site" → recommended option is vanilla HTML/CSS/JS -12. Present design sections one at a time, per the design-dialogue skill's convergence protocol. +13. Present design sections one at a time, per the design-dialogue skill's convergence protocol. Each section must be presented individually and approved via user prompt before proceeding to the next. Do NOT present the full design as a single block. Quick depth may combine sections. Standard/Deep MUST validate individually. -13. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). -14. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. +14. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). +15. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. PLANNING (Phase 2) -15. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. -16. Call validate_plan with the generated plan and task_complexity. +16. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. +17. Call validate_plan with the generated plan and task_complexity. You MUST call validate_plan BEFORE presenting the plan for approval. Do NOT - present the plan, write it to state_dir, or proceed to step 17 without first + present the plan, write it to state_dir, or proceed to step 18 without first calling validate_plan and resolving any error-severity violations. validate_plan enforces server-side: phase count limits, dependency cycles, unknown agents, file ownership conflicts, and agent-deliverable compatibility (read-only agents cannot be assigned to file-creating phases). If it returns violations with severity "error", fix them in the plan and re-validate. -17. Present plan for user approval (Approve / Revise / Abort via user prompt). -18. Write approved implementation plan to /plans/. +18. Present plan for user approval (Approve / Revise / Abort via user prompt). +19. Write approved implementation plan to /plans/. EXECUTION SETUP (Phase 3 — pre-delegation) -19. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. +20. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. Present ONLY "Parallel" and "Sequential" as execution mode options. Do NOT present "Ask" as a user-facing choice — "ask" is a setting value that means "prompt the user", not an execution mode the user selects. -20. Call `get_skill_content` with resources: ["session-management", "session-state"]. -21. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. -22. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. +21. Call `get_skill_content` with resources: ["session-management", "session-state"]. +22. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. +23. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. EXECUTION (Phase 3 — delegation loop) -23. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. +24. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. Dispatch by calling the agent's registered tool directly. Do NOT use the built-in generalist tool or invoke agents by bare name. Each Maestro agent carries specialized methodology, tool restrictions, temperature, and turn limits from its frontmatter that the generalist ignores. -24. After each agent returns, parse Task Report + Downstream Context from response. -25. Call transition_phase to persist results. +25. After each agent returns, parse Task Report + Downstream Context from response. +26. Call transition_phase to persist results. For parallel batches: call transition_phase INDIVIDUALLY for EVERY completed phase in the batch. The MCP tool writes files_created, files_modified, @@ -85,42 +93,42 @@ EXECUTION (Phase 3 — delegation loop) merge all agents' files into one call — the archive attributes files per phase, so empty payloads mean lost traceability. -26. Repeat steps 23-25 until all phases complete. +27. Repeat steps 24-26 until all phases complete. COMPLETION (Phase 4) -27. Call `get_skill_content` with resources: ["code-review"]. -28. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. +28. Call `get_skill_content` with resources: ["code-review"]. +29. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. If Critical/Major findings: re-delegate to the implementing agent to fix. The orchestrator MUST NOT write code directly. -29. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. -30. Present final summary with files changed, phase outcomes, and next steps. +30. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. +31. Present final summary with files changed, phase outcomes, and next steps. RECOVERY (referenced from any step on user request) If the user says the flow moved too fast: return to the most recent unanswered approval gate. If the user asks for implementation before approval: remind them Maestro requires approval first. If the user asks to skip execution-mode: remind them parallel/sequential is required unless MAESTRO_EXECUTION_MODE pins it. If an answer invalidates a prior choice: restate the updated assumption and re-run the relevant gate. -If delegation collapses to parent session without fallback approval: return to step 19 or re-scope the child-agent work packages. +If delegation collapses to parent session without fallback approval: return to step 20 or re-scope the child-agent work packages. -EXPRESS WORKFLOW (simple tasks only — jumped to from step 9) +EXPRESS WORKFLOW (simple tasks only — jumped to from step 10) EXPRESS MODE GATE BYPASS: Express bypasses the execution-mode gate entirely. Express always dispatches sequentially. Do NOT prompt for parallel/sequential. EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, archive_session) are unavailable, fall back to direct file writes on /state/active-session.md. -31. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. +32. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 11. Express sessions MUST have exactly one implementation phase with exactly one agent. -32. Ask 1-2 clarifying questions from Area 1 only. +33. Ask 1-2 clarifying questions from Area 1 only. Each question MUST use the user prompt tool (not plain text). Use the choose variant with 2-4 options where possible. Do NOT ask questions as plain text in the model response — the user prompt tool is the only input mechanism. -33. Present structured Express brief as plain text, then ask for approval. +34. Present structured Express brief as plain text, then ask for approval. The brief MUST be plain text output in the model response. The approval MUST be a SEPARATE user prompt tool call — not embedded in the @@ -128,14 +136,14 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch These are two distinct actions: first emit the brief as text, then call the user prompt tool for approval. Do NOT combine them into one text block. -34. On approval, create session with workflow_mode: "express", exactly 1 phase. - On rejection, revise. On second rejection, escalate to Standard → step 10. -35. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. -36. Delegate to the assigned agent. +35. On approval, create session with workflow_mode: "express", exactly 1 phase. + On rejection, revise. On second rejection, escalate to Standard → step 11. +36. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. +37. Delegate to the assigned agent. - Same dispatch rule as step 23: call agent by registered tool name, not generalist. + Same dispatch rule as step 24: call agent by registered tool name, not generalist. -37. Parse Task Report from the agent's response. Call transition_phase to persist results. +38. Parse Task Report from the agent's response. Call transition_phase to persist results. You MUST call transition_phase after the implementing agent returns. Extract files_created, files_modified, files_deleted, and downstream_context from the @@ -143,15 +151,15 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch state has no record of what was delivered. Do NOT skip to code review or archive without calling transition_phase first. -38. Delegate to the code reviewer agent. +39. Delegate to the code reviewer agent. If Critical/Major findings: re-delegate to implementing agent (1 retry). Orchestrator MUST NOT write code directly. If retry fails, escalate to user. -39. Call archive_session. -40. Present summary. +40. Call archive_session. +41. Present summary. EXPRESS RESUME (when resuming an Express session from get_session_status) -If phase is pending: re-generate and present brief (step 33). On approval, proceed to delegation (step 36). -If phase is in_progress: re-delegate with same scope (step 36). -If phase is completed but session is in_progress: run code review (step 38), then archive (step 39). +If phase is pending: re-generate and present brief (step 34). On approval, proceed to delegation (step 37). +If phase is in_progress: re-delegate with same scope (step 37). +If phase is completed but session is in_progress: run code review (step 39), then archive (step 40). diff --git a/scripts/setup-models.js b/scripts/setup-models.js deleted file mode 100755 index 90c54cf8..00000000 --- a/scripts/setup-models.js +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env node -'use strict'; - -const fs = require('fs'); -const path = require('path'); -const { atomicWriteSync } = require('../lib/core/atomic-write'); -const { resolveProjectRoot } = require('../lib/core/project-root-resolver'); - -/** - * Script to handle project-specific model selection for Maestro subagents. - * Checks for .gemini/settings.json and prompts for a choice of 3 modes if missing. - */ - -async function main() { - const projectRoot = resolveProjectRoot(); - const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); - - if (fs.existsSync(settingsPath)) { - // Already configured - return; - } - - const mode = process.argv[2]; - if (!mode) { - // If no mode is provided, we just exit. - // The orchestrator is responsible for providing the mode. - return; - } - - // Handle "skip" mode which only enables agents without overrides - if (mode === 'skip') { - const settings = { - experimental: { - enableAgents: true - } - }; - try { - atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); - console.log('Maestro initialized with default model inheritance.'); - console.log(`Settings saved to ${settingsPath}`); - } catch (err) { - console.error('Failed to write settings.json:', err.message); - process.exit(1); - } - return; - } - - if (!['quality', 'balanced', 'economic'].includes(mode)) { - console.error(`Invalid mode: ${mode}`); - process.exit(1); - } - - // Resolve the extension path to read the mode mapping - const extensionRoot = process.env.MAESTRO_EXTENSION_PATH || path.resolve(__dirname, '..'); - const modesPath = path.join(extensionRoot, 'lib', 'config', 'agent-modes.json'); - - let modes; - try { - modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); - } catch (err) { - console.error('Failed to read agent-modes.json:', err.message); - process.exit(1); - } - - const mapping = modes[mode]; - if (!mapping) { - console.error(`Unknown mode: ${mode}`); - process.exit(1); - } - - // Prepare the settings.json content - const settings = { - experimental: { - enableAgents: true - }, - agents: { - overrides: {} - } - }; - - for (const [agent, model] of Object.entries(mapping)) { - settings.agents.overrides[agent] = { - model: model - }; - } - - try { - atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); - console.log(`Successfully configured Maestro with "${mode}" mode.`); - console.log(`Settings saved to ${settingsPath}`); - } catch (err) { - console.error('Failed to write settings.json:', err.message); - process.exit(1); - } -} - -main(); From 7509f0a905e838c5a25dfe080230289f1804c497 Mon Sep 17 00:00:00 2001 From: sea212 Date: Mon, 6 Apr 2026 22:59:27 +0200 Subject: [PATCH 03/20] Update default agent models per mode --- plugins/maestro/src/config/agent-modes.json | 76 ++++++++++----------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/plugins/maestro/src/config/agent-modes.json b/plugins/maestro/src/config/agent-modes.json index 0802437c..b10072da 100644 --- a/plugins/maestro/src/config/agent-modes.json +++ b/plugins/maestro/src/config/agent-modes.json @@ -1,46 +1,46 @@ { "quality": { - "accessibility_specialist": "gemini-3-flash-preview", - "analytics_engineer": "gemini-3-flash-preview", - "api_designer": "gemini-3-flash-preview", - "architect": "gemini-3-flash-preview", - "code_reviewer": "gemini-3-flash-preview", + "accessibility_specialist": "gemini-3.1-pro-preview", + "analytics_engineer": "gemini-3.1-pro-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", + "code_reviewer": "gemini-3.1-pro-preview", "coder": "gemini-3-flash-preview", - "compliance_reviewer": "gemini-3-flash-preview", - "content_strategist": "gemini-3-flash-preview", + "compliance_reviewer": "gemini-3.1-pro-preview", + "content_strategist": "gemini-3.1-pro-preview", "copywriter": "gemini-3-flash-preview", - "data_engineer": "gemini-3-flash-preview", - "debugger": "gemini-3-flash-preview", - "design_system_engineer": "gemini-3-flash-preview", - "devops_engineer": "gemini-3-flash-preview", - "i18n_specialist": "gemini-3-flash-preview", - "performance_engineer": "gemini-3-flash-preview", - "product_manager": "gemini-3-flash-preview", + "data_engineer": "gemini-3.1-pro-preview", + "debugger": "gemini-3.1-pro-preview", + "design_system_engineer": "gemini-3.1-pro-preview", + "devops_engineer": "gemini-3.1-pro-preview", + "i18n_specialist": "gemini-3.1-pro-preview", + "performance_engineer": "gemini-3.1-pro-preview", + "product_manager": "gemini-3.1-pro-preview", "refactor": "gemini-3-flash-preview", - "security_engineer": "gemini-3-flash-preview", - "seo_specialist": "gemini-3-flash-preview", + "security_engineer": "gemini-3.1-pro-preview", + "seo_specialist": "gemini-3.1-pro-preview", "technical_writer": "gemini-3-flash-preview", - "tester": "gemini-3-flash-preview", - "ux_designer": "gemini-3-flash-preview" + "tester": "gemini-3.1-pro-preview", + "ux_designer": "gemini-3.1-pro-preview" }, "balanced": { "accessibility_specialist": "gemini-3-flash-preview", "analytics_engineer": "gemini-3-flash-preview", - "api_designer": "gemini-3-flash-preview", - "architect": "gemini-3-flash-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", "code_reviewer": "gemini-3-flash-preview", - "coder": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", "compliance_reviewer": "gemini-3-flash-preview", "content_strategist": "gemini-3-flash-preview", - "copywriter": "gemini-3-flash-preview", + "copywriter": "gemini-3.1-flash-lite-preview", "data_engineer": "gemini-3-flash-preview", - "debugger": "gemini-3-flash-preview", + "debugger": "gemini-3.1-pro-preview", "design_system_engineer": "gemini-3-flash-preview", "devops_engineer": "gemini-3-flash-preview", "i18n_specialist": "gemini-3-flash-preview", "performance_engineer": "gemini-3-flash-preview", - "product_manager": "gemini-3-flash-preview", - "refactor": "gemini-3-flash-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-flash-lite-preview", "security_engineer": "gemini-3-flash-preview", "seo_specialist": "gemini-3-flash-preview", "technical_writer": "gemini-3-flash-preview", @@ -48,26 +48,26 @@ "ux_designer": "gemini-3-flash-preview" }, "economic": { - "accessibility_specialist": "gemini-3-flash-preview", - "analytics_engineer": "gemini-3-flash-preview", + "accessibility_specialist": "gemini-3.1-flash-lite-preview", + "analytics_engineer": "gemini-3.1-flash-lite-preview", "api_designer": "gemini-3-flash-preview", - "architect": "gemini-3-flash-preview", + "architect": "gemini-3.1-pro-preview", "code_reviewer": "gemini-3-flash-preview", - "coder": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", "compliance_reviewer": "gemini-3-flash-preview", - "content_strategist": "gemini-3-flash-preview", - "copywriter": "gemini-3-flash-preview", + "content_strategist": "gemini-3.1-flash-lite-preview", + "copywriter": "gemini-3.1-flash-lite-preview", "data_engineer": "gemini-3-flash-preview", "debugger": "gemini-3-flash-preview", "design_system_engineer": "gemini-3-flash-preview", - "devops_engineer": "gemini-3-flash-preview", - "i18n_specialist": "gemini-3-flash-preview", - "performance_engineer": "gemini-3-flash-preview", - "product_manager": "gemini-3-flash-preview", - "refactor": "gemini-3-flash-preview", + "devops_engineer": "gemini-3.1-flash-lite-preview", + "i18n_specialist": "gemini-3.1-flash-lite-preview", + "performance_engineer": "gemini-3.1-flash-lite-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-flash-lite-preview", "security_engineer": "gemini-3-flash-preview", - "seo_specialist": "gemini-3-flash-preview", - "technical_writer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3.1-flash-lite-preview", + "technical_writer": "gemini-3.1-flash-lite-preview", "tester": "gemini-3-flash-preview", "ux_designer": "gemini-3-flash-preview" } From 01cefaa36a9fe59eff577f2d235ca65c3e82ce95 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 14:52:31 +0200 Subject: [PATCH 04/20] chore: add .worktrees to .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d164e1ab..ce8959b2 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,4 @@ temp/ docs/maestro/ docs/superpowers/ hooks/permissions.json +.worktrees From 024b9926b1a1981c07bd63bbc049ee83a80cfd4b Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 15:05:52 +0200 Subject: [PATCH 05/20] fix: Request gemini restart to activate settings.json --- plugins/maestro/src/references/orchestration-steps.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index f81a1ac8..acdaef06 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -9,7 +9,8 @@ STARTUP (Turn 1 — tool calls only, no text output) - **Balanced**: Balanced performance and cost - **Economic**: Lowest cost, lower performance - After selection, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. - - Continue to Step 4. + - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." + - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. 4. Call get_session_status — if active, present status and offer resume/archive. 5. Call assess_task_complexity. 6. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. From f3ad4dfa6757b573d97bcf3b3d0b55c95cd9ff27 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 15:06:00 +0200 Subject: [PATCH 06/20] feat: add codebase_investigator to subagent model mappings --- plugins/maestro/src/config/agent-modes.json | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/plugins/maestro/src/config/agent-modes.json b/plugins/maestro/src/config/agent-modes.json index b10072da..18969577 100644 --- a/plugins/maestro/src/config/agent-modes.json +++ b/plugins/maestro/src/config/agent-modes.json @@ -21,7 +21,8 @@ "seo_specialist": "gemini-3.1-pro-preview", "technical_writer": "gemini-3-flash-preview", "tester": "gemini-3.1-pro-preview", - "ux_designer": "gemini-3.1-pro-preview" + "ux_designer": "gemini-3.1-pro-preview", + "codebase_investigator": "gemini-3.1-pro-preview" }, "balanced": { "accessibility_specialist": "gemini-3-flash-preview", @@ -45,7 +46,8 @@ "seo_specialist": "gemini-3-flash-preview", "technical_writer": "gemini-3-flash-preview", "tester": "gemini-3-flash-preview", - "ux_designer": "gemini-3-flash-preview" + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3-flash-preview" }, "economic": { "accessibility_specialist": "gemini-3.1-flash-lite-preview", @@ -69,6 +71,7 @@ "seo_specialist": "gemini-3.1-flash-lite-preview", "technical_writer": "gemini-3.1-flash-lite-preview", "tester": "gemini-3-flash-preview", - "ux_designer": "gemini-3-flash-preview" + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3.1-flash-lite-preview" } } From 7f03e5543b1c404aaa330873aa6535f0af92cb20 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 15:00:32 +0200 Subject: [PATCH 07/20] feat: add 'Skip' option to subagent model config prompt --- .../maestro/src/references/orchestration-steps.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index acdaef06..f12eda75 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -5,12 +5,14 @@ STARTUP (Turn 1 — tool calls only, no text output) 3. Local Settings Check: - Check for the existence of `.gemini/settings.json` in the current working directory. - If it's missing, use `ask_user` with `type: 'choice'` to prompt for operating mode: - - **Quality**: Higher accuracy, higher cost - - **Balanced**: Balanced performance and cost - - **Economic**: Lowest cost, lower performance - - After selection, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. - - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." - - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. + - **Quality**: Higher accuracy, higher cost + - **Balanced**: Balanced performance and cost + - **Economic**: Lowest cost, lower performance + - **Skip**: Skip local model configuration (no settings.json will be created) + - After selection: + - If **Skip** was selected, do NOT call `setup_models`. + - Otherwise, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. + - Continue to Step 4. 4. Call get_session_status — if active, present status and offer resume/archive. 5. Call assess_task_complexity. 6. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. From ece5ee1df9f1f8cdd26ae85b5c02f720bb5fb703 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 16:05:58 +0200 Subject: [PATCH 08/20] fix: Merge mistake --- plugins/maestro/src/references/orchestration-steps.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index f12eda75..6214fed7 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -12,7 +12,8 @@ STARTUP (Turn 1 — tool calls only, no text output) - After selection: - If **Skip** was selected, do NOT call `setup_models`. - Otherwise, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. - - Continue to Step 4. + - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." + - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. 4. Call get_session_status — if active, present status and offer resume/archive. 5. Call assess_task_complexity. 6. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. From f6e794f29c99fbbc57bddb2e6804cf329c6971fa Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 16:33:05 +0200 Subject: [PATCH 09/20] ref: Use GEMINI.md for gemini model setup instructions --- GEMINI.md | 11 ++ .../src/references/orchestration-steps.md | 104 ++++++++---------- 2 files changed, 57 insertions(+), 58 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index 4d3051f9..dc84b92f 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -29,6 +29,17 @@ Before running orchestration commands: - If `initialize_workspace` appears in your available tools, call it with the resolved `state_dir`. This is the preferred path. - Otherwise, run `node ${extensionPath}/src/scripts/ensure-workspace.js ` as fallback. - Stop and report if either fails. +5. Subagent model assignment: + - Use `ask_user` with `type: 'choice'` to prompt for operating mode: + - **Quality**: Higher accuracy, higher cost + - **Balanced**: Balanced performance and cost + - **Economic**: Lowest cost, lower performance + - **Skip**: Use existing configuration if available, otherwise Gemini client decides + - After selection: + - If **Skip** was selected, do NOT call `setup_models`. + - Otherwise, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. + - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." + - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. ## Gemini CLI Integration Constraints diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index 6214fed7..e6f79e3b 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -2,31 +2,19 @@ STARTUP (Turn 1 — tool calls only, no text output) 0. If get_runtime_context appears in your available tools, call it. Carry the returned mappings (tool names, agent dispatch syntax, MCP prefix, paths) through the entire session. If unavailable, use the fallback mappings in the entry-point skill preamble. 1. Call resolve_settings. 2. Call initialize_workspace with resolved state_dir. - 3. Local Settings Check: - - Check for the existence of `.gemini/settings.json` in the current working directory. - - If it's missing, use `ask_user` with `type: 'choice'` to prompt for operating mode: - - **Quality**: Higher accuracy, higher cost - - **Balanced**: Balanced performance and cost - - **Economic**: Lowest cost, lower performance - - **Skip**: Skip local model configuration (no settings.json will be created) - - After selection: - - If **Skip** was selected, do NOT call `setup_models`. - - Otherwise, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. - - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." - - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. - 4. Call get_session_status — if active, present status and offer resume/archive. - 5. Call assess_task_complexity. - 6. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. - 7. STOP. Turn 1 is ONLY steps 1-6. No text, no design questions, no file reads. + 3. Call get_session_status — if active, present status and offer resume/archive. + 4. Call assess_task_complexity. + 5. Parse MAESTRO_DISABLED_AGENTS from resolved settings. Exclude listed agents from all planning. + 6. STOP. Turn 1 is ONLY steps 1-5. No text, no design questions, no file reads. CLASSIFICATION (Turn 2) - 8. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 14, 16, 21). - 9. Classify task as simple/medium/complex. Present classification with rationale. -10. Route: simple → Express (step 32). Medium/complex → continue to step 11. + 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 13, 15, 20). + 8. Classify task as simple/medium/complex. Present classification with rationale. + 9. Route: simple → Express (step 31). Medium/complex → continue to step 10. DESIGN (Phase 1) -11. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. -12. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: +10. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. +11. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: - Design depth selector (first design question) - Repository grounding (for existing codebases, skip for greenfield) - One question at a time via user prompt @@ -43,51 +31,51 @@ DESIGN (Phase 1) WRONG: user requests "fan site" → options include React, Next.js, Astro CORRECT: user requests "fan site" → recommended option is vanilla HTML/CSS/JS -13. Present design sections one at a time, per the design-dialogue skill's convergence protocol. +12. Present design sections one at a time, per the design-dialogue skill's convergence protocol. Each section must be presented individually and approved via user prompt before proceeding to the next. Do NOT present the full design as a single block. Quick depth may combine sections. Standard/Deep MUST validate individually. -14. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). -15. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. +13. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). +14. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. PLANNING (Phase 2) -16. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. -17. Call validate_plan with the generated plan and task_complexity. +15. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. +16. Call validate_plan with the generated plan and task_complexity. You MUST call validate_plan BEFORE presenting the plan for approval. Do NOT - present the plan, write it to state_dir, or proceed to step 18 without first + present the plan, write it to state_dir, or proceed to step 17 without first calling validate_plan and resolving any error-severity violations. validate_plan enforces server-side: phase count limits, dependency cycles, unknown agents, file ownership conflicts, and agent-deliverable compatibility (read-only agents cannot be assigned to file-creating phases). If it returns violations with severity "error", fix them in the plan and re-validate. -18. Present plan for user approval (Approve / Revise / Abort via user prompt). -19. Write approved implementation plan to /plans/. +17. Present plan for user approval (Approve / Revise / Abort via user prompt). +18. Write approved implementation plan to /plans/. EXECUTION SETUP (Phase 3 — pre-delegation) -20. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. +19. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. Present ONLY "Parallel" and "Sequential" as execution mode options. Do NOT present "Ask" as a user-facing choice — "ask" is a setting value that means "prompt the user", not an execution mode the user selects. -21. Call `get_skill_content` with resources: ["session-management", "session-state"]. -22. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. -23. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. +20. Call `get_skill_content` with resources: ["session-management", "session-state"]. +21. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. +22. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. EXECUTION (Phase 3 — delegation loop) -24. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. +23. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. Dispatch by calling the agent's registered tool directly. Do NOT use the built-in generalist tool or invoke agents by bare name. Each Maestro agent carries specialized methodology, tool restrictions, temperature, and turn limits from its frontmatter that the generalist ignores. -25. After each agent returns, parse Task Report + Downstream Context from response. -26. Call transition_phase to persist results. +24. After each agent returns, parse Task Report + Downstream Context from response. +25. Call transition_phase to persist results. For parallel batches: call transition_phase INDIVIDUALLY for EVERY completed phase in the batch. The MCP tool writes files_created, files_modified, @@ -97,42 +85,42 @@ EXECUTION (Phase 3 — delegation loop) merge all agents' files into one call — the archive attributes files per phase, so empty payloads mean lost traceability. -27. Repeat steps 24-26 until all phases complete. +26. Repeat steps 23-25 until all phases complete. COMPLETION (Phase 4) -28. Call `get_skill_content` with resources: ["code-review"]. -29. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. +27. Call `get_skill_content` with resources: ["code-review"]. +28. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. If Critical/Major findings: re-delegate to the implementing agent to fix. The orchestrator MUST NOT write code directly. -30. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. -31. Present final summary with files changed, phase outcomes, and next steps. +29. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. +30. Present final summary with files changed, phase outcomes, and next steps. RECOVERY (referenced from any step on user request) If the user says the flow moved too fast: return to the most recent unanswered approval gate. If the user asks for implementation before approval: remind them Maestro requires approval first. If the user asks to skip execution-mode: remind them parallel/sequential is required unless MAESTRO_EXECUTION_MODE pins it. If an answer invalidates a prior choice: restate the updated assumption and re-run the relevant gate. -If delegation collapses to parent session without fallback approval: return to step 20 or re-scope the child-agent work packages. +If delegation collapses to parent session without fallback approval: return to step 19 or re-scope the child-agent work packages. -EXPRESS WORKFLOW (simple tasks only — jumped to from step 10) +EXPRESS WORKFLOW (simple tasks only — jumped to from step 9) EXPRESS MODE GATE BYPASS: Express bypasses the execution-mode gate entirely. Express always dispatches sequentially. Do NOT prompt for parallel/sequential. EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, archive_session) are unavailable, fall back to direct file writes on /state/active-session.md. -32. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 11. +31. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. Express sessions MUST have exactly one implementation phase with exactly one agent. -33. Ask 1-2 clarifying questions from Area 1 only. +32. Ask 1-2 clarifying questions from Area 1 only. Each question MUST use the user prompt tool (not plain text). Use the choose variant with 2-4 options where possible. Do NOT ask questions as plain text in the model response — the user prompt tool is the only input mechanism. -34. Present structured Express brief as plain text, then ask for approval. +33. Present structured Express brief as plain text, then ask for approval. The brief MUST be plain text output in the model response. The approval MUST be a SEPARATE user prompt tool call — not embedded in the @@ -140,14 +128,14 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch These are two distinct actions: first emit the brief as text, then call the user prompt tool for approval. Do NOT combine them into one text block. -35. On approval, create session with workflow_mode: "express", exactly 1 phase. - On rejection, revise. On second rejection, escalate to Standard → step 11. -36. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. -37. Delegate to the assigned agent. +34. On approval, create session with workflow_mode: "express", exactly 1 phase. + On rejection, revise. On second rejection, escalate to Standard → step 10. +35. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. +36. Delegate to the assigned agent. - Same dispatch rule as step 24: call agent by registered tool name, not generalist. + Same dispatch rule as step 23: call agent by registered tool name, not generalist. -38. Parse Task Report from the agent's response. Call transition_phase to persist results. +37. Parse Task Report from the agent's response. Call transition_phase to persist results. You MUST call transition_phase after the implementing agent returns. Extract files_created, files_modified, files_deleted, and downstream_context from the @@ -155,15 +143,15 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch state has no record of what was delivered. Do NOT skip to code review or archive without calling transition_phase first. -39. Delegate to the code reviewer agent. +38. Delegate to the code reviewer agent. If Critical/Major findings: re-delegate to implementing agent (1 retry). Orchestrator MUST NOT write code directly. If retry fails, escalate to user. -40. Call archive_session. -41. Present summary. +39. Call archive_session. +40. Present summary. EXPRESS RESUME (when resuming an Express session from get_session_status) -If phase is pending: re-generate and present brief (step 34). On approval, proceed to delegation (step 37). -If phase is in_progress: re-delegate with same scope (step 37). -If phase is completed but session is in_progress: run code review (step 39), then archive (step 40). +If phase is pending: re-generate and present brief (step 33). On approval, proceed to delegation (step 36). +If phase is in_progress: re-delegate with same scope (step 36). +If phase is completed but session is in_progress: run code review (step 38), then archive (step 39). From f078b1f489caa4533310330f83108469614e4a86 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 17:04:58 +0200 Subject: [PATCH 10/20] fix: Move agent-modes.json in Gemini config folder --- {plugins/maestro/src => src}/config/agent-modes.json | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {plugins/maestro/src => src}/config/agent-modes.json (100%) diff --git a/plugins/maestro/src/config/agent-modes.json b/src/config/agent-modes.json similarity index 100% rename from plugins/maestro/src/config/agent-modes.json rename to src/config/agent-modes.json From 6a6f2af6eec7a029b4707e51b1205fe2b9bffb97 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 17:22:46 +0200 Subject: [PATCH 11/20] feat: Add setup_models MCP --- src/mcp/handlers/setup-models.js | 78 +++++++++++++++++++++++++++ src/mcp/tool-packs/workspace/index.js | 18 +++++++ 2 files changed, 96 insertions(+) create mode 100644 src/mcp/handlers/setup-models.js diff --git a/src/mcp/handlers/setup-models.js b/src/mcp/handlers/setup-models.js new file mode 100644 index 00000000..0a059043 --- /dev/null +++ b/src/mcp/handlers/setup-models.js @@ -0,0 +1,78 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { atomicWriteSync } = require('../../core/atomic-write'); + +/** + * Handle setup_models tool call. + * + * @param {Object} params - Tool arguments. + * @param {string} params.mode - The operating mode (quality, balanced, economic, skip). + * @param {string} projectRoot - The current project root. + * @returns {Promise} - Result of the operation. + */ +async function handleSetupModels(params, projectRoot) { + const mode = params.mode; + + if (mode === 'skip') { + return { status: 'skipped_model_setup' }; + } + + if (!['quality', 'balanced', 'economic'].includes(mode)) { + throw new Error(`Invalid mode: ${mode}`); + } + + const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); + + const { resolveExtensionRoot } = require('../utils/extension-root'); + const extensionRoot = resolveExtensionRoot(); + const modesPath = path.join(extensionRoot, 'src', 'config', 'agent-modes.json'); + + let modes; + try { + modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); + } catch (err) { + throw new Error(`Failed to read agent-modes.json: ${err.message}`); + } + + const mapping = modes[mode]; + if (!mapping) { + throw new Error(`Unknown mode: ${mode}`); + } + + let settings = {}; + if (fs.existsSync(settingsPath)) { + try { + const content = fs.readFileSync(settingsPath, 'utf8'); + settings = JSON.parse(content || '{}'); + } catch (err) { + throw new Error(`Existing .gemini/settings.json is corrupted`); + } + } + + // Ensure experimental.enableAgents is true + settings.experimental = settings.experimental || {}; + settings.experimental.enableAgents = true; + + // Extend agents.overrides + settings.agents = settings.agents || {}; + settings.agents.overrides = settings.agents.overrides || {}; + + for (const [agent, model] of Object.entries(mapping)) { + settings.agents.overrides[agent] = { + modelConfig: { + model, + }, + }; + } + + // Preserve existing settings while applying overrides + atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); + + return { status: 'success', mode }; +} + +module.exports = { + handleSetupModels, +}; diff --git a/src/mcp/tool-packs/workspace/index.js b/src/mcp/tool-packs/workspace/index.js index f381d3d5..32f6ed9b 100644 --- a/src/mcp/tool-packs/workspace/index.js +++ b/src/mcp/tool-packs/workspace/index.js @@ -9,6 +9,7 @@ const { } = require('../../handlers/assess-task-complexity'); const { handleValidatePlan } = require('../../handlers/validate-plan'); const { handleResolveSettings } = require('../../handlers/resolve-settings'); +const { handleSetupModels } = require('../../handlers/setup-models'); function createToolPack() { return defineToolPack({ @@ -76,12 +77,29 @@ function createToolPack() { }, }, }, + { + name: 'setup_models', + description: + 'Configure Maestro subagent models in .gemini/settings.json based on selected mode.', + inputSchema: { + type: 'object', + properties: { + mode: { + type: 'string', + enum: ['quality', 'balanced', 'economic', 'skip'], + description: 'The operating mode to configure.', + }, + }, + required: ['mode'], + }, + }, ], handlers: { initialize_workspace: handleInitializeWorkspace, assess_task_complexity: handleAssessTaskComplexity, validate_plan: handleValidatePlan, resolve_settings: handleResolveSettings, + setup_models: handleSetupModels, }, }); } From 0b72579a6263f0f8eb006074e2df0fac0e19502c Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 21:23:53 +0200 Subject: [PATCH 12/20] ref: require() at top --- src/mcp/handlers/setup-models.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mcp/handlers/setup-models.js b/src/mcp/handlers/setup-models.js index 0a059043..861eb9e1 100644 --- a/src/mcp/handlers/setup-models.js +++ b/src/mcp/handlers/setup-models.js @@ -3,6 +3,7 @@ const fs = require('fs'); const path = require('path'); const { atomicWriteSync } = require('../../core/atomic-write'); +const { resolveExtensionRoot } = require('../utils/extension-root'); /** * Handle setup_models tool call. @@ -25,7 +26,6 @@ async function handleSetupModels(params, projectRoot) { const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); - const { resolveExtensionRoot } = require('../utils/extension-root'); const extensionRoot = resolveExtensionRoot(); const modesPath = path.join(extensionRoot, 'src', 'config', 'agent-modes.json'); From af74ccf613f5d6519d8ee077a01e5833f1c2049e Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 22:41:30 +0200 Subject: [PATCH 13/20] ref: Align model declaration with best practices --- GEMINI.md | 11 --- .../gemini/commands/maestro/orchestrate.toml | 3 +- claude/src/references/orchestration-steps.md | 78 ++++++++++--------- commands/maestro/orchestrate.toml | 4 +- .../gemini/commands/maestro/orchestrate.toml | 4 +- .../src/references/orchestration-steps.md | 78 ++++++++++--------- .../gemini/commands/maestro/orchestrate.toml | 4 +- src/references/orchestration-steps.md | 78 ++++++++++--------- 8 files changed, 131 insertions(+), 129 deletions(-) diff --git a/GEMINI.md b/GEMINI.md index dc84b92f..4d3051f9 100644 --- a/GEMINI.md +++ b/GEMINI.md @@ -29,17 +29,6 @@ Before running orchestration commands: - If `initialize_workspace` appears in your available tools, call it with the resolved `state_dir`. This is the preferred path. - Otherwise, run `node ${extensionPath}/src/scripts/ensure-workspace.js ` as fallback. - Stop and report if either fails. -5. Subagent model assignment: - - Use `ask_user` with `type: 'choice'` to prompt for operating mode: - - **Quality**: Higher accuracy, higher cost - - **Balanced**: Balanced performance and cost - - **Economic**: Lowest cost, lower performance - - **Skip**: Use existing configuration if available, otherwise Gemini client decides - - After selection: - - If **Skip** was selected, do NOT call `setup_models`. - - Otherwise, call the `setup_models` MCP tool with the `mode` parameter set to the selected mode to create the file with the appropriate agent overrides. - - **Halt Execution**: Inform the user: "A restart of the Gemini client is necessary to activate the subagent model configuration. Restart the client and resume the session. I'll be waiting here." - - **Wait for signal**: STOP here and wait for the user to restart and signal to continue. Do NOT proceed to Step 4 in this turn. ## Gemini CLI Integration Constraints diff --git a/claude/src/platforms/gemini/commands/maestro/orchestrate.toml b/claude/src/platforms/gemini/commands/maestro/orchestrate.toml index 24e80006..db5113f0 100644 --- a/claude/src/platforms/gemini/commands/maestro/orchestrate.toml +++ b/claude/src/platforms/gemini/commands/maestro/orchestrate.toml @@ -18,10 +18,11 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then restart." Offer to continue without Plan Mode using `ask_user` for approvals. | +| Enter Plan Mode | `enter_plan_mode` | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | +| Define Agent Models | No Action (NOOP) | ## Execute diff --git a/claude/src/references/orchestration-steps.md b/claude/src/references/orchestration-steps.md index e6f79e3b..959ed087 100644 --- a/claude/src/references/orchestration-steps.md +++ b/claude/src/references/orchestration-steps.md @@ -8,13 +8,14 @@ STARTUP (Turn 1 — tool calls only, no text output) 6. STOP. Turn 1 is ONLY steps 1-5. No text, no design questions, no file reads. CLASSIFICATION (Turn 2) - 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 13, 15, 20). + 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 14, 16, 21). 8. Classify task as simple/medium/complex. Present classification with rationale. - 9. Route: simple → Express (step 31). Medium/complex → continue to step 10. + 9. Route: simple → Express (step 32). Medium/complex → continue to step 10. DESIGN (Phase 1) 10. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. -11. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: +11. Define Agent Models. +12. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: - Design depth selector (first design question) - Repository grounding (for existing codebases, skip for greenfield) - One question at a time via user prompt @@ -31,51 +32,51 @@ DESIGN (Phase 1) WRONG: user requests "fan site" → options include React, Next.js, Astro CORRECT: user requests "fan site" → recommended option is vanilla HTML/CSS/JS -12. Present design sections one at a time, per the design-dialogue skill's convergence protocol. +13. Present design sections one at a time, per the design-dialogue skill's convergence protocol. Each section must be presented individually and approved via user prompt before proceeding to the next. Do NOT present the full design as a single block. Quick depth may combine sections. Standard/Deep MUST validate individually. -13. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). -14. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. +14. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). +15. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. PLANNING (Phase 2) -15. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. -16. Call validate_plan with the generated plan and task_complexity. +16. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. +17. Call validate_plan with the generated plan and task_complexity. You MUST call validate_plan BEFORE presenting the plan for approval. Do NOT - present the plan, write it to state_dir, or proceed to step 17 without first + present the plan, write it to state_dir, or proceed to step 18 without first calling validate_plan and resolving any error-severity violations. validate_plan enforces server-side: phase count limits, dependency cycles, unknown agents, file ownership conflicts, and agent-deliverable compatibility (read-only agents cannot be assigned to file-creating phases). If it returns violations with severity "error", fix them in the plan and re-validate. -17. Present plan for user approval (Approve / Revise / Abort via user prompt). -18. Write approved implementation plan to /plans/. +18. Present plan for user approval (Approve / Revise / Abort via user prompt). +19. Write approved implementation plan to /plans/. EXECUTION SETUP (Phase 3 — pre-delegation) -19. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. +20. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. Present ONLY "Parallel" and "Sequential" as execution mode options. Do NOT present "Ask" as a user-facing choice — "ask" is a setting value that means "prompt the user", not an execution mode the user selects. -20. Call `get_skill_content` with resources: ["session-management", "session-state"]. -21. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. -22. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. +21. Call `get_skill_content` with resources: ["session-management", "session-state"]. +22. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. +23. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. EXECUTION (Phase 3 — delegation loop) -23. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. +24. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. Dispatch by calling the agent's registered tool directly. Do NOT use the built-in generalist tool or invoke agents by bare name. Each Maestro agent carries specialized methodology, tool restrictions, temperature, and turn limits from its frontmatter that the generalist ignores. -24. After each agent returns, parse Task Report + Downstream Context from response. -25. Call transition_phase to persist results. +25. After each agent returns, parse Task Report + Downstream Context from response. +26. Call transition_phase to persist results. For parallel batches: call transition_phase INDIVIDUALLY for EVERY completed phase in the batch. The MCP tool writes files_created, files_modified, @@ -85,24 +86,24 @@ EXECUTION (Phase 3 — delegation loop) merge all agents' files into one call — the archive attributes files per phase, so empty payloads mean lost traceability. -26. Repeat steps 23-25 until all phases complete. +27. Repeat steps 24-26 until all phases complete. COMPLETION (Phase 4) -27. Call `get_skill_content` with resources: ["code-review"]. -28. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. +28. Call `get_skill_content` with resources: ["code-review"]. +29. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. If Critical/Major findings: re-delegate to the implementing agent to fix. The orchestrator MUST NOT write code directly. -29. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. -30. Present final summary with files changed, phase outcomes, and next steps. +30. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. +31. Present final summary with files changed, phase outcomes, and next steps. RECOVERY (referenced from any step on user request) If the user says the flow moved too fast: return to the most recent unanswered approval gate. If the user asks for implementation before approval: remind them Maestro requires approval first. If the user asks to skip execution-mode: remind them parallel/sequential is required unless MAESTRO_EXECUTION_MODE pins it. If an answer invalidates a prior choice: restate the updated assumption and re-run the relevant gate. -If delegation collapses to parent session without fallback approval: return to step 19 or re-scope the child-agent work packages. +If delegation collapses to parent session without fallback approval: return to step 20 or re-scope the child-agent work packages. EXPRESS WORKFLOW (simple tasks only — jumped to from step 9) @@ -110,17 +111,18 @@ EXPRESS MODE GATE BYPASS: Express bypasses the execution-mode gate entirely. Exp EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, archive_session) are unavailable, fall back to direct file writes on /state/active-session.md. -31. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. +32. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. Express sessions MUST have exactly one implementation phase with exactly one agent. -32. Ask 1-2 clarifying questions from Area 1 only. +33. Define Agent Models. +34. Ask 1-2 clarifying questions from Area 1 only. Each question MUST use the user prompt tool (not plain text). Use the choose variant with 2-4 options where possible. Do NOT ask questions as plain text in the model response — the user prompt tool is the only input mechanism. -33. Present structured Express brief as plain text, then ask for approval. +35. Present structured Express brief as plain text, then ask for approval. The brief MUST be plain text output in the model response. The approval MUST be a SEPARATE user prompt tool call — not embedded in the @@ -128,14 +130,14 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch These are two distinct actions: first emit the brief as text, then call the user prompt tool for approval. Do NOT combine them into one text block. -34. On approval, create session with workflow_mode: "express", exactly 1 phase. +36. On approval, create session with workflow_mode: "express", exactly 1 phase. On rejection, revise. On second rejection, escalate to Standard → step 10. -35. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. -36. Delegate to the assigned agent. +37. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. +38. Delegate to the assigned agent. - Same dispatch rule as step 23: call agent by registered tool name, not generalist. + Same dispatch rule as step 24: call agent by registered tool name, not generalist. -37. Parse Task Report from the agent's response. Call transition_phase to persist results. +39. Parse Task Report from the agent's response. Call transition_phase to persist results. You MUST call transition_phase after the implementing agent returns. Extract files_created, files_modified, files_deleted, and downstream_context from the @@ -143,15 +145,15 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch state has no record of what was delivered. Do NOT skip to code review or archive without calling transition_phase first. -38. Delegate to the code reviewer agent. +40. Delegate to the code reviewer agent. If Critical/Major findings: re-delegate to implementing agent (1 retry). Orchestrator MUST NOT write code directly. If retry fails, escalate to user. -39. Call archive_session. -40. Present summary. +41. Call archive_session. +42. Present summary. EXPRESS RESUME (when resuming an Express session from get_session_status) -If phase is pending: re-generate and present brief (step 33). On approval, proceed to delegation (step 36). -If phase is in_progress: re-delegate with same scope (step 36). -If phase is completed but session is in_progress: run code review (step 38), then archive (step 39). +If phase is pending: re-generate and present brief (step 35). On approval, proceed to delegation (step 38). +If phase is in_progress: re-delegate with same scope (step 38). +If phase is completed but session is in_progress: run code review (step 40), then archive (step 41). diff --git a/commands/maestro/orchestrate.toml b/commands/maestro/orchestrate.toml index 24e80006..ae4aa3a6 100644 --- a/commands/maestro/orchestrate.toml +++ b/commands/maestro/orchestrate.toml @@ -18,10 +18,12 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then restart." Offer to continue without Plan Mode using `ask_user` for approvals. | +| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then Request Restart." Offer to continue without Plan Mode using `ask_user` for approvals. | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | +| Define Agent Models | `ask_user` for valid mode (`quality`, `balanced`, `economic`, `skip`) and call `setup_models` with the selected mode. Then Request Restart. | +| Request Restart | STOP here and wait for the user to restart and signal to continue. Do NOT proceed. | ## Execute diff --git a/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml b/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml index 24e80006..2644ece9 100644 --- a/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml +++ b/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml @@ -18,10 +18,12 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then restart." Offer to continue without Plan Mode using `ask_user` for approvals. | +| Enter Plan Mode | `enter_plan_mode` | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | +| Define Agent Models | No Action (NOOP) | +| Request Restart | STOP here and wait for the user to restart and signal to continue. Do NOT proceed. | ## Execute diff --git a/plugins/maestro/src/references/orchestration-steps.md b/plugins/maestro/src/references/orchestration-steps.md index e6f79e3b..959ed087 100644 --- a/plugins/maestro/src/references/orchestration-steps.md +++ b/plugins/maestro/src/references/orchestration-steps.md @@ -8,13 +8,14 @@ STARTUP (Turn 1 — tool calls only, no text output) 6. STOP. Turn 1 is ONLY steps 1-5. No text, no design questions, no file reads. CLASSIFICATION (Turn 2) - 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 13, 15, 20). + 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 14, 16, 21). 8. Classify task as simple/medium/complex. Present classification with rationale. - 9. Route: simple → Express (step 31). Medium/complex → continue to step 10. + 9. Route: simple → Express (step 32). Medium/complex → continue to step 10. DESIGN (Phase 1) 10. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. -11. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: +11. Define Agent Models. +12. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: - Design depth selector (first design question) - Repository grounding (for existing codebases, skip for greenfield) - One question at a time via user prompt @@ -31,51 +32,51 @@ DESIGN (Phase 1) WRONG: user requests "fan site" → options include React, Next.js, Astro CORRECT: user requests "fan site" → recommended option is vanilla HTML/CSS/JS -12. Present design sections one at a time, per the design-dialogue skill's convergence protocol. +13. Present design sections one at a time, per the design-dialogue skill's convergence protocol. Each section must be presented individually and approved via user prompt before proceeding to the next. Do NOT present the full design as a single block. Quick depth may combine sections. Standard/Deep MUST validate individually. -13. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). -14. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. +14. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). +15. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. PLANNING (Phase 2) -15. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. -16. Call validate_plan with the generated plan and task_complexity. +16. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. +17. Call validate_plan with the generated plan and task_complexity. You MUST call validate_plan BEFORE presenting the plan for approval. Do NOT - present the plan, write it to state_dir, or proceed to step 17 without first + present the plan, write it to state_dir, or proceed to step 18 without first calling validate_plan and resolving any error-severity violations. validate_plan enforces server-side: phase count limits, dependency cycles, unknown agents, file ownership conflicts, and agent-deliverable compatibility (read-only agents cannot be assigned to file-creating phases). If it returns violations with severity "error", fix them in the plan and re-validate. -17. Present plan for user approval (Approve / Revise / Abort via user prompt). -18. Write approved implementation plan to /plans/. +18. Present plan for user approval (Approve / Revise / Abort via user prompt). +19. Write approved implementation plan to /plans/. EXECUTION SETUP (Phase 3 — pre-delegation) -19. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. +20. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. Present ONLY "Parallel" and "Sequential" as execution mode options. Do NOT present "Ask" as a user-facing choice — "ask" is a setting value that means "prompt the user", not an execution mode the user selects. -20. Call `get_skill_content` with resources: ["session-management", "session-state"]. -21. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. -22. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. +21. Call `get_skill_content` with resources: ["session-management", "session-state"]. +22. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. +23. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. EXECUTION (Phase 3 — delegation loop) -23. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. +24. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. Dispatch by calling the agent's registered tool directly. Do NOT use the built-in generalist tool or invoke agents by bare name. Each Maestro agent carries specialized methodology, tool restrictions, temperature, and turn limits from its frontmatter that the generalist ignores. -24. After each agent returns, parse Task Report + Downstream Context from response. -25. Call transition_phase to persist results. +25. After each agent returns, parse Task Report + Downstream Context from response. +26. Call transition_phase to persist results. For parallel batches: call transition_phase INDIVIDUALLY for EVERY completed phase in the batch. The MCP tool writes files_created, files_modified, @@ -85,24 +86,24 @@ EXECUTION (Phase 3 — delegation loop) merge all agents' files into one call — the archive attributes files per phase, so empty payloads mean lost traceability. -26. Repeat steps 23-25 until all phases complete. +27. Repeat steps 24-26 until all phases complete. COMPLETION (Phase 4) -27. Call `get_skill_content` with resources: ["code-review"]. -28. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. +28. Call `get_skill_content` with resources: ["code-review"]. +29. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. If Critical/Major findings: re-delegate to the implementing agent to fix. The orchestrator MUST NOT write code directly. -29. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. -30. Present final summary with files changed, phase outcomes, and next steps. +30. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. +31. Present final summary with files changed, phase outcomes, and next steps. RECOVERY (referenced from any step on user request) If the user says the flow moved too fast: return to the most recent unanswered approval gate. If the user asks for implementation before approval: remind them Maestro requires approval first. If the user asks to skip execution-mode: remind them parallel/sequential is required unless MAESTRO_EXECUTION_MODE pins it. If an answer invalidates a prior choice: restate the updated assumption and re-run the relevant gate. -If delegation collapses to parent session without fallback approval: return to step 19 or re-scope the child-agent work packages. +If delegation collapses to parent session without fallback approval: return to step 20 or re-scope the child-agent work packages. EXPRESS WORKFLOW (simple tasks only — jumped to from step 9) @@ -110,17 +111,18 @@ EXPRESS MODE GATE BYPASS: Express bypasses the execution-mode gate entirely. Exp EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, archive_session) are unavailable, fall back to direct file writes on /state/active-session.md. -31. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. +32. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. Express sessions MUST have exactly one implementation phase with exactly one agent. -32. Ask 1-2 clarifying questions from Area 1 only. +33. Define Agent Models. +34. Ask 1-2 clarifying questions from Area 1 only. Each question MUST use the user prompt tool (not plain text). Use the choose variant with 2-4 options where possible. Do NOT ask questions as plain text in the model response — the user prompt tool is the only input mechanism. -33. Present structured Express brief as plain text, then ask for approval. +35. Present structured Express brief as plain text, then ask for approval. The brief MUST be plain text output in the model response. The approval MUST be a SEPARATE user prompt tool call — not embedded in the @@ -128,14 +130,14 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch These are two distinct actions: first emit the brief as text, then call the user prompt tool for approval. Do NOT combine them into one text block. -34. On approval, create session with workflow_mode: "express", exactly 1 phase. +36. On approval, create session with workflow_mode: "express", exactly 1 phase. On rejection, revise. On second rejection, escalate to Standard → step 10. -35. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. -36. Delegate to the assigned agent. +37. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. +38. Delegate to the assigned agent. - Same dispatch rule as step 23: call agent by registered tool name, not generalist. + Same dispatch rule as step 24: call agent by registered tool name, not generalist. -37. Parse Task Report from the agent's response. Call transition_phase to persist results. +39. Parse Task Report from the agent's response. Call transition_phase to persist results. You MUST call transition_phase after the implementing agent returns. Extract files_created, files_modified, files_deleted, and downstream_context from the @@ -143,15 +145,15 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch state has no record of what was delivered. Do NOT skip to code review or archive without calling transition_phase first. -38. Delegate to the code reviewer agent. +40. Delegate to the code reviewer agent. If Critical/Major findings: re-delegate to implementing agent (1 retry). Orchestrator MUST NOT write code directly. If retry fails, escalate to user. -39. Call archive_session. -40. Present summary. +41. Call archive_session. +42. Present summary. EXPRESS RESUME (when resuming an Express session from get_session_status) -If phase is pending: re-generate and present brief (step 33). On approval, proceed to delegation (step 36). -If phase is in_progress: re-delegate with same scope (step 36). -If phase is completed but session is in_progress: run code review (step 38), then archive (step 39). +If phase is pending: re-generate and present brief (step 35). On approval, proceed to delegation (step 38). +If phase is in_progress: re-delegate with same scope (step 38). +If phase is completed but session is in_progress: run code review (step 40), then archive (step 41). diff --git a/src/platforms/gemini/commands/maestro/orchestrate.toml b/src/platforms/gemini/commands/maestro/orchestrate.toml index 24e80006..ae4aa3a6 100644 --- a/src/platforms/gemini/commands/maestro/orchestrate.toml +++ b/src/platforms/gemini/commands/maestro/orchestrate.toml @@ -18,10 +18,12 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then restart." Offer to continue without Plan Mode using `ask_user` for approvals. | +| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then Request Restart." Offer to continue without Plan Mode using `ask_user` for approvals. | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | +| Define Agent Models | `ask_user` for valid mode (`quality`, `balanced`, `economic`, `skip`) and call `setup_models` with the selected mode. Then Request Restart. | +| Request Restart | STOP here and wait for the user to restart and signal to continue. Do NOT proceed. | ## Execute diff --git a/src/references/orchestration-steps.md b/src/references/orchestration-steps.md index e6f79e3b..959ed087 100644 --- a/src/references/orchestration-steps.md +++ b/src/references/orchestration-steps.md @@ -8,13 +8,14 @@ STARTUP (Turn 1 — tool calls only, no text output) 6. STOP. Turn 1 is ONLY steps 1-5. No text, no design questions, no file reads. CLASSIFICATION (Turn 2) - 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 13, 15, 20). + 7. Load the architecture reference: ["architecture"]. Do NOT load templates yet — they are loaded at their consumption points (steps 14, 16, 21). 8. Classify task as simple/medium/complex. Present classification with rationale. - 9. Route: simple → Express (step 31). Medium/complex → continue to step 10. + 9. Route: simple → Express (step 32). Medium/complex → continue to step 10. DESIGN (Phase 1) 10. Enter Plan Mode. If unavailable, follow the runtime preamble's Plan Mode fallback instructions. -11. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: +11. Define Agent Models. +12. Call `get_skill_content` with resources: ["design-dialogue"]. Follow the loaded protocol for: - Design depth selector (first design question) - Repository grounding (for existing codebases, skip for greenfield) - One question at a time via user prompt @@ -31,51 +32,51 @@ DESIGN (Phase 1) WRONG: user requests "fan site" → options include React, Next.js, Astro CORRECT: user requests "fan site" → recommended option is vanilla HTML/CSS/JS -12. Present design sections one at a time, per the design-dialogue skill's convergence protocol. +13. Present design sections one at a time, per the design-dialogue skill's convergence protocol. Each section must be presented individually and approved via user prompt before proceeding to the next. Do NOT present the full design as a single block. Quick depth may combine sections. Standard/Deep MUST validate individually. -13. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). -14. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. +14. Call `get_skill_content` with resources: ["design-document"]. Write approved design document to /plans/ (or Plan Mode tmp path). +15. If Plan Mode is active, exit Plan Mode with the plan path. Copy approved document to /plans/. PLANNING (Phase 2) -15. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. -16. Call validate_plan with the generated plan and task_complexity. +16. Call `get_skill_content` with resources: ["implementation-planning", "implementation-plan"]. Follow the loaded skill protocol. +17. Call validate_plan with the generated plan and task_complexity. You MUST call validate_plan BEFORE presenting the plan for approval. Do NOT - present the plan, write it to state_dir, or proceed to step 17 without first + present the plan, write it to state_dir, or proceed to step 18 without first calling validate_plan and resolving any error-severity violations. validate_plan enforces server-side: phase count limits, dependency cycles, unknown agents, file ownership conflicts, and agent-deliverable compatibility (read-only agents cannot be assigned to file-creating phases). If it returns violations with severity "error", fix them in the plan and re-validate. -17. Present plan for user approval (Approve / Revise / Abort via user prompt). -18. Write approved implementation plan to /plans/. +18. Present plan for user approval (Approve / Revise / Abort via user prompt). +19. Write approved implementation plan to /plans/. EXECUTION SETUP (Phase 3 — pre-delegation) -19. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. +20. Call `get_skill_content` with resources: ["execution"]. Follow its Execution Mode Gate. Present ONLY "Parallel" and "Sequential" as execution mode options. Do NOT present "Ask" as a user-facing choice — "ask" is a setting value that means "prompt the user", not an execution mode the user selects. -20. Call `get_skill_content` with resources: ["session-management", "session-state"]. -21. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. -22. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. +21. Call `get_skill_content` with resources: ["session-management", "session-state"]. +22. Create session via create_session with resolved execution_mode. Do NOT create before mode is resolved. +23. Call `get_skill_content` with resources: ["delegation", "validation", "agent-base-protocol", "filesystem-safety-protocol"]. EXECUTION (Phase 3 — delegation loop) -23. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. +24. For each phase (or parallel batch): call `get_agent` for the assigned agent, then delegate using the returned methodology and tool restrictions. Dispatch by calling the agent's registered tool directly. Do NOT use the built-in generalist tool or invoke agents by bare name. Each Maestro agent carries specialized methodology, tool restrictions, temperature, and turn limits from its frontmatter that the generalist ignores. -24. After each agent returns, parse Task Report + Downstream Context from response. -25. Call transition_phase to persist results. +25. After each agent returns, parse Task Report + Downstream Context from response. +26. Call transition_phase to persist results. For parallel batches: call transition_phase INDIVIDUALLY for EVERY completed phase in the batch. The MCP tool writes files_created, files_modified, @@ -85,24 +86,24 @@ EXECUTION (Phase 3 — delegation loop) merge all agents' files into one call — the archive attributes files per phase, so empty payloads mean lost traceability. -26. Repeat steps 23-25 until all phases complete. +27. Repeat steps 24-26 until all phases complete. COMPLETION (Phase 4) -27. Call `get_skill_content` with resources: ["code-review"]. -28. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. +28. Call `get_skill_content` with resources: ["code-review"]. +29. If execution changed non-documentation files, delegate to the code reviewer agent. Block on Critical/Major findings. If Critical/Major findings: re-delegate to the implementing agent to fix. The orchestrator MUST NOT write code directly. -29. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. -30. Present final summary with files changed, phase outcomes, and next steps. +30. If MAESTRO_AUTO_ARCHIVE is true (or unset), call archive_session. If false, inform user session is complete but not archived. +31. Present final summary with files changed, phase outcomes, and next steps. RECOVERY (referenced from any step on user request) If the user says the flow moved too fast: return to the most recent unanswered approval gate. If the user asks for implementation before approval: remind them Maestro requires approval first. If the user asks to skip execution-mode: remind them parallel/sequential is required unless MAESTRO_EXECUTION_MODE pins it. If an answer invalidates a prior choice: restate the updated assumption and re-run the relevant gate. -If delegation collapses to parent session without fallback approval: return to step 19 or re-scope the child-agent work packages. +If delegation collapses to parent session without fallback approval: return to step 20 or re-scope the child-agent work packages. EXPRESS WORKFLOW (simple tasks only — jumped to from step 9) @@ -110,17 +111,18 @@ EXPRESS MODE GATE BYPASS: Express bypasses the execution-mode gate entirely. Exp EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, archive_session) are unavailable, fall back to direct file writes on /state/active-session.md. -31. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. +32. Verify classification is simple. If task requires multiple phases or agents, override to medium → step 10. Express sessions MUST have exactly one implementation phase with exactly one agent. -32. Ask 1-2 clarifying questions from Area 1 only. +33. Define Agent Models. +34. Ask 1-2 clarifying questions from Area 1 only. Each question MUST use the user prompt tool (not plain text). Use the choose variant with 2-4 options where possible. Do NOT ask questions as plain text in the model response — the user prompt tool is the only input mechanism. -33. Present structured Express brief as plain text, then ask for approval. +35. Present structured Express brief as plain text, then ask for approval. The brief MUST be plain text output in the model response. The approval MUST be a SEPARATE user prompt tool call — not embedded in the @@ -128,14 +130,14 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch These are two distinct actions: first emit the brief as text, then call the user prompt tool for approval. Do NOT combine them into one text block. -34. On approval, create session with workflow_mode: "express", exactly 1 phase. +36. On approval, create session with workflow_mode: "express", exactly 1 phase. On rejection, revise. On second rejection, escalate to Standard → step 10. -35. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. -36. Delegate to the assigned agent. +37. Call `get_skill_content` with resources: ["agent-base-protocol", "filesystem-safety-protocol"] and prepend them to the delegation prompt. +38. Delegate to the assigned agent. - Same dispatch rule as step 23: call agent by registered tool name, not generalist. + Same dispatch rule as step 24: call agent by registered tool name, not generalist. -37. Parse Task Report from the agent's response. Call transition_phase to persist results. +39. Parse Task Report from the agent's response. Call transition_phase to persist results. You MUST call transition_phase after the implementing agent returns. Extract files_created, files_modified, files_deleted, and downstream_context from the @@ -143,15 +145,15 @@ EXPRESS MCP FALLBACK: If MCP state tools (create_session, transition_phase, arch state has no record of what was delivered. Do NOT skip to code review or archive without calling transition_phase first. -38. Delegate to the code reviewer agent. +40. Delegate to the code reviewer agent. If Critical/Major findings: re-delegate to implementing agent (1 retry). Orchestrator MUST NOT write code directly. If retry fails, escalate to user. -39. Call archive_session. -40. Present summary. +41. Call archive_session. +42. Present summary. EXPRESS RESUME (when resuming an Express session from get_session_status) -If phase is pending: re-generate and present brief (step 33). On approval, proceed to delegation (step 36). -If phase is in_progress: re-delegate with same scope (step 36). -If phase is completed but session is in_progress: run code review (step 38), then archive (step 39). +If phase is pending: re-generate and present brief (step 35). On approval, proceed to delegation (step 38). +If phase is in_progress: re-delegate with same scope (step 38). +If phase is completed but session is in_progress: run code review (step 40), then archive (step 41). From de6cbb25625e7d2d65a7f9331f6d7e62f20c4538 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Fri, 10 Apr 2026 22:49:20 +0200 Subject: [PATCH 14/20] fix: Same Gemini orchestrate.toml for all environments --- .../src/platforms/gemini/commands/maestro/orchestrate.toml | 5 +++-- .../src/platforms/gemini/commands/maestro/orchestrate.toml | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/claude/src/platforms/gemini/commands/maestro/orchestrate.toml b/claude/src/platforms/gemini/commands/maestro/orchestrate.toml index db5113f0..ae4aa3a6 100644 --- a/claude/src/platforms/gemini/commands/maestro/orchestrate.toml +++ b/claude/src/platforms/gemini/commands/maestro/orchestrate.toml @@ -18,11 +18,12 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` | +| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then Request Restart." Offer to continue without Plan Mode using `ask_user` for approvals. | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | -| Define Agent Models | No Action (NOOP) | +| Define Agent Models | `ask_user` for valid mode (`quality`, `balanced`, `economic`, `skip`) and call `setup_models` with the selected mode. Then Request Restart. | +| Request Restart | STOP here and wait for the user to restart and signal to continue. Do NOT proceed. | ## Execute diff --git a/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml b/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml index 2644ece9..ae4aa3a6 100644 --- a/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml +++ b/plugins/maestro/src/platforms/gemini/commands/maestro/orchestrate.toml @@ -18,11 +18,11 @@ This preamble maps generic step references to Gemini CLI tool syntax. | Load template/reference/protocol | `get_skill_content(resources: [""])` | | Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` | | MCP tools | `mcp_maestro_` (Gemini CLI also accepts bare names like `resolve_settings`) | -| Enter Plan Mode | `enter_plan_mode` | +| Enter Plan Mode | `enter_plan_mode` — if unavailable, tell user: "Run `gemini --settings` and set `experimental.plan` to `true`, then Request Restart." Offer to continue without Plan Mode using `ask_user` for approvals. | | Exit Plan Mode | `exit_plan_mode` with `plan_filename` | | User prompt (choose) | `ask_user` with `type: 'choice'` | | User prompt (approve) | `ask_user` with `type: 'yesno'` | -| Define Agent Models | No Action (NOOP) | +| Define Agent Models | `ask_user` for valid mode (`quality`, `balanced`, `economic`, `skip`) and call `setup_models` with the selected mode. Then Request Restart. | | Request Restart | STOP here and wait for the user to restart and signal to continue. Do NOT proceed. | ## Execute From 7796e692db0fb075765a04340b27b8a5beea5546 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 06:28:50 +0200 Subject: [PATCH 15/20] fix: don't overwrite existing subagent modelConfig --- src/mcp/handlers/setup-models.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/mcp/handlers/setup-models.js b/src/mcp/handlers/setup-models.js index 861eb9e1..78bcd5a0 100644 --- a/src/mcp/handlers/setup-models.js +++ b/src/mcp/handlers/setup-models.js @@ -61,9 +61,8 @@ async function handleSetupModels(params, projectRoot) { for (const [agent, model] of Object.entries(mapping)) { settings.agents.overrides[agent] = { - modelConfig: { - model, - }, + ...(settings.agents.overrides[agent] || {}), + modelConfig: { model }, }; } From e77335cb542169299dac15422b4773547301aff2 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 06:31:07 +0200 Subject: [PATCH 16/20] fix: adjust model preset --- src/config/agent-modes.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/config/agent-modes.json b/src/config/agent-modes.json index 18969577..4c3f63ef 100644 --- a/src/config/agent-modes.json +++ b/src/config/agent-modes.json @@ -5,7 +5,7 @@ "api_designer": "gemini-3.1-pro-preview", "architect": "gemini-3.1-pro-preview", "code_reviewer": "gemini-3.1-pro-preview", - "coder": "gemini-3-flash-preview", + "coder": "gemini-3.1-pro-preview", "compliance_reviewer": "gemini-3.1-pro-preview", "content_strategist": "gemini-3.1-pro-preview", "copywriter": "gemini-3-flash-preview", @@ -16,7 +16,7 @@ "i18n_specialist": "gemini-3.1-pro-preview", "performance_engineer": "gemini-3.1-pro-preview", "product_manager": "gemini-3.1-pro-preview", - "refactor": "gemini-3-flash-preview", + "refactor": "gemini-3.1-pro-preview", "security_engineer": "gemini-3.1-pro-preview", "seo_specialist": "gemini-3.1-pro-preview", "technical_writer": "gemini-3-flash-preview", @@ -53,7 +53,7 @@ "accessibility_specialist": "gemini-3.1-flash-lite-preview", "analytics_engineer": "gemini-3.1-flash-lite-preview", "api_designer": "gemini-3-flash-preview", - "architect": "gemini-3.1-pro-preview", + "architect": "gemini-3-flash-preview", "code_reviewer": "gemini-3-flash-preview", "coder": "gemini-3.1-flash-lite-preview", "compliance_reviewer": "gemini-3-flash-preview", @@ -65,7 +65,7 @@ "devops_engineer": "gemini-3.1-flash-lite-preview", "i18n_specialist": "gemini-3.1-flash-lite-preview", "performance_engineer": "gemini-3.1-flash-lite-preview", - "product_manager": "gemini-3.1-pro-preview", + "product_manager": "gemini-3-flash-preview", "refactor": "gemini-3.1-flash-lite-preview", "security_engineer": "gemini-3-flash-preview", "seo_specialist": "gemini-3.1-flash-lite-preview", @@ -74,4 +74,4 @@ "ux_designer": "gemini-3-flash-preview", "codebase_investigator": "gemini-3.1-flash-lite-preview" } -} +} \ No newline at end of file From 88ea5bd0c1929e25a574389be6219d5bda5b74ae Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 06:42:57 +0200 Subject: [PATCH 17/20] fix: added codebase_investigator to KNOWN_AGENTS --- src/core/agent-registry.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/agent-registry.js b/src/core/agent-registry.js index 428aa021..c6bca8bc 100644 --- a/src/core/agent-registry.js +++ b/src/core/agent-registry.js @@ -4,6 +4,7 @@ const KNOWN_AGENTS = Object.freeze([ 'architect', 'api_designer', 'code_reviewer', + 'codebase_investigator', // Native to gemini-cli 'coder', 'data_engineer', 'debugger', From d534db4a3aae884d3e76322a51631dc07f757593 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 06:50:17 +0200 Subject: [PATCH 18/20] test: setup-models.mcp and agent-modes.json --- tests/transforms/mcp-setup-models.test.js | 118 ++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 tests/transforms/mcp-setup-models.test.js diff --git a/tests/transforms/mcp-setup-models.test.js b/tests/transforms/mcp-setup-models.test.js new file mode 100644 index 00000000..9a4ef464 --- /dev/null +++ b/tests/transforms/mcp-setup-models.test.js @@ -0,0 +1,118 @@ +'use strict'; + +const { describe, it, after } = require('node:test'); +const assert = require('node:assert/strict'); +const fs = require('fs'); +const path = require('path'); +const os = require('os'); +const { handleSetupModels } = require('../../src/mcp/handlers/setup-models'); +const { KNOWN_AGENTS } = require('../../src/core/agent-registry'); + +// Mock atomicWriteSync to avoid real file writes if necessary, +// but handleSetupModels uses it from ../../core/atomic-write +// For these tests, we'll use a real temporary directory to ensure everything works as expected. + +// Mock MAESTRO_EXTENSION_PATH to the actual repo root during tests +const REPO_ROOT = path.resolve(__dirname, '../../'); +process.env.MAESTRO_EXTENSION_PATH = REPO_ROOT; + +describe('handleSetupModels', () => { + const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'maestro-test-')); + const dotGemini = path.join(tempDir, '.gemini'); + const settingsPath = path.join(dotGemini, 'settings.json'); + + it('should return skipped_model_setup when mode is skip', async () => { + const result = await handleSetupModels({ mode: 'skip' }, tempDir); + assert.deepEqual(result, { status: 'skipped_model_setup' }); + }); + + it('should throw if mode is invalid', async () => { + await assert.rejects( + () => handleSetupModels({ mode: 'invalid' }, tempDir), + /Invalid mode: invalid/ + ); + }); + + it('should create a fresh settings file if it does not exist', async () => { + if (fs.existsSync(settingsPath)) fs.unlinkSync(settingsPath); + if (!fs.existsSync(dotGemini)) fs.mkdirSync(dotGemini, { recursive: true }); + + const result = await handleSetupModels({ mode: 'balanced' }, tempDir); + assert.equal(result.status, 'success'); + assert.equal(result.mode, 'balanced'); + + assert.ok(fs.existsSync(settingsPath)); + const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); + assert.equal(settings.experimental.enableAgents, true); + assert.ok(settings.agents.overrides); + assert.ok(settings.agents.overrides.architect); + }); + + it('should preserve existing settings properties after merge', async () => { + const existingSettings = { + existingProp: 'value', + experimental: { + otherProp: true + }, + agents: { + overrides: { + architect: { + customProp: 'custom' + } + } + } + }; + fs.writeFileSync(settingsPath, JSON.stringify(existingSettings)); + + const result = await handleSetupModels({ mode: 'quality' }, tempDir); + assert.equal(result.status, 'success'); + + const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf8')); + assert.equal(settings.existingProp, 'value'); + assert.equal(settings.experimental.otherProp, true); + assert.equal(settings.experimental.enableAgents, true); + assert.equal(settings.agents.overrides.architect.customProp, 'custom'); + assert.ok(settings.agents.overrides.architect.modelConfig.model); + }); + + it('should throw meaningful error if settings file is corrupted', async () => { + fs.writeFileSync(settingsPath, 'corrupted json {'); + await assert.rejects( + () => handleSetupModels({ mode: 'balanced' }, tempDir), + /Existing .gemini\/settings.json is corrupted/ + ); + }); + + it('should throw meaningful error if agent-modes.json is missing', async () => { + const originalPath = process.env.MAESTRO_EXTENSION_PATH; + process.env.MAESTRO_EXTENSION_PATH = '/non/existent/path'; + try { + await assert.rejects( + () => handleSetupModels({ mode: 'balanced' }, tempDir), + /Failed to read agent-modes.json/ + ); + } finally { + process.env.MAESTRO_EXTENSION_PATH = originalPath; + } + }); + + after(() => { + fs.rmSync(tempDir, { recursive: true, force: true }); + }); +}); + +describe('agent-modes.json validation', () => { + it('should ensure all agents in all modes exist in KNOWN_AGENTS', () => { + const modesPath = path.resolve(__dirname, '../../src/config/agent-modes.json'); + const modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); + + for (const [mode, mapping] of Object.entries(modes)) { + for (const agent of Object.keys(mapping)) { + assert.ok( + KNOWN_AGENTS.includes(agent), + `Agent "${agent}" in mode "${mode}" is not in KNOWN_AGENTS` + ); + } + } + }); +}); From 6157df4ae3bb973ae5fc21e2399174834813d6a7 Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 07:05:00 +0200 Subject: [PATCH 19/20] test: satisfy tests/integration/zero-diff.test.js --- claude/src/config/agent-modes.json | 77 +++++++++++++++++++ claude/src/core/agent-registry.js | 1 + claude/src/mcp/handlers/setup-models.js | 77 +++++++++++++++++++ claude/src/mcp/tool-packs/workspace/index.js | 18 +++++ plugins/maestro/src/config/agent-modes.json | 77 +++++++++++++++++++ plugins/maestro/src/core/agent-registry.js | 1 + .../maestro/src/mcp/handlers/setup-models.js | 77 +++++++++++++++++++ .../src/mcp/tool-packs/workspace/index.js | 18 +++++ 8 files changed, 346 insertions(+) create mode 100644 claude/src/config/agent-modes.json create mode 100644 claude/src/mcp/handlers/setup-models.js create mode 100644 plugins/maestro/src/config/agent-modes.json create mode 100644 plugins/maestro/src/mcp/handlers/setup-models.js diff --git a/claude/src/config/agent-modes.json b/claude/src/config/agent-modes.json new file mode 100644 index 00000000..4c3f63ef --- /dev/null +++ b/claude/src/config/agent-modes.json @@ -0,0 +1,77 @@ +{ + "quality": { + "accessibility_specialist": "gemini-3.1-pro-preview", + "analytics_engineer": "gemini-3.1-pro-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", + "code_reviewer": "gemini-3.1-pro-preview", + "coder": "gemini-3.1-pro-preview", + "compliance_reviewer": "gemini-3.1-pro-preview", + "content_strategist": "gemini-3.1-pro-preview", + "copywriter": "gemini-3-flash-preview", + "data_engineer": "gemini-3.1-pro-preview", + "debugger": "gemini-3.1-pro-preview", + "design_system_engineer": "gemini-3.1-pro-preview", + "devops_engineer": "gemini-3.1-pro-preview", + "i18n_specialist": "gemini-3.1-pro-preview", + "performance_engineer": "gemini-3.1-pro-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-pro-preview", + "security_engineer": "gemini-3.1-pro-preview", + "seo_specialist": "gemini-3.1-pro-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3.1-pro-preview", + "ux_designer": "gemini-3.1-pro-preview", + "codebase_investigator": "gemini-3.1-pro-preview" + }, + "balanced": { + "accessibility_specialist": "gemini-3-flash-preview", + "analytics_engineer": "gemini-3-flash-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3-flash-preview", + "copywriter": "gemini-3.1-flash-lite-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3.1-pro-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3-flash-preview", + "i18n_specialist": "gemini-3-flash-preview", + "performance_engineer": "gemini-3-flash-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-flash-lite-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3-flash-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3-flash-preview" + }, + "economic": { + "accessibility_specialist": "gemini-3.1-flash-lite-preview", + "analytics_engineer": "gemini-3.1-flash-lite-preview", + "api_designer": "gemini-3-flash-preview", + "architect": "gemini-3-flash-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3.1-flash-lite-preview", + "copywriter": "gemini-3.1-flash-lite-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3-flash-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3.1-flash-lite-preview", + "i18n_specialist": "gemini-3.1-flash-lite-preview", + "performance_engineer": "gemini-3.1-flash-lite-preview", + "product_manager": "gemini-3-flash-preview", + "refactor": "gemini-3.1-flash-lite-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3.1-flash-lite-preview", + "technical_writer": "gemini-3.1-flash-lite-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3.1-flash-lite-preview" + } +} \ No newline at end of file diff --git a/claude/src/core/agent-registry.js b/claude/src/core/agent-registry.js index 428aa021..c6bca8bc 100644 --- a/claude/src/core/agent-registry.js +++ b/claude/src/core/agent-registry.js @@ -4,6 +4,7 @@ const KNOWN_AGENTS = Object.freeze([ 'architect', 'api_designer', 'code_reviewer', + 'codebase_investigator', // Native to gemini-cli 'coder', 'data_engineer', 'debugger', diff --git a/claude/src/mcp/handlers/setup-models.js b/claude/src/mcp/handlers/setup-models.js new file mode 100644 index 00000000..78bcd5a0 --- /dev/null +++ b/claude/src/mcp/handlers/setup-models.js @@ -0,0 +1,77 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { atomicWriteSync } = require('../../core/atomic-write'); +const { resolveExtensionRoot } = require('../utils/extension-root'); + +/** + * Handle setup_models tool call. + * + * @param {Object} params - Tool arguments. + * @param {string} params.mode - The operating mode (quality, balanced, economic, skip). + * @param {string} projectRoot - The current project root. + * @returns {Promise} - Result of the operation. + */ +async function handleSetupModels(params, projectRoot) { + const mode = params.mode; + + if (mode === 'skip') { + return { status: 'skipped_model_setup' }; + } + + if (!['quality', 'balanced', 'economic'].includes(mode)) { + throw new Error(`Invalid mode: ${mode}`); + } + + const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); + + const extensionRoot = resolveExtensionRoot(); + const modesPath = path.join(extensionRoot, 'src', 'config', 'agent-modes.json'); + + let modes; + try { + modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); + } catch (err) { + throw new Error(`Failed to read agent-modes.json: ${err.message}`); + } + + const mapping = modes[mode]; + if (!mapping) { + throw new Error(`Unknown mode: ${mode}`); + } + + let settings = {}; + if (fs.existsSync(settingsPath)) { + try { + const content = fs.readFileSync(settingsPath, 'utf8'); + settings = JSON.parse(content || '{}'); + } catch (err) { + throw new Error(`Existing .gemini/settings.json is corrupted`); + } + } + + // Ensure experimental.enableAgents is true + settings.experimental = settings.experimental || {}; + settings.experimental.enableAgents = true; + + // Extend agents.overrides + settings.agents = settings.agents || {}; + settings.agents.overrides = settings.agents.overrides || {}; + + for (const [agent, model] of Object.entries(mapping)) { + settings.agents.overrides[agent] = { + ...(settings.agents.overrides[agent] || {}), + modelConfig: { model }, + }; + } + + // Preserve existing settings while applying overrides + atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); + + return { status: 'success', mode }; +} + +module.exports = { + handleSetupModels, +}; diff --git a/claude/src/mcp/tool-packs/workspace/index.js b/claude/src/mcp/tool-packs/workspace/index.js index f381d3d5..32f6ed9b 100644 --- a/claude/src/mcp/tool-packs/workspace/index.js +++ b/claude/src/mcp/tool-packs/workspace/index.js @@ -9,6 +9,7 @@ const { } = require('../../handlers/assess-task-complexity'); const { handleValidatePlan } = require('../../handlers/validate-plan'); const { handleResolveSettings } = require('../../handlers/resolve-settings'); +const { handleSetupModels } = require('../../handlers/setup-models'); function createToolPack() { return defineToolPack({ @@ -76,12 +77,29 @@ function createToolPack() { }, }, }, + { + name: 'setup_models', + description: + 'Configure Maestro subagent models in .gemini/settings.json based on selected mode.', + inputSchema: { + type: 'object', + properties: { + mode: { + type: 'string', + enum: ['quality', 'balanced', 'economic', 'skip'], + description: 'The operating mode to configure.', + }, + }, + required: ['mode'], + }, + }, ], handlers: { initialize_workspace: handleInitializeWorkspace, assess_task_complexity: handleAssessTaskComplexity, validate_plan: handleValidatePlan, resolve_settings: handleResolveSettings, + setup_models: handleSetupModels, }, }); } diff --git a/plugins/maestro/src/config/agent-modes.json b/plugins/maestro/src/config/agent-modes.json new file mode 100644 index 00000000..4c3f63ef --- /dev/null +++ b/plugins/maestro/src/config/agent-modes.json @@ -0,0 +1,77 @@ +{ + "quality": { + "accessibility_specialist": "gemini-3.1-pro-preview", + "analytics_engineer": "gemini-3.1-pro-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", + "code_reviewer": "gemini-3.1-pro-preview", + "coder": "gemini-3.1-pro-preview", + "compliance_reviewer": "gemini-3.1-pro-preview", + "content_strategist": "gemini-3.1-pro-preview", + "copywriter": "gemini-3-flash-preview", + "data_engineer": "gemini-3.1-pro-preview", + "debugger": "gemini-3.1-pro-preview", + "design_system_engineer": "gemini-3.1-pro-preview", + "devops_engineer": "gemini-3.1-pro-preview", + "i18n_specialist": "gemini-3.1-pro-preview", + "performance_engineer": "gemini-3.1-pro-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-pro-preview", + "security_engineer": "gemini-3.1-pro-preview", + "seo_specialist": "gemini-3.1-pro-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3.1-pro-preview", + "ux_designer": "gemini-3.1-pro-preview", + "codebase_investigator": "gemini-3.1-pro-preview" + }, + "balanced": { + "accessibility_specialist": "gemini-3-flash-preview", + "analytics_engineer": "gemini-3-flash-preview", + "api_designer": "gemini-3.1-pro-preview", + "architect": "gemini-3.1-pro-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3-flash-preview", + "copywriter": "gemini-3.1-flash-lite-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3.1-pro-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3-flash-preview", + "i18n_specialist": "gemini-3-flash-preview", + "performance_engineer": "gemini-3-flash-preview", + "product_manager": "gemini-3.1-pro-preview", + "refactor": "gemini-3.1-flash-lite-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3-flash-preview", + "technical_writer": "gemini-3-flash-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3-flash-preview" + }, + "economic": { + "accessibility_specialist": "gemini-3.1-flash-lite-preview", + "analytics_engineer": "gemini-3.1-flash-lite-preview", + "api_designer": "gemini-3-flash-preview", + "architect": "gemini-3-flash-preview", + "code_reviewer": "gemini-3-flash-preview", + "coder": "gemini-3.1-flash-lite-preview", + "compliance_reviewer": "gemini-3-flash-preview", + "content_strategist": "gemini-3.1-flash-lite-preview", + "copywriter": "gemini-3.1-flash-lite-preview", + "data_engineer": "gemini-3-flash-preview", + "debugger": "gemini-3-flash-preview", + "design_system_engineer": "gemini-3-flash-preview", + "devops_engineer": "gemini-3.1-flash-lite-preview", + "i18n_specialist": "gemini-3.1-flash-lite-preview", + "performance_engineer": "gemini-3.1-flash-lite-preview", + "product_manager": "gemini-3-flash-preview", + "refactor": "gemini-3.1-flash-lite-preview", + "security_engineer": "gemini-3-flash-preview", + "seo_specialist": "gemini-3.1-flash-lite-preview", + "technical_writer": "gemini-3.1-flash-lite-preview", + "tester": "gemini-3-flash-preview", + "ux_designer": "gemini-3-flash-preview", + "codebase_investigator": "gemini-3.1-flash-lite-preview" + } +} \ No newline at end of file diff --git a/plugins/maestro/src/core/agent-registry.js b/plugins/maestro/src/core/agent-registry.js index 428aa021..c6bca8bc 100644 --- a/plugins/maestro/src/core/agent-registry.js +++ b/plugins/maestro/src/core/agent-registry.js @@ -4,6 +4,7 @@ const KNOWN_AGENTS = Object.freeze([ 'architect', 'api_designer', 'code_reviewer', + 'codebase_investigator', // Native to gemini-cli 'coder', 'data_engineer', 'debugger', diff --git a/plugins/maestro/src/mcp/handlers/setup-models.js b/plugins/maestro/src/mcp/handlers/setup-models.js new file mode 100644 index 00000000..78bcd5a0 --- /dev/null +++ b/plugins/maestro/src/mcp/handlers/setup-models.js @@ -0,0 +1,77 @@ +'use strict'; + +const fs = require('fs'); +const path = require('path'); +const { atomicWriteSync } = require('../../core/atomic-write'); +const { resolveExtensionRoot } = require('../utils/extension-root'); + +/** + * Handle setup_models tool call. + * + * @param {Object} params - Tool arguments. + * @param {string} params.mode - The operating mode (quality, balanced, economic, skip). + * @param {string} projectRoot - The current project root. + * @returns {Promise} - Result of the operation. + */ +async function handleSetupModels(params, projectRoot) { + const mode = params.mode; + + if (mode === 'skip') { + return { status: 'skipped_model_setup' }; + } + + if (!['quality', 'balanced', 'economic'].includes(mode)) { + throw new Error(`Invalid mode: ${mode}`); + } + + const settingsPath = path.join(projectRoot, '.gemini', 'settings.json'); + + const extensionRoot = resolveExtensionRoot(); + const modesPath = path.join(extensionRoot, 'src', 'config', 'agent-modes.json'); + + let modes; + try { + modes = JSON.parse(fs.readFileSync(modesPath, 'utf8')); + } catch (err) { + throw new Error(`Failed to read agent-modes.json: ${err.message}`); + } + + const mapping = modes[mode]; + if (!mapping) { + throw new Error(`Unknown mode: ${mode}`); + } + + let settings = {}; + if (fs.existsSync(settingsPath)) { + try { + const content = fs.readFileSync(settingsPath, 'utf8'); + settings = JSON.parse(content || '{}'); + } catch (err) { + throw new Error(`Existing .gemini/settings.json is corrupted`); + } + } + + // Ensure experimental.enableAgents is true + settings.experimental = settings.experimental || {}; + settings.experimental.enableAgents = true; + + // Extend agents.overrides + settings.agents = settings.agents || {}; + settings.agents.overrides = settings.agents.overrides || {}; + + for (const [agent, model] of Object.entries(mapping)) { + settings.agents.overrides[agent] = { + ...(settings.agents.overrides[agent] || {}), + modelConfig: { model }, + }; + } + + // Preserve existing settings while applying overrides + atomicWriteSync(settingsPath, JSON.stringify(settings, null, 2)); + + return { status: 'success', mode }; +} + +module.exports = { + handleSetupModels, +}; diff --git a/plugins/maestro/src/mcp/tool-packs/workspace/index.js b/plugins/maestro/src/mcp/tool-packs/workspace/index.js index f381d3d5..32f6ed9b 100644 --- a/plugins/maestro/src/mcp/tool-packs/workspace/index.js +++ b/plugins/maestro/src/mcp/tool-packs/workspace/index.js @@ -9,6 +9,7 @@ const { } = require('../../handlers/assess-task-complexity'); const { handleValidatePlan } = require('../../handlers/validate-plan'); const { handleResolveSettings } = require('../../handlers/resolve-settings'); +const { handleSetupModels } = require('../../handlers/setup-models'); function createToolPack() { return defineToolPack({ @@ -76,12 +77,29 @@ function createToolPack() { }, }, }, + { + name: 'setup_models', + description: + 'Configure Maestro subagent models in .gemini/settings.json based on selected mode.', + inputSchema: { + type: 'object', + properties: { + mode: { + type: 'string', + enum: ['quality', 'balanced', 'economic', 'skip'], + description: 'The operating mode to configure.', + }, + }, + required: ['mode'], + }, + }, ], handlers: { initialize_workspace: handleInitializeWorkspace, assess_task_complexity: handleAssessTaskComplexity, validate_plan: handleValidatePlan, resolve_settings: handleResolveSettings, + setup_models: handleSetupModels, }, }); } From 56d4542f09d96d02c522afcd8e6c6fbe05c7f90d Mon Sep 17 00:00:00 2001 From: Harald Heckmann Date: Mon, 13 Apr 2026 07:06:51 +0200 Subject: [PATCH 20/20] test: satisfy all tests --- tests/transforms/mcp-pack-composition.test.js | 1 + tests/transforms/mcp-workspace-pack.test.js | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/transforms/mcp-pack-composition.test.js b/tests/transforms/mcp-pack-composition.test.js index 43e687ca..8629e9d7 100644 --- a/tests/transforms/mcp-pack-composition.test.js +++ b/tests/transforms/mcp-pack-composition.test.js @@ -20,6 +20,7 @@ describe('mcp pack composition', () => { 'assess_task_complexity', 'validate_plan', 'resolve_settings', + 'setup_models', 'create_session', 'get_session_status', 'update_session', diff --git a/tests/transforms/mcp-workspace-pack.test.js b/tests/transforms/mcp-workspace-pack.test.js index 250f5cd9..0e295158 100644 --- a/tests/transforms/mcp-workspace-pack.test.js +++ b/tests/transforms/mcp-workspace-pack.test.js @@ -42,6 +42,7 @@ describe('workspace tool pack', () => { 'assess_task_complexity', 'validate_plan', 'resolve_settings', + 'setup_models', ] ); });