Design updates: hidden-sidebar chrome, chat-everywhere title bars, panel design pass#4932
Design updates: hidden-sidebar chrome, chat-everywhere title bars, panel design pass#4932andresdjasso wants to merge 85 commits into
Conversation
…ar, stationary panel toggle - Restructure the home input into a stacked card (grey tray behind the input) that hosts the All Chats launcher; the chat list expands inline within the tray - Open existing chats inline with no route remount via adoptResolvedChatId (now exposed from useChat), with hover-prefetch and the slide-in morph - Add a Codex-style chat title bar (title + action menu) to the open chat view - Make the right resource-panel collapse/expand a single stationary toggle outside the animating panel, so it no longer moves on collapse - Auto-hide the chat scrollbar; reveal it only while actively scrolling - Bump the home input corner radius to 17px Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…k, hover text reveal, dismiss-all Component (apps/sim/components/emcn/components/toast/toast.tsx): - Variants default/info/success/warning/error, each with a distinct outline icon (CircleAlert/TriangleAlert/CircleCheck/Info/Bell) rendered inline with the message in a neutral color — no badge; intent reads from icon + copy. - Stacking modeled on Sonner/Base-UI: a collapsed pile that fans open upward only when the cards are hovered. One fixed-duration expo-out tween drives all cards so rapid arrivals move in unison (no lagging card); cards arrive collapsed (expand is scoped to a wrapper around the cards, not the dismiss control). - Title vs subtext hierarchy: message is a medium, primary-color title; the optional description is lighter/smaller subtext. - Truncated text reveals its hidden lines on hover (RevealText): only the previously hidden lines blur in; the card height tracks the content so the action button stays pinned (no clipping). Larger bottom gradient fade hints at more text. - Concentric corner radius (16px = chip 8px + 8px padding); single-line cards use a tighter 12px so they don't read as pills. - Dismiss-all control: a small circular chip just outside the stack's bottom-left, shown at 2+ toasts. Linear auto-dismiss ring that restarts on each new arrival, pauses on hover, click to clear all; spring 'pop' entrance. - Bug fixes: route-scoped clearing (toasts no longer trail across navigation), dedup of the add/update double-fire, actionable toasts persist by default. Source/usage: - stores/terminal/console/store.ts: notifyBlockError now passes the block name as the title and the error as the description (title/subtext), plus the dedup window. - app/playground/page.tsx: Toast section added to the EMCN gallery. - New EMCN icons: circle-alert, circle-check, info, triangle-alert. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…llery tooling - New MessageCircle glyph in the emcn house style (24px viewBox, 1.55 stroke), filling a lucide-only gap from the audit; now used for the chat surfaces - Icon design worklist + lucide->emcn migration map docs for the redesign pass - render-icon-gallery script + generated gallery for side-by-side review Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…page wiring - Activity view components (agent identity, parallel agents, shimmer status) with model + tests, plus a standalone /activity-preview render harness - Chat resource persistence/types extended through the copilot contract, post handler, and resource tool handlers - Embedded pages (Tables, Knowledge, Integrations) accept open-callbacks so the chat resource panel can navigate within tabs instead of routing away - Chat history list extracted into a shared searchable, recency-bucketed component used by the All Chats tray and the title-bar switcher Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…anel design pass
Sidebar / chrome:
- Remove the sidebar's Chats section and the collapsed icon rail entirely;
collapsing now hides the menu to zero width and the content goes full-bleed
- Single SidebarToggle lives at the top-left of page title bars (both states);
hovering it while collapsed opens the menu as a popover-styled, content-fit
flyout anchored below the bar; clicking pins the sidebar open
- Flyout pins open while popups launched from it (workspace menu) are showing
- "New chat" nav item swaps the house icon for the new MessageCircle
Chat view:
- ChatTitleBar always renders (incl. new-chat view) with a "Chats / {title}"
breadcrumb switcher; close (x) hides the chat pane while the resource panel
takes full width and the switcher moves inline into the tabs bar
- ChatSwitcher promoted to a workspace-level control rendered on every page
header (Tables/Files/Knowledge/Scheduled/Logs via ResourceHeader) and
floating on the workflow canvas, so chats are reachable from anywhere
- Guardrails: chat pane restores when the resource panel closes; embedded
pages suppress duplicate chrome via SidebarToggleHidden context
Design pass:
- Resource tabs become ghost chips (30px, rounded-lg, active surface) in a
44px bar matching the chat title bar; icon buttons unified at 30px with
surface-active hover; 7px equal-distance edge insets for all pill controls
- Chat dropdown matches the flyout anchor rhythm (6px below bar, 8px inset);
emcn PopoverContent gains an alignOffset passthrough
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Fixed 44px bar (was padding-derived) with a unified 16px gutter across the breadcrumb and title-only variants - Sidebar toggle and right-edge actions pull out 9px so their hover pills sit 7px from the panel edge, equal to the pill's vertical clearance - Action/create buttons standardized to the 30px rounded-lg pill with surface-active hover, matching every other title-bar control Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rumb group The sidebar toggle's 9px pull-out was clipped by the breadcrumb container's overflow-hidden; the toggle and chat switcher now sit beside it instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
…pty state The home page's title chip fell back to the most recently updated chat; that fallback is now scoped to non-chat pages via an isNewChat flag the title bar sets whenever no chat is open. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Orchestration failures previously persisted nothing for the assistant turn — the post-stream history refetch then silently erased the streamed activity, leaving the user staring at their own message with no explanation. - withErrorContentBlock mirrors the cancelled-turn pattern: keeps partial content/tool blocks and appends an inline <mothership-error> tag (already understood by the message renderer) plus a terminal error-status block - Both failure paths persist: orchestration-returned failures keep their partial work; thrown errors persist a minimal errored turn Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, never replace Switching chats no longer swaps the resource panel's tab set. Tabs now behave like browser tabs, owned by the user per workspace; chats relate to artifacts by provenance, not containment: - New persisted mothership-tabs store (tabs + active per workspace); entering a chat merges its artifacts additively (deduped) and focuses its last-touched one, never closing what's already open - Tabs the active chat surfaced carry a provenance dot (hidden on hover/active) - Closing/reordering tabs is session-only and no longer mutates the chat's persisted resources; closed tabs stay closed for the rest of the chat visit and re-open on re-entry - Manual attaches (+ dropdown, context chips) still record provenance on the open chat via the existing persistence path - Ephemeral resources (streaming previews) stay chat-scoped and unpersisted; panel expand/collapse + chat-pane guardrails now key off the strip Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… scroll the strip Horizontal trackpad swipes carry a small deltaY, so the deltaY-only handler preventDefault()'d the native pan and scrolled by the jitter amount instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mpressed tabs, switcher dropdown The panel bar now mirrors the chat pane: one prominent identity chip per pane. - Active resource renders as a title chip (icon + full name + chevron) whose dropdown lists every open tab, grouped "From this chat" / "Other open tabs" with hover close controls — provenance moved here from the per-tab dots - Inactive tabs compress browser-style (max-width truncation, icon always visible); beyond five they collapse into a +N chip instead of scroll-clipping; the strip's scroll/edge-scroll machinery is gone - Dots now mean "changed while unfocused": a chat's artifacts merge in marked unseen except the focused one, and viewing or closing a tab clears it - Standalone pages (ResourceHeader, workflow canvas) demote the chat switcher to an icon-only chip so the page title owns the bar Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…y for the true remainder Replaces the fixed five-tab cap with measured capacity: the strip and the name-dependent title chip are observed (ResizeObserver, with a window-resize fallback), and whole tab slots are fitted into the remaining width. Zero-width measurements (panel collapsed or mid-expand-animation) are ignored so a bogus early measure can't collapse everything into the dropdown, and capacity starts permissive until the first trustworthy layout pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…down, +N lists only hidden tabs The all-tabs switcher dropdown duplicated the strip and made +N feel like a third concept. Now every tab lives in exactly one place: the active resource is a plain title chip, visible tabs switch by clicking, and the +N chip is the only dropdown, listing just the tabs that didn't fit. Selecting one promotes it to active, so it leaves the overflow naturally. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…asured width, overflow the rest Replaces the fixed 84px slot estimate (which squeezed labels even with room to spare) with real per-tab measurement: a hidden measuring row renders every inactive tab at natural width, and the capacity pass greedily fits whole tabs into the strip, sending only the true remainder to +N. Inline labels keep a 240px ceiling purely as a pathological-name guard, mirrored in measurement so render and fitting agree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…lumbing Removes the unfocused-change indicator from inline tabs and switcher rows, along with the updatedTabKeys state, marking, and clearing in home. Also escapes a literal NUL byte that had crept into the namesKey join separator. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…between bars The pair rendered as loose children of each bar, inheriting whichever gap that bar used (gap-1 in the chat title bar, gap-1.5 in the tab strip, gap-2 in the resource header) — so the switcher drifted a couple of pixels when the chat pane closed or across pages. It now lives in its own gap-1 cluster everywhere, keeping the toggle at 7px and the switcher at 41px in every state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ons the strip Drops the spotlight-first layout (clicking a tab yanked it to the left edge). Tabs now render in strip order with the active one highlighted where it sits. The width fit runs over the ordered list; if the active tab lands beyond the fit (e.g. picked from the +N dropdown), it surfaces at the end of the visible row with its width reserved, since it has no inline position to keep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…'s chrome Container now keeps the popover's canonical 6px inset and rounded-xl instead of a p-0 override with its own 8px padding; rows drop to the canonical 13px text with the 2px row gap; the forced 240px min-width goes down to 180 so the dropdown hugs its content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…used panel tab Selecting a chat from a resource page used to teleport to the chat view with whatever the strip last held — the one thing missing was the page you were on. The switcher now derives the page's resource from the pathname (page tabs for tables/knowledge/logs/scheduled-tasks, item tabs for table/KB/workflow detail routes), opens it focused in the workspace strip, and navigates with ?resource= pinned. The chat-entry merge respects that pin: a URL-pinned resource that isn't one of the chat's artifacts keeps focus instead of being displaced by the chat's most recent artifact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…no reserved tab width Tabs carried a permanent 20px right padding for the hover ×, leaving dead space on idle tabs. The × now overlays the label's tail on hover, sitting on a gradient fade of the hover fill so it stays readable; idle tabs keep the chip's symmetric padding and their width never changes on hover. The hidden measuring row drops the same padding so fitting stays in sync. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rive the panel again Asking the agent to "switch to Telecom_Leads_CRM" answered in prose but never moved the panel. use-chat still carried the old focus-on-touch logic via its internal setActiveResourceId, but the workspace tab-store migration orphaned that state — nothing rendered it. Adds an onResourceTouched(resource) callback fired at the three touch sites (stream resource ops, successful Read tool calls, workflow activation), regardless of whether the resource was already an artifact; home bridges it to the tab store with openTabs + focus, so the panel follows the conversation. File-streaming suppression is respected. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…clipping Wraps the message scroller in a relative container and overlays a 40px bottom strip — a bg gradient plus the faintest backdrop blur, both masked to ramp in toward the edge — so scrolled content dissolves above the input rather than cutting off at the scroller boundary. Applies to both chat layouts; pointer-events pass through. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the icon system with self-hosted Hugeicons (free, stroke-rounded) vendored into @/components/emcn/icons — zero runtime icon deps. - Vendor 150+ icons from @hugeicons/core-free-icons into the emcn barrel via scripts/hugeicons-map.ts + scripts/hugeicons-generate.ts (dev-only source). Icons gain a `size` prop; 4 bespoke animated icons (Loader, RefreshCw, Download, Layout) kept custom. - Migrate ~172 consumers off lucide-react to the emcn barrel; remove lucide-react dependency entirely (Github brand logo -> @/components/icons). - Fix chevron sizing: replace ~24 non-square classes (h-[6px] w-[10px], tuned to the dead 10x6 viewBox) with canonical size-[14px]. - Sidebar/chat icon updates: Table->TableIcon, knowledge base->DatabaseIcon, Files nav->File, scheduled tasks->CalendarClock, Logs->ThirdBracketSquare, PanelLeft/PanelRight, BubbleChatDelay/Spark for the two chat bubbles. - Send buttons -> ArrowUp02; integration row arrows -> ArrowRight02. - Workflow icon -> WorkflowSquare04; Integrations -> Plug02. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…et thumb The list scroller sat inside the panel's 8px gutter, so the full-width global scrollbar floated mid-panel and read as a fat dead column. The scroller now bleeds to the dropdown edge (-mx-2/px-2, the workspace dropdown's pattern) so the scrollbar occupies the former padding, and the thumb is clipped to a 4px pill inset 2px from the edge (transparent border + content-box clip), with scrollbar-width:thin for Firefox. Row alignment is unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Replace the icon system with self-hosted Hugeicons (free, stroke-rounded) vendored into @/components/emcn/icons — zero runtime icon deps. - Vendor 150+ icons from @hugeicons/core-free-icons into the emcn barrel via scripts/hugeicons-map.ts + scripts/hugeicons-generate.ts (dev-only source). Icons gain a `size` prop; 4 bespoke animated icons (Loader, RefreshCw, Download, Layout) kept custom. - Migrate ~172 consumers off lucide-react to the emcn barrel; remove lucide-react dependency entirely (Github brand logo -> @/components/icons). - Fix chevron sizing: replace ~24 non-square classes (h-[6px] w-[10px], tuned to the dead 10x6 viewBox) with canonical size-[14px]. - Sidebar/chat icon updates: Table->TableIcon, knowledge base->DatabaseIcon, Files nav->File, scheduled tasks->CalendarClock, Logs->ThirdBracketSquare, PanelLeft/PanelRight, BubbleChatDelay/Spark for the two chat bubbles. - Send buttons -> ArrowUp02; integration row arrows -> ArrowRight02. - Workflow icon -> WorkflowSquare08; Integrations -> Plug02. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The flyout's fixed top-[50px] was tuned for the flush title bar; in floating-stage mode the toggle sits ~28px lower (under the peek bar, inside the front card), so the flyout covered the stack's identity bars and title. Position and max-height now follow the mode, keeping the peek bar and the toggle that opened it visible above the panel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…chat The right panel drops the tab strip entirely. It is now a single-resource stage per workspace: whatever the Mothership conversation last touches — a table, file, knowledge base, workspace page, or a workflow's full editor — takes the panel, replacing what was there. Workflows no longer navigate away from the chat; they render as the full editor inside the panel like any other resource. - stores/mothership-stage replaces stores/mothership-tabs (one staged resource per workspace instead of a tab strip) - PanelHeader (icon + live name + actions + close) replaces ResourceTabs; the switcher list, +N overflow, drag reorder, and AddResourceDropdown retire with it (the picker hook lives on as resource-pickers for the chat input's + menu) - the workflow route keeps the docked chat but loses the stage stack, flips, peek bars, and floating-stage chrome; a non-workflow resource touched there stages on the home surface and the chat follows via URL - workspace chrome and sidebar store drop the floating-stage mode Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rowth The on-disk cache (.next/dev/cache/turbopack) writes ~9GB per cold compile of this app and accumulates across sessions (observed 29GB and 58GB), and starting on a large stale cache is also what replays the PostCSS fork bomb. Bounded disk beats faster restarts here: with the flag off, .next holds steady around ~350MB. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
While a Mothership chat is on screen (chat route or the workflow route's docked chat), sidebar navigation stops swapping the whole page: Tables, Knowledge base, Scheduled tasks, Logs, and workflow rows stage their destination on the chat's resource panel instead, so only the right side switches. Without an open chat, navigation is unchanged. Modifier clicks still follow the href (new tab etc). - lib/mothership/chat-aware-nav reads the open chat from window.location (both chat mirrors are replaceState-written, invisible to usePathname) - setStage always restages so re-clicking the current destination re-expands a collapsed panel - Files keeps plain navigation: its page has no embedded panel view yet Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Staging a workspace page (Tables, Knowledge Base, Logs, Scheduled Tasks) or a knowledge base in the chat's resource panel showed two stacked headers: the panel's title bar plus the page's own Resource.Header. Now views that bring their own header keep it as the single header — the panel skips its bar and injects its chrome instead: - PanelChromeProvider/usePanelChrome: the panel provides its leading cluster and trailing controls; Resource.Header absorbs them, compacts to the 44px panel rhythm, and swaps its standalone chrome cluster for the panel's (SidebarToggleRevealed escapes the content's hidden scope while the chat pane is collapsed) - PanelTrailingControls extracted (close + collapse-toggle spacer), shared by PanelHeader and the injected page headers - PanelHeader title restyled to Resource.Header's treatment (chip geometry, 14px icon, body text) so every staged view reads identically Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…are nav files.tsx gets the navigation abstraction Tables/Knowledge already had: an `embedded` prop routes folder browsing through component state instead of `?folderId=`, and opening a file is delegated to the host via `onOpenFile` instead of pushing the detail route. Standalone-only flows (`?new=1`, `/files/[fileId]`, the hidden-tab redirect) are gated off and unreachable embedded; downloads keep their direct URLs. - `files` registered in MOTHERSHIP_PAGES + page icon + EmbeddedPage case (opening a file stages it as a panel file resource) - the sidebar Files item becomes chat-aware like the other pages, and the chat switcher maps the file detail route to a file resource when opening a chat from it Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Opening the resource panel with nothing staged showed a blank pane. It is now a quick-open surface: a search across every stageable workspace resource (pages, workflows, tables, files, knowledge bases), the resources most recently on stage, and the workspace area pages as browse entries. Selecting anything stages it in place. - the stage store tracks per-workspace recents (newest first, deduped, capped at 8, persisted) alongside the staged resource - enter animation staggers the list 75ms behind the search via animation-fill-mode: both, so content stays visible when animations never run (reduced motion, hidden tabs) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adds the brand logotype (the "Sim" word, new SimLogotype icon drawn in currentColor so themes drive the color) centered above the empty state's search in --text-subtle — a soft grey brand moment in both modes. Decorative only: aria-hidden, sized via height + w-auto. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
--text-subtle read too heavy for a decorative mark; half opacity tracks both themes toward the brand asset's original #EAEAEA feel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
py-[7px] derived the height from content, and a 31px action chip pushed the row to 45px — leaving the header divider 1px below the chat title bar's across the split. A fixed h-[44px] (matching the chat bar and PanelHeader) keeps every staged view's header height, divider, and vertically centered controls identical regardless of content. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat/panel split width was a transient inline style, so switching chats (route remount), staging a different view, collapsing, or reloading snapped the chat back to the default split. A small persisted store (mothership-panel) now keeps the user's widths: - the resource panel saves its width on drag end and re-applies it (viewport-clamped) whenever it's visible beside the chat pane - the workflow route's docked chat pane does the same with its own stored width, so the chat reads as one consistent size everywhere - clamping happens at apply time, never at save, so a narrow window doesn't permanently shrink the remembered width Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Opening a document from an embedded knowledge base routed to the full /knowledge/[id]/[documentId] page, closing the chat beside it. The KB detail now follows the established embed pattern: - KnowledgeBase gets `embedded`: document clicks (row + View Tags) swap to the Document view inside the panel via component state - Document gets delegated back-navigation (onNavigateToKnowledgeBase / onNavigateToRoot): the breadcrumb walk and post-delete landing return within the panel — root lands on the staged Knowledge Base page - standalone routes are untouched (no props -> same router paths) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Embedded mode degraded the canvas to a read-only preview: no dragging, connecting, or selecting, no block action bars, no editor Panel, no Deploy. `embedded` now means panel-hosted, not reduced: - full interactivity, gated by permissions only (drag, connect, select, edge editing, block menus, undo/redo controls, search/replace, diff controls, OAuth modals) - the editor Panel (Toolbar/Editor tabs, Deploy, Run) always renders; the panel header's duplicate Run action retires with it - the auto-fit machinery runs only until the first successful fit (the panel may still be width-animating open) — after that the user owns the viewport like any editor What embedded still does: props-based identity, collab join/leave, and skipping the route-level redirect/title chrome the panel header covers. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The header's ✕ cleared the stage and the panel auto-collapsed with it. Now clearing the stage keeps the panel open on the empty state (search, recents, browse) — only the collapse toggle closes the panel. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The chat's effective floor was much larger than intended: on the chat surface the panel was capped at 65% of the viewport (a 1680px window left the chat stuck at ~588px) plus a 320px flex floor, and the workflow route's docked chat stopped at 360px. - the panel's max is now viewport minus a fixed 280px chat floor (MOTHERSHIP_WIDTH.CHAT_MIN replaces MAX_PERCENTAGE), so the chat can reach the same minimum on any screen size - the home chat pane's flex floor drops 320px -> 280px to match - the docked chat's drag minimum and default clamp drop 360px -> 280px Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The open-chat title bar still rendered the pre-split chip (no divider), so the control changed design the moment a chat opened. It now renders the same split pill as the icon-only and closed-chat states — both segments open Recents there; the split is the family look. Also pulls the chevron closer to the text across all three variants (title segment pr-1.5 -> pr-1, chevron segment px-1.5 -> px-1), so the chevron reads as part of the chip instead of floating beside it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
canCloseChat required a staged resource, so the quick-open empty state — now a legitimate panel view — left the chat unclosable, and the restore effect would have snapped it right back. Now: - the chat can hide whenever the panel is visible (staged content or empty state alike) - the chat only force-restores when the panel collapses, so the view never blanks - with the chat hidden, the empty state gains the slim 44px chrome bar (sidebar toggle + chat switcher + toggle spacer) so the way back to the conversation stays reachable Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The only cap was 30% of the viewport, so on wide monitors the sidebar could drag out to 750px+, crushing the chat and resource panel. The clamp is now min(400px, 30% of viewport) — applied in the store clamp (persisted values self-heal on load) and the live drag handler. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Standalone pages' Resource.Header derived its height from padding (py-[8.5px] -> 48px with the border), so the sidebar toggle and chat switcher sat 2px lower than on chat surfaces (44px bars) and the divider line moved — switching pages made the corner icons visibly jump. The header is now a fixed h-[44px] in both standalone and panel modes, matching the chat title bar and the workflow canvas cluster. Also evens out the icon-only chat-switcher segment (pl-2 pr-1 -> px-2): the recents icon was 2px off-center in its half of the split pill. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The workflow page was the last holdout: its title and chrome floated over the canvas (with a gradient fade) while the editor Panel and Deploy/Run pinned to the very top — so the same workflow read differently standalone vs staged in the chat panel (which has a real header bar). The route now renders the canonical 44px bordered header (sidebar toggle + chat switcher + workflow name) with the canvas and editor Panel below it, exactly matching the staged structure and every other main view. The floating cluster and canvas top-fade retire. With a chat docked, the cluster hides (the chat pane's bar carries it) and the two 44px bars align across the divider. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Non-chat pages rendered a compact icon-only chip while chat surfaces showed the titled split, so the control kept changing shape between pages. The iconOnly prop is gone: every surface now renders the titled split pill — icon + the most recent chat's name (capped at 200px) opens that chat outright, the chevron opens Recents. Variant selection is derived (onOpenChat -> reopen split; chatId/isNewChat -> recents split; otherwise the most-recent split). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The panel's close button lived inside whichever header the staged view happened to render, so headerless states (loading skeletons, not-found views, anything that skips its Resource.Header) silently dropped it — leaving no way to close, and only the overlay toggle to collapse. Both controls are now a single host-owned overlay cluster pinned to the panel's top-right (the pattern the collapse toggle already used): - home renders [close][toggle] absolutely; close shows whenever a resource is staged and the panel is open, regardless of what the content renders - PanelTrailingControls becomes pure footprint spacers (close + toggle) for header rows; PanelCloseButton is the extracted real control - the empty state keeps toggle-only (nothing staged, nothing to close) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The Logs page header (and the log not-found view) still drew the old Library glyph while the sidebar, resource registry, and panel rows had moved to the Logs icon. Aliased as LogsIcon (the page components own the bare name). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The panel transitioned border-width along with width, so hiding the chat pane (panel border-l -> border-l-0 + snap to full width) animated the 1px border away over 200ms — a ghost line flashing at the main content's left edge. Border toggles are instant now; only width and min-width animate. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The panel's close X inherited the 16px header-icon class while the chat pane's close runs 14px — the size that reads right, since the X glyph is optically larger than other glyphs at equal box size. Close glyphs are now 14px on both sides; non-X header icons (sidebar toggle, panel toggle, preview mode) stay at the canonical 16px. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…mmit The persisted split-width store (stores/mothership-panel) never made it into "the split remembers" — the branch referenced a module that only existed in the working tree. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The empty-state logotype's sheen sweep referenced animate-logo-shimmer, which had no keyframe in the Tailwind config — the band parked off-canvas and never moved. Adds the sweep (1.4s ease-in-out after a 400ms settle, forwards so it parks off the right edge), in SVG user units (2x the 796 viewBox width). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
There are 3 total unresolved issues (including 2 from previous reviews).
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit c245784. Configure here.
| (fileId: string, fileName: string, options?: { isNew?: boolean; folderId?: string | null }) => { | ||
| if (embedded) { | ||
| onOpenFileRef.current?.(fileId, fileName) | ||
| return |
There was a problem hiding this comment.
Embedded file clicks do nothing
Medium Severity
In embedded panel mode, opening a file only calls the optional onOpenFile callback. If the host passes embedded without that handler, row clicks and context-menu open become silent no-ops instead of opening the file.
Reviewed by Cursor Bugbot for commit c245784. Configure here.


What this branch does
A design-engineering pass over the workspace shell: the sidebar, chat, and resource panel now behave as one coherent surface — chat is reachable from every page, the panel is a workspace-owned tab strip, and the chrome follows a single spacing system.
Highlights
Workspace-owned tab strip (browser-tab semantics)
+Ndropdown that lists only the hidden tabs. Selecting from+Npromotes the tab into the visible row.Chat everywhere
Sidebar collapse
Design system pass
Sync
origin/main(136 commits, v0.7.3) into the branch.🤖 Generated with Claude Code