// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/ai-integration/gemini/settings-generator.ts — Gemini settings generator (SPEC-267)
import { writeFileSync, mkdirSync, existsSync, readFileSync } from 'node:fs';
import { join } from 'node:path';
const HOOK_SCRIPTS_DIR = '.gemini/hooks';
// Shell scripts stored as plain strings — bash $ chars must NOT be template-interpolated
const HOOK_SCRIPT_SESSION_START = [
    '#!/usr/bin/env bash',
    '# Injected by Planu — session-start.sh',
    'BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
    'SPEC=$(echo "$BRANCH" | grep -oE \'SPEC-[0-9]+\' || echo "")',
    'if [ -n "$SPEC" ]; then',
    '  echo "Active spec: $SPEC | Branch: $BRANCH"',
    'else',
    '  echo "No active spec branch. Create a spec first."',
    'fi',
].join('\n');
const HOOK_SCRIPT_SESSION_END = [
    '#!/usr/bin/env bash',
    '# session-end.sh — optionally auto-commit planu/ changes',
    'if [ "$PLANU_ENABLE_AUTOCOMMIT" != "true" ]; then',
    '  exit 0',
    'fi',
    'if git diff --quiet HEAD -- planu/ 2>/dev/null; then',
    '  exit 0',
    'fi',
    'git add planu/specs/ planu/conventions.json && git commit -m "chore: auto-save planu session state" --no-verify 2>/dev/null || true',
].join('\n');
const HOOK_SCRIPT_BEFORE_AGENT = [
    '#!/usr/bin/env bash',
    '# before-agent.sh — inject active spec context',
    'BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
    'SPEC=$(echo "$BRANCH" | grep -oE \'SPEC-[0-9]+\' || echo "")',
    '[ -n "$SPEC" ] && echo "Spec in scope: $SPEC" || echo "No spec branch active."',
].join('\n');
const HOOK_SCRIPT_NOOP = [
    '#!/usr/bin/env bash',
    '# noop.sh — placeholder for future hooks',
    'exit 0',
].join('\n');
const HOOK_SCRIPT_BEFORE_TOOL_SELECTION = [
    '#!/usr/bin/env bash',
    '# before-tool-selection.sh — warn if no spec branch for write ops',
    'BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
    'if echo "$BRANCH" | grep -qE \'feat/SPEC-|fix/SPEC-\'; then',
    '  exit 0',
    'fi',
    'echo "WARNING: No spec branch active. Writing code without a spec is discouraged."',
].join('\n');
const HOOK_SCRIPT_BEFORE_TOOL = [
    '#!/usr/bin/env bash',
    '# before-tool.sh — scan for destructive operations',
    'TOOL_NAME="${TOOL_NAME:-}"',
    'if echo "$TOOL_NAME" | grep -qiE \'delete|remove|drop|truncate\'; then',
    '  echo "WARNING: Destructive operation detected: $TOOL_NAME"',
    'fi',
].join('\n');
const HOOK_SCRIPT_AFTER_TOOL = [
    '#!/usr/bin/env bash',
    '# after-tool.sh — verify spec when modifying src/',
    'TOOL_INPUT="${TOOL_INPUT:-}"',
    'if echo "$TOOL_INPUT" | grep -q \'src/\'; then',
    '  BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
    '  if ! echo "$BRANCH" | grep -qE \'feat/SPEC-|fix/SPEC-\'; then',
    '    echo "NOTICE: src/ modified outside a spec branch."',
    '  fi',
    'fi',
].join('\n');
const HOOK_SCRIPT_PRE_COMPRESS = [
    '#!/usr/bin/env bash',
    '# pre-compress.sh — trigger session_checkpoint',
    'echo "Session checkpoint triggered before context compression."',
].join('\n');
const HOOK_SCRIPT_NOTIFICATION = [
    '#!/usr/bin/env bash',
    '# notification.sh — show approved specs queue when idle',
    'echo "Planu queue: run \'list_specs --status approved\' to see pending specs."',
].join('\n');
function buildHooks() {
    return [
        {
            event: 'SessionStart',
            command: `bash ${HOOK_SCRIPTS_DIR}/session-start.sh`,
            timeout: 5000,
        },
        {
            event: 'SessionEnd',
            command: `bash ${HOOK_SCRIPTS_DIR}/session-end.sh`,
            timeout: 10000,
        },
        {
            event: 'BeforeAgent',
            command: `bash ${HOOK_SCRIPTS_DIR}/before-agent.sh`,
            timeout: 5000,
        },
        {
            event: 'AfterAgent',
            command: `bash ${HOOK_SCRIPTS_DIR}/noop.sh`,
            timeout: 1000,
        },
        {
            event: 'BeforeModel',
            command: `bash ${HOOK_SCRIPTS_DIR}/noop.sh`,
            timeout: 1000,
        },
        {
            event: 'AfterModel',
            command: `bash ${HOOK_SCRIPTS_DIR}/noop.sh`,
            timeout: 1000,
        },
        {
            event: 'BeforeToolSelection',
            command: `bash ${HOOK_SCRIPTS_DIR}/before-tool-selection.sh`,
            timeout: 3000,
        },
        {
            event: 'BeforeTool',
            command: `bash ${HOOK_SCRIPTS_DIR}/before-tool.sh`,
            timeout: 3000,
        },
        {
            event: 'AfterTool',
            command: `bash ${HOOK_SCRIPTS_DIR}/after-tool.sh`,
            timeout: 3000,
        },
        {
            event: 'PreCompress',
            command: `bash ${HOOK_SCRIPTS_DIR}/pre-compress.sh`,
            timeout: 10000,
        },
        {
            event: 'Notification',
            command: `bash ${HOOK_SCRIPTS_DIR}/notification.sh`,
            timeout: 3000,
        },
    ];
}
function buildHookScripts() {
    return {
        'session-start.sh': HOOK_SCRIPT_SESSION_START,
        'session-end.sh': HOOK_SCRIPT_SESSION_END,
        'before-agent.sh': HOOK_SCRIPT_BEFORE_AGENT,
        'noop.sh': HOOK_SCRIPT_NOOP,
        'before-tool-selection.sh': HOOK_SCRIPT_BEFORE_TOOL_SELECTION,
        'before-tool.sh': HOOK_SCRIPT_BEFORE_TOOL,
        'after-tool.sh': HOOK_SCRIPT_AFTER_TOOL,
        'pre-compress.sh': HOOK_SCRIPT_PRE_COMPRESS,
        'notification.sh': HOOK_SCRIPT_NOTIFICATION,
    };
}
export function generateGeminiSettings(_projectPath) {
    return {
        hooks: buildHooks(),
    };
}
export function writeGeminiSettings(projectPath) {
    const geminiDir = join(projectPath, '.gemini');
    const hooksDir = join(projectPath, HOOK_SCRIPTS_DIR);
    /* v8 ignore start */
    if (!existsSync(geminiDir)) {
        mkdirSync(geminiDir, { recursive: true });
    }
    if (!existsSync(hooksDir)) {
        mkdirSync(hooksDir, { recursive: true });
    }
    /* v8 ignore stop */
    const settingsPath = join(geminiDir, 'settings.json');
    const settings = generateGeminiSettings(projectPath);
    let existing = {};
    /* v8 ignore start */
    if (existsSync(settingsPath)) {
        try {
            existing = JSON.parse(readFileSync(settingsPath, 'utf8'));
        }
        catch {
            // ignore malformed JSON — overwrite
        }
    }
    /* v8 ignore stop */
    const merged = {
        ...existing,
        hooks: settings.hooks,
    };
    writeFileSync(settingsPath, JSON.stringify(merged, null, 2) + '\n', 'utf8');
    const scripts = buildHookScripts();
    for (const [filename, content] of Object.entries(scripts)) {
        const scriptPath = join(hooksDir, filename);
        /* v8 ignore start */
        if (!existsSync(scriptPath)) {
            writeFileSync(scriptPath, content, { encoding: 'utf8', mode: 0o755 });
        }
        /* v8 ignore stop */
    }
}
//# sourceMappingURL=settings-generator.js.map