Agentic UI: Application Settings#3979
Conversation
There was a problem hiding this comment.
Pull request overview
This PR brings Studio’s application-level settings into the new agentic UI (apps/ui) by adding a dedicated /settings route with tabbed sections (Settings/Usage/Keyboard/Skills/MCP), wiring the necessary connector/query plumbing, and updating sidebar navigation so the user row acts as the primary entry point to Settings.
Changes:
- Adds a new Settings route and a redesigned SettingsView with tabs, save UX (including unsaved-change blocking), and keyboard shortcut handling.
- Introduces new data-layer capabilities (app globals, snapshot usage + delete-all, WordPress skills, offline detection) across connectors and queries.
- Updates sidebar/user-menu/site-list behavior and styling to treat Settings as a first-class navigation destination.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/ui/src/ui-classic/router/route-settings/index.tsx | Updates settings route search param parsing to normalize tab ids. |
| apps/ui/src/ui-classic/router/layout-root/index.tsx | Adds root-level listener to open Settings from connector events. |
| apps/ui/src/lib/docs-links.ts | Adds new docs link keys for CLI/MCP/Skills. |
| apps/ui/src/index.css | Adds select z-index token + tweaks highlighted listbox row styling for dark chrome. |
| apps/ui/src/hooks/use-offline.ts | Introduces a hook for online/offline guards in UI flows. |
| apps/ui/src/data/queries/use-wordpress-skills.ts | Adds query + mutations for global WordPress skill status/actions. |
| apps/ui/src/data/queries/use-snapshots.ts | Adds per-user query keys + snapshot usage query + delete-all mutation helpers. |
| apps/ui/src/data/queries/use-app-globals.ts | Adds app globals query (platform/app metadata) with infinite staleness. |
| apps/ui/src/data/core/types.ts | Extends Connector contract + adds new types (AppGlobals, SnapshotUsage, SkillStatus, etc.). |
| apps/ui/src/data/core/index.ts | Re-exports newly added data-core types. |
| apps/ui/src/data/core/connectors/ipc/index.ts | Implements new Connector methods in IPC mode (snapshot usage, prefs, skills, settings events, etc.). |
| apps/ui/src/data/core/connectors/hosted/index.ts | Implements hosted/browser-mode behavior for new Connector methods (mostly no-ops / placeholders). |
| apps/ui/src/components/user-menu/style.module.css | Restyles user menu row to behave like a first-class selected/active navigation row. |
| apps/ui/src/components/user-menu/index.tsx | Makes clicking the user row open Settings directly; adds “active” state and removes theme toggle menu. |
| apps/ui/src/components/user-menu/index.test.tsx | Adds coverage for Settings navigation + active highlighting behavior. |
| apps/ui/src/components/site-list/style.module.css | Aligns site row hover/active colors with new sidebar tokens. |
| apps/ui/src/components/site-list/index.tsx | Prevents MRU auto-expansion when not on the dashboard root (e.g., in Settings). |
| apps/ui/src/components/site-list/index.test.tsx | Adds tests for MRU expansion behavior on / vs /settings. |
| apps/ui/src/components/sidebar-layout/style.module.css | Adds shared sidebar row background tokens; fixes collapsed toggle interaction via pointer-events. |
| apps/ui/src/components/sidebar-layout/index.tsx | Adjusts children rendering order to keep overlay/toggle layering correct. |
| apps/ui/src/components/settings-view/style.module.css | Major styling update for new settings layout (header tabs, panels, rows, meters, code block). |
| apps/ui/src/components/settings-view/preferences.ts | Extracts preferences form normalization/diff logic into helpers. |
| apps/ui/src/components/settings-view/preferences.test.ts | Adds focused tests for new preferences helper behavior. |
| apps/ui/src/components/settings-view/index.tsx | Replaces legacy preferences DataForm with full tabbed settings experience and new panels (Usage/Keyboard/Skills/MCP). |
| apps/ui/src/components/settings-view/index.test.tsx | Adds broad coverage for settings save/dirty-blocking/tab rendering/hosted hiding/usage/skills/mcp copy/account actions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
📊 Performance Test ResultsComparing 0f64d77 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) |
|
|
||
| fireEvent.click( screen.getByRole( 'button', { name: 'Install' } ) ); | ||
| fireEvent.click( screen.getByRole( 'button', { name: 'Remove' } ) ); | ||
| fireEvent.click( screen.getByRole( 'button', { name: 'Install all' } ) ); |
| async confirmDeleteAllPreviewSites(): Promise< boolean > { | ||
| const CANCEL_BUTTON_INDEX = 0; | ||
| const DELETE_BUTTON_INDEX = 1; | ||
| const { response } = ( await ipcApi.showMessageBox( { |
katinthehatsite
left a comment
There was a problem hiding this comment.
Some general notes:
- Changing languages did nothing for me: after I saved my settings, the app remained in English
- I also think we could adjust the position of the
Report an issueandDocs- I would expect these to go in some sort of general settings rather than in my account settings - Finally, I am finding this to be quite a big PR so it is hard to review - do you think it could be split into smaller PRs?
bcotrim
left a comment
There was a problem hiding this comment.
Some feedback from my testing:
- Do we need the "Save" button? Couldn't we save the changes automatically as the user changes it? I am aware that some options like changing language, would have some bigger side effects, but I consider it to be an UX improvement.
- Language setting doesn't appear to be working
- ⌘ ↩ is adding a newline, ↩ send the message
- ⌘ [ and ⌘ ] are not so easy to use in non US keyboards, could we use arrows instead?
- Should we have a back button to navigate away from the settings and back to where the user was?
- The settings icon in the left corner only appears for logged out users, could we make it consistent?
| [] | ||
| const handleColorSchemeChange = useCallback( | ||
| ( colorScheme: ColorScheme ) => { | ||
| if ( ! isColorScheme( colorScheme ) ) { |
There was a problem hiding this comment.
isColorScheme can’t fire — colorScheme is already typed ColorScheme and the only caller passes a literal from colorSchemeElements(). Drop the function + guard.


Related issues
How AI was used in this PR
Codex helped port the existing Studio application preferences into the new agentic UI, iterate on visual polish with repeated light/dark checks, add focused tests, and run code review passes with a subagent and Claude. I reviewed the resulting behavior and asked for targeted revisions throughout the implementation.
Executive summary
This PR brings app-level Studio settings into the new agentic UI as a dedicated
/settingsroute. It replaces the temporary user-menu preferences surface with a first-class tabbed settings screen covering Settings, Usage, Keyboard, Skills, and MCP.Reviewers should focus on whether the new settings surface fits the agentic UI architecture, keeps desktop-only behavior correctly gated, and preserves existing preferences behavior while adding the new Usage, Skills, and MCP affordances.
Proposed Changes
Review guide
Please review carefully:
appGlobals.platform !== 'browser'; hosted/browser mode should not briefly expose unavailable native controls.diffPreferencesFromSaved()should only send changed fields, preserve null/unset behavior for editor and terminal, and handle unsupported saved locales safely.copyText()resolves and should handle failures without unhandled rejections.apps/uishould use--wpds-color-*tokens, not Studio legacy--color-frame-*tokens.Diff breakdown
Settings surface:
apps/ui/src/components/settings-view/index.tsxapps/ui/src/components/settings-view/style.module.cssapps/ui/src/components/settings-view/preferences.tsNavigation and sidebar:
apps/ui/src/ui-classic/router/route-settings/index.tsxapps/ui/src/ui-classic/router/layout-root/index.tsxapps/ui/src/components/user-menu/*apps/ui/src/components/site-list/*apps/ui/src/components/sidebar-layout/*Data and connector plumbing:
apps/ui/src/data/core/types.tsapps/ui/src/data/core/connectors/ipc/index.tsapps/ui/src/data/core/connectors/hosted/index.tsapps/ui/src/data/queries/use-app-globals.tsapps/ui/src/data/queries/use-snapshots.tsapps/ui/src/data/queries/use-wordpress-skills.tsapps/ui/src/hooks/use-offline.tsTests:
apps/ui/src/components/settings-view/index.test.tsxapps/ui/src/components/settings-view/preferences.test.tsapps/ui/src/components/user-menu/index.test.tsxapps/ui/src/components/site-list/index.test.tsxScreenshots
The hosted UI screenshots below cover the high-level settings surfaces in both light and dark mode, captured at 900px wide with seeded sites in the sidebar. Native-only desktop controls are hidden in hosted mode and are covered by tests.
Settings
Usage
Keyboard
Skills
MCP
Known tradeoffs and follow-ups
apps/ui; it does not migrate legacyapps/studiorenderer settings.Safety checklist
Connectorcontract.Testing Instructions
Pre-merge Checklist