Repository navigation
feat: shell rail v2 with light and dark themes - #687
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughWarning Review details and warnings were omitted to fit the comment limit. |
|
React Doctor found no new issues. 🎉 Reviewed by React Doctor for commit |
|
| onCreated: session => | ||
| jumpToSession({ | ||
| sessionId: session.id, | ||
| agentName: session.agent_name, | ||
| workspaceId: session.workspace_id, | ||
| }), |
There was a problem hiding this comment.
Session opens on wrong desktop If someone sends a prompt from an empty desktop and switches desktops while the session is being created, this callback opens the session without the originating desktop ID. The window manager then uses the currently active desktop, so the new session appears somewhere other than where the prompt was sent.
| ports.manager.switchDesktop(desktopId); | ||
| return ports.coordinator.userOpen({ ...fresh, desktopId }); |
Comments Outside DiffThese findings could not be posted inline.
|
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Re-values the surface ramp, hairlines, text, signals and shadows to the v2 brand spec, adds a [data-theme=light] token set, the new sunken/surface-2/selected/well roles, inverted primary, card/elevated/pop shadows and the rail shell geometry. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
window_manager.gaps default to 0, new_window_policy defaults to beside_focus, and bindings.bottom_center defaults to zoom now that the dock no longer owns the bottom edge. Explicit user values keep winning. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Tiled frames drop radius, border and shadow; floating frames keep a hairline and elevated shadow. Traffic lights become minimize/zoom/close icon buttons at the trailing edge, and root window heads show the identity well. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The shell becomes a grid with the topbar across the top and the rail beside the desk. The dock band reservation, dock magnification, dock separators and the dock New Session control are removed; the pager moves into the topbar tray. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…tables Cards and surfaces sit on canvas with the card shadow, Surface gains a sunken variant, menus and popovers use the pop shadow with 32px items, the table header is a muted label row, and the link variant stops using the needs-you orange. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Swaps Geist/JetBrains Mono for Inter and Geist Mono, moves the weight ladder to 425/500/600 and the body to 14.5px, retunes radii and control heights, lifts muted greys to WCAG AA, routes shadows through theme adapters so the light theme reaches shadow utilities, and themes Storybook by data-theme. The marketing site pins its previous type baseline. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Adds the main_stack arrangement to layout.arrange (first window takes a 60% main column, the rest stack in the side column), the unbound layout.arrange.main-stack palette action, tool schema, OpenAPI, CLI help, docs and the official skill reference. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The deck becomes a sunken strip whose active tab is a surface plate with concave feet fused to the head; inactive tabs are split by hairlines that hide next to hover and the active tab. Snap defaults mirror the flush daemon defaults and deck gestures wait for the measured, rail-offset origin. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The menubar becomes a flat 52px topbar that reserves the macOS traffic-light space in Electron, drops the Settings control, and hosts the pager dots (with an orange dot for an off-screen desktop that needs you) next to an All desktops button that toggles the overview. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The DESIGN.md generator emits dark and light columns and resolves theme adapters; contrast suites run per theme; the glaze and focus-ring lint rules reject theme-blind white or black ink; the marketing site keeps its orange CTA. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Adds the InputGroup composer variant with tool and send buttons, quiet and segment Button options, pill filter chips, StateGlyph failed/stopped/still, ToolCallRow.Group inset panels with a mint running ring, the approval-card Dock anatomy, KindIcon glyph nodes, Panel on the card surface, RouteNav as pill segments and 15px count badges. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The renderer reports its theme preference to the desktop shell, which persists it and sets nativeTheme.themeSource before any window exists so every page, including boot, paints the right theme with no flash. Toasts, the loop editor canvas, the cron builder, brand marks and the running terminal follow the resolved theme. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…o-level surfaces Bordered canvas-soft panels become canvas cards with the card shadow, insets move to the sunken surface, selection turns neutral instead of orange, onboarding drops the orange progress rules, and agent/worktree states render through StateGlyph. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…l anchors layout.arrange keeps treating every named window as its own participant; the shell's deck-preserving arrangement is an additive keep_frames option co-shipped through the contract, OpenAPI, generated types, CLI --keep-frames, the compozy__layout_arrange tool, docs and the official skill. Agent terminal windows anchored to a session inside a floating frame take the floating fallback instead of failing the open. Found by the second Codex review. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
…d task windows ListingToolbar search collapses to an icon toggle that opens the real field instead of shrinking to a clipped input, and task list/dashboard windows whose live data is suspended read as loading instead of 'No tasks yet'. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The dock no longer takes the minimize branch for a target the topology already reports as minimized when the client frame still lists it as focused, so the hollow-ring click restores the window (VC-06). Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The manager's shared resource/inline-field conflict guard now rejects keep_frames with resource_id, so HTTP/UDS, the tool and the CLI agree and execute matches preview. Found by the third Codex review. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
The collapsible search keeps the field while it is focused or holds a query (read from the live value, controlled or uncontrolled), remounts an uncontrolled field from its live value, and forwards disabled to the toggle. Found by the third Codex review. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Fixes the product-language check: design notes, DESIGN.md prose, token comments, the lint rule message, the site stylesheet comment and QA scenarios now use CompozyOS or drop the brand where the sentence is about the accent colour. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Extracts sub-components, pure helpers and sub-hooks from the 38 functions React Doctor flagged as too complex on this branch (useTasksPage and useTaskDetailPage split into focused hooks with identical view-models), returns a fragment from the session work-entry list, and exposes aria-pressed instead of aria-selected on session rows only while a selection is open. Also carries the remaining CompozyOS wording fixes in TS sources. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
E2E-030 measured the Marketplace head's drag spacer before the route published its Refresh/Add actions, so under CI load the pointer landed on the Refresh tooltip trigger and no drag started. The spec now waits for the source head to settle and grips a midpoint that is stable across frames. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… spawn wake TestUDSTransportWindowManagerMatchesHTTP now sets new_window_policy=floating before its journey, since its floating-stack premise no longer holds under the beside_focus default. E2E-006 waits for the needs-attention wake instead of the first wake; the 'completed' child wake from #685 arrives first, which kept this test red on main. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… lands on a window A single arrange participant returns its own frame under every arrangement, so a lone deck keeps its stack identity with keep_frames. Floating opens walk distinct cascade candidates that restart on the next diagonal before clamping at the desktop edge, so a new window never sits exactly over an existing one. Found by Greptile. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
… show floating decks The desktop shell serializes theme preference writes latest-wins so desktop-theme.json always ends on the last reported choice, and All desktops thumbnails render floating tab decks as floating tiles instead of dropping them. Found by Greptile. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
New windows now join the focused window as a tab (new default `new_window_policy = "tab"`); an empty desktop still gets one full pane. The rail keeps focus-first clicks and adds Option-click (split beside focus), Shift-click (new desktop) and a right-click menu with every destination, including an explicit floating window (`floating` on window.open, `compozy window open --floating`, `compozy__window_open`). Fixes found by the E2E pass on the new default: tile snaps store the exact zone fraction on odd desk widths, fallback focus after a close lands on the tab the frame shows, and Continue/Fork "New window" keeps opening as a split so the source stays visible. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
An empty desktop now shows "What should we work on?" above the real session composer, with an agent picker that defaults to the project's agent. Sending creates the session with the prompt as its first message and opens it on that desktop; a failed start keeps the words, an unresolved agent hands off to the New session dialog, and Global scope asks for a project. The unsent prompt is kept per project, and the old global draft slot is discarded. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Answers the review of the first cut of the shell rail redesign: - Surfaces: black chrome, a darker pane, cards one step lighter with a hairline, popovers/dialogs/sheets above them; chrome gets its own hover and selected plates. - Shell: topbar and rail are one surface around a rounded inset panel. - Type moves down one step (body 13.5, headings 15, KPIs 20) and every web surface uses the semantic ladder. - Controls share one height ladder (buttons 22/26/30/34/36, inputs 30, compact and toolbars 26, composer row 28), one inverted primary per view, plain dot-and-text status, plate-only pressed states and one 1.75 icon stroke. - Sessions: full-width transcript and main's tool rows again, the session list open by default (older saved state migrates once), and a composer that no longer fades when Send is disabled. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
React Doctor flagged five functions whose spans the sweep edited (SecretField, SplitPane, AgentHeartbeatOps, SettingsInlineSaveControls, WorktreeRefSelect) for high control-flow complexity. Their branches move into small subcomponents and pure helpers; props, copy, data-slots and test ids are unchanged. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Main moved useOsAttention onto useSessionCatalog; the shell-rail test for untitled session titles still mocked useSessions. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Review findings on #687: - An empty-desktop prompt now opens its session on the desktop it was sent from, even if the operator switches desktops while the session is created (`useAttentionJump` accepts an explicit `desktopId`). - "Open in new desktop" returns to the previous desktop and removes the new one when the open fails, and says so. - The live tool row announces "Running …" as a polite status; the parallel count is announced from a sibling status outside its button. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
| }); | ||
| return { | ||
| sessions: query.data?.pages[0]?.sessions ?? [], | ||
| ready: workspaceId !== null && !query.isLoading, | ||
| ready: !pending && !query.isLoading, |
There was a problem hiding this comment.
Failed read blocks session launch After an initial catalog request fails in Global scope,
ready becomes true even though no sessions were fetched. The dock treats the empty result as “no sessions” and asks the user to pick a project before its fresh lookup can run. Existing sessions therefore cannot be opened through that dock click.
What & why
CompozyOS gets the shell rail v2 redesign from
docs/design/opendesign/shell-rail/(boardshell-rail-v2.html,DESIGN-NOTES.md,brand-spec.md,IMPLEMENTATION-PLAN.md), implemented across the daemon,@compozy/ui, the web app, the desktop shell, the docs and the official skill. The UI has a light and a dark theme. The rail and the topbar form one chrome surface around a rounded content panel, windows tile edge to edge inside it, and new windows open as tabs by default.Polish round 2 (this update) answers the review of the first cut:
main.main's clean rows (no dark box).Screenshots (1600×1000, dark · light)
What changes for users
Shell
Sessions
main.main's minimal rows.Theme
compozy.theme) and applied before first paint. The Electron shell follows the theme with no flash.Design system (
@compozy/ui,tokens.css,DESIGN.md)#0a0a0a/#f2f2f3· pane#131313/#fff· card#1a1a1a/#fff+ hairline + shadow · popover#1c1c1c/#fff· sunken#0e0e0e/#f7f7f8· hover#232323/#f4f4f5· chrome platesrail-hover/rail-selected.shadow-cardandshadow-popstart with a 1pxlinering, so cards, menus, dialogs, sheets and toasts read one step above what they cover.web/srcorpackages/ui/src.secondary sm; text linkslink; pressed states are a plate, never a ring; dialog footers use the default size.UIProvider(the hand-drawn rail glyphs match it); 2 only for the send arrow and small check marks.Pill form="plain"(dot + text). The Switch has a white knob on a mid-grey track in both themes.KindIconidentity well, the composerInputGroup, pop menus, two-level Card/Surface (sunken), quiet tables, container-query layout primitives.ToolCallRow.Groupis deleted (tool rows are back tomain).App surfaces. Sessions, Tasks, Loops (runs, editor, DAG), Automation, Scheduler, Home, Settings, Onboarding, Agents, Workspaces, Profiles, Marketplace, Extensions, Knowledge, Vault, Terminal, the command palette, the bell, toasts and dialogs were swept onto the ladder in both themes: cards on
bg-card, one primary per view, plain status, aligned control heights, no ad-hoc sizes.Marketing site (
packages/site) keeps its own warm theme and fonts (D9).Bugs fixed along the way (each with a regression test)
keep_framesoption.beside_focusfell back to floating when focus was stale.How you verified it
make gate: all affected lanes pass (see the checklist below).tabdefault (rail click → one frame, two tabs; ⌥-click → split).tabpolicy andfloatingopen in the window-manager reducers, the sidebar-state migration, the empty-desktop composer (per-project drafts, send, failure, Global scope), rail gestures and menu, the terminal bridge and the routing coordinator.Impact
[window_manager], SD-013 public regime, no key renames):gaps.*8/10 → 0,new_window_policyfloating→tab(new value;beside_focusandfloatingremain),bindings.bottom_centerreserved → zoom. Explicit user values win. The release note carries the migration block with the old values.new_window_policy = "tab"; an optionalfloatingflag onwindow.open(HTTP/UDS DTO, OpenAPI, generated web types,compozy__window_open, andcompozy window open --floating); themain_stackarrangement and the optionalkeep_framesflag onlayout.arrange. New palette idslayout.arrange.main-stack,layout.arrange.columns,window.move_to_desktop.1..9, all unbound.open:falseis dropped, collapsed threads are kept); the old global empty-desktop draft key is discarded.skills/compozy/references/{window-management,native-tools}.md,DESIGN.md, the DS reference,COPY.md, the glossary,docs/_memory/change-impact.md, the release note and the affected QA scenarios.ToolCallRow.Group,--container-transcript,--font-weight-display,--size-deck-add,QueueHealthSparkline,LoopStatusPill.Follow-ups found during QA (out of scope, pre-existing)
session prompt <same session> '<text>'(interrupt_fallback). Evidence in the QA walk report. Pre-existing, session runtime.discardflag on CloseWindowCommand (wire change + codegen).config seton quoted keys likewindow_manager.shortcuts."palette.open"fails with a duplicate-key error once the key exists;config set+config reloaddoesn't push to open web clients..compozy/config.tomlthat pins the whole[window_manager]section silently shadows user-scope changes from the CLI/Settings./qa-executionverdict pass over the changed scenarios (user-invoked only). Agents walked the scenarios and fixed what they found, but did not record verdicts.How this was built
The controller (Claude Opus 5.5) orchestrated Claude Code Opus 5.5 workers on this branch. Round 1: ten herdr workers (tokens, theme, go-wm, shell, frame, prims and three surface sweeps) plus three Codex reviews. Round 2: a written polish contract and six Opus workers — foundation, shell, window-open, session, empty-desktop and a settings sweep — in three waves (fixes, surface sweep, review fixes), the full web E2E suite, and an independent Claude Code Fable 5.1 (high) review with a confirmation round. The controller verified every slice in a real lab and committed.
make gatepasses locally; this PR is delivered only after its required CI checks are green🤖 Generated with Claude Code