Files
msd-core/hooks/gsd-intel-prune.js
Lex Christopherson 39ea6f4457 refactor(hooks): rename intel hooks with gsd- prefix
- intel-index.js → gsd-intel-index.js
- intel-session.js → gsd-intel-session.js
- intel-prune.js → gsd-intel-prune.js

Consistent naming allows installer to manage GSD hooks easily.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-20 00:50:09 -06:00

79 lines
2.1 KiB
JavaScript

#!/usr/bin/env node
/**
* Intel Prune Hook (Stop event)
*
* Removes stale entries from index.json when files no longer exist.
* Runs after each Claude response to keep intel fresh.
*
* Fast: Only does fs.existsSync checks, no file reading.
* Silent: Never blocks or errors, always exits 0.
*/
const fs = require('fs');
const path = require('path');
function pruneIndex() {
const intelDir = path.join(process.cwd(), '.planning', 'intel');
const indexPath = path.join(intelDir, 'index.json');
// Only run if intel directory exists (opt-in check)
if (!fs.existsSync(intelDir)) {
return { pruned: 0, total: 0 };
}
// Read existing index
let index;
try {
const content = fs.readFileSync(indexPath, 'utf8');
index = JSON.parse(content);
} catch (e) {
// No index or invalid JSON
return { pruned: 0, total: 0 };
}
if (!index.files || typeof index.files !== 'object') {
return { pruned: 0, total: 0 };
}
// Check each file and collect deleted ones
const filePaths = Object.keys(index.files);
const deleted = filePaths.filter(filePath => !fs.existsSync(filePath));
if (deleted.length === 0) {
return { pruned: 0, total: filePaths.length };
}
// Remove deleted entries
for (const filePath of deleted) {
delete index.files[filePath];
}
index.updated = Date.now();
// Write updated index
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2));
// Regenerate conventions and summary after pruning
// Import detection logic from intel-index.js would be complex,
// so we just update the index. Conventions/summary stay until
// next PostToolUse or /gsd:analyze-codebase refresh.
return { pruned: deleted.length, total: filePaths.length };
}
// Read JSON from stdin (standard hook pattern)
let input = '';
process.stdin.setEncoding('utf8');
process.stdin.on('data', chunk => input += chunk);
process.stdin.on('end', () => {
try {
// Stop hook receives session data, but we don't need it
// Just prune stale entries
pruneIndex();
process.exit(0);
} catch (error) {
// Silent failure - never block Claude
process.exit(0);
}
});