// tools/reconcile-session-safeguard-hook.ts — SPEC-585: Install PreCompaction session-safeguard hook
// Writes .claude/hooks/planu-session-safeguard.sh and registers PreCompaction (or Stop fallback)
// in .claude/settings.json. Idempotent.
import { readFile, writeFile, mkdir, chmod } from 'node:fs/promises';
import { existsSync } from 'node:fs';
import { join, dirname, resolve } from 'node:path';
import { fileURLToPath } from 'node:url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const HOOK_TEMPLATE_PATH = resolve(__dirname, '../config/hook-templates/planu-session-safeguard.sh');
const HOOK_RELATIVE_PATH = '.claude/hooks/planu-session-safeguard.sh';
const SETTINGS_PATH = '.claude/settings.json';
const HOOK_COMMAND = 'bash .claude/hooks/planu-session-safeguard.sh';
/** Detect whether PreCompaction hook type is supported by checking CLAUDE_CODE_VERSION env var. */
function detectHookType() {
    const version = process.env.CLAUDE_CODE_VERSION ?? '';
    if (!version) {
        // Unknown version — default to PreCompaction (newer Claude Code) with Stop fallback handled below
        return 'PreCompaction';
    }
    // PreCompaction was introduced in Claude Code. Any version string present is treated as supporting it.
    return 'PreCompaction';
}
async function readSettings(projectPath) {
    const settingsFile = join(projectPath, SETTINGS_PATH);
    try {
        const raw = await readFile(settingsFile, 'utf-8');
        return JSON.parse(raw);
    }
    catch {
        return {};
    }
}
async function writeSettings(projectPath, data) {
    const settingsFile = join(projectPath, SETTINGS_PATH);
    await mkdir(dirname(settingsFile), { recursive: true });
    await writeFile(settingsFile, JSON.stringify(data, null, 2) + '\n', 'utf-8');
}
function hookAlreadyRegistered(settings, hookType) {
    const entries = settings.hooks?.[hookType];
    if (!Array.isArray(entries)) {
        return false;
    }
    return entries.some((e) => Array.isArray(e.hooks) && e.hooks.some((h) => h.command === HOOK_COMMAND));
}
async function installHookFile(projectPath) {
    const hookDest = join(projectPath, HOOK_RELATIVE_PATH);
    const alreadyExists = existsSync(hookDest);
    let templateContent;
    try {
        templateContent = await readFile(HOOK_TEMPLATE_PATH, 'utf-8');
    }
    catch {
        templateContent =
            [
                '#!/usr/bin/env bash',
                'set -uo pipefail',
                'log="${CLAUDE_PROJECT_DIR:-.}/.claude/logs/session-safeguard.log"',
                'mkdir -p "$(dirname "$log")"',
                '{',
                '  echo "[$(date -u +%FT%TZ)] session-safeguard fired"',
                '  cd "${CLAUDE_PROJECT_DIR:-.}" || exit 0',
                '  current=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "")',
                '  if [[ -n "$current" && "$current" != "HEAD" ]]; then',
                '    git push origin "$current" --no-verify 2>&1 || echo "push failed or nothing to push"',
                '  fi',
                '} >> "$log" 2>&1',
                'exit 0',
            ].join('\n') + '\n';
    }
    await mkdir(dirname(hookDest), { recursive: true });
    await writeFile(hookDest, templateContent, 'utf-8');
    await chmod(hookDest, 0o755);
    return !alreadyExists;
}
async function registerHookInSettings(projectPath, hookType) {
    const settings = await readSettings(projectPath);
    if (hookAlreadyRegistered(settings, hookType)) {
        return false;
    }
    const entry = {
        matcher: '',
        hooks: [{ type: 'command', command: HOOK_COMMAND }],
    };
    const hooksMap = settings.hooks ?? {};
    const hookEntries = hooksMap[hookType];
    const existing = Array.isArray(hookEntries) ? hookEntries : [];
    const updated = {
        ...settings,
        hooks: {
            ...(settings.hooks ?? {}),
            [hookType]: [...existing, entry],
        },
    };
    await writeSettings(projectPath, updated);
    return true;
}
/** Install the session-safeguard hook file and register it in .claude/settings.json. Idempotent. */
export async function installSessionSafeguardHook(projectPath) {
    const resolved = resolve(projectPath);
    const hookType = detectHookType();
    const hookInstalled = await installHookFile(resolved);
    // Register primary hook type
    let settingsUpdated = await registerHookInSettings(resolved, hookType);
    // Also register Stop hook as fallback when primary is PreCompaction
    if (hookType === 'PreCompaction') {
        const stopUpdated = await registerHookInSettings(resolved, 'Stop');
        settingsUpdated = settingsUpdated || stopUpdated;
    }
    return { hookInstalled, settingsUpdated, hookType };
}
//# sourceMappingURL=reconcile-session-safeguard-hook.js.map