From a027534e372110640a420c914509efbaf266e4cb Mon Sep 17 00:00:00 2001 From: TJ Date: Mon, 24 Aug 2026 09:01:57 -0700 Subject: [PATCH 01/11] fix(site): keep at least 8 characters of the model name visible in the model selector trigger The trigger's min-w-0 chain let the label collapse to zero width when the composer badge row was full, leaving only the provider icon and chevron. Give the label a min-w-[8ch] floor and remove the min-w-0 overrides so the floor propagates; the badge overflow (+N) pill absorbs the remaining pressure. The gap between the label and the chevron is unchanged. --- .../components/ChatElements/ModelSelector.tsx | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx index 0ec76e0c1eb..49273c7611f 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx @@ -163,12 +163,16 @@ export const ModelSelector: FC = ({ type="button" variant="subtle" className={cn( - "h-7 min-w-0 shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", + "h-7 shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", className, )} onTouchStart={onTriggerTouchStart} > - + {/* No min-w-0 here or on the button: the label's min-w-[8ch] + * floor below must propagate up so the trigger never shrinks + * past roughly 8 characters of the model name. Siblings (the + * badge row's +N overflow pill) absorb the remaining pressure. */} + {selectedModel && ( = ({ /> )} - {triggerLabel} + {/* Keep at least 8 characters visible before truncating. + * truncate clips inside this span, so the chevron's gap to + * the ellipsis stays constant. */} + {triggerLabel} From 9dbf76e2f25030ff8ccce900459ad5cb7fe27ac3 Mon Sep 17 00:00:00 2001 From: TJ Date: Mon, 24 Aug 2026 10:03:45 -0700 Subject: [PATCH 02/11] fix(site): floor the model selector trigger width instead of removing min-w-0 Removing min-w-0 made the label wrapper's automatic minimum the full nowrap label width, so nothing could shrink: truncation stopped and the chevron was pushed out and clipped. Restore the original inner structure (min-w-0 wrapper + truncate label) and put an explicit min-width on the trigger button: 8ch of label plus the fixed chrome (padding, provider icon, gaps, chevron). The button now shrinks and truncates normally but never below ~8 characters, with the chevron always inside the pill. --- .../components/ChatElements/ModelSelector.tsx | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx index 49273c7611f..ff384b569d3 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx @@ -162,17 +162,17 @@ export const ModelSelector: FC = ({ role="combobox" type="button" variant="subtle" + // min-w floor: keep roughly 8ch of the model name visible before + // truncation kicks in. 3.125rem covers the fixed chrome around + // the label (px-2 padding, size-3 provider icon, two gap-1 gaps, + // size-3.5 chevron) so the label and chevron never get clipped. className={cn( - "h-7 shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", + "h-7 min-w-[calc(8ch+3.125rem)] shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", className, )} onTouchStart={onTriggerTouchStart} > - {/* No min-w-0 here or on the button: the label's min-w-[8ch] - * floor below must propagate up so the trigger never shrinks - * past roughly 8 characters of the model name. Siblings (the - * badge row's +N overflow pill) absorb the remaining pressure. */} - + {selectedModel && ( = ({ /> )} - {/* Keep at least 8 characters visible before truncating. - * truncate clips inside this span, so the chevron's gap to - * the ellipsis stays constant. */} - {triggerLabel} + {triggerLabel} From fc59496fecca683ab4d04b3df34e91f3cb082167 Mon Sep 17 00:00:00 2001 From: TJ Date: Tue, 25 Aug 2026 10:50:11 -0700 Subject: [PATCH 03/11] fix(site): give the workspace pill the same 8-character width floor With the model selector no longer collapsing, the shrink pressure moved to the workspace pill, whose overflow-hidden wrapper clipped it down to just the status icon with no chevron. Raise its md min-width from 2.75rem to the same 8ch + 3.125rem floor as the model selector, and make the trigger fill the wrapper so the truncating name span shrinks instead of the wrapper clipping the chevron. --- site/src/pages/AgentsPage/components/WorkspacePill.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/site/src/pages/AgentsPage/components/WorkspacePill.tsx b/site/src/pages/AgentsPage/components/WorkspacePill.tsx index c72851e8835..a06459c59a9 100644 --- a/site/src/pages/AgentsPage/components/WorkspacePill.tsx +++ b/site/src/pages/AgentsPage/components/WorkspacePill.tsx @@ -126,7 +126,9 @@ export const WorkspacePill: FC = ({ } }} > - + {/* md floor: ~8ch of the workspace name + 3.125rem of chrome + * (padding, status icon, gaps, chevron), matching ModelSelector. */} + setTooltipOpen(v && !open)} @@ -138,7 +140,7 @@ export const WorkspacePill: FC = ({ aria-label={`${workspace.name} workspace menu`} className={cn( "inline-flex min-w-0 cursor-pointer items-center justify-center gap-1 rounded-full border-0 bg-transparent p-0 text-xs font-medium text-content-secondary transition-colors hover:bg-surface-tertiary hover:text-content-primary", - "size-7 md:size-auto md:max-w-[200px] md:justify-start md:px-2 md:py-0.5", + "size-7 md:size-auto md:w-full md:max-w-[200px] md:justify-start md:px-2 md:py-0.5", )} > Date: Tue, 25 Aug 2026 11:11:15 -0700 Subject: [PATCH 04/11] fix(site): use valid calc syntax for the model selector width floor calc() requires whitespace around +, and Tailwind arbitrary values encode spaces as underscores. calc(8ch+3.125rem) produced invalid CSS that was silently dropped, so the floor never applied. --- .../pages/AgentsPage/components/ChatElements/ModelSelector.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx index ff384b569d3..685c4fbc816 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx @@ -167,7 +167,7 @@ export const ModelSelector: FC = ({ // the label (px-2 padding, size-3 provider icon, two gap-1 gaps, // size-3.5 chevron) so the label and chevron never get clipped. className={cn( - "h-7 min-w-[calc(8ch+3.125rem)] shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", + "h-7 min-w-[calc(8ch_+_3.125rem)] shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", className, )} onTouchStart={onTriggerTouchStart} From 501fd98511c92e66ca4fc75672d933cad7294102 Mon Sep 17 00:00:00 2001 From: TJ Date: Tue, 25 Aug 2026 11:12:32 -0700 Subject: [PATCH 05/11] fix(site): use valid calc syntax for the workspace pill width floor calc() requires whitespace around +, and Tailwind arbitrary values encode spaces as underscores. calc(8ch+3.125rem) produced invalid CSS that was silently dropped, so the floor never applied. --- site/src/pages/AgentsPage/components/WorkspacePill.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/pages/AgentsPage/components/WorkspacePill.tsx b/site/src/pages/AgentsPage/components/WorkspacePill.tsx index a06459c59a9..31947073cc3 100644 --- a/site/src/pages/AgentsPage/components/WorkspacePill.tsx +++ b/site/src/pages/AgentsPage/components/WorkspacePill.tsx @@ -128,7 +128,7 @@ export const WorkspacePill: FC = ({ > {/* md floor: ~8ch of the workspace name + 3.125rem of chrome * (padding, status icon, gaps, chevron), matching ModelSelector. */} - + setTooltipOpen(v && !open)} From 21646ec7e00040a09d1ea59690d21884f7ba093a Mon Sep 17 00:00:00 2001 From: Tracy Johnson Date: Tue, 25 Aug 2026 18:33:42 +0000 Subject: [PATCH 06/11] fix(site): let the workspace pill wrapper shrink so the pill truncates The plain span wrapping WorkspacePill had an automatic minimum equal to the pill's full content width, so under pressure the pill never shrank and was clipped to just its icon. Make the wrapper a flex container that can shrink, with the same md 8ch + chrome floor as the pill itself. Verified in Storybook at narrow desktop panel widths: both pills hold 8 characters with ellipsis and visible chevrons. --- site/src/pages/AgentsPage/components/AgentChatInput.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.tsx index cad62b611b6..ba13c651ba6 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.tsx @@ -1448,7 +1448,11 @@ export const AgentChatInput: FC = ({ * when there's no overflow but still occupies * layout space, preventing measurement flicker. */} {workspace && workspaceAgent && chatId && ( - + // flex + explicit min-width let this wrapper shrink below its + // content so the pill truncates; a plain span's automatic + // minimum is the pill's full width, which blocks shrinking and + // clips the pill instead. The md floor matches WorkspacePill. + Date: Tue, 25 Aug 2026 18:58:03 +0000 Subject: [PATCH 07/11] fix(site): collapse the workspace pill into overflow before it miniaturizes Treat the attached workspace like the other overflow-managed badges. When the row overflows and the workspace would otherwise survive only as a tiny minimum-width pill, stop rendering it in the visible row and surface it through the +N overflow popover instead. Update the stories to exercise the real attached-workspace path used by the chat view. --- .../components/AgentChatInput.stories.tsx | 22 +++++++ .../AgentsPage/components/AgentChatInput.tsx | 64 ++++++++++++------- 2 files changed, 63 insertions(+), 23 deletions(-) diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx index e049a49c2fa..1b05b4eddf2 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx @@ -1479,6 +1479,21 @@ export const OverflowBadges: Story = { ], selectedWorkspaceId: "ws-1", onWorkspaceChange: fn(), + attachedWorkspace: { + id: "ws-1", + name: "my-long-workspace-name", + route: "/@admin/my-long-workspace-name", + statusIcon: , + statusLabel: "Workspace running", + }, + workspace: { + ...MockWorkspace, + id: "ws-1", + name: "my-long-workspace-name", + owner_name: "admin", + }, + workspaceAgent: MockWorkspaceAgent, + chatId: "overflow-chat-id", }, parameters: { viewport: { defaultViewport: "mobile2" }, @@ -1552,6 +1567,13 @@ export const LongWorkspaceNameMobile: Story = { ...mcpDefaults, mcpServers: [githubMCPConnected], selectedMCPServerIds: [githubMCPConnected.id], + attachedWorkspace: { + id: MockWorkspace.id, + name: "my-super-extremely-long-workspace-name-that-overflows", + route: `/@${MockWorkspace.owner_name}/my-super-extremely-long-workspace-name-that-overflows`, + statusIcon: , + statusLabel: "Workspace running", + }, workspace: { ...MockWorkspace, name: "my-super-extremely-long-workspace-name-that-overflows", diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.tsx index ba13c651ba6..7b107a5cdf7 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.tsx @@ -584,6 +584,9 @@ export const AgentChatInput: FC = ({ const [overflowPopoverOpen, setOverflowPopoverOpen] = useState(false); const shouldOverflowPlanningBadge = planModeEnabled && contextUsage !== undefined; + const shouldShowWorkspacePill = Boolean( + attachedWorkspace && workspace && workspaceAgent && chatId, + ); // Ordered list of active tool badge data so we can determine // which ones ended up in the overflow popover. @@ -591,10 +594,9 @@ export const AgentChatInput: FC = ({ if (shouldOverflowPlanningBadge) { allBadges.push({ kind: "planning" }); } - // When workspace data is available, WorkspacePill handles - // the display (including app dropdown). Otherwise fall back - // to the simple attached-workspace ToolBadge. - if (!(workspace && workspaceAgent && chatId) && attachedWorkspace) { + if (shouldShowWorkspacePill) { + allBadges.push({ kind: "attached-workspace", ...attachedWorkspace! }); + } else if (attachedWorkspace) { allBadges.push({ kind: "attached-workspace", ...attachedWorkspace }); } if (shouldShowSelectedWorkspaceBadge && selectedWorkspace) { @@ -606,7 +608,11 @@ export const AgentChatInput: FC = ({ const overflowCount = useOverflowCount(badgeContainerRef, allBadges.length); const visibleCount = Math.max(0, allBadges.length - overflowCount); - const overflowBadges = allBadges.slice(visibleCount); + const adjustedVisibleCount = + overflowCount > 0 && shouldShowWorkspacePill + ? Math.max(0, visibleCount - 1) + : visibleCount; + const overflowBadges = allBadges.slice(adjustedVisibleCount); const handleRemoveWorkspace = () => onWorkspaceChange?.(null); const removeWorkspaceHandler = onWorkspaceChange @@ -1447,31 +1453,43 @@ export const AgentChatInput: FC = ({ * hide and reorder via CSS. The pill is invisible * when there's no overflow but still occupies * layout space, preventing measurement flicker. */} - {workspace && workspaceAgent && chatId && ( - // flex + explicit min-width let this wrapper shrink below its - // content so the pill truncates; a plain span's automatic - // minimum is the pill's full width, which blocks shrinking and - // clips the pill instead. The md floor matches WorkspacePill. - - - - )}
{allBadges.map((badge, i) => { - const isOverflow = overflowCount > 0 && i >= visibleCount; + const isOverflow = i >= adjustedVisibleCount; + const key = badge.kind === "mcp" ? badge.server.id : badge.kind; + if (badge.kind === "attached-workspace") { + if (isOverflow) { + return null; + } + if ( + shouldShowWorkspacePill && + workspace && + workspaceAgent && + chatId + ) { + return ( + + + + ); + } + } return ( Date: Tue, 25 Aug 2026 19:07:07 +0000 Subject: [PATCH 08/11] fix(site): remove the workspace pill's icon-only state in favor of +N overflow The below-md icon-only variant was the remaining tiny state: at narrow viewports the pill collapsed to a bare status icon that always fit, so it never entered the overflow popover. Render name and chevron at every breakpoint with the 8ch floor; when the floored pill no longer fits, the badge overflow system moves it into the +N popover. The pill renders whenever workspace data is present, with attachedWorkspace only enriching its overflow-popover fallback badge. --- .../components/AgentChatInput.stories.tsx | 20 +++-- .../AgentsPage/components/AgentChatInput.tsx | 78 +++++++++---------- .../AgentsPage/components/WorkspacePill.tsx | 26 +++---- 3 files changed, 63 insertions(+), 61 deletions(-) diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx index 1b05b4eddf2..7389403ddb5 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx @@ -1561,7 +1561,7 @@ export const ContextNearLimit: Story = { }, }; -/** Long workspace name at iPhone SE width — verifies truncation. */ +/** Long workspace name at iPhone SE width — collapses into +N overflow. */ export const LongWorkspaceNameMobile: Story = { args: { ...mcpDefaults, @@ -1587,15 +1587,23 @@ export const LongWorkspaceNameMobile: Story = { }, play: async ({ canvasElement }) => { const canvas = within(canvasElement); - // The workspace pill button should be present. - const pill = await canvas.findByRole("button", { - name: /workspace menu/, + // Too narrow for the pill's minimum width: it must collapse into + // the overflow popover instead of clipping to a tiny pill. + const overflowPill = await canvas.findByRole("button", { + name: /more item/, }); await waitFor(() => { - expect(pill).toBeVisible(); + expect(overflowPill).toBeVisible(); }); + await userEvent.click(overflowPill); + const popover = await within(document.body).findByRole("dialog"); + expect( + within(popover).getByText( + "my-super-extremely-long-workspace-name-that-overflows", + ), + ).toBeInTheDocument(); // The toolbar row should not cause horizontal overflow. - const toolbar = pill.closest( + const toolbar = overflowPill.closest( ".flex.items-center.justify-between", ) as HTMLElement; if (toolbar?.parentElement) { diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.tsx index 7b107a5cdf7..4d48c3d254b 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.tsx @@ -584,9 +584,16 @@ export const AgentChatInput: FC = ({ const [overflowPopoverOpen, setOverflowPopoverOpen] = useState(false); const shouldOverflowPlanningBadge = planModeEnabled && contextUsage !== undefined; - const shouldShowWorkspacePill = Boolean( - attachedWorkspace && workspace && workspaceAgent && chatId, - ); + + // When workspace data is available the badge renders as the + // interactive WorkspacePill; its overflow-popover fallback uses the + // richer attachedWorkspace data when present. + let workspacePillBadge: ToolBadgeData | undefined; + if (workspace && workspaceAgent && chatId) { + workspacePillBadge = attachedWorkspace + ? { kind: "attached-workspace", ...attachedWorkspace } + : { kind: "workspace", name: workspace.name }; + } // Ordered list of active tool badge data so we can determine // which ones ended up in the overflow popover. @@ -594,8 +601,8 @@ export const AgentChatInput: FC = ({ if (shouldOverflowPlanningBadge) { allBadges.push({ kind: "planning" }); } - if (shouldShowWorkspacePill) { - allBadges.push({ kind: "attached-workspace", ...attachedWorkspace! }); + if (workspacePillBadge) { + allBadges.push(workspacePillBadge); } else if (attachedWorkspace) { allBadges.push({ kind: "attached-workspace", ...attachedWorkspace }); } @@ -608,11 +615,7 @@ export const AgentChatInput: FC = ({ const overflowCount = useOverflowCount(badgeContainerRef, allBadges.length); const visibleCount = Math.max(0, allBadges.length - overflowCount); - const adjustedVisibleCount = - overflowCount > 0 && shouldShowWorkspacePill - ? Math.max(0, visibleCount - 1) - : visibleCount; - const overflowBadges = allBadges.slice(adjustedVisibleCount); + const overflowBadges = allBadges.slice(visibleCount); const handleRemoveWorkspace = () => onWorkspaceChange?.(null); const removeWorkspaceHandler = onWorkspaceChange @@ -1458,38 +1461,35 @@ export const AgentChatInput: FC = ({ className="flex min-w-0 items-center gap-1 overflow-hidden" > {allBadges.map((badge, i) => { - const isOverflow = i >= adjustedVisibleCount; - const key = badge.kind === "mcp" ? badge.server.id : badge.kind; - if (badge.kind === "attached-workspace") { - if (isOverflow) { - return null; - } - if ( - shouldShowWorkspacePill && - workspace && - workspaceAgent && - chatId - ) { - return ( - - - - ); - } + const isOverflow = overflowCount > 0 && i >= visibleCount; + if ( + badge === workspacePillBadge && + workspace && + workspaceAgent && + chatId + ) { + return ( + + + + ); } return ( = ({ } }} > - {/* md floor: ~8ch of the workspace name + 3.125rem of chrome - * (padding, status icon, gaps, chevron), matching ModelSelector. */} - + {/* Floor of ~8ch of name + 3.125rem chrome (padding, status icon, + * gaps, chevron). Below the floor the overflow system moves the + * pill into the +N popover instead of shrinking it further. */} + setTooltipOpen(v && !open)} @@ -139,29 +140,22 @@ export const WorkspacePill: FC = ({ type="button" aria-label={`${workspace.name} workspace menu`} className={cn( - "inline-flex min-w-0 cursor-pointer items-center justify-center gap-1 rounded-full border-0 bg-transparent p-0 text-xs font-medium text-content-secondary transition-colors hover:bg-surface-tertiary hover:text-content-primary", - "size-7 md:size-auto md:w-full md:max-w-[200px] md:justify-start md:px-2 md:py-0.5", + "inline-flex min-w-0 cursor-pointer items-center justify-start gap-1 rounded-full border-0 bg-transparent p-0 text-xs font-medium text-content-secondary transition-colors hover:bg-surface-tertiary hover:text-content-primary", + "h-7 w-full max-w-[200px] px-2 py-0.5", )} > - - - {workspace.name} - + + {workspace.name} - - {statusLabel} - + {statusLabel} From 6ee9c04a9eed21f4db119f0a7856e629171fd7a8 Mon Sep 17 00:00:00 2001 From: Tracy Johnson Date: Tue, 25 Aug 2026 21:46:27 +0000 Subject: [PATCH 09/11] fix(site): remove emdash from story comment --- site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx index 7389403ddb5..40fe6c53c23 100644 --- a/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx +++ b/site/src/pages/AgentsPage/components/AgentChatInput.stories.tsx @@ -1561,7 +1561,7 @@ export const ContextNearLimit: Story = { }, }; -/** Long workspace name at iPhone SE width — collapses into +N overflow. */ +/** Long workspace name at iPhone SE width collapses into +N overflow. */ export const LongWorkspaceNameMobile: Story = { args: { ...mcpDefaults, From 88211a4016b7ab64af035bc5c880fdd49940b298 Mon Sep 17 00:00:00 2001 From: TJ Date: Wed, 26 Aug 2026 10:01:38 -0700 Subject: [PATCH 10/11] Update ModelSelector.tsx --- .../components/ChatElements/ModelSelector.tsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx index 685c4fbc816..bdce00b8aaf 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx @@ -162,9 +162,7 @@ export const ModelSelector: FC = ({ role="combobox" type="button" variant="subtle" - // min-w floor: keep roughly 8ch of the model name visible before - // truncation kicks in. 3.125rem covers the fixed chrome around - // the label (px-2 padding, size-3 provider icon, two gap-1 gaps, + // min-w floor: ~8ch visible before truncation. // size-3.5 chevron) so the label and chevron never get clipped. className={cn( "h-7 min-w-[calc(8ch_+_3.125rem)] shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", @@ -200,11 +198,8 @@ export const ModelSelector: FC = ({ contentClassName, )} onOpenAutoFocus={(event) => { - // On touch devices, auto-focusing the search input pops the - // software keyboard as soon as the picker opens, hiding the - // model list behind it. Only keep the WAI-ARIA combobox - // focus-into-input behavior for fine pointers (keyboard and - // mouse users on desktop). + // Touch devices on open auto-focus search with sw keyboard, hide model list. + // Keep WAI-ARIA combobox focus-into-input behavior for fine pointers. if (matchMedia("(pointer: coarse)").matches) { event.preventDefault(); } From ff37112666609d9881d18bbaec86cfe81e738df2 Mon Sep 17 00:00:00 2001 From: Tracy Johnson Date: Wed, 26 Aug 2026 17:20:23 +0000 Subject: [PATCH 11/11] fix(site): repair comment fragments and trailing whitespace in ModelSelector --- .../AgentsPage/components/ChatElements/ModelSelector.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx index bdce00b8aaf..d2e53e702dd 100644 --- a/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx +++ b/site/src/pages/AgentsPage/components/ChatElements/ModelSelector.tsx @@ -162,8 +162,8 @@ export const ModelSelector: FC = ({ role="combobox" type="button" variant="subtle" - // min-w floor: ~8ch visible before truncation. - // size-3.5 chevron) so the label and chevron never get clipped. + // min-w floor: ~8ch of the label plus 3.125rem of fixed chrome + // stay visible before truncation kicks in. className={cn( "h-7 min-w-[calc(8ch_+_3.125rem)] shrink justify-start gap-1 rounded-full border-0 bg-surface-secondary px-2 py-0.5 text-xs font-medium shadow-none transition-colors hover:bg-surface-tertiary hover:text-content-primary focus:ring-0 focus-visible:ring-2 focus-visible:ring-content-link [&>svg]:!size-3.5 [&>svg]:p-0 [&>svg]:shrink-0 [&>svg]:transition [&>svg]:hover:text-content-primary [&>img]:!size-3 [&>img]:!p-0", className, @@ -198,8 +198,9 @@ export const ModelSelector: FC = ({ contentClassName, )} onOpenAutoFocus={(event) => { - // Touch devices on open auto-focus search with sw keyboard, hide model list. - // Keep WAI-ARIA combobox focus-into-input behavior for fine pointers. + // Touch devices auto-focus search on open, and the software + // keyboard hides the model list. Keep the WAI-ARIA combobox + // focus-into-input behavior for fine pointers only. if (matchMedia("(pointer: coarse)").matches) { event.preventDefault(); }