Skip to content

[Feature] Slash picker: per-function semantic icons; reserve the brand accent for the active state #1164

@Astro-Han

Description

@Astro-Han

What task are you trying to do?

When I open the slash picker, I want to recognize each entry at a glance — a builtin action (/open, /compact), a custom command, an MCP command, or a skill — by a meaningful icon, and I want the picker itself to feel calm while the brand color clearly signals "this skill is actually engaged for my turn."

Which area would this change affect?

UI or design system

What do you do today?

Today the slash picker rows have no leading icon at all. Entry type is conveyed only by a small right-side text badge (Skill / MCP / Custom). On the white popover that badge renders as borderless, low-contrast gray text — --surface-base and --surface-raised both resolve to #ffffff, so the "pill" has no visible fill. There is no fast visual scan: builtins, custom commands, MCP commands, and skills all look nearly identical and you have to read each label + description.

Separately, #1156 gave skills a brand-orange glyph in the composer pill and the sent bubble, but the picker has no matching treatment, so the affordance is inconsistent across the three surfaces (menu → composer → bubble).

What would a good result look like?

A single, consistent icon language across the slash picker, built entirely from existing packages/ui assets (no new artwork):

  1. Per-function semantic icons, not just a 3-way type tag. The classification descends from "Command / Skill / MCP" to the concrete function. Builtins map to action glyphs (open-file, new-session, archive, branch, …); custom commands use the command glyph; MCP commands use the mcp glyph; skills use a generic skill (sparkle) glyph for now.
  2. The menu stays neutral. All picker icons are rendered in the muted foreground color (--fg-weak). The brand accent is removed from the picker.
  3. The brand accent means "in effect," not "is a skill." --brand-primary (#ff5910) is reserved for the active / in-effect state — the inline chip in the composer and the sent bubble (already shipped in feat(app): open the slash picker anywhere and insert inline skill chips #1156). The transition "gray in the menu → orange once selected and active" communicates selected vs actually engaged.
  4. Drop the redundant right-side badge. The leading icon now carries the type, so the Skill / MCP / Custom text badge is removed. Keybind hints stay on the right.

What would count as done?

  • Each builtin slash command shows its mapped semantic icon in the picker (mapping below).
  • Custom commands show the command glyph; MCP commands show the mcp glyph; skills show the skill glyph — all in --fg-weak.
  • No brand-orange appears in picker rows; the composer pill and sent bubble keep brand-orange (unchanged from feat(app): open the slash picker anywhere and insert inline skill chips #1156).
  • The right-side source badge (Skill/MCP/Custom) is removed from the picker row.
  • All glyphs reuse existing assets (packages/ui/src/components/icon.tsx registry + assets/icons/command-default.svg); no new SVGs are added.
  • Verified by a snapshot/e2e of the picker showing the mixed entry types with their icons, neutral coloring, and no badge.

What should stay out of scope?

Which audience does this matter to most?

Both

Extra context

Relationship to other work

Proposed builtin → icon mapping (all glyphs already exist in icon.tsx; tweakable):

Command (id) Trigger Icon key Command (id) Trigger Icon key
file.open /open open-file session.share /share square-arrow-top-right
session.new /new new-session session.unshare /unshare close-small
session.compact /compact archive terminal.toggle /terminal terminal
session.fork /fork branch model.choose /model models
session.undo /undo arrow-left mcp.toggle /mcp mcp
session.redo /redo arrow-right agent.cycle /agent agent
workspace.toggle /workspace worktree custom command command
MCP command mcp skill skill (generic)

Integration points (for the implementer)

  • Add an icon: string field to SlashCommandpackages/app/src/components/prompt-input/slash-popover.tsx.
  • Populate it in the slashCommands memo — packages/app/src/components/prompt-input/popover-controllers.ts: builtins via an id → icon key map, custom via source (skillskill, mcpmcp, else command).
  • Render a leading icon in the row (reuse the resolution path in packages/ui/src/components/command-icon.tsx, extended to resolve the chrome icon.tsx registry keys); remove the badge <Show> block.
  • Color: picker icons use --fg-weak; do not apply --brand-primary in the picker.

Design rationale (three questions, in order)

  • Simple enough? One rule — icon = function, one neutral color in the menu — replaces the invisible badge with a device that also aids alignment. Fewer parts than today.
  • Elegant? A single icon logic across the whole list (no mixing of "action" vs "type" semantics within one menu), one reserved accent, no badge.
  • Reassuring? "Gray in the menu, orange when engaged" needs no explanation and matches the chip the user just inserted; selecting is fully reversible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low priorityappApplication behavior and product flowsenhancementNew feature or requestuiDesign system and user interface

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions