// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/git-hook-injector.ts — Inject planu auto-stage snippet into project git pre-commit hook
// SPEC-347: auto-stage planu HTML files so they are never left out of commits
import { readFile, writeFile, access, constants } from 'node:fs/promises';
import { join, resolve } from 'node:path';
const PLANU_SNIPPET = `\n# Planu: optional auto-stage specs (SPEC-466 — only source-of-truth files)\nif [ "$PLANU_ENABLE_AUTOCOMMIT" = "true" ]; then\n  git add planu/specs/ planu/conventions.json 2>/dev/null || true\nfi\n`;
const PLANU_MARKER = 'git add planu/';
async function fileExists(filePath) {
    try {
        await access(filePath, constants.F_OK);
        return true;
    }
    catch {
        return false;
    }
}
async function packageJsonHasDep(projectPath, depName) {
    try {
        const pkgPath = join(projectPath, 'package.json');
        const raw = await readFile(pkgPath, 'utf-8');
        const pkg = JSON.parse(raw);
        const deps = {
            ...pkg.dependencies,
            ...pkg.devDependencies,
        };
        return depName in deps;
    }
    catch {
        return false;
    }
}
export async function detectHookSystem(projectPath) {
    if (await fileExists(join(projectPath, '.husky'))) {
        return 'husky';
    }
    if ((await fileExists(join(projectPath, 'lefthook.yml'))) ||
        (await fileExists(join(projectPath, 'lefthook.yaml')))) {
        return 'lefthook';
    }
    if (await packageJsonHasDep(projectPath, 'simple-git-hooks')) {
        return 'simple-git-hooks';
    }
    if (await fileExists(join(projectPath, '.git', 'hooks', 'pre-commit'))) {
        return 'native';
    }
    return 'none';
}
async function injectIntoFile(hookFile) {
    let content;
    try {
        content = await readFile(hookFile, 'utf-8');
    }
    catch {
        content = '#!/bin/sh\n';
    }
    if (content.includes(PLANU_MARKER)) {
        return { injected: false, alreadyPresent: true };
    }
    await writeFile(hookFile, content + PLANU_SNIPPET, 'utf-8');
    return { injected: true, alreadyPresent: false };
}
export async function injectPlanuAutoStage(projectPath) {
    const hookSystem = await detectHookSystem(projectPath);
    const absPath = resolve(projectPath);
    if (hookSystem === 'husky') {
        const hookFile = join(absPath, '.husky', 'pre-commit');
        const { injected, alreadyPresent } = await injectIntoFile(hookFile);
        return { injected, hookSystem, hookFile, alreadyPresent };
    }
    if (hookSystem === 'native') {
        const hookFile = join(absPath, '.git', 'hooks', 'pre-commit');
        const { injected, alreadyPresent } = await injectIntoFile(hookFile);
        return { injected, hookSystem, hookFile, alreadyPresent };
    }
    // lefthook / simple-git-hooks: cannot auto-inject, return manual instructions
    const manualInstructions = hookSystem === 'lefthook'
        ? `Add to lefthook.yml under pre-commit commands:\n  - run: '[ "$PLANU_ENABLE_AUTOCOMMIT" = "true" ] && git add planu/specs/ planu/conventions.json 2>/dev/null || true'`
        : `Add to package.json "simple-git-hooks"."pre-commit":\n  "[ \\"$PLANU_ENABLE_AUTOCOMMIT\\" = \\"true\\" ] && git add planu/specs/ planu/conventions.json 2>/dev/null || true"`;
    return {
        injected: false,
        hookSystem,
        hookFile: '',
        alreadyPresent: false,
        manualInstructions,
    };
}
//# sourceMappingURL=git-hook-injector.js.map