fix: finish hook fallback and canonical session follow-ups

This commit is contained in:
Affaan Mustafa
2026-03-25 03:44:03 -04:00
parent 7b510c886e
commit 9c5ca92e6e
9 changed files with 108 additions and 28 deletions

View File

@@ -341,8 +341,10 @@ src/main.ts
// Override HOME to a temp dir for isolated getAllSessions/getSessionById tests
// On Windows, os.homedir() uses USERPROFILE, not HOME — set both for cross-platform
const tmpHome = path.join(os.tmpdir(), `ecc-session-mgr-test-${Date.now()}`);
const tmpSessionsDir = path.join(tmpHome, '.claude', 'sessions');
fs.mkdirSync(tmpSessionsDir, { recursive: true });
const tmpCanonicalSessionsDir = path.join(tmpHome, '.claude', 'session-data');
const tmpLegacySessionsDir = path.join(tmpHome, '.claude', 'sessions');
fs.mkdirSync(tmpCanonicalSessionsDir, { recursive: true });
fs.mkdirSync(tmpLegacySessionsDir, { recursive: true });
const origHome = process.env.HOME;
const origUserProfile = process.env.USERPROFILE;
@@ -355,7 +357,10 @@ src/main.ts
{ name: '2026-02-10-session.tmp', content: '# Old format session' },
];
for (let i = 0; i < testSessions.length; i++) {
const filePath = path.join(tmpSessionsDir, testSessions[i].name);
const targetDir = testSessions[i].name === '2026-02-10-session.tmp'
? tmpLegacySessionsDir
: tmpCanonicalSessionsDir;
const filePath = path.join(targetDir, testSessions[i].name);
fs.writeFileSync(filePath, testSessions[i].content);
// Stagger modification times so sort order is deterministic
const mtime = new Date(Date.now() - (testSessions.length - i) * 60000);
@@ -423,8 +428,8 @@ src/main.ts
})) passed++; else failed++;
if (test('getAllSessions ignores non-.tmp files', () => {
fs.writeFileSync(path.join(tmpSessionsDir, 'notes.txt'), 'not a session');
fs.writeFileSync(path.join(tmpSessionsDir, 'compaction-log.txt'), 'log');
fs.writeFileSync(path.join(tmpCanonicalSessionsDir, 'notes.txt'), 'not a session');
fs.writeFileSync(path.join(tmpCanonicalSessionsDir, 'compaction-log.txt'), 'log');
const result = sessionManager.getAllSessions({ limit: 100 });
assert.strictEqual(result.total, 5, 'Should only count .tmp session files');
})) passed++; else failed++;

View File

@@ -146,6 +146,15 @@ function runTests() {
assert.strictEqual(utils.sanitizeSessionId('my-project_123'), 'my-project_123');
})) passed++; else failed++;
if (test('sanitizeSessionId avoids Windows reserved device names', () => {
for (const reservedName of ['CON', 'prn', 'Aux', 'nul', 'COM1', 'lpt9']) {
const sanitized = utils.sanitizeSessionId(reservedName);
assert.ok(sanitized, `Expected sanitized output for ${reservedName}`);
assert.notStrictEqual(sanitized.toUpperCase(), reservedName.toUpperCase());
assert.ok(/-[a-f0-9]{6}$/i.test(sanitized), `Expected deterministic hash suffix for ${reservedName}, got ${sanitized}`);
}
})) passed++; else failed++;
if (test('sanitizeSessionId returns null for empty or punctuation-only values', () => {
assert.strictEqual(utils.sanitizeSessionId(''), null);
assert.strictEqual(utils.sanitizeSessionId(null), null);