feat(code): canvas — Home space with channels, gen-UI dashboards (WIP)#2492
Closed
adamleithp wants to merge 24 commits into
Closed
feat(code): canvas — Home space with channels, gen-UI dashboards (WIP)#2492adamleithp wants to merge 24 commits into
adamleithp wants to merge 24 commits into
Conversation
Wrap the app in a left app rail (square Quill icon-lg buttons) switching between a new Home space (/ hello-world scene + its own sidenav) and the existing Code app (/code). Rail reserves macOS traffic-light space and is a titlebar drag region. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Give the Home sidenav Quill folder collapsibles with a placeholder nav (Features, Resources). The Features > Website item opens a new blank /website canvas route. Centralize Home-space detection in canvas/spaces.ts so the whole space shares its chrome. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add @json-render/core + @json-render/react. The /website canvas now renders an agent-built, data-driven UI on the left with a chat panel hugging the right. - Main CanvasGenService reuses AgentService (PostHog MCP auto-enabled) to run an ephemeral __preview__ session per thread with a json-render system prompt and bypassPermissions, forwards ACP session updates through @json-render/core's mixed-stream parser to assemble the Spec, and streams typed events over tRPC. - AgentService gains systemPromptOverride to replace the coding-agent prompt for non-coding surfaces (keeps only project scoping). - Renderer: shared json-render catalog (Page/Grid/Card/Stat/Table/BarList/…) + Radix registry, a thin canvasChatStore, a scoped subscription registrar, and the chat/composer UI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The renderer could OOM/crash while streaming a generated spec: partial or malformed mid-stream frames were rendered and could recurse infinitely. - Main only emits a spec once its root element actually exists (no partial frames). - Wrap CanvasRenderer in an ErrorBoundary keyed on the spec, so a bad frame is caught and rendering recovers on the next valid frame. - Only render when isNonEmptySpec(spec). - Make the canvas subscription idempotent per thread (guards StrictMode double-mounts from stacking IPC listeners). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an Inbox rail item (above Code) that opens a full-screen /inbox route reusing InboxView, without the code app chrome (header/sidebar/space-switcher). The existing /code/inbox route is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a numeric Quill destructive badge to the Inbox rail button, mirroring the code sidebar's actionable-report count. Extract the count into a shared useInboxSignalCount hook that reuses the sidebar's query cache (no extra polling). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Expand the Website space with a breadcrumb topbar and sub-navigation: - /website is now a layout (breadcrumb topbar: Website > <page>) with children: index (canvas), new (TaskInput reused via onTaskCreated), settings (placeholder), and tasks/$taskId (TaskDetail reused). - New tasks created from /website/new route into the Website space at /website/tasks/$id (not /code) and are tracked in a persisted websiteTasksStore. - HomeSidebar gains a Website section: Canvas, New task, Settings, plus the list of created tasks to return to. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render HomeSidebar nav items as Quill Button (variant default, size sm, full-width left-aligned), expressing active via data-selected. Active logic unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the Website "Canvas" entry with "Dashboards": /website redirects to the default dashboard at /website/dashboards/$dashboardId, which renders mock website-data dashboards (traffic, acquisition, engagement, conversion, performance). The breadcrumb second crumb is a Quill combobox to switch the active dashboard by name (Website > [dashboard]). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an Edit toggle (Quill outline button, ml-auto, data-selected) to the dashboards breadcrumb bar. When active, the dashboard swaps its tiles for the gen-UI canvas + side chat input for that dashboard. Make the canvas chat store multi-thread (one thread per dashboard) so each dashboard keeps its own chat and generated canvas. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Disable base-ui combobox filtering (filter={null}) so the dashboard dropdown
always lists every dashboard instead of collapsing to the selected one.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the mock dashboards with real, file-backed ones: a main DashboardsService stores each dashboard as JSON (a json-render spec) under <appData>/dashboards. - Dashboards list, combobox, and sidebar count now come from the saved files. - A dashboard renders its saved spec read-only; Edit drops into the gen-UI canvas + chat for that dashboard's thread. - Topbar Save (enabled when the generated spec differs from saved) persists it; Save as fork copies the current spec into a new dashboard. - Empty state + sidebar "New dashboard" create a blank dashboard and open it in edit mode. Saved dashboards survive a refresh. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Wrap create+navigate in try/catch with a toast + log so a failed New dashboard action (e.g. backend not reachable) no longer silently does nothing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking Save now opens a Quill dialog to confirm/enter the dashboard name before persisting. The dashboard name in the breadcrumb (edit mode) is also inline-editable: hovering shows a faint border, clicking swaps to a Quill input sized to match the text (no layout shift), committing on Enter/blur. Save is disabled while renaming and re-enabled on blur. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Revert to the dropdown switcher in edit mode and a direct Save (no name dialog, no click-to-rename input). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add a Quill button group (refresh | gear) to the dashboard topbar. Refresh
refetches the dashboard data; the gear dropdown selects Static (manual refresh)
or a Polling interval (10s, 10min). While polling, the main button counts down
("Refreshing in XX"). Polling pauses in edit mode so the data stays put.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…tching Wrap the Polling label and interval items in DropdownMenuGroup so the Menu.GroupLabel has its required Menu.Group context (fixes the MenuGroupRootContext error). Spin the refresh icon (motion-safe:animate-spin) while the dashboard data is fetching. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The canvas nav rail and Home/Website/Inbox spaces mount in one place (__root.tsx). Gate that mount on a new project-bluebird flag: when off, the app is the pre-canvas code-only shell. Stranded users on a canvas-only path (cold-boot restore, stale deep link) are sent to /code once flags resolve, so flagged users aren't bounced off /website during the load window. - New PROJECT_BLUEBIRD_FLAG constant; defaults on in dev so local canvas work isn't hidden behind a flag PostHog doesn't serve locally. - New useFeatureFlagsLoaded hook to defer the redirect until a flag value is trustworthy rather than acting on the false-before-load default. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- /website index is now a 3-wide card grid of live dashboard previews
(CanvasRenderer scaled to a thumbnail) instead of redirecting to the first
dashboard. Clicking a card opens the full dashboard.
- Each card has a hover-revealed "..." menu (outline) with a destructive
Delete, rendered as a sibling of the card link so it never navigates.
- New dashboards.delete endpoint + deleteDashboard mutation (ENOENT treated as
success).
- HomeSidebar nav items now actually highlight the active route: Quill's Button
doesn't style data-selected, so consume it via a Tailwind utility (mirrors
SidebarItem) and gate the attr on `active || undefined`.
- Dashboard breadcrumbs are now Website > Dashboards [> {name}], with the
middle crumb linking back to the index.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Editing a saved dashboard rendered WebsiteCanvas, which only shows the chat thread's spec. A freshly opened board has no thread yet, so the canvas fell back to EMPTY_THREAD (spec: null) and looked wiped. Seed the thread from the saved dashboard spec when entering edit, via a new ensureSpec action that only hydrates an empty thread (never clobbers a live stream or in-session edits). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ettings) Replace the placeholder Website/Features/Resources nav with server-backed channels (desktop file-system folders). Each channel gets its own dashboards (channel-scoped, file-backed), tasks, and settings, routed under /website/$channelId. Adds channel create/delete, a Slack-style create modal, orphan-dashboard migration into the first channel, and breadcrumb/nav polish. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Dev-only
Everything is gated behind the
project-bluebirdfeature flag (default-on in dev, off for all prod users). Flag off ⇒ the app is today's code-only shell. Not enabled for real users.What's here
A Slack-like app nav rail (Home / Inbox / Code) plus a full Home space built around channels:
@json-renderspec from chat; edit mode swaps to the canvas + chat, Save/fork persists./website/$channelId/...; settings is a per-channel placeholder.Status / open questions
desktop_file_system); logged-out shows an empty state.Testing
pnpm --filter code typecheck— clean.Created with PostHog Code