| 40 | const CITADEL_UI = process.env.CITADEL_UI === 'true'; |
| 41 | |
| 42 | // For CITADEL_UI (desktop app): structured JSON to stdout. |
| 43 | // For CLI: human-readable message to stderr — Claude Code includes stderr in the |
| 44 | // hook error that the agent reads, so this is what surfaces as the block reason. |
| 45 | function hookOutput(hookName, action, message, data = {}) { |
| 46 | if (CITADEL_UI) { |
| 47 | process.stdout.write(JSON.stringify({ |
| 48 | hook: hookName, |
| 49 | action, |
| 50 | message, |
| 51 | timestamp: new Date().toISOString(), |
| 52 | data, |
| 53 | })); |
| 54 | } else { |
| 55 | process.stderr.write(message); |
| 56 | } |
| 57 | } |