feat: Desktop-Shell Host-Switcher Menu — Per-Host Accent Color, Manual Reorder, Per-Host Waiting Counts - #588
Merged
sahil-noon merged 4 commits intoAug 13, 2026
Conversation
There was a problem hiding this comment.
Pull request overview
Enhances the desktop shell’s host-switcher dropdown so hosts are easier to distinguish and manage, while preserving the invariant that host list order defines the ⌥⌘1–9 / ⇧Ctrl+1–9 accelerator mapping.
Changes:
- Persist and project per-host
accentColor, render it as a left-edge accent bar (hex-validated before style interpolation). - Add manual host reordering (drag grip + ⌥↑/⌥↓) via a new
servers:reorderIPC channel,moveHoststore mutator, and native menu rebuild. - Join per-host background waiting counts from the view registry into
servers:list, render as an amber● Nchip on non-active rows.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| fab/changes/260813-1i7j-host-switcher-color-reorder-waiting/plan.md | Generated plan/acceptance criteria for the feature set. |
| fab/changes/260813-1i7j-host-switcher-color-reorder-waiting/intake.md | Intake record describing UX decisions and constraints (accelerator-order semantics). |
| fab/changes/260813-1i7j-host-switcher-color-reorder-waiting/.status.yaml | Change status/metadata for the fab pipeline. |
| fab/changes/260813-1i7j-host-switcher-color-reorder-waiting/.history.jsonl | Pipeline history log entries for the change. |
| docs/memory/run-kit/ui-patterns.md | Documents the updated switcher row model and reorder/waiting semantics. |
| docs/memory/run-kit/desktop-shell.md | Documents hosts.json schema addition (accentColor), reorder bridge semantics, and waiting-count join. |
| app/frontend/src/lib/shell.ts | Extends ShellServer typing/validation and adds optional reorder capability wrappers. |
| app/frontend/src/lib/shell.test.ts | Adds tests for optional fields parsing and reorder capability degradation/behavior. |
| app/frontend/src/lib/shell-strip.ts | Derives row model with strict hex validation and background-only waiting. |
| app/frontend/src/lib/shell-strip.test.ts | Adds unit coverage for accent/waiting derivation rules. |
| app/frontend/src/components/shell-titlebar-strip.tsx | Implements accent bar, waiting chip, drag + ⌥↑/⌥↓ reorder, and optimistic UI updates. |
| app/frontend/src/components/shell-titlebar-strip.test.tsx | Adds component tests for bars/chips/reorder gestures and older-shell degradation. |
| app/desktop/src/preload.ts | Exposes servers.reorder invoker on window.runkitShell. |
| app/desktop/src/main.ts | Persists theme color to hosts store, adds servers:reorder, and joins waiting counts into servers:list. |
| app/desktop/src/hosts.ts | Adds accentColor field tolerance, setHostAccentColor, and moveHost mutator; projects accentColor. |
| app/desktop/src/hosts.test.ts | Adds tests for parsing tolerance, mutator short-circuit/no-op behavior, move/clamp, and projection rules. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+216
to
+226
| const current = rowsRef.current; | ||
| const from = current.findIndex((r) => r.id === dragId); | ||
| const to = current.findIndex((r) => r.id === targetId); | ||
| if (from === -1 || to === -1) return; | ||
| setServers((prev) => { | ||
| if (!prev) return prev; | ||
| const next = [...prev]; | ||
| const [moved] = next.splice(from, 1); | ||
| next.splice(to, 0, moved); | ||
| return next; | ||
| }); |
Collaborator
Author
There was a problem hiding this comment.
Fixed — onRowDragOver now resolves the from/to indexes by id inside the setServers functional updater, so batched dragover updates always splice against the exact array being updated (the ref-derived outer indexes are gone). (7e21ba0)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Meta
1i7jexcludes
fab/,docs/· generated by fab-kit v2.20.1Pipeline: intake ✓ → apply ✓ → review ✓ → hydrate ✓ → ship → review-pr
Summary
The desktop shell's host-switcher dropdown renders indistinguishable rows and its list order is frozen at insertion order — yet order IS the ⌥⌘1–9 / ⇧Ctrl+1–9 accelerator map, and a waiting agent on a background host is invisible until the user switches there. This change gives each host row a left-edge bar in its instance accent color (persisted in hosts.json as an additive optional field), adds manual reordering via a hover drag grip and ⌥↑/⌥↓ keyboard moves with live accelerator-hint re-numbering, and shows each background host's cached waiting-agent count as an amber ● N. All three legs ride existing machinery (theme-color capture, badge:set caches, the id-keyed hosts.json mutator pattern); alphabetical auto-sort was explicitly rejected because it silently remaps accelerators.
Changes
accentColorpersisted in hosts.json with lastPath-style tolerance, hex-validated before renderingservers:reorderIPC channel, id-keyed array-move mutator, native menu rebuild after reorderbadgeCountcaches into theservers:listprojection; dock badge stays active-host-only