diff --git a/web/src/catalog.test.ts b/web/src/catalog.test.ts index 57fa9a1..560ee31 100644 --- a/web/src/catalog.test.ts +++ b/web/src/catalog.test.ts @@ -105,6 +105,38 @@ describe("blocked-work indicator (#83)", () => { }); }); +describe("agent-reported detail (#112)", () => { + const ago = (ms: number): string => new Date(Date.now() - ms).toISOString(); + + it("renders the reported detail right after the duration on line 2", () => { + const s = session({ + id: "aaaaaaaa-0000-0000-0000-000000000020", + status: "Dead", + activity: "Error", + activity_since: ago(90_000), + activity_detail: "cargo build failed", + }); + const el = renderSidebar(storeWith([s])).el; + const line2 = rowFor(el, s.id)?.querySelector(".card-line2"); + expect(line2?.querySelector(".activity-detail")?.textContent).toBe("cargo build failed"); + const order = [...line2!.children].map((c) => c.className); + expect(order.indexOf("activity-detail")).toBeGreaterThan(order.indexOf("activity-duration")); + expect(order.indexOf("activity-detail")).toBeLessThan( + order.findIndex((c) => c.startsWith("card-flag")), + ); + }); + + it("omits the detail when no report is in force", () => { + const s = session({ + id: "aaaaaaaa-0000-0000-0000-000000000021", + activity: "Active", + activity_since: ago(90_000), + }); + const el = renderSidebar(storeWith([s])).el; + expect(rowFor(el, s.id)?.querySelector(".activity-detail")).toBeNull(); + }); +}); + describe("session cards (#107)", () => { const ago = (ms: number): string => new Date(Date.now() - ms).toISOString(); diff --git a/web/src/catalog.ts b/web/src/catalog.ts index cefca49..a4d517a 100644 --- a/web/src/catalog.ts +++ b/web/src/catalog.ts @@ -42,6 +42,9 @@ function metaLine(s: Session, now: number): string { const fragments = [ ``, duration ? `${duration}` : "", + s.activity_detail + ? `${escapeHtml(s.activity_detail)}` + : "", blockers ? `⚠ ${escapeHtml(formatInTheWay(blockers))}` : "", diff --git a/web/src/styles.css b/web/src/styles.css index 4b533e9..ea4060e 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -851,6 +851,17 @@ textarea { flex: 0 0 auto; } +/* Agent-reported detail (#112): sits after the duration, shrinks with an + ellipsis so it never pushes the trailing fragments off the line. */ +.activity-detail { + color: var(--faint); + flex: 0 1 auto; + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + /* Blocked-work / exited / command fragments recede: the ⚠ glyph already signals severity and "exited" dims with the row. */ .card-flag {