Merge PR #8074: fix(coding-agent): display subagent registration time locally (@anatoli-tsinovoy)

This commit is contained in:
can1357
2026-08-11 15:06:13 +02:00
4 changed files with 36 additions and 2 deletions
+1
View File
@@ -14,6 +14,7 @@
- Fixed `/vibe` mode losing the pre-vibe toolset when a session already in vibe mode switches into another session that is also in vibe mode, which left `bash`, `edit`, `write`, `grep`, `glob`, `task`, and `hub` silently unavailable after exiting the mode; the pre-vibe toolset is now recorded on the `mode_change` entry and restored from there.
- Preserved extension-filtered pasted image payloads and source links when `/goal`, `/plan`, or `/vibe` submits the composer draft.
- Fixed Agent Hub lineage registration timestamps displaying in UTC instead of the user's local timezone.
## [17.2.12] - 2026-08-08
@@ -36,6 +36,7 @@ import { type AgentRef, AgentRegistry, type AgentStatus, MAIN_AGENT_ID } from ".
import { registerPersistedSubagents } from "../../registry/persisted-agents";
import { USER_INTERRUPT_LABEL } from "../../session/messages";
import { shortenPath, truncateToWidth } from "../../tools/render-utils";
import { formatLocalDateTimeWithOffset } from "../../utils/local-date";
import type { ObservableSession, SessionObserverRegistry } from "../session-observer-registry";
import { theme } from "../theme/theme";
import { matchesSelectDown, matchesSelectUp } from "../utils/keybinding-matchers";
@@ -829,7 +830,7 @@ export class AgentHubOverlayComponent extends Container implements SelectListMou
`Spawned by ${sanitizeDisplayText(ref.parentId ?? MAIN_AGENT_ID)}${children.length > 0 ? ` · ${children.length} children` : ""}`,
);
if (children.length > 0) add(theme.fg("dim", formatChildIds(children, width)));
add(theme.fg("dim", `Registered ${new Date(ref.createdAt).toISOString().slice(0, 16).replace("T", " ")}Z`));
add(theme.fg("dim", `Registered ${formatLocalDateTimeWithOffset(new Date(ref.createdAt))}`));
section("Changes");
add(
@@ -5,3 +5,16 @@ export function formatLocalCalendarDate(date: Date = new Date()): string {
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
/** Format a local date and minute with a compact numeric UTC offset. */
export function formatLocalDateTimeWithOffset(date: Date): string {
const offsetMinutes = date.getTimezoneOffset();
const offsetSign = offsetMinutes <= 0 ? "+" : "-";
const absoluteOffset = Math.abs(offsetMinutes);
const offsetHours = Math.floor(absoluteOffset / 60);
const offsetRemainderMinutes = absoluteOffset % 60;
const pad2 = (value: number): string => String(value).padStart(2, "0");
return `${formatLocalCalendarDate(date)} ${pad2(date.getHours())}:${pad2(date.getMinutes())} ${offsetSign}${pad2(
offsetHours,
)}:${pad2(offsetRemainderMinutes)}`;
}
@@ -579,6 +579,7 @@ describe("Agent hub row ordering", () => {
it("renders aggregate usage and a selected-agent inspector without inventing change attribution", () => {
geometry = stubStdoutGeometry(140);
geometry.setRows(28);
const createdAt = Date.parse("2026-08-09T20:15:00Z");
const agents = new AgentRegistry();
agents.register({
id: "Reviewer",
@@ -591,6 +592,7 @@ describe("Agent hub row ordering", () => {
patchPath: "/tmp/Reviewer.patch",
branchName: "omp/task/Reviewer",
},
createdAt,
});
const observers = new SessionObserverRegistry();
vi.spyOn(observers, "getSessions").mockReturnValue([
@@ -634,7 +636,24 @@ describe("Agent hub row ordering", () => {
expect(rendered).toContain("Security Reviewer");
expect(rendered).toContain("read · src/session/agent-session.ts");
expect(rendered).toContain("31K/128K 24%");
expect(rendered).toContain("Registered ");
const createdDate = new Date(createdAt);
const localDateTime = createdDate.toLocaleString("sv-SE", {
year: "numeric",
month: "2-digit",
day: "2-digit",
hour: "2-digit",
minute: "2-digit",
});
const offsetMinutes = -createdDate.getTimezoneOffset();
const offsetSign = offsetMinutes >= 0 ? "+" : "-";
const absoluteOffset = Math.abs(offsetMinutes);
const offset = `${offsetSign}${String(Math.floor(absoluteOffset / 60)).padStart(2, "0")}:${String(
absoluteOffset % 60,
).padStart(2, "0")}`;
const registeredLine = `Registered ${localDateTime} ${offset}`;
expect(rendered).toContain(registeredLine);
expect(rendered).not.toMatch(/Registered \d{4}-\d{2}-\d{2} \d{2}:\d{2}Z/u);
expect(Bun.stripANSI(hub.render(96).join("\n"))).toContain(registeredLine);
expect(rendered).toContain("Shared workspace · per-agent LoC not attributable");
expect(rendered).toContain("Output /tmp/Reviewer.md");
expect(rendered).toContain("Patch /tmp/Reviewer.patch");