From f1769ec910b1032d650d2a57017ef67d87f025bc Mon Sep 17 00:00:00 2001 From: harshitsinghbhandari <24b4506@iitb.ac.in> Date: Fri, 17 Apr 2026 19:52:15 +0530 Subject: [PATCH] fix: address final lifecycle review findings (#122) --- package.json | 4 +-- packages/web/src/lib/__tests__/types.test.ts | 34 ++++++++++++++++++++ packages/web/src/lib/types.ts | 31 +++++++++++++++--- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index a0b3d4af4..1664c7a64 100644 --- a/package.json +++ b/package.json @@ -10,13 +10,13 @@ "packageManager": "pnpm@9.15.4", "type": "module", "scripts": { - "build": "pnpm -r --workspace-concurrency=1 build", + "build": "pnpm -r build", "dev": "pnpm --filter @aoagents/ao-web dev", "lint": "eslint .", "lint:fix": "eslint . --fix", "format": "prettier --write .", "format:check": "prettier --check .", - "typecheck": "pnpm -r --workspace-concurrency=1 typecheck", + "typecheck": "pnpm -r typecheck", "test": "pnpm -r --filter '!@aoagents/ao-web' test", "test:integration": "pnpm --filter @aoagents/ao-integration-tests test:integration", "clean": "pnpm -r clean", diff --git a/packages/web/src/lib/__tests__/types.test.ts b/packages/web/src/lib/__tests__/types.test.ts index c49c37d99..3083a3906 100644 --- a/packages/web/src/lib/__tests__/types.test.ts +++ b/packages/web/src/lib/__tests__/types.test.ts @@ -5,6 +5,8 @@ import { describe, it, expect } from "vitest"; import { getAttentionLevel, + getActivitySignalLabel, + getActivitySignalReasonLabel, isPRMergeReady, TERMINAL_STATUSES, TERMINAL_ACTIVITIES, @@ -779,3 +781,35 @@ describe("constants sync with core", () => { expect(NON_RESTORABLE_STATUSES).toBe(CORE_NON_RESTORABLE_STATUSES); }); }); + +describe("activity signal fallback", () => { + it("treats legacy idle activity without a timestamp as stale", () => { + const session = createSession({ + activity: "idle", + activitySignal: undefined, + }); + + expect(getActivitySignalLabel(session)).toBe("idle (stale)"); + expect(getActivitySignalReasonLabel(session)).toBe("missing timestamp"); + }); + + it("treats legacy blocked activity without a timestamp as stale", () => { + const session = createSession({ + activity: "blocked", + activitySignal: undefined, + }); + + expect(getActivitySignalLabel(session)).toBe("blocked (stale)"); + expect(getActivitySignalReasonLabel(session)).toBe("missing timestamp"); + }); + + it("keeps legacy active activity valid", () => { + const session = createSession({ + activity: "active", + activitySignal: undefined, + }); + + expect(getActivitySignalLabel(session)).toBe("active"); + expect(getActivitySignalReasonLabel(session)).toBeNull(); + }); +}); diff --git a/packages/web/src/lib/types.ts b/packages/web/src/lib/types.ts index bc289c224..a19e73e3f 100644 --- a/packages/web/src/lib/types.ts +++ b/packages/web/src/lib/types.ts @@ -295,14 +295,35 @@ export function getLifecycleEvidence(session: DashboardSession): string | null { } function resolveActivitySignal(session: DashboardSession): DashboardActivitySignal { - return ( - session.activitySignal ?? { - state: session.activity === null ? "unavailable" : "valid", + if (session.activitySignal) { + return session.activitySignal; + } + + if (session.activity === null) { + return { + state: "unavailable", + activity: null, + timestamp: null, + source: "none", + }; + } + + if (session.activity === "idle" || session.activity === "blocked") { + return { + state: "stale", activity: session.activity, timestamp: null, source: "none", - } - ); + detail: "missing_timestamp", + }; + } + + return { + state: "valid", + activity: session.activity, + timestamp: null, + source: "none", + }; } export function getActivitySignalLabel(session: DashboardSession): string {