Skip to content

Latest commit

 

History

History
177 lines (141 loc) · 14.1 KB

File metadata and controls

177 lines (141 loc) · 14.1 KB

Vibbi UI Parity Spec: Copy Cursor

The governing UI rulebook for vibbi. Until further notice this document is the prime directive for every UI decision.

Prime directive

  • Copy Cursor. When in doubt about any UI element, match Cursor. Visual Studio Code is the secondary reference, and since Cursor is a VS Code fork, most of the answer is VS Code.
  • Total parity intent: fonts, icons, colors, spacing, and every UI element look and feel like Cursor. Every divider is movable. Every panel is dockable.
  • Research first. Before building any UI feature or committing UI work, look at how Cursor (then VS Code) does it. Use subagents to research when the answer is not already captured here.

How we build (working rules)

  • Research-first: each UI feature starts with a short "how does Cursor/VS Code do this" pass. Reuse this document and cabinet/_research/2026-07-30-ui-research-cursor-vscode-workbench.md; only spawn new research when they do not cover it, then fold new findings back into this file.
  • Parity check before commit: every commit that touches UI is checked against the relevant rule here (layout, docking, fonts, tokens, icons, sizing).
  • Single concern per file: one component, service, or concept per file. Split a file the moment it grows a second responsibility.
  • Refactor at every step: leave each touched area cleaner than found. No drift, no accumulated technical debt. If a change reveals a structural problem, fix the structure rather than working around it.
  • Token-driven: never hard-code a color, font, or size that has a design token. All visual values resolve to the design tokens defined here and in ui/src/shell/tokens.css.

1. Layout and regions (the workbench)

The window is a workbench of resizable regions. Default arrangement, outer edge inward:

flowchart LR
  AB[Activity Bar - fixed 48px chrome]
  subgraph dock [Resizable dock grid - sashes between every region]
    SB[Primary Side Bar - Explorer / Search / SCM / Run]
    ED[Editor group - multi-tab, splittable grid]
    PN[Panel - Terminal / Problems / Output, docked under the editor]
    SSB[Secondary Side Bar - AI chat, right]
  end
  TB[Title Bar - menu / command center / layout controls]
  STB[Status Bar - 22px]
  AB --- SB
  SB --- ED
  ED --- SSB
  ED --- PN
Loading
  • Title Bar (custom, frameless): menu bar, optional center command center, window controls, layout-toggle buttons.
  • Activity Bar: fixed 48px icon rail; each icon is a view container that swaps the Primary Side Bar content; account/settings pinned at the bottom.
  • Primary Side Bar (left by default): Explorer, Search, Source Control, Run and Debug, Extensions. One container shown at a time; a container can stack multiple views as collapsible sections.
  • Editor group area (center): multi-tab editor groups arranged in an arbitrary grid.
  • Panel (bottom by default): Terminal, Problems, Output, Debug Console; movable to left/right/top.
  • Secondary Side Bar (right by default): where the AI chat pane lives, always opposite the Primary Side Bar.
  • Status Bar (bottom): workspace items left, active-file items right.

Full feature and keybinding inventory: see cabinet/_research/2026-07-30-ui-research-cursor-vscode-workbench.md.

2. Docking and resizing rules (movable and dockable everything)

This is the behavioral contract. The layout is a persisted, sash-joined grid; every internal boundary drags, most parts relocate by drag-and-drop, and the whole arrangement restores across sessions.

  • Sashes: every region boundary except the Activity Bar edge is a draggable sash - Primary Side Bar / editor, editor / Panel (whichever edge the panel is docked to), editor / Secondary Side Bar, and every gap between editor groups in a split.
    • Grab zone 4px (workbench.sash.size, 1-20); visible line 1px; hover highlight uses the sash.hoverBorder token after a 300ms delay (workbench.sash.hoverDelay, 0-2000).
    • Double-click a sash resets the adjacent parts toward even distribution.
  • Drag-and-drop docking:
    • Drag an editor tab to a group edge to split; drop into another group's tab strip to move it.
    • Drag a view header to relocate it between Primary Side Bar, Secondary Side Bar, and Panel, or drop onto another view to form a tabbed group.
    • Drop a view onto an Activity Bar container to move it there.
    • Keyboard: Move View / Move Focused View; Reset View Locations restores defaults.
  • Editor groups: tile into a grid (View - Editor Layout presets); toggle orientation Shift+Alt+0; split-in-group Ctrl+K Ctrl+Shift+\; maximize Ctrl+K Ctrl+M (or double-click a tab); lockable groups (new editors avoid a locked group; terminal editors auto-lock).
  • Panel: move left/right/top/bottom; alignment center/justify/left/right; maximize (chevron or Toggle Maximized Panel).
  • Floating/auxiliary windows: pull an editor or the panel into its own OS window (Move Editor into New Window, Ctrl+K O to copy); floating windows hold their own grid, support compact mode and always-on-top, and restore after restart.
  • Persistence: side bar and panel sizes and visibility, view locations, the editor grid, locked groups, pinned tabs, panel position and alignment, and floating windows all persist per session. Reset View Locations is the escape hatch.

Default keybindings (Windows/Linux; macOS in parentheses):

  • Toggle Primary Side Bar Ctrl+B (Cmd+B)
  • Toggle Panel Ctrl+J
  • Toggle Secondary Side Bar Ctrl+Alt+B (Opt+Cmd+B)
  • Terminal Ctrl+` ; new Ctrl+Shift+` ; split Ctrl+Shift+5
  • Split editor Ctrl+\ ; split in group Ctrl+K Ctrl+Shift+\ ; toggle orientation Shift+Alt+0
  • Maximize editor group Ctrl+K Ctrl+M ; move editor to new window Ctrl+K O
  • Command Palette Ctrl+Shift+P ; Go to File Ctrl+P

Cursor keeps these but rebinds several chords for AI (Ctrl+K, Ctrl+L, Ctrl+I); verify any chord that overlaps AI actions.

3. Fonts

  • Workbench chrome (menus, side bar, tabs, status bar, trees): the VS Code system-UI stack, no user font setting.
    • -apple-system, BlinkMacSystemFont, "Segoe WPC", "Segoe UI", system-ui, "Ubuntu", "Droid Sans", sans-serif
    • Base UI size approximately 13px.
  • Editor (monospace): platform defaults - Consolas (Windows), Menlo (macOS), 'Droid Sans Mono', monospace (Linux); default editor.fontSize 14, line height derived from font size.
  • Terminal: inherits the editor monospace family; size 12-14.
  • Not app fonts: CursorGothic, JetBrains Mono, and Cursor Orange #f54e00 are the marketing website's fonts and accent, not the editor's. Do not use them for the app chrome. Vibbi currently uses JetBrains Mono for the editor - acceptable as a deliberate choice, but the chrome font must stay the system-UI stack for parity.

4. Color tokens and theme (Cursor Dark / Anysphere)

Colors resolve to design tokens, never hard-coded. The token vocabulary is VS Code's theme-color namespace; the values target Cursor's default dark theme (the Anysphere family). Vibbi's live palette is the source of truth in ui/src/shell/tokens.css and ui/src/editor/theme.ts; keep the two in sync with the values below.

Structural token vocabulary (map each to a CSS variable):

  • Base: foreground, focusBorder, contrastBorder, selection.background
  • Title bar: titleBar.activeBackground, titleBar.activeForeground, titleBar.border
  • Activity Bar: activityBar.background, activityBar.foreground, activityBar.inactiveForeground, activityBar.activeBorder, activityBar.border, activityBarBadge.background, activityBarBadge.foreground
  • Side Bar: sideBar.background, sideBar.foreground, sideBar.border, sideBarTitle.foreground, sideBarSectionHeader.background/foreground/border
  • Lists/trees: list.activeSelectionBackground/foreground, list.inactiveSelectionBackground, list.hoverBackground, list.focusBackground
  • Editor: editor.background, editor.foreground, editorGroupHeader.tabsBackground, editorGroup.border
  • Tabs: tab.activeBackground, tab.inactiveBackground, tab.activeForeground, tab.inactiveForeground, tab.border, tab.activeBorderTop, tab.hoverBackground
  • Panel: panel.background, panel.border, panelTitle.activeForeground/inactiveForeground, panelTitle.activeBorder
  • Status Bar: statusBar.background, statusBar.foreground, statusBar.border, statusBar.noFolderBackground, statusBar.debuggingBackground
  • Inputs/controls: input.*, dropdown.*, button.background/foreground/hoverBackground, badge.*, scrollbarSlider.*, editorWidget.*, sash.hoverBorder

Target values (Anysphere Dark; community-extracted, flagged approximate - verify against the shipped Cursor build for pixel parity):

  • Chrome is one flat surface #181818 across title bar, activity bar, side bar, tabs, panel, and status bar (Cursor's look is flatter than VS Code Dark Modern, which layers #181818 chrome under #1F1F1F editor).
  • Editor background #181818, foreground #E4E4E4.
  • Accent (active/primary) #228df2 (blue); focus indigo #5b51ec; editor selection #163761.
  • Syntax palette (vibbi's current, in ui/src/editor/theme.ts): string #A8CC7C, function #EBC88D, variable/param #EFB080, number #F8C762, type #82D2CE, keyword/constant #AAA0FA, punctuation #D6D6DD, comment #6D6D6D italic. If the shipped Cursor Anysphere differs, prefer the shipped values and update theme.ts plus this list together.
  • VS Code Dark Modern (secondary reference): accent #0078D4, editor #1F1F1F, chrome #181818.

5. Icons

  • Workbench glyphs are Codicons - a single monochrome icon font; color comes from the theme, not the font. Reference an icon by two classes: codicon codicon-<id> (or $(id) in labels; ~spin animates).
  • Common ids by function:
    • Explorer/files files, file, folder, folder-opened, new-file, new-folder
    • Search search, replace, case-sensitive, whole-word, regex, filter
    • Source control source-control, git-branch, git-commit, git-merge, diff
    • Run/debug debug-alt, run-all, debug-start, debug-stop, debug-restart
    • Extensions extensions
    • Chat/AI comment-discussion, sparkle, mention, robot
    • Terminal terminal, split-horizontal, split-vertical
    • Browser globe, browser, link-external
    • Chevrons/twisties chevron-up/down/left/right, expand-all, collapse-all
    • Close/overflow close, close-all, ellipsis, kebab-vertical
    • Status error, warning, info, pass, bell, git-branch
    • Common add, refresh, sync (use $(sync~spin) for progress)
    • Window controls chrome-minimize, chrome-maximize, chrome-restore, chrome-close
    • Layout layout-sidebar-left, layout-sidebar-right, layout-panel, editor-layout
  • Product icon theme: the workbench glyph set can be replaced wholesale; Cursor ships the default codicon set (no separate selectable product icon theme). Default workbench.productIconTheme is Default.
  • File icon theme (icons next to filenames): VS Code ships Seti (default) and Minimal. Cursor inherits Seti by default. Vibbi currently uses Material Icon Theme - a deliberate deviation; keep it only if intended, otherwise move toward Seti for parity.
  • Activity Bar icons render at 24px glyph inside a 48px item; badges are a rounded pill (min ~18px, collapsing to a dot) colored by activityBarBadge.*.

6. Sizing and spacing (default metrics, px)

The workbench keys off a 22px row unit, a 48px Activity Bar, and a 35px tab strip, all scaled by the zoom factor. Values marked src are hardcoded VS Code constants; approx values drift between releases and platforms - verify against the target build for pixel parity.

  • Activity Bar width 48 (24px glyph) - src
  • Status Bar height 22 - src
  • Tree/list row height 22 - src; tree indent per level 8 (range 4-40) - src
  • Editor tab height 35 (compact option available) - docs
  • Fixed tab min/max width 50 / 160 - src
  • Sash grab size 4 (20 on touch) - src; sash hover delay 300ms - src
  • Editor scrollbar thickness 14; workbench scrollbars thinner (~10, overlay) - src/approx
  • Title bar height ~30 (~35 with command center) - approx
  • Primary Side Bar default ~300, min ~170 - approx
  • Breadcrumbs height ~22 - approx
  • UI/chrome font ~13 - approx
  • Focus outline 1px (focusBorder) - approx

7. Interaction surfaces

  • Command Palette Ctrl+Shift+P; Quick Open (Go to File) Ctrl+P; Go to Symbol Ctrl+Shift+O; Go to Line Ctrl+G.
  • Context menus everywhere (tree, editor, tabs, panels, terminal tabs).
  • Notifications and progress toasts, bottom-right by default.
  • These are one Quick Input widget with different prefixes; keep the command registry and menu bar as views over the same command set.

8. The AI pane (Cursor specifics)

  • A right-hand pane hosting Chat/Agent. Multiple conversations via chat tabs (a tab per conversation, orange dot when awaiting input), plus side chats (attached child threads) and a searchable history.
  • Modes: Agent (default), Ask (read-only), Plan, Debug, Manual, custom modes; a mode picker and model picker at the top of the input; a context ring showing context-window usage.
  • In-editor AI: inline edit prompt widget, Tab ghost-text with next-edit jump, and live in-place accept/reject diffs.
  • Full detail: cabinet/_research/2026-07-30-ui-research-cursor-vscode-workbench.md, Part 2.

Sources