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

Function main

hooks_src/post-edit.js:50–111  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

48// ── Main ─────────────────────────────────────────────────────────────────────
49
50function main() {
51 let input = '';
52 process.stdin.setEncoding('utf8');
53 process.stdin.on('data', (chunk) => { input += chunk; });
54 process.stdin.on('end', () => {
55 const startTime = Date.now();
56 let event;
57 try {
58 event = JSON.parse(input);
59 } catch {
60 process.exit(0);
61 }
62
63 const toolName = event.tool_name || '';
64 // Wall-clock timing from Claude Code (ms, excluding permission prompts)
65 const durationMs = typeof event.duration_ms === 'number' ? event.duration_ms : null;
66 const agentId = event.agent_id || null;
67 const agentType = event.agent_type || null;
68
69 // Only run on Edit and Write operations
70 if (toolName !== 'Edit' && toolName !== 'Write') {
71 process.exit(0);
72 }
73
74 // Extract file path from tool input
75 const filePath = event.tool_input?.file_path || event.tool_input?.path || '';
76 if (!filePath) {
77 process.exit(0);
78 }
79
80 const pathCheck = health.validatePath(filePath);
81 if (!pathCheck.safe) {
82 health.securityWarning('post-edit', `Possible injection in file path — ${pathCheck.violation}. Skipping typecheck.`);
83 process.exit(0);
84 }
85
86 const relativePath = path.relative(PROJECT_ROOT, filePath).replace(/\\/g, '/');
87
88 // Capture durable knowledge close to the write so a disposable clone does
89 // not depend solely on a clean SessionEnd event. Non-memory edits take only
90 // the allowlist check and never open SQLite.
91 syncRepositoryMemory(filePath, relativePath);
92
93 // Determine which hot-path lenses apply to this file
94 const lenses = selectHotPathLenses(filePath, relativePath);
95
96 // Run selected lenses
97 let exitCode = 0;
98 for (const lens of lenses) {
99 const lensResult = runHotLens(lens, filePath, relativePath);
100 if (lensResult > exitCode) exitCode = lensResult;
101 }
102
103 health.logTiming('post-edit', Date.now() - startTime, {
104 file: relativePath,
105 lenses: lenses.join(','),
106 typecheck: _typecheckOutcome || (exitCode === 0 ? 'pass' : 'fail'),
107 tool_duration_ms: durationMs,

Callers 1

post-edit.jsFile · 0.70

Calls 2

selectHotPathLensesFunction · 0.85
runHotLensFunction · 0.85

Tested by

no test coverage detected