From 611c10d532961bfea1d6cc93041e0477cc4b814d Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 13 Feb 2026 20:49:49 +0000 Subject: [PATCH] fix: sort session files by mtime instead of alphabetically Session IDs use the format YYYY-MM-DD-, so alphabetical sorting picks whichever session has the highest random hex suffix, not the most recent one. This caused checkpoint() to always attach the same session's git note to every commit when multiple sessions existed for the same day. Sort by file modification time in getMostRecentCompletedId, listCompletedSessions, and findRecentSession. https://claude.ai/code/session_01Y33sCLqbB9YHAJNsPzEJgp --- src/session.ts | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/session.ts b/src/session.ts index 45f8aa9..8325bb9 100644 --- a/src/session.ts +++ b/src/session.ts @@ -1,6 +1,15 @@ import { execSync } from "node:child_process"; import crypto from "node:crypto"; -import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from "node:fs"; +import { + appendFileSync, + existsSync, + mkdirSync, + readdirSync, + readFileSync, + renameSync, + statSync, + writeFileSync, +} from "node:fs"; import { join } from "node:path"; import YAML from "yaml"; import { addNoteFromFile, currentBranch, diffStat, headSha } from "./git.js"; @@ -427,8 +436,9 @@ export async function findRecentSession(repoRoot: string): Promise f.endsWith(".md")) - .sort() - .reverse(); + .sort((a, b) => { + return statSync(join(compDir, b)).mtimeMs - statSync(join(compDir, a)).mtimeMs; + }); const cutoff = Date.now() - 24 * 60 * 60 * 1000; for (const file of files) { @@ -986,8 +996,9 @@ export function getMostRecentCompletedId(repoRoot: string): string | null { if (!existsSync(compDir)) return null; const files = readdirSync(compDir) .filter((f) => f.endsWith(".md")) - .sort() - .reverse(); + .sort((a, b) => { + return statSync(join(compDir, b)).mtimeMs - statSync(join(compDir, a)).mtimeMs; + }); if (files.length === 0) return null; return files[0]!.replace(".md", ""); } @@ -996,11 +1007,11 @@ export function getMostRecentCompletedId(repoRoot: string): string | null { export function listCompletedSessions(repoRoot: string): string[] { const compDir = completedDir(repoRoot); if (!existsSync(compDir)) return []; - return readdirSync(compDir) - .filter((f) => f.endsWith(".md")) - .map((f) => f.replace(".md", "")) - .sort() - .reverse(); + const files = readdirSync(compDir).filter((f) => f.endsWith(".md")); + files.sort((a, b) => { + return statSync(join(compDir, b)).mtimeMs - statSync(join(compDir, a)).mtimeMs; + }); + return files.map((f) => f.replace(".md", "")); } /** Parse YAML frontmatter from a markdown file */