62 lines
3.3 KiB
JavaScript
62 lines
3.3 KiB
JavaScript
import { z } from "zod";
|
|
import { execSync } from 'child_process';
|
|
import { createContentResponse, createErrorResponse } from "./utils.js"; // Only need response creators
|
|
|
|
export function registerInitializeProjectTool(server) {
|
|
server.addTool({
|
|
name: "initialize_project", // snake_case for tool name
|
|
description: "Initializes a new Task Master project structure in the current working directory by running 'task-master init'.",
|
|
parameters: z.object({
|
|
projectName: z.string().optional().describe("The name for the new project."),
|
|
projectDescription: z.string().optional().describe("A brief description for the project."),
|
|
projectVersion: z.string().optional().describe("The initial version for the project (e.g., '0.1.0')."),
|
|
authorName: z.string().optional().describe("The author's name."),
|
|
skipInstall: z.boolean().optional().default(false).describe("Skip installing dependencies automatically."),
|
|
addAliases: z.boolean().optional().default(false).describe("Add shell aliases (tm, taskmaster) to shell config file."),
|
|
yes: z.boolean().optional().default(false).describe("Skip prompts and use default values or provided arguments."),
|
|
// projectRoot is not needed here as 'init' works on the current directory
|
|
}),
|
|
execute: async (args, { log }) => { // Destructure context to get log
|
|
try {
|
|
log.info(`Executing initialize_project with args: ${JSON.stringify(args)}`);
|
|
|
|
// Construct the command arguments carefully
|
|
// Using npx ensures it uses the locally installed version if available, or fetches it
|
|
let command = 'npx task-master init';
|
|
const cliArgs = [];
|
|
if (args.projectName) cliArgs.push(`--name "${args.projectName.replace(/"/g, '\\"')}"`); // Escape quotes
|
|
if (args.projectDescription) cliArgs.push(`--description "${args.projectDescription.replace(/"/g, '\\"')}"`);
|
|
if (args.projectVersion) cliArgs.push(`--version "${args.projectVersion.replace(/"/g, '\\"')}"`);
|
|
if (args.authorName) cliArgs.push(`--author "${args.authorName.replace(/"/g, '\\"')}"`);
|
|
if (args.skipInstall) cliArgs.push('--skip-install');
|
|
if (args.addAliases) cliArgs.push('--aliases');
|
|
if (args.yes) cliArgs.push('--yes');
|
|
|
|
command += ' ' + cliArgs.join(' ');
|
|
|
|
log.info(`Constructed command: ${command}`);
|
|
|
|
// Execute the command in the current working directory of the server process
|
|
// Capture stdout/stderr. Use a reasonable timeout (e.g., 5 minutes)
|
|
const output = execSync(command, { encoding: 'utf8', stdio: 'pipe', timeout: 300000 });
|
|
|
|
log.info(`Initialization output:\n${output}`);
|
|
|
|
// Return a standard success response manually
|
|
return createContentResponse(
|
|
"Project initialized successfully.",
|
|
{ output: output } // Include output in the data payload
|
|
);
|
|
|
|
} catch (error) {
|
|
// Catch errors from execSync or timeouts
|
|
const errorMessage = `Project initialization failed: ${error.message}`;
|
|
const errorDetails = error.stderr?.toString() || error.stdout?.toString() || error.message; // Provide stderr/stdout if available
|
|
log.error(`${errorMessage}\nDetails: ${errorDetails}`);
|
|
|
|
// Return a standard error response manually
|
|
return createErrorResponse(errorMessage, { details: errorDetails });
|
|
}
|
|
}
|
|
});
|
|
}
|