#!/usr/bin/env node /** * Pre-commit guard: refuses the commit if docs/work/_system/_state.json is staged * but is not byte-identical to what `pnpm work rebuild-state` would emit * given the current markdown content of docs/work/. * * Run from .husky/pre-commit AFTER lint-staged and AFTER the conditional * rebuild-state + re-stage step. By that point the staged _state.json * should already match the rebuild output. This script is the safety net * for the case where someone hand-edits _state.json without going through * rebuild-state. * * Exit codes: * 0 — _state.json is in sync (or not staged at all) * 1 — _state.json is staged but out of sync */ import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; import { execSync } from "node:child_process"; import { buildState } from "./state-builder.mjs"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const REPO_ROOT = path.resolve(__dirname, "..", ".."); const WORK_ROOT = path.join(REPO_ROOT, "docs", "work"); const STATE_FILE = path.join(WORK_ROOT, "_system", "_state.json"); function stagedFiles() { const out = execSync("git diff --cached --name-only", { cwd: REPO_ROOT, encoding: "utf8", }); return out.split("\n").filter(Boolean); } function main() { const staged = stagedFiles(); const stateRel = path.relative(REPO_ROOT, STATE_FILE); if ( !staged.includes(stateRel) && !staged.some((f) => f.startsWith("docs/work/") && f.endsWith(".md")) ) { process.exit(0); } if (!fs.existsSync(STATE_FILE)) { console.error( "✗ state-sync-guard: docs/work/_system/_state.json missing. Run `pnpm work rebuild-state`.", ); process.exit(1); } const onDisk = fs.readFileSync(STATE_FILE, "utf8"); const fresh = JSON.stringify(buildState(WORK_ROOT), null, 2) + "\n"; // The `updated_at` timestamp will always differ. Strip it from both sides // before comparing. const stripUpdatedAt = (s) => s.replace(/"updated_at":\s*"[^"]+",?\s*\n?/, ""); if (stripUpdatedAt(onDisk) === stripUpdatedAt(fresh)) { process.exit(0); } console.error( "✗ state-sync-guard: docs/work/_system/_state.json is out of sync with markdown.", ); console.error(" Run: pnpm work rebuild-state"); console.error(" Then: git add docs/work/_system/_state.json"); process.exit(1); } main();