#!/usr/bin/env node
/**
 * git-guard.cjs — PreToolUse hook (matcher: Bash).
 *
 * Blocks git WRITE commands issued by Claude Code: commit, push, branch <name>,
 * checkout -b, switch -c, tag, worktree add, reset --hard, merge, rebase.
 * Read-only git (status, diff, log, branch -a, for-each-ref, …) stays allowed.
 *
 * Mechanism — PreToolUse exit code 2 BLOCKS the tool call and feeds the message
 * back to Claude. Exit 1 only logs a warning and lets the action through (the
 * classic trap), so we deliberately use exit 2. We also emit the structured
 * `permissionDecision: "block"` output, mirroring appsettings-guard.sh.
 *
 * Pure Node — no jq, no bash — so it behaves identically on Windows / WSL /
 * Git Bash / macOS / Linux. Deployed to ~/.claude/hooks/git-guard.cjs and
 * registered in ~/.claude/settings.json by `ss install` / `ss upgrade`.
 *
 * Manual override — set GIT_GUARD_OFF=1 in the environment (or settings.json
 * "env") to disable the guard for a session. This is a USER-only switch: a value
 * set inside a Claude Bash/PowerShell call lives in that child shell and does NOT
 * reach this hook's parent process, so Claude cannot self-bypass — only the user
 * (who controls the launch env / settings.json) can flip it.
 */
'use strict';

// User-only kill switch (see header). Off by default.
const off = process.env.GIT_GUARD_OFF;
if (off && off !== '0' && off.toLowerCase() !== 'false') process.exit(0);

function readStdin() {
  try {
    return require('fs').readFileSync(0, 'utf8');
  } catch {
    return '';
  }
}

let cmd = '';
try {
  const input = JSON.parse(readStdin());
  cmd = (input && input.tool_input && input.tool_input.command) || '';
} catch {
  // Not JSON / nothing to inspect — allow.
  process.exit(0);
}

if (!cmd) process.exit(0);

// git WRITE verbs requiring MANUAL approval. `branch\s+[^-]` blocks
// `git branch <name>` (create) while leaving `git branch -a` (list) allowed.
// Multi-command lines are caught by the `(^|[;&|\s])` prefix (e.g. `cd x && git commit`).
const WRITE_RE =
  /(^|[;&|\s])git\s+(commit|push|branch\s+[^-]|checkout\s+-b|switch\s+-c|tag|worktree\s+add|reset\s+--hard|merge|rebase)/i;

if (!WRITE_RE.test(cmd)) process.exit(0);

const reason =
  "🚫 Commande git d'écriture bloquée par git-guard (PreToolUse). " +
  'Branches, commits, push, tags, worktrees : validation MANUELLE requise. ' +
  "Propose la commande en une phrase et attends mon accord explicite.";

process.stdout.write(
  JSON.stringify({
    continue: true,
    hookSpecificOutput: {
      hookEventName: 'PreToolUse',
      permissionDecision: 'block',
      permissionDecisionReason: reason,
    },
  }),
);
process.stderr.write(reason + '\n');
process.exit(2);
