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

Function collectWaveSignals

hooks_src/post-tool-batch.js:86–125  ·  view source on GitHub ↗

* Read the last 20 hook-timing entries and surface anything from the * last 30 seconds that Claude should know about. * * Surfaces: * - Typecheck failures from post-edit (exits 2) in this wave * - Large wave size (>3 files modified) as a summary

()

Source from the content-addressed store, hash-verified

84 * - Large wave size (>3 files modified) as a summary
85 */
86function collectWaveSignals() {
87 const signals = [];
88
89 try {
90 const timingPath = path.join(PROJECT_ROOT, '.planning', 'telemetry', 'hook-timing.jsonl');
91 if (!fs.existsSync(timingPath)) return signals;
92
93 const lines = fs.readFileSync(timingPath, 'utf8')
94 .split('\n')
95 .filter(Boolean)
96 .slice(-20);
97
98 const recentEdits = new Set();
99 const now = Date.now();
100 const WAVE_WINDOW_MS = 30000;
101
102 for (const line of lines) {
103 try {
104 const entry = JSON.parse(line);
105 if (entry.hook !== 'post-edit') continue;
106 const entryTime = new Date(entry.timestamp).getTime();
107 if (now - entryTime > WAVE_WINDOW_MS) continue;
108
109 if (entry.file) recentEdits.add(entry.file);
110
111 if (entry.typecheck === 'fail') {
112 signals.push(`typecheck: FAIL in ${entry.file}`);
113 }
114 } catch { continue; }
115 }
116
117 if (recentEdits.size > 3) {
118 const fileList = [...recentEdits].slice(0, 3).join(', ');
119 const overflow = recentEdits.size > 3 ? ` (+${recentEdits.size - 3} more)` : '';
120 signals.push(`wave: ${recentEdits.size} files modified — ${fileList}${overflow}`);
121 }
122 } catch { /* fail-safe: never block */ }
123
124 return signals;
125}
126
127main();

Callers 1

mainFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected