diff --git a/Releases/v4.0.3+/.claude/hooks/SecurityValidator.hook.ts b/Releases/v4.0.3+/.claude/hooks/SecurityValidator.hook.ts index 9c302d4..a8cf075 100755 --- a/Releases/v4.0.3+/.claude/hooks/SecurityValidator.hook.ts +++ b/Releases/v4.0.3+/.claude/hooks/SecurityValidator.hook.ts @@ -63,9 +63,22 @@ import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'fs'; import { join } from 'path'; import { homedir } from 'os'; -import { parse as parseYaml } from 'yaml'; +import type { parse as YamlParse } from 'yaml'; import { configPath, codePath } from './lib/paths'; +// Lazy yaml load — static `import 'yaml'` crashes module load when the package +// isn't resolvable from this hook's directory. +let parseYaml: typeof YamlParse | null = null; + +async function ensureYamlLoaded(): Promise { + if (parseYaml) return; + try { + parseYaml = (await import('yaml')).parse; + } catch { + parseYaml = null; + } +} + // ======================================== // Security Event Logging // ======================================== @@ -220,6 +233,16 @@ function loadPatterns(): PatternsConfig { }; } + if (!parseYaml) { + return { + version: '0.0', + philosophy: { mode: 'permissive', principle: 'YAML parser unavailable - fail open' }, + bash: { trusted: [], blocked: [], confirm: [], alert: [] }, + paths: { zeroAccess: [], readOnly: [], confirmWrite: [], noDelete: [] }, + projects: {} + }; + } + try { const content = readFileSync(patternsPath, 'utf-8'); patternsCache = parseYaml(content) as PatternsConfig; @@ -551,6 +574,7 @@ function handleRead(input: HookInput): void { // ======================================== async function main(): Promise { + await ensureYamlLoaded(); let input: HookInput; try {