Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
// person declined, a `<tool_use_error>`, a timeout; Codex's `{"status":"declined"}` and exit code;
// an MCP server's JSON error. Compare arms shows the `tool-error-look` experiment's three looks.
import { agentPaneEntry } from "../../../gallery/format";
import { activity, assistant, chat, tool, user } from "../../../gallery/fixtures/acpmux";
import { activity, assistant, chat, summary, tool, user } from "../../../gallery/fixtures/acpmux";
import { minutesAgo } from "../../../gallery/clock";
import type { AcpmuxActivity } from "../model";
import type { PlayContext } from "../../../gallery/play";
Expand Down Expand Up @@ -179,6 +179,10 @@ const failedStep = chat(
5.8,
),
assistant("One lane is paused on its queue: studio-mac/land-queue. Nothing else is stuck.", 5),
// The turn's end, as a finished turn has one: without it the turn draws as it came, the group
// starts open and the play's click closed it (its steps then left the DOM before the wait in
// slow renders, and the reply under it rose as it shut).
summary(4.9, { status: "completed", toolCount: 4 }),
],
{ harness: "claude", model: "claude-opus-5-5" },
);
Expand Down
25 changes: 24 additions & 1 deletion webviews/src/gallery/frame/pages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { CodeRouterOps } from "../../pages/coderouter/types";
import { MockCodeRouterProvider } from "../../pages/coderouter/mockProvider";
import { ACTION_RUN as CHANGELOG_ACTION_RUN, ChangelogOps } from "../../pages/changelog/types";
import { MockChangelogProvider } from "../../pages/changelog/mockProvider";
import { PAINT_AFTER_NAME } from "../../pages/shared/paintGate";
import { diffViewerLabelsFor, diffViewerLanguage, loadDiffViewerLabels } from "../../labels";
import type {
AppsPageVariant,
Expand Down Expand Up @@ -425,7 +426,29 @@ export async function mountChangelogPage(state: ChangelogPageVariant, _context:
if (state.route) history.replaceState(null, "", state.route);
document.documentElement.dataset.cmuxPage = "changelog";
document.documentElement.dataset.cmuxWebviewKind = "changelog";
await import("../../pages/changelog/main");
await showAfterPaintHold(() => import("../../pages/changelog/main"));
}

/**
* Mounts a page that holds its first frame (pages/shared/paintGate.ts `holdFirstPaint`) and shows
* it once that hold settles, as the app's host does (PagePaintProbe, PanePaintHold): the reader's
* first frame is the page with its first screen's data in. Without it the stage painted the
* loading placeholders whenever the mock host's replies (a timer each) came after the first
* frame, and the days under them moved as the notes arrived: pages.changelog#sheet scored 0 in one
* render and 0.248 in the next. Hidden with `display: none` (no boxes, so nothing it lays out
* meanwhile counts as a shift; a section sizes nothing, so each day near the viewport, and those
* under it, load their notes at once); the page's own 400 ms bound still shows a late page.
*/
async function showAfterPaintHold(mount: () => Promise<unknown>): Promise<void> {
const root = document.getElementById("root");
const display = root?.style.display ?? "";
if (root) root.style.display = "none";
try {
await mount();
await (window as unknown as Record<string, unknown>)[PAINT_AFTER_NAME];
} finally {
if (root) root.style.display = display;
}
}

const never = (): Promise<never> => new Promise(() => undefined);
Expand Down
9 changes: 8 additions & 1 deletion webviews/src/pages/home-channels/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -582,9 +582,13 @@ body,
}

/* Composer popovers (ui/Popover places them on the dropdown layer). */
/* One size whatever the search leaves: the popover opens above the composer, so a list that
shrank as each letter filtered it pulled the search field and grid down under the caret. */
.hc-emoji.ui-popover {
--hc-emoji-popover-height: 340px;
width: 324px;
max-height: 340px;
height: var(--hc-emoji-popover-height);
max-height: var(--hc-emoji-popover-height);
display: flex;
flex-direction: column;
padding: 8px;
Expand Down Expand Up @@ -614,7 +618,10 @@ body,
}
.hc-emoji-grid {
display: grid;
flex: 1;
min-height: 0;
grid-template-columns: repeat(8, 1fr);
align-content: start;
gap: 2px;
margin-top: 8px;
overflow-y: auto;
Expand Down
Loading