fix: distinguish agent code/shell blocks from user message bubbles (#1497)

* fix: distinguish agent code/shell blocks from user message bubbles

Code blocks and shell command output shared the same accent bubble
background as user message bubbles, making them hard to tell apart at
full width. Give them a distinct neutral gray background plus a subtle
border.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>

* fix: apply neutral code bubble to all agent output cards + add second accent

Extend the neutral code-bubble background to the remaining agent output
cards (files-changed card, reply preview, edited-file diff, todo list,
streaming-turn cards) so none of them share the user message bubble
background. Introduce a violet --ui-accent-2 used on code/shell header
labels so the blocks pop.

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
This commit is contained in:
Caroline di Vittorio 2026-06-11 09:44:10 -07:00 • committed by GitHub
parent 8c7b789122
commit 5515fff44c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 14 additions and 10 deletions

View file

@ -449,7 +449,7 @@ export function ChatView({ tabId }: ChatViewProps) {
)}
{hasStreamingChangedFiles && (
<div
className={`border border-[var(--ui-border)] bg-[var(--ui-accent-bubble)] px-3 pt-2 pb-4 flex items-center justify-between gap-3 text-xs rounded-b-none ${(hasTodos || hasActiveLoops) ? "rounded-t-none border-t-0" : "rounded-t-xl"}`}
className={`border border-[var(--ui-border)] bg-[var(--ui-code-bubble)] px-3 pt-2 pb-4 flex items-center justify-between gap-3 text-xs rounded-b-none ${(hasTodos || hasActiveLoops) ? "rounded-t-none border-t-0" : "rounded-t-xl"}`}
>
<span className="text-[color:var(--ui-text-muted)] truncate">
{streamingChangedFiles.length} file{streamingChangedFiles.length === 1 ? "" : "s"} changed
@ -537,7 +537,7 @@ const LoopManagerBlock = forwardRef<HTMLDivElement, LoopManagerBlockProps>(funct
<button
type="button"
onClick={onOpenLoopManager}
className="w-full border border-[var(--ui-border)] bg-[var(--ui-accent-bubble)] px-3 pt-2 pb-4 flex items-center justify-between gap-3 text-xs rounded-t-xl rounded-b-none mb-0 hover:bg-[var(--ui-bg-hover)] transition-colors"
className="w-full border border-[var(--ui-border)] bg-[var(--ui-code-bubble)] px-3 pt-2 pb-4 flex items-center justify-between gap-3 text-xs rounded-t-xl rounded-b-none mb-0 hover:bg-[var(--ui-bg-hover)] transition-colors"
>
<span className="flex items-center gap-3">
<span className="relative flex h-2 w-2">

View file

@ -104,9 +104,9 @@ export function CodeBlock({ text, language }: CodeBlockProps) {
};
return (
<div className="my-2 max-w-full overflow-hidden rounded-xl bg-[var(--ui-accent-bubble)]">
<div className="my-2 max-w-full overflow-hidden rounded-xl border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bubble)]">
<div className="flex items-center justify-between px-3 py-2 text-xs">
<span className="text-[color:var(--ui-text-muted)]">{displayLanguage}</span>
<span className="font-mono text-[color:var(--ui-accent-2)]">{displayLanguage}</span>
<button
type="button"
onClick={handleCopy}

View file

@ -187,7 +187,7 @@ const TurnChangedFilesCard = memo(function TurnChangedFilesCard({
}, []);
return (
<div className="mt-3 rounded-xl bg-[var(--ui-accent-bubble)] overflow-hidden">
<div className="mt-3 rounded-xl border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bubble)] overflow-hidden">
<div className="px-3 py-2 text-xs text-[color:var(--ui-text-muted)] border-b border-[var(--ui-border)] flex items-center gap-2">
<span>{files.length} file{files.length === 1 ? "" : "s"} changed</span>
<span className="text-green-400">+{totals.additions}</span>

View file

@ -183,7 +183,7 @@ export const ReplyCard = memo(function ReplyCard({ chunk }: ReplyCardProps) {
<span>{headerLabel(isLinear, chunk.status)}</span>
</div>
{body && (
<div className="overflow-hidden rounded-xl bg-[var(--ui-accent-bubble)]">
<div className="overflow-hidden rounded-xl border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bubble)]">
<div className="max-h-[250px] overflow-auto px-3 py-2 text-[13px] text-[color:var(--ui-text)]">
{isLinear ? (
<Markdown content={body} />

View file

@ -64,9 +64,9 @@ export const ShellCommand = memo(function ShellCommand({
</button>
{expanded && (
<div className="rounded-xl bg-[var(--ui-accent-bubble)] mt-1 overflow-hidden max-h-[250px] flex flex-col">
<div className="rounded-xl border border-[var(--ui-border-subtle)] bg-[var(--ui-code-bubble)] mt-1 overflow-hidden max-h-[250px] flex flex-col">
<div className="px-3 pt-2 pb-1 font-mono text-xs shrink-0">
<div className="text-[color:var(--ui-text-dim)] mb-2">bash</div>
<div className="text-[color:var(--ui-accent-2)] mb-2">bash</div>
<div className="text-[color:var(--ui-text)] font-semibold whitespace-pre overflow-x-auto">
<span className="text-[color:var(--ui-text-dim)]">$ </span>
{command}

View file

@ -54,7 +54,7 @@ export function TodoList({ todos, className = "", runActive = false }: TodoListP
const completed = todos.filter((t) => t.status === "completed").length;
return (
<div className={`font-sans text-xs rounded-xl border border-[var(--ui-border)] bg-[var(--ui-accent-bubble)] overflow-hidden ${className}`}>
<div className={`font-sans text-xs rounded-xl border border-[var(--ui-border)] bg-[var(--ui-code-bubble)] overflow-hidden ${className}`}>
<button
type="button"
className="w-full px-3 py-2 flex items-center gap-2 text-left hover:bg-white/5 transition-colors"

View file

@ -186,7 +186,7 @@ const InlineDiffCollapsible = memo(function InlineDiffCollapsible({
</button>
</div>
<div className="rounded-lg bg-[var(--ui-accent-bubble)] overflow-hidden border border-[var(--ui-border-subtle)]">
<div className="rounded-lg bg-[var(--ui-code-bubble)] overflow-hidden border border-[var(--ui-border-subtle)]">
<div className="px-3 py-2 flex items-center gap-2">
<span className={`text-[13px] truncate flex-1 min-w-0 ${isError ? "text-red-400" : "text-[color:var(--ui-accent)]"}`}>
{filePath}

View file

@ -9,7 +9,9 @@
--ui-text-muted: oklch(0.45 0.017 213.2);
--ui-text-dim: oklch(0.56 0.021 213.5);
--ui-accent: oklch(0.52 0.105 223.128);
--ui-accent-2: oklch(0.52 0.16 295);
--ui-accent-bubble: oklch(0.955 0.015 223);
--ui-code-bubble: oklch(0.962 0.002 247.9);
--ui-sidebar: oklch(0.987 0.002 197.1);
--ui-sidebar-hover: oklch(0.963 0.002 197.1);
--ui-success: oklch(0.62 0.17 145);
@ -28,7 +30,9 @@
--ui-text-muted: oklch(0.723 0.014 214.4);
--ui-text-dim: oklch(0.56 0.021 213.5);
--ui-accent: oklch(0.715 0.143 215.221);
--ui-accent-2: oklch(0.78 0.13 295);
--ui-accent-bubble: oklch(0.274 0.04 223);
--ui-code-bubble: oklch(0.248 0.004 228.8);
--ui-sidebar: oklch(0.218 0.008 223.9);
--ui-sidebar-hover: oklch(0.275 0.011 216.9);
--ui-success: oklch(0.62 0.17 145);