site-mariage/.claude/hooks/lib/strict-runtime.js
Corentin Joguet bff653acd6 first commit
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 10:30:37 +02:00

82 lines
2.1 KiB
JavaScript

// Shared runtime helpers for the BYAN Strict Mode hooks.
//
// Reads two files :
// - .claude/hooks/lib/strict-config.json : generated from strict-mode.yaml
// by byan-sync-rules (static config : thresholds, keywords, banners).
// - .byan-strict/state.json : the live session state written by the
// byan_strict_* MCP tools (lib/strict-mode.js).
//
// Hooks only READ here. The authoritative writes live in the MCP tools.
const fs = require('fs');
const path = require('path');
function projectRoot() {
return process.env.CLAUDE_PROJECT_DIR || process.cwd();
}
function readJson(filePath) {
try {
if (!fs.existsSync(filePath)) return null;
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
} catch {
return null;
}
}
function loadConfig() {
const p = path.join(projectRoot(), '.claude', 'hooks', 'lib', 'strict-config.json');
return readJson(p);
}
function loadState() {
const p = path.join(projectRoot(), '.byan-strict', 'state.json');
return readJson(p);
}
// A strict session is "engaged" when it is active, has a locked scope, and
// has not been completed yet. This is the window where enforcement applies.
function isEngaged(state) {
return Boolean(state && state.active && state.scope_lock && !state.completed);
}
function passCount(state) {
return state && Array.isArray(state.self_verify_passes)
? state.self_verify_passes.length
: 0;
}
function lastVerdict(state) {
const passes = state && state.self_verify_passes;
if (!Array.isArray(passes) || passes.length === 0) return null;
return passes[passes.length - 1].verdict;
}
function readStdin() {
return new Promise((resolve) => {
if (process.stdin.isTTY) return resolve('');
let data = '';
process.stdin.on('data', (c) => (data += c));
process.stdin.on('end', () => resolve(data));
process.stdin.on('error', () => resolve(data));
});
}
function parseJson(raw) {
try {
return raw ? JSON.parse(raw) : {};
} catch {
return {};
}
}
module.exports = {
projectRoot,
loadConfig,
loadState,
isEngaged,
passCount,
lastVerdict,
readStdin,
parseJson,
};