MCPcopy Create free account
hub / github.com/SethGammon/Citadel / run

Function run

hooks_src/external-action-gate.js:69–188  ·  view source on GitHub ↗
(input)

Source from the content-addressed store, hash-verified

67 `[Citadel] External-action policy check failed closed (${reason}).\n` +
68 `The command was not run. Repair the hook input or policy configuration before retrying.\n`,
69 { reason }
70 );
71 process.exit(2);
72}
73
74function readGatePolicy() {
75 const sourcePath = path.join(health.PROJECT_ROOT, '.claude', 'harness.json');
76 if (fs.existsSync(sourcePath)) {
77 const raw = JSON.parse(fs.readFileSync(sourcePath, 'utf8'));
78 // Validate the source policy even if activation later falls back to an
79 // effective/default receipt. A malformed safety policy must not disappear.
80 readExternalActionPolicy(raw);
81 }
82 return readExternalActionPolicy(health.readConfig());
83}
84
85function main() {
86 let input = '';
87 process.stdin.setEncoding('utf8');
88 process.stdin.on('data', (chunk) => { input += chunk; });
89 process.stdin.on('end', () => {
90 try {
91 run(input);
92 } catch (error) {
93 failClosed('runtime-failure', error);
94 }
95 });
96}
97
98function run(input) {
99 let event;
100 try {
101 event = JSON.parse(input);
102 } catch (error) {
103 failClosed('parse-failure', error);
104 }
105
106 if (!event || typeof event !== 'object' || Array.isArray(event)) {
107 failClosed('invalid-input', new TypeError('hook input must be an object'));
108 }
109
110 if (typeof event.tool_name !== 'string' || !event.tool_name) {
111 failClosed('invalid-input', new TypeError('tool_name must be a non-empty string'));
112 }
113
114 if (event.tool_name !== 'Bash') process.exit(0);
115
116 if (!event.tool_input || typeof event.tool_input !== 'object' || Array.isArray(event.tool_input)) {
117 failClosed('invalid-input', new TypeError('Bash tool_input must be an object'));
118 }
119 const command = event.tool_input.command;
120 if (typeof command !== 'string' || !command.trim()) {
121 failClosed('invalid-input', new TypeError('Bash command must be a non-empty string'));
122 }
123
124 const policy = readGatePolicy();
125 const action = detectExternalAction(command, policy);
126

Callers 1

mainFunction · 0.70

Calls 3

readExternalActionPolicyFunction · 0.85
detectExternalActionFunction · 0.85
hookOutputFunction · 0.70

Tested by

no test coverage detected