Merge pull request #1429 from Tibsfox/fix/update-cache-dir-1421
fix(hooks): use shared cache dir and correct stale hooks path
This commit is contained in:
@@ -29,7 +29,10 @@ function detectConfigDir(baseDir) {
|
||||
|
||||
const globalConfigDir = detectConfigDir(homeDir);
|
||||
const projectConfigDir = detectConfigDir(cwd);
|
||||
const cacheDir = path.join(globalConfigDir, 'cache');
|
||||
// Use a shared, tool-agnostic cache directory to avoid multi-runtime
|
||||
// resolution mismatches where check-update writes to one runtime's cache
|
||||
// but statusline reads from another (#1421).
|
||||
const cacheDir = path.join(homeDir, '.cache', 'gsd');
|
||||
const cacheFile = path.join(cacheDir, 'gsd-update-check.json');
|
||||
|
||||
// VERSION file locations (check project first, then global)
|
||||
@@ -65,10 +68,10 @@ const child = spawn(process.execPath, ['-e', `
|
||||
} catch (e) {}
|
||||
|
||||
// Check for stale hooks — compare hook version headers against installed VERSION
|
||||
// Hooks live inside get-shit-done/hooks/, not configDir/hooks/
|
||||
// Hooks are installed at configDir/hooks/ (e.g. ~/.claude/hooks/) (#1421)
|
||||
let staleHooks = [];
|
||||
if (configDir) {
|
||||
const hooksDir = path.join(configDir, 'get-shit-done', 'hooks');
|
||||
const hooksDir = path.join(configDir, 'hooks');
|
||||
try {
|
||||
if (fs.existsSync(hooksDir)) {
|
||||
const hookFiles = fs.readdirSync(hooksDir).filter(f => f.startsWith('gsd-') && f.endsWith('.js'));
|
||||
|
||||
@@ -92,8 +92,12 @@ process.stdin.on('end', () => {
|
||||
}
|
||||
|
||||
// GSD update available?
|
||||
// Check shared cache first (#1421), fall back to runtime-specific cache for
|
||||
// backward compatibility with older gsd-check-update.js versions.
|
||||
let gsdUpdate = '';
|
||||
const cacheFile = path.join(claudeDir, 'cache', 'gsd-update-check.json');
|
||||
const sharedCacheFile = path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json');
|
||||
const legacyCacheFile = path.join(claudeDir, 'cache', 'gsd-update-check.json');
|
||||
const cacheFile = fs.existsSync(sharedCacheFile) ? sharedCacheFile : legacyCacheFile;
|
||||
if (fs.existsSync(cacheFile)) {
|
||||
try {
|
||||
const cache = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
|
||||
|
||||
@@ -1007,19 +1007,54 @@ describe('stale hook filter', () => {
|
||||
// ─── stale hook path regression (#1249) ──────────────────────────────────────
|
||||
|
||||
describe('stale hook path', () => {
|
||||
test('gsd-check-update.js checks get-shit-done/hooks/ not configDir/hooks/', () => {
|
||||
test('gsd-check-update.js checks configDir/hooks/ where hooks are actually installed (#1421)', () => {
|
||||
const content = fs.readFileSync(
|
||||
path.join(__dirname, '..', 'hooks', 'gsd-check-update.js'), 'utf-8'
|
||||
);
|
||||
// Hooks are installed at configDir/hooks/ (e.g. ~/.claude/hooks/),
|
||||
// not configDir/get-shit-done/hooks/ which doesn't exist (#1421)
|
||||
assert.ok(
|
||||
content.includes("path.join(configDir, 'get-shit-done', 'hooks')"),
|
||||
'stale hook check must look in configDir/get-shit-done/hooks/, not configDir/hooks/'
|
||||
content.includes("path.join(configDir, 'hooks')"),
|
||||
'stale hook check must look in configDir/hooks/ where hooks are actually installed'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ─── shared cache directory regression (#1421) ─────────────────────────────────
|
||||
|
||||
describe('shared cache directory (#1421)', () => {
|
||||
test('gsd-check-update.js writes cache to shared ~/.cache/gsd/ directory', () => {
|
||||
const content = fs.readFileSync(
|
||||
path.join(__dirname, '..', 'hooks', 'gsd-check-update.js'), 'utf-8'
|
||||
);
|
||||
// Cache must use a tool-agnostic path so statusline can find it
|
||||
// regardless of which runtime (Claude, Gemini, OpenCode) ran the check
|
||||
assert.ok(
|
||||
!content.includes("path.join(configDir, 'hooks')") ||
|
||||
content.indexOf("path.join(configDir, 'get-shit-done', 'hooks')") <
|
||||
content.indexOf("path.join(configDir, 'hooks')") + 100, // allow the old pattern only if corrected version exists first
|
||||
'should not use the wrong hooks path'
|
||||
content.includes("path.join(homeDir, '.cache', 'gsd')"),
|
||||
'check-update must write cache to ~/.cache/gsd/ (shared, tool-agnostic)'
|
||||
);
|
||||
});
|
||||
|
||||
test('gsd-statusline.js checks shared cache first, falls back to legacy (#1421)', () => {
|
||||
const content = fs.readFileSync(
|
||||
path.join(__dirname, '..', 'hooks', 'gsd-statusline.js'), 'utf-8'
|
||||
);
|
||||
// Statusline must check the shared cache path first
|
||||
assert.ok(
|
||||
content.includes("path.join(homeDir, '.cache', 'gsd', 'gsd-update-check.json')"),
|
||||
'statusline must check shared cache at ~/.cache/gsd/gsd-update-check.json'
|
||||
);
|
||||
// Must fall back to legacy runtime-specific cache for backward compat
|
||||
assert.ok(
|
||||
content.includes("path.join(claudeDir, 'cache', 'gsd-update-check.json')"),
|
||||
'statusline must fall back to legacy cache at claudeDir/cache/gsd-update-check.json'
|
||||
);
|
||||
// Shared cache must be checked before legacy (existsSync order matters)
|
||||
const sharedIdx = content.indexOf('sharedCacheFile');
|
||||
const legacyIdx = content.indexOf('legacyCacheFile');
|
||||
assert.ok(
|
||||
sharedIdx < legacyIdx,
|
||||
'shared cache must be defined and checked before legacy cache'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user