/**
 * ClaudeExecutor
 *
 * Handles Claude Code binary execution for session management.
 * Uses modern Claude Code CLI flags:
 * - --system-prompt for persistent context
 * - --output-format stream-json for streaming
 * - --resume for session persistence
 * - --name for session identification
 * - --model for model selection
 */
import { execSync, spawn } from 'child_process';
import { existsSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
export class ClaudeExecutor {
    claudeBin;
    schemaDir;
    constructor(config) {
        this.claudeBin = config?.claudeBin || process.env.CLAUDE_BIN || this.detectClaudeBin();
        this.schemaDir = config?.schemaDir || join(__dirname, '../../../schema');
    }
    detectClaudeBin() {
        const home = process.env.HOME || process.env.USERPROFILE || '';
        const possiblePaths = [
            join(home, '.claude/local/claude'),
            'claude'
        ];
        for (const p of possiblePaths) {
            try {
                execSync(`${p} --version`, { stdio: 'pipe' });
                return p;
            }
            catch { /* try next */ }
        }
        return join(home, '.claude/local/claude');
    }
    /**
     * Initialize a new Claude Code session with schema loading.
     * Uses --system-prompt for persistent SpecVerse context.
     */
    async initialize(options) {
        const prompt = this.buildInitPrompt(options);
        const args = [
            '--session-id', options.sessionId,
            '--print',
            '--output-format', 'json',
            '--permission-mode', 'plan',
            '--name', `specverse-session-${options.sessionId.slice(0, 8)}`,
        ];
        // Add schema directory for context
        if (existsSync(this.schemaDir)) {
            args.push('--add-dir', this.schemaDir);
        }
        // Add system prompt for persistent SpecVerse context
        args.push('--system-prompt', `You are a SpecVerse specification assistant helping generate and modify .specly files.
   - Prompt Version: ${options.pver || 'default'}
   - Session: ${options.sessionId}
   - Schema loaded from: ${this.schemaDir}`);
        args.push('-p', prompt);
        try {
            const result = execSync([this.claudeBin, ...args.map(a => a.includes(' ') ? `"${a}"` : a)].join(' '), { encoding: 'utf8', stdio: 'pipe', timeout: 60000 });
            if (!this.verifyInitialization(result)) {
                throw new Error('Failed to initialize session: schemas not loaded');
            }
            return options.sessionId;
        }
        catch (error) {
            throw new Error(`Claude Code initialization failed: ${error.message}`);
        }
    }
    /**
     * Resume existing session with new prompt (blocking).
     */
    async resume(sessionId, prompt) {
        const args = [
            '--resume', sessionId,
            '--print',
            '--output-format', 'json',
            '-p', prompt,
        ];
        try {
            const result = execSync([this.claudeBin, ...args.map(a => a.includes(' ') ? `"${a}"` : a)].join(' '), { encoding: 'utf8', stdio: 'pipe', timeout: 300000 });
            return result;
        }
        catch (error) {
            throw new Error(`Claude Code resume failed: ${error.message}`);
        }
    }
    /**
     * Resume with streaming output (non-blocking).
     * Returns a ChildProcess — caller reads stdout for stream-json messages.
     */
    resumeStreaming(sessionId, prompt) {
        const args = [
            '--resume', sessionId,
            '--print',
            '--output-format', 'stream-json',
            '--include-partial-messages',
            '-p', prompt,
        ];
        return spawn(this.claudeBin, args, {
            stdio: ['pipe', 'pipe', 'pipe'],
            env: { ...process.env },
        });
    }
    buildInitPrompt(options) {
        const schemaAI = join(this.schemaDir, 'SPECVERSE-SCHEMA-AI.yaml');
        const minimalRef = join(this.schemaDir, 'MINIMAL-SYNTAX-REFERENCE.specly');
        return `Initialize SpecVerse AI session.

Load these schema files for reference:
- ${schemaAI} (YAML schema with AI guidance)
- ${minimalRef} (minimal syntax reference)

Session config:
- Prompt version: ${options.pver || 'default'}
- Session ID: ${options.sessionId}
- Name: ${options.name || 'unnamed'}

Acknowledge ready with a brief summary of loaded schemas.`;
    }
    verifyInitialization(result) {
        try {
            const parsed = JSON.parse(result);
            return parsed && (parsed.result || parsed.content || parsed.output);
        }
        catch {
            // Non-JSON result — check for common success indicators
            return result.includes('schema') || result.includes('ready') || result.includes('loaded') || result.length > 10;
        }
    }
}
//# sourceMappingURL=claude-executor.js.map