fix: recover missing Reasonix sessions

This commit is contained in:
liujing
2026-07-17 17:02:49 +08:00
parent fb39ab289a
commit 717d4344ee
6 changed files with 179 additions and 8 deletions
+47 -1
View File
@@ -384,6 +384,17 @@ function getWorkspaceFromJsonl(jsonlPath: string): string | undefined {
return undefined;
}
function reasonixProjectDir(projectsDir: string, repoRoot: string): string {
const projectKey = path.resolve(repoRoot).replaceAll(path.sep, "-");
return path.join(projectsDir, projectKey);
}
function isSessionInReasonixProject(jsonlPath: string, projectsDir: string, repoRoot: string): boolean {
const sessionsDir = path.join(reasonixProjectDir(projectsDir, repoRoot), "sessions");
const relative = path.relative(sessionsDir, jsonlPath);
return relative !== "" && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
}
function listJsonlFiles(dir: string, repoRoot?: string): string[] {
if (!fs.existsSync(dir)) return [];
const result: string[] = [];
@@ -411,7 +422,7 @@ function listJsonlFiles(dir: string, repoRoot?: string): string[] {
if (fs.existsSync(metaFile)) {
if (repoRoot) {
const ws = getWorkspaceFromJsonl(full);
if (ws === repoRoot) {
if (ws === repoRoot || isSessionInReasonixProject(full, dir, repoRoot)) {
result.push(full);
}
} else {
@@ -427,6 +438,41 @@ function listJsonlFiles(dir: string, repoRoot?: string): string[] {
return result;
}
function sessionContainsPlanTitle(jsonlPath: string, planTitle: string): boolean {
try {
const content = fs.readFileSync(jsonlPath, "utf8");
return content.includes(`# Implementation Task: ${planTitle}`);
} catch {
return false;
}
}
export function findReasonixSessionForWorkflow(
repoRoot: string,
planTitle: string,
startedAt?: string,
completedAt?: string,
): string | undefined {
const homeDir = process.env.HOME || os.homedir();
const projectsDir = path.join(homeDir, ".reasonix", "projects");
const startMs = startedAt ? Date.parse(startedAt) : Number.NEGATIVE_INFINITY;
const endMs = completedAt ? Date.parse(completedAt) : Number.POSITIVE_INFINITY;
const toleranceMs = 5000;
const candidates = listJsonlFiles(projectsDir, repoRoot).filter((file) => {
if (!sessionContainsPlanTitle(file, planTitle)) return false;
try {
const mtimeMs = fs.statSync(file).mtimeMs;
return mtimeMs >= startMs - toleranceMs && mtimeMs <= endMs + toleranceMs;
} catch {
return false;
}
});
candidates.sort((a, b) => fs.statSync(b).mtimeMs - fs.statSync(a).mtimeMs);
return candidates[0];
}
function detectNewSessionFile(beforeSnapshot: Set<string>, searchDirs: string[], repoRoot: string): string | undefined {
const candidates: string[] = [];
for (const dir of searchDirs) {