Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 1 addition & 2 deletions webviews/src/agent-session/acpmux/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7620,7 +7620,7 @@ function AcpmuxPane() {
: undefined,
[quick, inspectorLocal, remoteControlState],
);
// Compact from Session Info's Context and the composer ring's card sends the agent's own /compact
// Compact from Session Info's Context sends the agent's own /compact
// with the reach a context-full failure's Compact has: only where the agent lists it, never to a
// View Only chat or a read-only pane, never the next chat during a switch's hold (#17537 had it on
// the ring; #20454 dropped its wiring).
Expand Down Expand Up @@ -11770,7 +11770,6 @@ function AcpmuxPane() {
chips={ComposerChips}
permissionAccess={permissionAccess}
onOpenContext={inspector.reveal ? () => inspector.reveal?.("context") : undefined}
onCompact={compactChat}
draft={draft}
onUnsentDraft={quick ? undefined : onNewChatDraft}
onTyping={quick ? undefined : postTyping}
Expand Down
5 changes: 0 additions & 5 deletions webviews/src/agent-session/acpmux/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,6 @@ type Props = {
authBlocked?: boolean;
/// Opens the Inspector at its Context section: the context ring's card links to it (Details ›).
onOpenContext?(): void;
/// Sends the agent its `/compact`: the ring's card offers Compact only with it (App.tsx `compactChat`).
onCompact?(): void;
};

/// The prompt box with the agent's `/` command menu:
Expand Down Expand Up @@ -487,7 +485,6 @@ export function Composer({
authBlocked = false,
placeholder,
onOpenContext,
onCompact,
}: Props) {
const t = useT();
const chrome = useComposerChrome();
Expand Down Expand Up @@ -2330,9 +2327,7 @@ export function Composer({
size={usage?.size}
setup={usage?.setup}
breakdown={snapshot.summary?.contextBreakdown}
working={snapshot.isWorking}
onOpenDetails={onOpenContext}
onCompact={onCompact}
/>
)
}
Expand Down
14 changes: 1 addition & 13 deletions webviews/src/agent-session/acpmux/ComposerPickers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1379,20 +1379,16 @@ export function ContextRing({
size,
setup,
breakdown: reported,
onCompact,
onOpenDetails,
working = false,
}: {
used?: number;
size?: number;
/// Tokens the agent took before the conversation; the card splits it out when known.
setup?: number;
/// Claude Code's /context (`summary.contextBreakdown`): its categories replace the bar and parts.
breakdown?: unknown;
onCompact?(): void;
/// Opens the Inspector at its Context section; the card shows Details › only with it.
onOpenDetails?(): void;
working?: boolean;
}) {
const t = useT();
const hover = useHoverCard(HOVER_INTENT.tooltipDelay);
Expand Down Expand Up @@ -1455,7 +1451,7 @@ export function ContextRing({
document.addEventListener("pointerdown", onPress, true);
return () => document.removeEventListener("pointerdown", onPress, true);
}, [closeCard, pinned]);
/// The card's buttons the keyboard reaches (Compact, Details ›).
/// The card's buttons the keyboard reaches (Details ›).
const cardButtons = () => [...(card.current?.querySelectorAll<HTMLElement>("button:not(:disabled)") ?? [])];
/// Leaves the card forward: to whatever the page tabs to after the ring, and the card closes.
const tabPastCard = () => {
Expand Down Expand Up @@ -1565,14 +1561,6 @@ export function ContextRing({
size={size}
setup={setup}
breakdown={reported}
working={working}
onCompact={
onCompact &&
(() => {
closeCard();
onCompact();
})
}
onOpenDetails={
onOpenDetails &&
(() => {
Expand Down
21 changes: 5 additions & 16 deletions webviews/src/agent-session/acpmux/ContextCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,16 +72,12 @@ export function compactBreakdownRows(breakdown: Breakdown): CompactBreakdownRow[
export function ContextCardBody({
used,
size,
working,
onCompact,
onOpenDetails,
breakdown: reported,
}: {
used: number;
size: number;
setup?: number;
working: boolean;
onCompact?(): void;
onOpenDetails?(): void;
breakdown?: unknown;
}) {
Expand Down Expand Up @@ -127,19 +123,12 @@ export function ContextCardBody({
))}
</ul>
)}
{(onCompact || onOpenDetails) && (
{onOpenDetails && (
<div className="acpmux-context-card-foot">
{onCompact && (
<button type="button" className="acpmux-context-card-compact" disabled={working} onClick={onCompact}>
{t("context.compact")}
</button>
)}
{onOpenDetails && (
<button type="button" className="acpmux-context-card-details" onClick={onOpenDetails}>
{t("context.details")}
<span aria-hidden="true">›</span>
</button>
)}
<button type="button" className="acpmux-context-card-details" onClick={onOpenDetails}>
{t("context.details")}
<span aria-hidden="true">›</span>
</button>
</div>
)}
</>
Expand Down
8 changes: 0 additions & 8 deletions webviews/src/agent-session/acpmux/ContextRing.gallery.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ type Props = {
setup?: number;
breakdown?: unknown;
details?: boolean;
/// The agent lists `/compact`: the card offers Compact (App.tsx `compactChat`).
compact?: boolean;
wheel?: "compact" | "standard" | "minimal";
};

Expand All @@ -32,7 +30,6 @@ function GalleryContextRing(props: Props) {
breakdown={props.breakdown}
// The chat's Inspector reveal (App.tsx); the gallery has no Inspector to open.
onOpenDetails={props.details ? () => {} : undefined}
onCompact={props.compact ? () => {} : undefined}
/>
<button
type="button"
Expand Down Expand Up @@ -109,11 +106,6 @@ export default componentEntry<Props>({
props: { used: 111_000, size: 475_000, setup: 21_000, details: true },
play: hoverCard,
},
"card-claude-compact": {
note: 'Hover on a Claude chat whose agent lists /compact: the card ends with Compact beside Details › (Leo, 2026-10-28: "You don\'t have the compact session"; #17537 had it, #20454 dropped its wiring).',
props: { used: 111_000, size: 475_000, setup: 21_000, details: true, compact: true },
play: hoverCard,
},
"card-codex": {
note: "Hover on a Codex chat that reports only the window: the left-aligned card stays compact with one summary line and a thin usage bar.",
props: { used: 111_000, size: 475_000, details: true },
Expand Down
7 changes: 0 additions & 7 deletions webviews/src/agent-session/acpmux/contextCard.css
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@
margin-top: var(--ds-space-1);
}

.acpmux-context-card-compact,
.acpmux-context-card-details {
height: var(--cmux-control-height);
padding: 0 var(--ds-space-1);
Expand All @@ -156,17 +155,11 @@

.acpmux-context-card-details span { margin-inline-start: auto; }

.acpmux-context-card-compact:hover:not(:disabled),
.acpmux-context-card-details:hover {
background: var(--acpmux-menu-hover);
color: var(--agent-text);
}

.acpmux-context-card-compact:disabled {
opacity: 0.5;
}

.acpmux-context-card-compact:focus-visible,
.acpmux-context-card-details:focus-visible {
outline: 1.5px solid var(--agent-text);
outline-offset: 1px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
// (`summary.contextBreakdown`) splits it by category, with the MCP tools, memory files and skills
// it names under folds; without one, the parts are what is used and the free space. The composer's
// context ring draws the same breakdown in its details (ComposerPickers ContextRing). Where the agent
// lists `/compact`, Compact ends it, as the ring's card offers it (Leo, 2026-10-28: "You don't have
// lists `/compact`, Compact ends it; the ring's card has none (Leo, 2026-10-28: "You don't have
// the compact session").
import { useState } from "react";
import { useT } from "../i18n";
Expand Down Expand Up @@ -192,7 +192,7 @@ export function ContextSection({
/// Sends the chat's agent its `/compact` (App.tsx `compactChat`); unset where the agent lists no
/// compact command or the chat cannot be sent to, so no Compact shows.
onCompact?: () => void;
/// A turn runs: Compact is off until it ends, as the composer ring's card has it (ContextCard).
/// A turn runs: Compact is off until it ends.
working?: boolean;
}) {
const t = useT();
Expand Down
2 changes: 1 addition & 1 deletion webviews/test/agent-pane-turn-tokens.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ for (const [harness, family] of [
// still carries the setup value for the context summary, but it is intentionally not guessed into
// the small Codex-style hover surface.
const compactCard = (usage: { used: number; size: number; setup?: number }) =>
renderToStaticMarkup(<ContextCardBody {...usage} working={false} />).includes("acpmux-context-card-line");
renderToStaticMarkup(<ContextCardBody {...usage} />).includes("acpmux-context-card-line");

test("a usage record's reported setup reaches the context summary while the tooltip stays compact", async () => {
const withSetup: Step = [
Expand Down
21 changes: 9 additions & 12 deletions webviews/test/chat-inspector-context-breakdown.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,10 @@ test("the composer ring keeps Claude's breakdown details and uses a compact tool
expect(plain.querySelector(".acpmux-context-card-bar")).not.toBeNull();
});

// Leo, 2026-10-28: "You don't have the compact session." Compact in Session Info's Context and the
// ring's card: only where the App hands a compact (the agent lists /compact and the chat can be sent
// to), off while a turn runs.
// Leo, 2026-10-28: "You don't have the compact session." Compact in Session Info's Context: only
// where the App hands a compact (the agent lists /compact and the chat can be sent to), off while a
// turn runs. The composer ring's card has none (Leo, 2026-10-31: "JUST F***ING REMOVE COMPACT FROM
// THE F***ING POPOVER").
const compactButton = (container: ParentNode) =>
[...container.querySelectorAll<HTMLButtonElement>(".acpmux-chat-inspector-context__actions button")].find(
(button) => button.textContent === "Compact",
Expand Down Expand Up @@ -229,16 +230,12 @@ test("Session Info's Compact is off while a turn runs", async () => {
expect(sent).toEqual([]);
});

test("the composer ring's card shows Compact again when the App hands one, and sends it", async () => {
test("the composer ring's card has no Compact, only Details", async () => {
const container = installDom();
root = createRoot(container);
const sent: string[] = [];
await act(async () =>
root!.render(<ContextRing used={60_000} size={200_000} onCompact={() => sent.push("compact")} />),
);
await act(async () => root!.render(<ContextRing used={60_000} size={200_000} onOpenDetails={() => {}} />));
await act(async () => container.querySelector<HTMLButtonElement>(".acpmux-context-ring")!.click());
const compact = document.querySelector<HTMLButtonElement>(".acpmux-context-card-compact")!;
expect(compact.textContent).toBe("Compact");
await act(async () => compact.click());
expect(sent).toEqual(["compact"]);
const buttons = [...document.querySelectorAll<HTMLButtonElement>(".acpmux-context-card button")];
expect(buttons.map((button) => button.className)).toEqual(["acpmux-context-card-details"]);
expect(buttons.some((button) => button.textContent === "Compact")).toBe(false);
});
Loading