import { exec } from "node:child_process";
import { promisify } from "node:util";
import { z } from "zod";
import { createToolFactory, PermissionLevel, ToolCategory } from "../types.js";
const execAsync = promisify(exec);
/**
 * Bash tool - Executes bash commands in a persistent shell session.
 */
export const bashToolFactory = createToolFactory("bash", () => ({
    description: `
Executes a given bash command in a persistent shell session with optional timeout, ensuring proper handling and security measures.

IMPORTANT: This tool is for terminal operations like git, npm, docker, etc. DO NOT use it for file operations (reading, writing, editing, searching, finding files) - use the specialized tools for this instead.
`,
    category: ToolCategory.GENERAL,
    defaultPermission: PermissionLevel.PROMPT,
    inputSchema: z.object({
        command: z.string().describe("Command to execute"),
        description: z
            .string()
            .optional()
            .describe("Description of what command does"),
        timeout: z
            .number()
            .optional()
            .default(120000)
            .describe("Timeout in ms (max 600000, default 120000)"),
        run_in_background: z
            .boolean()
            .optional()
            .default(false)
            .describe("Run in background (default: false)"),
    }),
    execute: async ({ command, description: _description, timeout, run_in_background }, options) => {
        try {
            if (run_in_background) {
                // For background execution, spawn without waiting
                const childProcess = exec(command, {
                    timeout,
                    maxBuffer: 10 * 1024 * 1024, // 10MB
                });
                return {
                    success: true,
                    message: "Command started in background",
                    pid: childProcess.pid,
                };
            }
            // For foreground execution, wait for completion
            const { stdout, stderr } = await execAsync(command, {
                timeout,
                maxBuffer: 10 * 1024 * 1024, // 10MB
                signal: options?.abortSignal,
            });
            return {
                success: true,
                stdout: stdout || "",
                stderr: stderr || "",
                exitCode: 0,
            };
        }
        catch (error) {
            // Handle timeout
            if (error.killed && error.signal === "SIGTERM") {
                throw new Error(`Command timed out after ${timeout}ms`);
            }
            // Handle non-zero exit code
            return {
                success: false,
                stdout: error.stdout || "",
                stderr: error.stderr || "",
                exitCode: error.code || 1,
                error: error.message,
            };
        }
    },
}));
//# sourceMappingURL=bash.js.map