Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,4 @@ temp/
docs/maestro/
docs/superpowers/
hooks/permissions.json
.worktrees
77 changes: 77 additions & 0 deletions claude/src/config/agent-modes.json
Original file line number Diff line number Diff line change
@@ -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"
}
}
1 change: 1 addition & 0 deletions claude/src/core/agent-registry.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const KNOWN_AGENTS = Object.freeze([
'architect',
'api_designer',
'code_reviewer',
'codebase_investigator', // Native to gemini-cli
'coder',
'data_engineer',
'debugger',
Expand Down
77 changes: 77 additions & 0 deletions claude/src/mcp/handlers/setup-models.js
Original file line number Diff line number Diff line change
@@ -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<Object>} - 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,
};
18 changes: 18 additions & 0 deletions claude/src/mcp/tool-packs/workspace/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -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,
},
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,12 @@ This preamble maps generic step references to Gemini CLI tool syntax.
| Load template/reference/protocol | `get_skill_content(resources: ["<name>"])` |
| Delegate to agent | Call agent tool by name: `coder(query: "...")`, `tester(query: "...")`, `design_system_engineer(query: "...")` |
| MCP tools | `mcp_maestro_<tool_name>` (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

Expand Down
Loading
Loading