Agentic UI: Simplify Sidebar with new Site-Centric Focus#3998
Closed
shaunandrews wants to merge 14 commits into
Closed
Agentic UI: Simplify Sidebar with new Site-Centric Focus#3998shaunandrews wants to merge 14 commits into
shaunandrews wants to merge 14 commits into
Conversation
Removes the dead toggleSpacer markup and now-unused agent-run hooks, dedupes findActiveSiteKey via findSessionSiteKey, measures drag slot boundaries once at drag start instead of per pointermove, stabilizes the New chat shortcut handler, reverts the stray allowpopups cast, and simplifies the floating-toggle CSS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drops the local Tooltip.Provider delay={ 0 } wrappers on the chat footer, composer toolbar, and site dropdown so every tooltip inherits the app-wide provider's default hover delay and shares its hover group. Moves the zero delay into the composer test harness to keep those assertions deterministic.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
shaunandrews
marked this pull request as ready for review
July 3, 2026 18:13
…-sidebar # Conflicts: # apps/ui/src/components/sidebar-header/index.tsx # apps/ui/src/components/sidebar-layout/index.tsx # apps/ui/src/components/sidebar-layout/style.module.css # apps/ui/src/components/site-settings-view/index.tsx # apps/ui/src/components/site-settings-view/style.module.css # apps/ui/src/components/user-menu/index.tsx # apps/ui/src/ui-classic/components/session-view/index.tsx # apps/ui/src/ui-classic/components/session-view/style.module.css
…toggle Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collaborator
📊 Performance Test ResultsComparing f027d2d vs trunk app-size
site-editor
site-startup
Results are median values from multiple test runs. Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff) |
This was referenced Jul 8, 2026
bcotrim
added a commit
that referenced
this pull request
Jul 13, 2026
…4129) ## Related issues - Related to STU-1985 — piece 1 of splitting #3998 into small PRs ## How AI was used in this PR Commit cherry-picked from #3998 (authored by @shaunandrews with AI assistance); Claude Code handled the cherry-pick onto trunk and ran lint/typecheck/tests. ## Proposed Changes - The composer toolbar (add-attachment, model pill, stop, send) and the site dropdown trigger each wrapped their tooltip in a local `Tooltip.Provider delay={ 0 }`, so those tooltips popped instantly while the rest of the app used the default hover delay. - Drops the local overrides so every tooltip inherits the app-wide provider (`AppProviders`) and its default delay/hover group — one consistent tooltip feel across the app. - The composer test harness keeps a zero delay locally so its assertions stay deterministic. ## Testing Instructions - Open the agentic UI and hover the composer buttons (attachment, model pill, send/stop) and the site dropdown trigger. - Tooltips should appear after the same default hover delay as other tooltips in the app (no longer instantly), and still display correctly. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Shaun Andrews <shaun@automattic.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
bcotrim
added a commit
that referenced
this pull request
Jul 13, 2026
## Related issues - Related to STU-1985 (follow-up: splitting the work around #3998 into small PRs) ## How AI was used in this PR Implemented with Claude Code from a detailed plan (target location, migration hook point, race handling). Code, migration tests, and verification steps reviewed by me. ## Proposed Changes AI chat sessions were the last piece of Studio state still living in the Electron `userData` dir (`~/Library/Application Support/Studio/sessions`, `%APPDATA%\Studio\sessions`) — a historical accident: sessions shipped (#2767) just before the `~/.studio` config split (#2793), and only the config JSONs moved. This PR consolidates sessions under `~/.studio/sessions`, resolved via a new `getSessionsDirectory()` helper in `well-known-paths.ts` next to the other config paths. Existing sessions are migrated by a shared `Migration` registered in **both** existing migration pipelines — the CLI's (runs as yargs middleware on every invocation) and the desktop's (runs at boot, before the main window exists) — so it covers CLI-only and desktop-only users alike. A lockfile serializes concurrent desktop + CLI first runs. After moving the files, the migration **leaves a symlink at the legacy location** (a junction on Windows — no privileges needed) pointing at `~/.studio/sessions`. That makes the move transparent to everything that still resolves the old path: older Studio/CLI versions running next to a newer one keep reading *and writing* the same store, and absolute paths persisted inside session entries (e.g. screenshot artifacts from `take_screenshot`) keep resolving — no session data rewriting needed. If linking fails (e.g. network-redirected `%APPDATA%`), the migration degrades to a self-healing merge that sweeps straggler files into the new root on every run — destination wins on collisions, cross-volume moves fall back to copy+remove. Failures are logged with home-dir-sanitized paths; success is silent like the other CLI migrations. User impact: none visible — sessions and their screenshots keep working in both the desktop app and the CLI, from the new location, across version skew between surfaces. The E2E path overrides (`E2E_APP_DATA_PATH`) keep their previous semantics, and the migration is skipped under E2E/dev sandboxes so test runs can't touch real sessions. The experimental hosted backend's session path was updated to match so it keeps reading the same sessions desktop/CLI write. ## Testing Instructions 1. With existing sessions under the old location (`~/Library/Application Support/Studio/sessions`), run `npm run cli:build && node apps/cli/dist/cli/main.mjs code sessions list` — all sessions listed, files now under `~/.studio/sessions`, old path is now a symlink to it (`ls -l`). 2. Run it again — idempotent no-op, same list. 3. Old-version compatibility: with the link in place, sessions written to the old path (simulating an outdated surface) land in `~/.studio/sessions`, and old screenshot artifacts render in the desktop conversation view (their persisted absolute paths resolve through the link). 4. Start the desktop app, open Studio Code — session history intact, new sessions land under `~/.studio/sessions/YYYY/MM/DD/`. 5. Fresh setup (no old dir): sessions are created directly under `~/.studio/sessions`. To revert the migration between scenarios (removes the link, then moves the sessions back so the migration runs again — bare `rm` refuses to delete a real directory, so it only ever removes the link): ```bash # macOS rm ~/Library/Application\ Support/Studio/sessions && mv ~/.studio/sessions ~/Library/Application\ Support/Studio/sessions ``` ```powershell # Windows (PowerShell) (Get-Item $env:APPDATA\Studio\sessions).Delete(); Move-Item ~\.studio\sessions $env:APPDATA\Studio\sessions ``` ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors?
bcotrim
added a commit
that referenced
this pull request
Jul 14, 2026
## Related issues - Related to STU-1985 (splitting #3998 into reviewable pieces) - Extracted from #3998 (`extract-site-centric-sidebar`) ## How AI was used in this PR Claude Code ported the `ReorderableList` component verbatim from #3998 (Shaun's commit, preserved as author), adapted the order-persistence wiring from the reference branch onto trunk's group-based sidebar, and adapted/extended the tests. All changes reviewed and verified locally (lint, typecheck, unit tests). ## Proposed Changes Sites in the agentic UI sidebar can now be reordered by dragging, so users can arrange their list to match how they work instead of being stuck with an imposed order. - Dragging a site's header row lifts it into a floating preview with a drop placeholder and smooth FLIP animations (disabled under `prefers-reduced-motion`); clicks, chat links, and action buttons keep working as before. - While a drag is active, every site's chat sublist collapses so rows are uniform and long lists are easy to rearrange, and dragging near the sidebar's top or bottom edge auto-scrolls the list. - The order persists via the same per-site `sortOrder` appdata field the legacy sidebar uses, so a custom order survives restarts and stays consistent between both sidebars. The renderer owns the order for the session — seeded once at startup, changed only by drags — so background refetches can never reorder or flicker the list; the saved order is also patched into the persisted query cache so a reload paints the right order immediately (review feedback). In the browser (`studio ui` / hosted), where there is no appdata, the order is kept in `localStorage`. - Behavior change: the sidebar previously sorted sites by most-recent chat activity; it now uses the stored `sortOrder` (falling back to name), so the list stays stable and only changes when the user rearranges it. Chats not assigned to a known site (the old "Unassigned" group) are no longer shown; that logic gets cleaned up in a follow-up PR. The drag mechanics live in a generic `ReorderableList` component (pointer-event based, 4px drag threshold, drop hit-testing against rects captured at drag start, post-drag click suppression) that later pieces of the #3998 split will reuse. ## Testing Instructions 1. `npm start`, open the agentic UI with a few sites created. 2. Drag a site by its header row: a floating preview follows the pointer, a placeholder marks the drop slot, and other rows animate out of the way. Drop it and confirm the new order. 3. Restart the app — the order should persist. 4. Confirm normal interactions still work: clicking a site header toggles its chats, chat links navigate, the status/new-chat/menu buttons work, and dragging from the chat sublist does **not** reorder. 5. Check the drag visuals in both light and dark mode. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? --------- Co-authored-by: Shaun Andrews <shaun@automattic.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
bcotrim
added a commit
that referenced
this pull request
Jul 14, 2026
## Related issues - Related to STU-1985 (chat-history-below-composer thread of the split; does not close the issue) - Split from #3998 (`extract-site-centric-sidebar`) — "add" half of the add-before-remove sequencing: this PR adds the session chat controls below the composer while the sidebar keeps its current chat sublists; a follow-up PR makes the sidebar site-centric. ## How AI was used in this PR Claude Code adapted the session-chrome portion of @shaunandrews' `extract-site-centric-sidebar` branch onto trunk (his authorship is preserved via `Co-authored-by`), and implemented the ⌘N accelerator fix. All changes reviewed by @bcotrim. ## Proposed Changes We want chat access to live with the conversation rather than in the sidebar, and to discourage multiple concurrent chats per site. This PR adds a footer row below the composer in the agentic UI (`apps/ui`) for sessions that belong to a site: - **Chat history menu**: opens upward, lists the site's chats newest-first with first-prompt titles and relative timestamps, marks the current chat, and offers a per-row archive action on hover. Empty state shows "No chats yet". - **Archived chats dialog**: reachable from the history menu (entry shows the count); selecting an archived chat reopens it. - **New chat button**: creates a fresh session for the current site and navigates to it; disabled while creating; ⌘N/Ctrl+N shortcut shown in the tooltip. - **⌘N conflict fix**: the desktop menu bound `CommandOrControl+N` to "File → Add Site…", which consumed the key before the renderer ever saw it — so the New chat shortcut could never work in the desktop app. When the agentic UI is active, the menu item no longer registers the accelerator (the item itself remains). The classic UI keeps ⌘N for Add Site unchanged. ## Testing Instructions Enable the **Agentic UI** feature flag and open a chat session that belongs to a site: 1. A footer row appears bottom-left below the composer with a history button and a "New chat" button; while the session is loading, the layout doesn't jump. 2. Open the chat history menu: it opens upward, lists only this site's non-archived chats newest-first, titles from the first prompt (truncating cleanly when long), relative timestamps, and the active chat highlighted/marked as current. 3. Hover a history row: the timestamp swaps to an archive button; archiving removes the chat from the menu and it appears in the "Archived chats" dialog (menu entry shows the count). Reopening an archived chat switches to it. 4. Click "New chat" (or press ⌘N/Ctrl+N): a fresh session for the site is created and opened; the button is disabled while creating; the tooltip shows the shortcut. 5. **Desktop ⌘N**: with the agentic UI active, File → Add Site… shows no ⌘N shortcut and ⌘N starts a new chat. With the flag off (classic UI), ⌘N still opens Add Site. Toggling the flag from the dev Feature Flags menu updates the menu after the renderer reloads. 6. A site with no other chats shows "No chats yet" in the menu. 7. Verify in both light and dark mode. ## Pre-merge Checklist - [ ] Have you checked for TypeScript, React or other console errors? --------- Co-authored-by: Shaun Andrews <191598+shaunandrews@users.noreply.github.com>
1 task
bcotrim
marked this pull request as draft
July 14, 2026 16:21
bcotrim
added a commit
that referenced
this pull request
Jul 16, 2026
## Related issues - Related to STU-1985 - Final extraction from #3998 (built on the already-landed #4131, #4133, and #4134) ## How AI was used in this PR Claude (Fable 5) extracted and adapted this change from the #3998 reference branch under close direction, preserving Shaun Andrews' original work via co-authored commits, and re-verified the result (typecheck, unit tests, light/dark visual pass in the browser UI). Code was human-reviewed throughout. ## Proposed Changes This is the capstone of the site-centric sidebar work: the sidebar becomes a flat list of sites, with no per-site chat sublists. - Clicking a site opens its most recent (non-archived) chat, or starts a new chat when the site has none. Chat history is no longer browsed from the sidebar — that moved below the composer in #4133. - Each site row carries a single activity indicator that aggregates all of the site's sessions, with priority: live-site sync > needs an answer > working > new message. This keeps long site lists calm while still surfacing what needs attention. - Row quick actions (site actions menu + start/stop status button) appear on hover/focus; drag-to-reorder from #4134 keeps working on the flat rows. - Status colors move to shared `--studio-color-status-*` tokens: the wpds palette has no vivid status colors (`--wpds-color-fg-content-success` resolves to near-black at dot size), which also fixes the session header's running dot rendering almost black. - Chrome polish: full-bleed 44px site icon with overlaid status badge in the site dropdown, flattened site icons, a visible hover tint on the sidebar create button, the floating sidebar toggle moved to the bottom-left, and aligned settings-header padding. Two product decisions to be aware of (intentional for now): - **Unread "new message" badges are in-memory only** — they reset (seed as all-seen) on every launch. - **The current chat is indicated via `aria-current` + active-row styling**, not the literal "Current chat" label from the mockups. ## Testing Instructions - Start Studio with `npm start` and enable the `Agentic UI` feature flag. - Confirm the sidebar shows a flat list of sites (no chat sublists): clicking a site with chats opens its latest chat; a site without chats opens the new-chat view. - Hover a row: the site actions menu and start/stop button appear; right side shows a green dot for running sites, a play affordance for stopped ones. - Send a prompt on one site, switch to another: the first row shows a working spinner, then a "New message" badge when the turn completes; answering a pending question clears the "Needs an answer" indicator. - Drag a site row to reorder; the order persists across restarts. - Delete a site you're currently viewing and confirm you land back on the home view. - Check the sidebar and site dropdown in **both light and dark mode**. ## Pre-merge Checklist - [x] Have you checked for TypeScript, React or other console errors? 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Shaun Andrews <191598+shaunandrews@users.noreply.github.com>
Contributor
|
Closing this in favor of smaller PRs split from this work (with @shaunandrews' commits carried over where they applied — thanks for the design and original implementation! 🙌). Extracted from this PR:
Follow-ups from reviewing it: |
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.
Related issues
How AI was used in this PR
Codex helped extract and iterate on the site-centric Agentic UI sidebar, then verified the final branch with linting, typecheck, targeted tests, and a running local app session. Claude Code later ported the latest sidebar-relevant refinements from the exploration branch (
explore-site-centric-conversation-chrome) and re-verified with lint, typecheck, and the targeted tests. The PR remains draft because it is a visual/navigation change that needs human review in the app.Executive summary
This PR simplifies Agentic UI around sites as the primary object. The sidebar no longer behaves like a chat list; it focuses on local sites, their status, and their latest conversation. Chat creation and chat history moved into the chat panel footer so previous conversations remain reachable without making the sidebar carry two navigation models.
Site rows now open the latest chat, or start a new site chat when no chat exists. Site settings remain available through the existing settings route.
Proposed Changes
ReorderableListcomponent (same behavior, less code, reusable for future sidebar groups).Dialog.Contentfor correct popup spacing, and gives the sidebar's create button a visible hover tint in both color schemes.Review guide
Okay to skim
Diff breakdown
apps/ui/src/components/reorderable-listcomponent; the site list now consumes it. Existing drag-reorder tests cover the swap unchanged.apps/ui/src/lib/last-visited.tshelper, recorded by the dashboard layout and read by the/index route.Known tradeoffs and follow-ups
allowpopupswarning. No new typecheck or targeted test failures were observed.Safety checklist
apps/ui.Testing Instructions
npm run typecheck.npm test -- apps/ui/src/components/site-list/index.test.tsx apps/ui/src/components/user-menu/index.test.tsx apps/ui/src/components/sidebar-layout/index.test.tsx apps/ui/src/ui-classic/components/session-view/session-chat-actions.test.tsx.npm startand confirm Studio launches from this branch.Pre-merge Checklist