import { z } from 'zod';
import { UnifiedTool } from './registry.js';
import { executeOpenCodeCLI } from '../utils/opencodeExecutor.js';
import { STATUS_MESSAGES, ERROR_MESSAGES, MANAGERS } from '../constants.js';
// Schema with prompt and optional working directory
const managerToolSchema = z.object({
prompt: z.string().min(1).describe("Task or question about this domain"),
cwd: z.string().optional().describe("Working directory for opencode. Target project must have agent files (run init-project.sh first)."),
});
/**
* Create a specialized tool for a specific full-stack manager.
* Uses the corresponding opencode agent (e.g., --agent frontend-manager).
*/
function createManagerTool(meta: typeof MANAGERS[number]): UnifiedTool {
return {
name: meta.id,
description: meta.description,
zodSchema: managerToolSchema,
prompt: {
description: `Specialized OpenCode agent for ${meta.name}. Focus: ${meta.focus}`,
},
category: 'fullstack',
execute: async (args, onProgress) => {
const { prompt, cwd } = args;
if (!prompt?.trim()) {
throw new Error(ERROR_MESSAGES.NO_PROMPT_PROVIDED);
}
// Use the manager's agent directly - agent file must exist in .opencode/agent/
const result = await executeOpenCodeCLI(
prompt as string,
meta.id, // Agent name matches tool id (e.g., 'frontend-manager')
undefined, // Use server-configured model
onProgress,
cwd as string | undefined
);
return `${STATUS_MESSAGES.OPENCODE_RESPONSE}\n${result}`;
}
};
}
/**
* Generate all manager tools
*/
export function generateManagerTools(): UnifiedTool[] {
return MANAGERS.map(meta => createManagerTool(meta));
}