Explorar el Código

feat(feat): align sub-agent task rows with v2 design (#35167)

usrnk1 hace 2 meses
padre
commit
5c860d4142

+ 1 - 1
packages/app/src/components/prompt-input.tsx

@@ -1776,7 +1776,7 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
                             class="max-w-[160px] justify-start capitalize"
                             class="max-w-[160px] justify-start capitalize"
                             style={control()}
                             style={control()}
                           >
                           >
-                            <span class="truncate">
+                            <span class="truncate leading-5">
                               {props.controls.model.selection.variant.current() ?? language.t("common.default")}
                               {props.controls.model.selection.variant.current() ?? language.t("common.default")}
                             </span>
                             </span>
                             <span class="-ml-0.5 -mr-1 flex shrink-0">
                             <span class="-ml-0.5 -mr-1 flex shrink-0">

+ 35 - 8
packages/session-ui/src/components/basic-tool.css

@@ -185,6 +185,14 @@
     background-color 0.15s ease,
     background-color 0.15s ease,
     color 0.15s ease;
     color 0.15s ease;
 
 
+  [data-component="task-tool-surface"] {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    min-width: 0;
+    flex: 1 1 auto;
+  }
+
   [data-slot="basic-tool-tool-info-structured"] {
   [data-slot="basic-tool-tool-info-structured"] {
     flex: 1 1 auto;
     flex: 1 1 auto;
     min-width: 0;
     min-width: 0;
@@ -250,16 +258,30 @@
 
 
 body[data-new-layout] {
 body[data-new-layout] {
   [data-component="task-tool-card"] {
   [data-component="task-tool-card"] {
-    padding: 8px 12px 8px 10px;
-    border-radius: 8px;
+    gap: 8px;
+    padding: 0;
+    border-radius: 0;
     border: 0;
     border: 0;
     border-color: transparent;
     border-color: transparent;
-    background: var(--task-agent-background, light-dark(#fafafa, rgba(250, 250, 250, 0.15)));
-    box-shadow: inset 0 0 0 0.5px var(--task-agent-border, var(--v2-border-border-base));
+    background: transparent;
+    box-shadow: none;
+
+    [data-component="task-tool-surface"] {
+      padding: 8px 12px;
+      border-radius: 8px;
+      background: var(--v2-background-bg-layer-01);
+    }
 
 
     [data-component="task-tool-spinner"],
     [data-component="task-tool-spinner"],
-    [data-component="task-tool-title"] {
-      color: var(--task-agent-color, var(--text-strong));
+    [data-component="task-tool-icon"] {
+      display: inline-flex;
+      align-items: center;
+      justify-content: center;
+      flex-shrink: 0;
+
+      [data-component="icon"] {
+        color: var(--task-agent-color, var(--v2-icon-icon-base));
+      }
     }
     }
 
 
     [data-component="task-tool-title"] {
     [data-component="task-tool-title"] {
@@ -270,6 +292,7 @@ body[data-new-layout] {
       font-size: 13px;
       font-size: 13px;
       line-height: 20px;
       line-height: 20px;
       letter-spacing: -0.04px;
       letter-spacing: -0.04px;
+      color: var(--v2-text-text-base);
       flex: none;
       flex: none;
       flex-grow: 0;
       flex-grow: 0;
     }
     }
@@ -281,7 +304,7 @@ body[data-new-layout] {
       font-size: 13px;
       font-size: 13px;
       line-height: 20px;
       line-height: 20px;
       letter-spacing: -0.04px;
       letter-spacing: -0.04px;
-      color: light-dark(var(--v2-text-text-base), #fafafa);
+      color: var(--v2-text-text-base);
       font-variation-settings: "slnt" 0;
       font-variation-settings: "slnt" 0;
       flex: none;
       flex: none;
       flex-grow: 0;
       flex-grow: 0;
@@ -294,7 +317,11 @@ body[data-new-layout] {
     &:hover,
     &:hover,
     &:focus-visible {
     &:focus-visible {
       border-color: transparent;
       border-color: transparent;
-      background: var(--task-agent-background, light-dark(#fafafa, rgba(250, 250, 250, 0.15)));
+      background: transparent;
+
+      [data-component="task-tool-surface"] {
+        background: var(--v2-background-bg-layer-01);
+      }
     }
     }
   }
   }
 }
 }

+ 34 - 39
packages/session-ui/src/components/message-part.tsx

@@ -371,22 +371,12 @@ const agentTones: Record<string, string> = {
   plan: "var(--icon-agent-plan-base)",
   plan: "var(--icon-agent-plan-base)",
 }
 }
 
 
-const v2AgentTones: Record<string, { color: string; border: string; background: string }> = {
-  build: {
-    color: "var(--v2-agent-build-solid)",
-    border: "var(--v2-agent-build-border)",
-    background: "var(--v2-agent-build-background)",
-  },
-  explore: {
-    color: "var(--v2-agent-explore-solid)",
-    border: "var(--v2-agent-explore-border)",
-    background: "var(--v2-agent-explore-background)",
-  },
-  plan: {
-    color: "var(--v2-agent-plan-solid)",
-    border: "var(--v2-agent-plan-border)",
-    background: "var(--v2-agent-plan-background)",
-  },
+const v2AgentTones: Record<string, string> = {
+  build: "var(--v2-agent-build-solid)",
+  explore: "var(--v2-agent-explore-solid)",
+  plan: "var(--v2-agent-plan-solid)",
+  review: "var(--v2-agent-review-solid)",
+  writer: "var(--v2-agent-writer-solid)",
 }
 }
 
 
 const agentThemeColors: Record<string, string> = {
 const agentThemeColors: Record<string, string> = {
@@ -433,19 +423,17 @@ function tone(name: string) {
 function taskAgent(
 function taskAgent(
   raw: unknown,
   raw: unknown,
   list?: readonly { name: string; color?: string }[],
   list?: readonly { name: string; color?: string }[],
-): { name?: string; color?: string; v2Color?: string; border?: string; background?: string } {
+): { name?: string; color?: string; v2Color?: string } {
   if (typeof raw !== "string" || !raw) return {}
   if (typeof raw !== "string" || !raw) return {}
   const key = raw.toLowerCase()
   const key = raw.toLowerCase()
   const item = list?.find((entry) => entry.name === raw || entry.name.toLowerCase() === key)
   const item = list?.find((entry) => entry.name === raw || entry.name.toLowerCase() === key)
   const v2Tone = item?.color ? undefined : v2AgentTones[key]
   const v2Tone = item?.color ? undefined : v2AgentTones[key]
   const color = agentColor(item?.color, agentThemeColors) ?? agentTones[key] ?? tone(key)
   const color = agentColor(item?.color, agentThemeColors) ?? agentTones[key] ?? tone(key)
-  const v2Color = agentColor(item?.color, v2AgentThemeColors) ?? v2Tone?.color ?? color
+  const v2Color = agentColor(item?.color, v2AgentThemeColors) ?? v2Tone ?? color
   return {
   return {
     name: item?.name ?? `${raw[0]!.toUpperCase()}${raw.slice(1)}`,
     name: item?.name ?? `${raw[0]!.toUpperCase()}${raw.slice(1)}`,
     color,
     color,
     v2Color,
     v2Color,
-    border: v2Tone?.border ?? `color-mix(in srgb, ${v2Color} 48%, transparent)`,
-    background: v2Tone?.background ?? `color-mix(in srgb, ${v2Color} 12%, transparent)`,
   }
   }
 }
 }
 
 
@@ -1937,8 +1925,6 @@ ToolRegistry.register({
     const title = createMemo(() => agent().name ?? i18n.t("ui.tool.agent.default"))
     const title = createMemo(() => agent().name ?? i18n.t("ui.tool.agent.default"))
     const tone = createMemo(() => agent().color)
     const tone = createMemo(() => agent().color)
     const v2Tone = createMemo(() => agent().v2Color)
     const v2Tone = createMemo(() => agent().v2Color)
-    const border = createMemo(() => agent().border)
-    const background = createMemo(() => agent().background)
     const subtitle = createMemo(() => {
     const subtitle = createMemo(() => {
       const value =
       const value =
         typeof props.input.description === "string" && props.input.description
         typeof props.input.description === "string" && props.input.description
@@ -1983,25 +1969,34 @@ ToolRegistry.register({
         style={{
         style={{
           "--task-agent-color": v2Tone(),
           "--task-agent-color": v2Tone(),
           "--task-agent-legacy-color": tone(),
           "--task-agent-legacy-color": tone(),
-          "--task-agent-border": border(),
-          "--task-agent-background": background(),
         }}
         }}
       >
       >
-        <div data-slot="basic-tool-tool-info-structured">
-          <div data-slot="basic-tool-tool-info-main">
-            <Show when={running()}>
-              <span data-component="task-tool-spinner" style={{ color: tone() ?? "var(--icon-interactive-base)" }}>
-                <Show when={newLayout()} fallback={<Spinner />}>
-                  <SessionProgressIndicatorV2
-                    style={{ color: v2Tone() ?? "light-dark(var(--v2-text-text-base), #ffffff)" }}
-                  />
-                </Show>
-              </span>
-            </Show>
-            <span data-component="task-tool-title">{title()}</span>
-            <Show when={subtitle()}>
-              <span data-slot="basic-tool-tool-subtitle">{subtitle()}</span>
-            </Show>
+        <div data-component="task-tool-surface">
+          <div data-slot="basic-tool-tool-info-structured">
+            <div data-slot="basic-tool-tool-info-main">
+              <Show
+                when={running()}
+                fallback={
+                  <Show when={newLayout()}>
+                    <span data-component="task-tool-icon">
+                      <Icon name="subagent" size="small" />
+                    </span>
+                  </Show>
+                }
+              >
+                <span data-component="task-tool-spinner" style={{ color: tone() ?? "var(--icon-interactive-base)" }}>
+                  <Show when={newLayout()} fallback={<Spinner />}>
+                    <SessionProgressIndicatorV2
+                      style={{ color: v2Tone() ?? "light-dark(var(--v2-text-text-base), #ffffff)" }}
+                    />
+                  </Show>
+                </span>
+              </Show>
+              <span data-component="task-tool-title">{title()}</span>
+              <Show when={subtitle()}>
+                <span data-slot="basic-tool-tool-subtitle">{subtitle()}</span>
+              </Show>
+            </div>
           </div>
           </div>
         </div>
         </div>
         <Show when={clickable()}>
         <Show when={clickable()}>

+ 46 - 1
packages/session-ui/src/components/timeline-playground.stories.tsx

@@ -359,6 +359,34 @@ const TOOL_SAMPLES = {
     title: "Agent (Explore)",
     title: "Agent (Explore)",
     metadata: { sessionId: "sub-session-1" },
     metadata: { sessionId: "sub-session-1" },
   },
   },
+  "task build": {
+    tool: "task",
+    input: { description: "Implement the settings page", subagent_type: "build", prompt: "Build it" },
+    output: "Implemented the settings page.",
+    title: "Agent (Build)",
+    metadata: { sessionId: "sub-session-2" },
+  },
+  "task plan": {
+    tool: "task",
+    input: { description: "Plan the migration strategy", subagent_type: "plan", prompt: "Plan it" },
+    output: "Drafted a 4-step migration plan.",
+    title: "Agent (Plan)",
+    metadata: { sessionId: "sub-session-3" },
+  },
+  "task themed": {
+    tool: "task",
+    input: { description: "Review the diff for regressions", subagent_type: "review", prompt: "Review it" },
+    output: "No regressions found.",
+    title: "Agent (Review)",
+    metadata: { sessionId: "sub-session-4" },
+  },
+  "task fallback": {
+    tool: "task",
+    input: { description: "Write release notes", subagent_type: "writer", prompt: "Write them" },
+    output: "Release notes drafted.",
+    title: "Agent (Writer)",
+    metadata: { sessionId: "sub-session-5" },
+  },
   webfetch: {
   webfetch: {
     tool: "webfetch",
     tool: "webfetch",
     input: { url: "https://solidjs.com/docs/latest/api" },
     input: { url: "https://solidjs.com/docs/latest/api" },
@@ -1216,6 +1244,7 @@ function Playground() {
 
 
   const data = createMemo(() => ({
   const data = createMemo(() => ({
     session: [session()],
     session: [session()],
+    agent: [{ name: "build" }, { name: "plan" }, { name: "explore" }, { name: "review" }],
     session_status: {},
     session_status: {},
     session_diff: {},
     session_diff: {},
     message: { [session().id]: state.messages },
     message: { [session().id]: state.messages },
@@ -1342,6 +1371,19 @@ function Playground() {
     ])
     ])
   }
   }
 
 
+  const addAgentTasksTurn = () => {
+    addFullTurn("Run subagents with every agent type", [
+      toolPart(TOOL_SAMPLES.task),
+      toolPart(TOOL_SAMPLES["task build"]),
+      toolPart(TOOL_SAMPLES["task plan"]),
+      toolPart(TOOL_SAMPLES["task themed"]),
+      toolPart(TOOL_SAMPLES["task fallback"]),
+      toolPart(TOOL_SAMPLES.task, "running"),
+      toolPart(TOOL_SAMPLES["task build"], "running"),
+      toolPart(TOOL_SAMPLES["task plan"], "running"),
+    ])
+  }
+
   const addKitchenSink = () => {
   const addKitchenSink = () => {
     // User message variants
     // User message variants
     addUser("short")
     addUser("short")
@@ -1727,6 +1769,9 @@ function Playground() {
                 <button style={btnStyle} onClick={addReasoningFullTurn}>
                 <button style={btnStyle} onClick={addReasoningFullTurn}>
                   full turn
                   full turn
                 </button>
                 </button>
+                <button style={btnStyle} onClick={addAgentTasksTurn}>
+                  agent tasks
+                </button>
                 <button style={btnAccent} onClick={addKitchenSink}>
                 <button style={btnAccent} onClick={addKitchenSink}>
                   kitchen sink
                   kitchen sink
                 </button>
                 </button>
@@ -1966,7 +2011,7 @@ function Playground() {
       {/* Main area: timeline preview */}
       {/* Main area: timeline preview */}
       <div
       <div
         ref={previewRef!}
         ref={previewRef!}
-        style={{ flex: "1", overflow: "auto", "min-width": "0", "background-color": "var(--background-stronger)" }}
+        style={{ flex: "1", overflow: "auto", "min-width": "0", "background-color": "var(--v2-background-bg-base)" }}
       >
       >
         <DataProvider data={data()} directory="/project">
         <DataProvider data={data()} directory="/project">
           <FileComponentProvider component={FileStub}>
           <FileComponentProvider component={FileStub}>

+ 1 - 0
packages/ui/src/components/icon.stories.tsx

@@ -68,6 +68,7 @@ const names = [
   "magnifying-glass-menu",
   "magnifying-glass-menu",
   "window-cursor",
   "window-cursor",
   "task",
   "task",
+  "subagent",
   "stop",
   "stop",
   "layout-left",
   "layout-left",
   "layout-left-partial",
   "layout-left-partial",

+ 4 - 1
packages/ui/src/components/icon.tsx

@@ -52,6 +52,7 @@ const icons = {
   "magnifying-glass-menu": `<path d="M2.08325 10.0002H4.58325M2.08325 5.41683H5.41659M2.08325 14.5835H5.41659M16.4583 13.9585L18.7499 16.2502M17.9166 10.0002C17.9166 12.9917 15.4915 15.4168 12.4999 15.4168C9.50838 15.4168 7.08325 12.9917 7.08325 10.0002C7.08325 7.00862 9.50838 4.5835 12.4999 4.5835C15.4915 4.5835 17.9166 7.00862 17.9166 10.0002Z" stroke="currentColor" stroke-linecap="square"/>`,
   "magnifying-glass-menu": `<path d="M2.08325 10.0002H4.58325M2.08325 5.41683H5.41659M2.08325 14.5835H5.41659M16.4583 13.9585L18.7499 16.2502M17.9166 10.0002C17.9166 12.9917 15.4915 15.4168 12.4999 15.4168C9.50838 15.4168 7.08325 12.9917 7.08325 10.0002C7.08325 7.00862 9.50838 4.5835 12.4999 4.5835C15.4915 4.5835 17.9166 7.00862 17.9166 10.0002Z" stroke="currentColor" stroke-linecap="square"/>`,
   "window-cursor": `<path d="M17.9166 10.4167V3.75H2.08325V17.0833H10.4166M17.9166 13.5897L11.6666 11.6667L13.5897 17.9167L15.032 15.0321L17.9166 13.5897Z" stroke="currentColor" stroke-width="1.07143" stroke-linecap="square"/><path d="M5.00024 6.125C5.29925 6.12518 5.54126 6.36795 5.54126 6.66699C5.54108 6.96589 5.29914 7.20783 5.00024 7.20801C4.7012 7.20801 4.45843 6.966 4.45825 6.66699C4.45825 6.36784 4.70109 6.125 5.00024 6.125ZM7.91626 6.125C8.21541 6.125 8.45825 6.36784 8.45825 6.66699C8.45808 6.966 8.21531 7.20801 7.91626 7.20801C7.61736 7.20783 7.37542 6.96589 7.37524 6.66699C7.37524 6.36795 7.61726 6.12518 7.91626 6.125ZM10.8333 6.125C11.1324 6.125 11.3752 6.36784 11.3752 6.66699C11.3751 6.966 11.1323 7.20801 10.8333 7.20801C10.5342 7.20801 10.2914 6.966 10.2913 6.66699C10.2913 6.36784 10.5341 6.125 10.8333 6.125Z" fill="currentColor" stroke="currentColor" stroke-width="0.25" stroke-linecap="square"/>`,
   "window-cursor": `<path d="M17.9166 10.4167V3.75H2.08325V17.0833H10.4166M17.9166 13.5897L11.6666 11.6667L13.5897 17.9167L15.032 15.0321L17.9166 13.5897Z" stroke="currentColor" stroke-width="1.07143" stroke-linecap="square"/><path d="M5.00024 6.125C5.29925 6.12518 5.54126 6.36795 5.54126 6.66699C5.54108 6.96589 5.29914 7.20783 5.00024 7.20801C4.7012 7.20801 4.45843 6.966 4.45825 6.66699C4.45825 6.36784 4.70109 6.125 5.00024 6.125ZM7.91626 6.125C8.21541 6.125 8.45825 6.36784 8.45825 6.66699C8.45808 6.966 8.21531 7.20801 7.91626 7.20801C7.61736 7.20783 7.37542 6.96589 7.37524 6.66699C7.37524 6.36795 7.61726 6.12518 7.91626 6.125ZM10.8333 6.125C11.1324 6.125 11.3752 6.36784 11.3752 6.66699C11.3751 6.966 11.1323 7.20801 10.8333 7.20801C10.5342 7.20801 10.2914 6.966 10.2913 6.66699C10.2913 6.36784 10.5341 6.125 10.8333 6.125Z" fill="currentColor" stroke="currentColor" stroke-width="0.25" stroke-linecap="square"/>`,
   task: `<path d="M9.99992 2.0835V17.9168M7.08325 3.75016H2.08325V16.2502H7.08325M12.9166 16.2502H17.9166V3.75016H12.9166" stroke="currentColor" stroke-linecap="square"/>`,
   task: `<path d="M9.99992 2.0835V17.9168M7.08325 3.75016H2.08325V16.2502H7.08325M12.9166 16.2502H17.9166V3.75016H12.9166" stroke="currentColor" stroke-linecap="square"/>`,
+  subagent: `<path d="M4.5 5C4.5 4.72386 4.72386 4.5 5 4.5H11C11.2761 4.5 11.5 4.72386 11.5 5V11C11.5 11.2761 11.2761 11.5 11 11.5H5C4.72386 11.5 4.5 11.2761 4.5 11V5Z" fill="currentColor"/><path d="M13.5 2C13.7761 2 14 2.22386 14 2.5V13.5C14 13.7761 13.7761 14 13.5 14H2.5C2.22386 14 2 13.7761 2 13.5V2.5C2 2.22386 2.22386 2 2.5 2H13.5ZM3 13H13V3H3V13Z" fill="currentColor"/>`,
   stop: `<rect x="5" y="5" width="10" height="10" fill="currentColor"/>`,
   stop: `<rect x="5" y="5" width="10" height="10" fill="currentColor"/>`,
   status: `<path d="M2 10V18H18V10M2 10V2H18V10M2 10H18M5 6H9M5 14H9" stroke="currentColor"/>`,
   status: `<path d="M2 10V18H18V10M2 10V2H18V10M2 10H18M5 6H9M5 14H9" stroke="currentColor"/>`,
   "status-active": `<path d="M18 2H2V10H18V2Z" fill="currentColor" fill-opacity="0.1"/>
   "status-active": `<path d="M18 2H2V10H18V2Z" fill="currentColor" fill-opacity="0.1"/>
@@ -110,7 +111,9 @@ const symbol = (name: keyof typeof icons) => `opencode-icon-${name}`
 let spriteInserted = false
 let spriteInserted = false
 
 
 function viewBox(name: keyof typeof icons) {
 function viewBox(name: keyof typeof icons) {
-  return name === "magnifying-glass" || name === "arrow-undo-down" ? "0 0 16 16" : "0 0 20 20"
+  return name === "magnifying-glass" || name === "arrow-undo-down" || name === "subagent"
+    ? "0 0 16 16"
+    : "0 0 20 20"
 }
 }
 
 
 function ensureSprite() {
 function ensureSprite() {

+ 20 - 16
packages/ui/src/styles/theme.css

@@ -281,15 +281,17 @@
   --icon-agent-docs-base: #fcb239;
   --icon-agent-docs-base: #fcb239;
   --icon-agent-ask-base: #2090f5;
   --icon-agent-ask-base: #2090f5;
   --icon-agent-build-base: #034cff;
   --icon-agent-build-base: #034cff;
-  --v2-agent-plan-solid: var(--v2-pink-900);
-  --v2-agent-plan-border: rgba(200, 61, 139, 0.5);
-  --v2-agent-plan-background: rgba(253, 236, 243, 0.33);
-  --v2-agent-build-solid: var(--v2-blue-900);
-  --v2-agent-build-border: rgba(59, 92, 246, 0.5);
-  --v2-agent-build-background: rgba(236, 241, 254, 0.33);
+  --v2-agent-plan-solid: var(--v2-pink-800);
+  --v2-agent-plan-border: rgba(200, 61, 139, 0.20);
+  --v2-agent-plan-background: rgba(253, 236, 243, 0.10);
+  --v2-agent-build-solid: var(--v2-blue-800);
+  --v2-agent-build-border: rgba(44, 71, 200, 0.10);
+  --v2-agent-build-background: rgba(236, 241, 254, 0.10);
   --v2-agent-explore-solid: var(--v2-yellow-900);
   --v2-agent-explore-solid: var(--v2-yellow-900);
-  --v2-agent-explore-border: rgba(142, 114, 49, 0.5);
-  --v2-agent-explore-background: rgba(254, 250, 236, 0.33);
+  --v2-agent-explore-border: rgba(203, 159, 52, 0.20);
+  --v2-agent-explore-background: rgba(254, 250, 236, 0.1);
+  --v2-agent-review-solid: var(--v2-green-800);
+  --v2-agent-writer-solid: var(--v2-purple-700);
   --icon-on-success-base: rgba(18, 201, 5, 0.9);
   --icon-on-success-base: rgba(18, 201, 5, 0.9);
   --icon-on-success-hover: rgba(45, 186, 38, 0.9);
   --icon-on-success-hover: rgba(45, 186, 38, 0.9);
   --icon-on-success-selected: rgba(7, 137, 1, 0.9);
   --icon-on-success-selected: rgba(7, 137, 1, 0.9);
@@ -551,14 +553,16 @@
     --icon-agent-ask-base: #2090f5;
     --icon-agent-ask-base: #2090f5;
     --icon-agent-build-base: #9dbefe;
     --icon-agent-build-base: #9dbefe;
     --v2-agent-plan-solid: var(--v2-pink-400);
     --v2-agent-plan-solid: var(--v2-pink-400);
-    --v2-agent-plan-border: rgba(250, 188, 216, 0.5);
-    --v2-agent-plan-background: rgba(247, 213, 228, 0.1);
-    --v2-agent-build-solid: var(--v2-blue-400);
-    --v2-agent-build-border: rgba(215, 226, 252, 0.5);
-    --v2-agent-build-background: rgba(215, 226, 252, 0.1);
-    --v2-agent-explore-solid: var(--v2-yellow-400);
-    --v2-agent-explore-border: rgba(247, 229, 181, 0.5);
-    --v2-agent-explore-background: rgba(252, 239, 208, 0.1);
+    --v2-agent-plan-border: rgba(247, 153, 198, 0.20);
+    --v2-agent-plan-background: rgba(170, 53, 118, 0.05);
+    --v2-agent-build-solid: var(--v2-blue-300);
+    --v2-agent-build-border: rgba(162, 188, 255, 0.20);
+    --v2-agent-build-background: rgba(38, 63, 169, 0.05);
+    --v2-agent-explore-solid: var(--v2-yellow-300);
+    --v2-agent-explore-border: rgba(243, 218, 155, 0.20);
+    --v2-agent-explore-background: rgba(172, 136, 51, 0.05);
+    --v2-agent-review-solid: var(--v2-green-300);
+    --v2-agent-writer-solid: var(--v2-purple-400);
     --icon-on-success-base: rgba(18, 201, 5, 0.9);
     --icon-on-success-base: rgba(18, 201, 5, 0.9);
     --icon-on-success-hover: rgba(53, 192, 45, 0.9);
     --icon-on-success-hover: rgba(53, 192, 45, 0.9);
     --icon-on-success-selected: rgba(77, 225, 68, 0.9);
     --icon-on-success-selected: rgba(77, 225, 68, 0.9);

+ 20 - 16
packages/ui/src/theme/v2/mapping.ts

@@ -4,27 +4,31 @@ import { V2_AVATAR_DARK, V2_AVATAR_LIGHT } from "./avatar"
 const ref = (name: string): V2ColorValue => `var(--${name})`
 const ref = (name: string): V2ColorValue => `var(--${name})`
 
 
 const lightAgentTokens: Record<string, V2ColorValue> = {
 const lightAgentTokens: Record<string, V2ColorValue> = {
-  "v2-agent-plan-solid": ref("v2-pink-900"),
-  "v2-agent-plan-border": "rgba(200, 61, 139, 0.5)",
-  "v2-agent-plan-background": "rgba(253, 236, 243, 0.33)",
-  "v2-agent-build-solid": ref("v2-blue-900"),
-  "v2-agent-build-border": "rgba(59, 92, 246, 0.5)",
-  "v2-agent-build-background": "rgba(236, 241, 254, 0.33)",
+  "v2-agent-plan-solid": ref("v2-pink-800"),
+  "v2-agent-plan-border": "rgba(200, 61, 139, 0.20)",
+  "v2-agent-plan-background": "rgba(253, 236, 243, 0.10)",
+  "v2-agent-build-solid": ref("v2-blue-800"),
+  "v2-agent-build-border": "rgba(44, 71, 200, 0.20)",
+  "v2-agent-build-background": "rgba(236, 241, 254, 0.10)",
   "v2-agent-explore-solid": ref("v2-yellow-900"),
   "v2-agent-explore-solid": ref("v2-yellow-900"),
-  "v2-agent-explore-border": "rgba(142, 114, 49, 0.5)",
-  "v2-agent-explore-background": "rgba(254, 250, 236, 0.33)",
+  "v2-agent-explore-border": "rgba(203, 159, 52, 0.20)",
+  "v2-agent-explore-background": "rgba(254, 250, 236, 0.1)",
+  "v2-agent-review-solid": ref("v2-green-800"),
+  "v2-agent-writer-solid": ref("v2-purple-700"),
 }
 }
 
 
 const darkAgentTokens: Record<string, V2ColorValue> = {
 const darkAgentTokens: Record<string, V2ColorValue> = {
   "v2-agent-plan-solid": ref("v2-pink-400"),
   "v2-agent-plan-solid": ref("v2-pink-400"),
-  "v2-agent-plan-border": "rgba(250, 188, 216, 0.5)",
-  "v2-agent-plan-background": "rgba(247, 213, 228, 0.1)",
-  "v2-agent-build-solid": ref("v2-blue-400"),
-  "v2-agent-build-border": "rgba(215, 226, 252, 0.5)",
-  "v2-agent-build-background": "rgba(215, 226, 252, 0.1)",
-  "v2-agent-explore-solid": ref("v2-yellow-400"),
-  "v2-agent-explore-border": "rgba(247, 229, 181, 0.5)",
-  "v2-agent-explore-background": "rgba(252, 239, 208, 0.1)",
+  "v2-agent-plan-border": "rgba(247, 153, 198, 0.20)",
+  "v2-agent-plan-background": "rgba(170, 53, 118, 0.05)",
+  "v2-agent-build-solid": ref("v2-blue-300"),
+  "v2-agent-build-border": "rgba(162, 188, 255, 0.20)",
+  "v2-agent-build-background": "rgba(38, 63, 169, 0.05)",
+  "v2-agent-explore-solid": ref("v2-yellow-300"),
+  "v2-agent-explore-border": "rgba(243, 218, 155, 0.20)",
+  "v2-agent-explore-background": "rgba(172, 136, 51, 0.05)",
+  "v2-agent-review-solid": ref("v2-green-300"),
+  "v2-agent-writer-solid": ref("v2-purple-400"),
 }
 }
 
 
 const light: Record<string, V2ColorValue> = {
 const light: Record<string, V2ColorValue> = {

+ 30 - 24
packages/ui/src/v2/styles/theme.css

@@ -77,15 +77,17 @@
     --v2-state-fg-info: var(--v2-blue-800);
     --v2-state-fg-info: var(--v2-blue-800);
     --v2-state-border-info: var(--v2-blue-300);
     --v2-state-border-info: var(--v2-blue-300);
 
 
-    --v2-agent-plan-solid: var(--v2-pink-900);
-    --v2-agent-plan-border: rgba(200, 61, 139, 0.5);
-    --v2-agent-plan-background: rgba(253, 236, 243, 0.33);
-    --v2-agent-build-solid: var(--v2-blue-900);
-    --v2-agent-build-border: rgba(59, 92, 246, 0.5);
-    --v2-agent-build-background: rgba(236, 241, 254, 0.33);
+    --v2-agent-plan-solid: var(--v2-pink-800);
+    --v2-agent-plan-border: rgba(200, 61, 139, 0.20);
+    --v2-agent-plan-background: rgba(253, 236, 243, 0.10);
+    --v2-agent-build-solid: var(--v2-blue-800);
+    --v2-agent-build-border: rgba(44, 71, 200, 0.10);
+    --v2-agent-build-background: rgba(236, 241, 254, 0.10);
     --v2-agent-explore-solid: var(--v2-yellow-900);
     --v2-agent-explore-solid: var(--v2-yellow-900);
-    --v2-agent-explore-border: rgba(142, 114, 49, 0.5);
-    --v2-agent-explore-background: rgba(254, 250, 236, 0.33);
+    --v2-agent-explore-border: rgba(203, 159, 52, 0.20);
+    --v2-agent-explore-background: rgba(254, 250, 236, 0.1);
+    --v2-agent-review-solid: var(--v2-green-800);
+    --v2-agent-writer-solid: var(--v2-purple-700);
 
 
     /* ── Project avatar (fixed; theme-independent) ── */
     /* ── Project avatar (fixed; theme-independent) ── */
     --v2-avatar-fg: #ffffffff;
     --v2-avatar-fg: #ffffffff;
@@ -316,15 +318,17 @@
     --v2-state-fg-info: var(--v2-blue-800);
     --v2-state-fg-info: var(--v2-blue-800);
     --v2-state-border-info: var(--v2-blue-300);
     --v2-state-border-info: var(--v2-blue-300);
 
 
-    --v2-agent-plan-solid: var(--v2-pink-900);
-    --v2-agent-plan-border: rgba(200, 61, 139, 0.5);
-    --v2-agent-plan-background: rgba(253, 236, 243, 0.33);
-    --v2-agent-build-solid: var(--v2-blue-900);
-    --v2-agent-build-border: rgba(59, 92, 246, 0.5);
-    --v2-agent-build-background: rgba(236, 241, 254, 0.33);
+    --v2-agent-plan-solid: var(--v2-pink-800);
+    --v2-agent-plan-border: rgba(200, 61, 139, 0.20);
+    --v2-agent-plan-background: rgba(253, 236, 243, 0.10);
+    --v2-agent-build-solid: var(--v2-blue-800);
+    --v2-agent-build-border: rgba(44, 71, 200, 0.10);
+    --v2-agent-build-background: rgba(236, 241, 254, 0.10);
     --v2-agent-explore-solid: var(--v2-yellow-900);
     --v2-agent-explore-solid: var(--v2-yellow-900);
-    --v2-agent-explore-border: rgba(142, 114, 49, 0.5);
-    --v2-agent-explore-background: rgba(254, 250, 236, 0.33);
+    --v2-agent-explore-border: rgba(203, 159, 52, 0.20);
+    --v2-agent-explore-background: rgba(254, 250, 236, 0.1);
+    --v2-agent-review-solid: var(--v2-green-800);
+    --v2-agent-writer-solid: var(--v2-purple-700);
 
 
     --v2-elevation-raised:
     --v2-elevation-raised:
       0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8),
       0px 2px 4px 0px var(--v2-alpha-dark-4), 0px 1px 2px -1px var(--v2-alpha-dark-8),
@@ -437,14 +441,16 @@
     --v2-state-border-info: var(--v2-blue-900);
     --v2-state-border-info: var(--v2-blue-900);
 
 
     --v2-agent-plan-solid: var(--v2-pink-400);
     --v2-agent-plan-solid: var(--v2-pink-400);
-    --v2-agent-plan-border: rgba(250, 188, 216, 0.5);
-    --v2-agent-plan-background: rgba(247, 213, 228, 0.1);
-    --v2-agent-build-solid: var(--v2-blue-400);
-    --v2-agent-build-border: rgba(215, 226, 252, 0.5);
-    --v2-agent-build-background: rgba(215, 226, 252, 0.1);
-    --v2-agent-explore-solid: var(--v2-yellow-400);
-    --v2-agent-explore-border: rgba(247, 229, 181, 0.5);
-    --v2-agent-explore-background: rgba(252, 239, 208, 0.1);
+    --v2-agent-plan-border: rgba(247, 153, 198, 0.20);
+    --v2-agent-plan-background: rgba(170, 53, 118, 0.05);
+    --v2-agent-build-solid: var(--v2-blue-300);
+    --v2-agent-build-border: rgba(162, 188, 255, 0.20);
+    --v2-agent-build-background: rgba(38, 63, 169, 0.05);
+    --v2-agent-explore-solid: var(--v2-yellow-300);
+    --v2-agent-explore-border: rgba(243, 218, 155, 0.20);
+    --v2-agent-explore-background: rgba(172, 136, 51, 0.05);
+    --v2-agent-review-solid: var(--v2-green-300);
+    --v2-agent-writer-solid: var(--v2-purple-400);
 
 
     --v2-avatar-fg: #ffffffff;
     --v2-avatar-fg: #ffffffff;
     --v2-avatar-bg-orange: #723d22ff;
     --v2-avatar-bg-orange: #723d22ff;