/**
 * Dev command — runs the project's own dev script.
 *
 * Detects the package manager (bun/npm/pnpm/yarn) from the project,
 * then runs `<pm> run dev`. Before spawning, injects Agentuity AI
 * Gateway environment variables so LLM SDK calls (OpenAI, Anthropic,
 * Groq) are automatically routed through the gateway when the user
 * has an AGENTUITY_SDK_KEY configured.
 */
import { spawn } from 'node:child_process';
import { resolve } from 'node:path';
import { z } from 'zod';
import { getCommand } from "../../command-prefix.js";
import { getAuth, loadConfig, loadProjectSDKKey } from "../../config.js";
import { ErrorCode } from "../../errors.js";
import * as tui from "../../tui.js";
import { createCommand } from "../../types.js";
import { detectFrameworkWithPackageJson } from "../build/detect/index.js";
import { detectPackageManager, getRunCommand } from "../build/detect/util.js";
const DEFAULT_PORT = 3000;
export const command = createCommand({
    name: 'dev',
    description: 'Run the project development server',
    tags: ['mutating', 'slow'],
    idempotent: true,
    optional: { project: true },
    examples: [
        { command: getCommand('dev'), description: 'Start development server' },
        { command: getCommand('dev --port 8080'), description: 'Specify custom port' },
    ],
    schema: {
        options: z.object({
            port: z
                .number()
                .min(1024)
                .max(65535)
                .optional()
                .describe('Port to pass to the dev server via PORT env var'),
            script: z
                .string()
                .optional()
                .describe('Custom script name to run instead of "dev" (e.g., "dev:web")'),
        }),
    },
    async handler(ctx) {
        const { opts, projectDir, logger } = ctx;
        const rootDir = resolve(projectDir);
        // Read package.json
        const { packageJson } = await detectFrameworkWithPackageJson(rootDir);
        if (!packageJson) {
            tui.fatal('No package.json found. Ensure you are in a JS/TS project directory.', ErrorCode.CONFIG_INVALID);
        }
        // Determine which script to run
        const scriptName = opts.script ?? 'dev';
        if (!packageJson.scripts?.[scriptName]) {
            const available = packageJson.scripts
                ? Object.keys(packageJson.scripts).join(', ')
                : 'none';
            tui.fatal(`No "${scriptName}" script found in package.json. Available scripts: ${available}`, ErrorCode.CONFIG_INVALID);
        }
        // Detect package manager
        const pm = await detectPackageManager(rootDir);
        const runCmd = getRunCommand(pm);
        // Build the command
        const cmd = runCmd.split(' ');
        cmd.push(scriptName);
        // Build environment
        const env = { ...process.env };
        const port = opts.port ?? DEFAULT_PORT;
        env.PORT = String(port);
        // Resolve SDK key: env → .env files → auth profile
        if (!env.AGENTUITY_SDK_KEY) {
            const sdkKey = await loadProjectSDKKey(logger, rootDir);
            if (sdkKey) {
                env.AGENTUITY_SDK_KEY = sdkKey;
            }
            else {
                // No project-level SDK key — fall back to CLI auth key
                const auth = await getAuth();
                if (auth?.apiKey) {
                    env.AGENTUITY_SDK_KEY = auth.apiKey;
                    tui.warning('No linked Agentuity project found. Using your auth key for AI Gateway.');
                    tui.arrow(`Link this project: ${tui.colorInfo(tui.bold('agentuity project import'))}`);
                    tui.newline();
                }
            }
        }
        // Load profile config to get transport URL for gateway routing
        const config = await loadConfig();
        if (config?.overrides?.transport_url && !env.AGENTUITY_TRANSPORT_URL) {
            env.AGENTUITY_TRANSPORT_URL = config.overrides.transport_url;
        }
        if (config?.overrides?.catalyst_url && !env.AGENTUITY_CATALYST_URL) {
            env.AGENTUITY_CATALYST_URL = config.overrides.catalyst_url;
        }
        // Inject AI Gateway env vars so LLM SDKs route through Agentuity
        const gatewayInjected = injectGatewayEnv(env, logger);
        if (gatewayInjected) {
            tui.info('AI Gateway: routing LLM requests through Agentuity');
        }
        else if (!env.OPENAI_API_KEY && !env.ANTHROPIC_API_KEY) {
            tui.warning('No AI API keys found. Run ' +
                tui.bold('agentuity auth login') +
                ' to enable AI Gateway routing.');
        }
        // Run the dev command, inheriting stdio for full interactivity.
        // We use child_process.spawn directly here (rather than the
        // spawnInherit shim) so we can forward signals to the child.
        const [command, ...args] = cmd;
        const proc = spawn(command, args, {
            cwd: rootDir,
            env: { ...process.env, ...env },
            stdio: 'inherit',
        });
        // Forward signals
        const signalHandler = (signal) => {
            proc.kill(signal === 'SIGINT' ? 'SIGINT' : 'SIGTERM');
        };
        process.on('SIGINT', signalHandler);
        process.on('SIGTERM', signalHandler);
        const exitCode = await new Promise((resolve) => {
            proc.once('close', (code) => resolve(code));
        });
        process.off('SIGINT', signalHandler);
        process.off('SIGTERM', signalHandler);
        if (exitCode !== 0 && exitCode !== 130) {
            // 130 = SIGINT (Ctrl+C), which is normal
            logger.debug('Dev server exited with code %d', exitCode);
        }
        process.exit(exitCode ?? 0);
    },
});
const GATEWAY_PROVIDERS = [
    { apiKeyEnv: 'OPENAI_API_KEY', baseUrlEnv: 'OPENAI_BASE_URL', provider: 'openai' },
    { apiKeyEnv: 'ANTHROPIC_API_KEY', baseUrlEnv: 'ANTHROPIC_BASE_URL', provider: 'anthropic' },
    { apiKeyEnv: 'GROQ_API_KEY', baseUrlEnv: 'GROQ_BASE_URL', provider: 'groq' },
];
/**
 * Inject AI Gateway environment variables into the child process env.
 *
 * For each LLM provider, if the user hasn't set their own API key
 * (or it matches the SDK key), we redirect to the Agentuity gateway.
 * This lets `openai`, `@anthropic-ai/sdk`, and `groq-sdk` work
 * out of the box without separate provider API keys.
 */
function injectGatewayEnv(env, logger) {
    const sdkKey = env.AGENTUITY_SDK_KEY;
    if (!sdkKey)
        return false;
    let injected = false;
    const gatewayUrl = env.AGENTUITY_AIGATEWAY_URL ||
        env.AGENTUITY_TRANSPORT_URL ||
        env.AGENTUITY_CATALYST_URL ||
        'https://catalyst-usc.agentuity.cloud';
    for (const { apiKeyEnv, baseUrlEnv, provider } of GATEWAY_PROVIDERS) {
        const currentKey = env[apiKeyEnv];
        // If the user provided their own key (different from SDK key), leave it alone
        if (currentKey && currentKey !== sdkKey) {
            continue;
        }
        env[apiKeyEnv] = sdkKey;
        env[baseUrlEnv] = `${gatewayUrl}/gateway/${provider}`;
        logger.debug('AI Gateway: routing %s through %s', provider, env[baseUrlEnv]);
        injected = true;
    }
    return injected;
}
//# sourceMappingURL=index.js.map