// Mirror of Claude Code's settings-discovery walk for hook resolution.
// Run at spawn time so the operator can see which hook events Claude Code
// would actually load for the PTY about to start. If a Stop hook entry
// lives in an unread settings.json (e.g. wrong cwd, wrong CLAUDE_CONFIG_DIR),
// the absence shows up in the `hooksResolved=` field of `pty-spawn-start`.
//
// Claude Code's order, from the docs:
//   1. enterprise managed settings (skipped here — out of scope)
//   2. user settings: $CLAUDE_CONFIG_DIR/settings.json (or ~/.claude/settings.json)
//   3. project settings: walk parents of cwd up to .git for
//      .claude/settings.json and .claude/settings.local.json
// We accumulate the set of hook event names declared across all readable
// files. We do NOT execute or rank-order them — this is observability,
// not policy.
import { existsSync, readFileSync, statSync } from 'node:fs';
import { dirname, join } from 'node:path';
import { homedir } from 'node:os';
const HOOK_EVENTS = [
    'PreToolUse',
    'PostToolUse',
    'UserPromptSubmit',
    'Stop',
    'SubagentStop',
    'PreCompact',
    'Notification',
    'SessionStart',
    'SessionEnd',
];
function readSettings(path) {
    try {
        if (!existsSync(path))
            return null;
        const raw = readFileSync(path, 'utf-8');
        return JSON.parse(raw);
    }
    catch {
        return null;
    }
}
function eventsWithHooks(parsed, into) {
    if (!parsed || typeof parsed !== 'object')
        return;
    const hooks = parsed.hooks;
    if (!hooks || typeof hooks !== 'object')
        return;
    for (const event of HOOK_EVENTS) {
        const list = hooks[event];
        if (Array.isArray(list) && list.length > 0)
            into.add(event);
    }
}
function isDir(path) {
    try {
        return statSync(path).isDirectory();
    }
    catch {
        return false;
    }
}
/** Walk cwd's parents up to (and including) the first .git ancestor, or to
 *  filesystem root if no .git is found. At each level, look for
 *  `.claude/settings.json` and `.claude/settings.local.json`. */
function projectSettingsPaths(cwd) {
    const out = [];
    let cur = cwd;
    // Bound the walk to avoid pathological symlink loops.
    for (let i = 0; i < 64; i++) {
        out.push(join(cur, '.claude', 'settings.json'));
        out.push(join(cur, '.claude', 'settings.local.json'));
        if (isDir(join(cur, '.git')))
            break;
        const parent = dirname(cur);
        if (parent === cur)
            break;
        cur = parent;
    }
    return out;
}
/** Resolve the set of hook event names Claude Code would load for a PTY
 *  launched with the given `cwd` and `CLAUDE_CONFIG_DIR`. */
export function discoverHooks(spawnCwd, claudeConfigDir) {
    const userSettingsPath = join(claudeConfigDir ?? join(homedir(), '.claude'), 'settings.json');
    const projectPaths = projectSettingsPaths(spawnCwd);
    const found = new Set();
    eventsWithHooks(readSettings(userSettingsPath), found);
    for (const p of projectPaths)
        eventsWithHooks(readSettings(p), found);
    return HOOK_EVENTS.filter((e) => found.has(e));
}
//# sourceMappingURL=hooks-discovery.js.map