Merge pull request #3586 from jeremymcs/fix/elapsed-timer-lost-on-resume
fix(gsd): persist elapsed timer across session resume
This commit is contained in:
commit
7b7cad0de9
3 changed files with 59 additions and 4 deletions
|
|
@ -585,10 +585,11 @@ export function updateProgressWidget(
|
|||
lines.push(rightAlign(headerLeft, headerRight, width));
|
||||
|
||||
// Worktree/branch right-aligned below header
|
||||
if (worktreeName && cachedBranch) {
|
||||
lines.push(rightAlign("", theme.fg("dim", `${worktreeName} (${cachedBranch})`), width));
|
||||
} else if (cachedBranch) {
|
||||
lines.push(rightAlign("", theme.fg("dim", cachedBranch), width));
|
||||
const branchLabel = worktreeName && cachedBranch
|
||||
? `${worktreeName} (${cachedBranch})`
|
||||
: cachedBranch ?? "";
|
||||
if (branchLabel) {
|
||||
lines.push(rightAlign("", theme.fg("dim", branchLabel), width));
|
||||
}
|
||||
|
||||
// Show health signal details when degraded (yellow/red)
|
||||
|
|
|
|||
|
|
@ -895,6 +895,7 @@ export async function pauseAuto(
|
|||
sessionFile: s.pausedSessionFile,
|
||||
activeEngineId: s.activeEngineId,
|
||||
activeRunDir: s.activeRunDir,
|
||||
autoStartTime: s.autoStartTime,
|
||||
};
|
||||
const runtimeDir = join(gsdRoot(s.originalBasePath || s.basePath), "runtime");
|
||||
mkdirSync(runtimeDir, { recursive: true });
|
||||
|
|
@ -1137,6 +1138,7 @@ export async function startAuto(
|
|||
s.activeRunDir = meta.activeRunDir ?? null;
|
||||
s.originalBasePath = meta.originalBasePath || base;
|
||||
s.stepMode = meta.stepMode ?? requestedStepMode;
|
||||
s.autoStartTime = meta.autoStartTime || Date.now();
|
||||
s.paused = true;
|
||||
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
||||
logWarning("session", `pause file cleanup failed: ${err instanceof Error ? err.message : String(err)}`, { file: "auto.ts" });
|
||||
|
|
@ -1162,6 +1164,7 @@ export async function startAuto(
|
|||
s.currentMilestoneId = meta.milestoneId;
|
||||
s.originalBasePath = meta.originalBasePath || base;
|
||||
s.stepMode = meta.stepMode ?? requestedStepMode;
|
||||
s.autoStartTime = meta.autoStartTime || Date.now();
|
||||
s.paused = true;
|
||||
// Clean up the persisted file — we're consuming it
|
||||
try { unlinkSync(pausedPath); } catch (err) { /* non-fatal */
|
||||
|
|
@ -1194,6 +1197,7 @@ export async function startAuto(
|
|||
s.cmdCtx = ctx;
|
||||
s.basePath = base;
|
||||
setLogBasePath(base);
|
||||
if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now();
|
||||
s.unitDispatchCount.clear();
|
||||
s.unitLifetimeDispatches.clear();
|
||||
if (!getLedger()) initMetrics(base);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
// GSD2 — Verify autoStartTime is persisted in paused-session.json and restored on resume
|
||||
// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>
|
||||
|
||||
/**
|
||||
* auto-start-time-persistence.test.ts — Ensures autoStartTime survives
|
||||
* cross-session resume via paused-session.json (#3585).
|
||||
*
|
||||
* Source-code regression guards: verify auto.ts saves and restores
|
||||
* autoStartTime so the elapsed timer doesn't vanish after /exit + resume.
|
||||
*/
|
||||
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import { join, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const AUTO_TS_PATH = join(__dirname, "..", "auto.ts");
|
||||
|
||||
const source = readFileSync(AUTO_TS_PATH, "utf-8");
|
||||
|
||||
test("pauseAuto persists autoStartTime in paused-session.json (#3585)", () => {
|
||||
assert.ok(
|
||||
source.includes("autoStartTime: s.autoStartTime"),
|
||||
"pausedMeta must include autoStartTime so the timer survives /exit",
|
||||
);
|
||||
});
|
||||
|
||||
test("cross-session resume restores autoStartTime from paused-session.json (#3585)", () => {
|
||||
const matches = source.match(/s\.autoStartTime\s*=\s*meta\.autoStartTime/g);
|
||||
assert.ok(
|
||||
matches && matches.length >= 2,
|
||||
"both resume paths (custom workflow + milestone) must restore autoStartTime from meta",
|
||||
);
|
||||
});
|
||||
|
||||
test("resume path falls back to Date.now() when autoStartTime is missing (#3585)", () => {
|
||||
assert.ok(
|
||||
source.includes("meta.autoStartTime || Date.now()"),
|
||||
"restore should fall back to Date.now() for old paused-session files without autoStartTime",
|
||||
);
|
||||
});
|
||||
|
||||
test("resume path guards against zero autoStartTime (#3585)", () => {
|
||||
assert.ok(
|
||||
source.includes("if (!s.autoStartTime || s.autoStartTime <= 0) s.autoStartTime = Date.now()"),
|
||||
"resume path must set autoStartTime to Date.now() if still zero after restore",
|
||||
);
|
||||
});
|
||||
Loading…
Add table
Reference in a new issue