Skip to content

Commit 841beea

Browse files
committed
fix: handle dotted reserved snapshot names
1 parent 61992f7 commit 841beea

2 files changed

Lines changed: 19 additions & 7 deletions

File tree

‎scripts/loop-status.js‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,12 @@ function sanitizeSnapshotName(value, fallback = 'session') {
626626
return sanitized;
627627
}
628628
if (sanitized && isWindowsReservedBasename(sanitized)) {
629-
return `${sanitized}-${hashString(raw).slice(0, 8)}`;
629+
const firstDotIndex = sanitized.indexOf('.');
630+
const hashSuffix = hashString(raw).slice(0, 8);
631+
if (firstDotIndex === -1) {
632+
return `${sanitized}-${hashSuffix}`;
633+
}
634+
return `${sanitized.slice(0, firstDotIndex)}-${hashSuffix}${sanitized.slice(firstDotIndex)}`;
630635
}
631636

632637
const prefix = sanitized ? sanitized.slice(0, 48).replace(/[._-]+$/g, '') : fallback;

‎tests/scripts/loop-status.test.js‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,9 @@ function runTests() {
642642
writeTranscript(homeDir, '-Users-affoon-project-windows-name', 'con.jsonl', [
643643
assistantMessage('2026-04-30T09:55:00.000Z', 'con', 'Loop checkpoint.'),
644644
]);
645+
writeTranscript(homeDir, '-Users-affoon-project-windows-name', 'con-txt.jsonl', [
646+
assistantMessage('2026-04-30T09:56:00.000Z', 'con.txt', 'Loop checkpoint.'),
647+
]);
645648

646649
const result = run([
647650
'--home',
@@ -657,13 +660,17 @@ function runTests() {
657660

658661
const indexPath = path.join(snapshotDir, 'index.json');
659662
const indexPayload = JSON.parse(fs.readFileSync(indexPath, 'utf8'));
660-
const snapshotName = path.basename(indexPayload.sessions[0].snapshotPath);
661-
assert.strictEqual(indexPayload.sessions[0].sessionId, 'con');
662-
assert.notStrictEqual(snapshotName.toLowerCase(), 'con.json');
663+
assert.strictEqual(indexPayload.sessions.length, 2);
663664

664-
const snapshotPayload = JSON.parse(fs.readFileSync(indexPayload.sessions[0].snapshotPath, 'utf8'));
665-
assert.strictEqual(snapshotPayload.schemaVersion, 'ecc.loop-status.session.v1');
666-
assert.strictEqual(snapshotPayload.session.sessionId, 'con');
665+
for (const sessionIndex of indexPayload.sessions) {
666+
const snapshotName = path.basename(sessionIndex.snapshotPath);
667+
assert.notStrictEqual(snapshotName.toLowerCase(), `${sessionIndex.sessionId}.json`);
668+
assert.ok(!/^(con|prn|aux|nul|com[1-9]|lpt[1-9])$/i.test(snapshotName.split('.')[0]));
669+
670+
const snapshotPayload = JSON.parse(fs.readFileSync(sessionIndex.snapshotPath, 'utf8'));
671+
assert.strictEqual(snapshotPayload.schemaVersion, 'ecc.loop-status.session.v1');
672+
assert.strictEqual(snapshotPayload.session.sessionId, sessionIndex.sessionId);
673+
}
667674
} finally {
668675
fs.rmSync(homeDir, { recursive: true, force: true });
669676
fs.rmSync(snapshotDir, { recursive: true, force: true });

0 commit comments

Comments
 (0)