From 60bb0ef064d8e62f67d2350be2e1ae3670e974dd Mon Sep 17 00:00:00 2001 From: whoisasx Date: Fri, 3 Jul 2026 18:28:44 +0530 Subject: [PATCH] fix: hide unknown activity state in inspector --- .../components/SessionInspector.test.tsx | 46 ++++++++++++++++--- .../renderer/components/SessionInspector.tsx | 17 +++++-- 2 files changed, 53 insertions(+), 10 deletions(-) diff --git a/frontend/src/renderer/components/SessionInspector.test.tsx b/frontend/src/renderer/components/SessionInspector.test.tsx index a5d654777..77c0bd67a 100644 --- a/frontend/src/renderer/components/SessionInspector.test.tsx +++ b/frontend/src/renderer/components/SessionInspector.test.tsx @@ -173,7 +173,7 @@ describe("SessionInspector Activity section", () => { it.each([ ["idle", "Idle"], ["active", "Working"], - ["waiting_input", "Input needed"], + ["waiting_input", "Input Needed"], ["exited", "Exited"], ] as const)("renders %s from raw session activity", (state, label) => { renderWithQuery( @@ -188,6 +188,40 @@ describe("SessionInspector Activity section", () => { expect(activitySection().getByText(label)).toBeInTheDocument(); }); + it("renders unknown activity as unavailable instead of leaking the internal enum", () => { + renderWithQuery( + , + ); + + expect(activitySection().getByText("Activity Unavailable")).toBeInTheDocument(); + expect(activitySection().queryByText("Unknown")).not.toBeInTheDocument(); + }); + + it("falls back to unavailable when no activity has been reported", () => { + renderWithQuery(); + + expect(activitySection().getByText("Activity Unavailable")).toBeInTheDocument(); + }); + + it("keeps the last known activity visible when the daemon reports no signal", () => { + renderWithQuery( + , + ); + + const activityRow = activitySection().getByText("Idle").closest(".inspector-timeline__ev") as HTMLElement; + expect(within(activityRow).getByText("No Signal")).toBeInTheDocument(); + }); + it("does not derive the Activity label from PR-oriented session status", () => { renderWithQuery( { ); expect(activitySection().getByText("Idle")).toBeInTheDocument(); - expect(activitySection().queryByText("Input needed")).not.toBeInTheDocument(); + expect(activitySection().queryByText("Input Needed")).not.toBeInTheDocument(); }); it.each([ - ["ci_failed", "CI failed"], - ["changes_requested", "Changes requested"], + ["ci_failed", "CI Failed"], + ["changes_requested", "Changes Requested"], ] as const)("renders %s as an SCM state in the current Activity row", (status, label) => { renderWithQuery( { expect(activitySection().getByText("Opened")).toBeInTheDocument(); expect(activitySection().getByText("PR #7")).toBeInTheDocument(); const activityRow = activitySection().getByText("Idle").closest(".inspector-timeline__ev") as HTMLElement; - expect(within(activityRow).getByText("CI failed")).toBeInTheDocument(); - expect(within(activityRow).getByText("Changes requested")).toBeInTheDocument(); + expect(within(activityRow).getByText("CI Failed")).toBeInTheDocument(); + expect(within(activityRow).getByText("Changes Requested")).toBeInTheDocument(); }); it("orders timeline milestones around the combined current state row", () => { diff --git a/frontend/src/renderer/components/SessionInspector.tsx b/frontend/src/renderer/components/SessionInspector.tsx index 485ea448d..192c2677c 100644 --- a/frontend/src/renderer/components/SessionInspector.tsx +++ b/frontend/src/renderer/components/SessionInspector.tsx @@ -298,6 +298,11 @@ function ActivityTimeline({ session }: { session: WorkspaceSession }) { + {session.status === "no_signal" ? ( + + + + ) : null} {scmTimelineStates(session).map((state) => ( @@ -352,16 +357,20 @@ function ActivityTimeline({ session }: { session: WorkspaceSession }) { const ACTIVITY_PILL: Record = { active: { label: "Working", tone: "var(--orange)", breathe: true }, idle: { label: "Idle", tone: "var(--fg-muted)", breathe: false }, - waiting_input: { label: "Input needed", tone: "var(--amber)", breathe: false }, + waiting_input: { label: "Input Needed", tone: "var(--amber)", breathe: false }, exited: { label: "Exited", tone: "var(--fg-muted)", breathe: false }, - unknown: { label: "Unknown", tone: "var(--fg-muted)", breathe: false }, + unknown: { label: "Activity Unavailable", tone: "var(--fg-muted)", breathe: false }, +}; + +const ACTIVITY_WARNING_PILL: Record<"no_signal", { label: string; tone: string; breathe: boolean }> = { + no_signal: { label: "No Signal", tone: "var(--fg-muted)", breathe: false }, }; type ScmTimelineState = "ci_failed" | "changes_requested" | "conflict"; const SCM_PILL: Record = { - ci_failed: { label: "CI failed", tone: "var(--red)", breathe: false }, - changes_requested: { label: "Changes requested", tone: "var(--amber)", breathe: false }, + ci_failed: { label: "CI Failed", tone: "var(--red)", breathe: false }, + changes_requested: { label: "Changes Requested", tone: "var(--amber)", breathe: false }, conflict: { label: "Conflict", tone: "var(--red)", breathe: false }, };