Skip to content

Agentic UI: Application Settings#3979

Open
shaunandrews wants to merge 5 commits into
trunkfrom
stu-1882-port-application-preferences
Open

Agentic UI: Application Settings#3979
shaunandrews wants to merge 5 commits into
trunkfrom
stu-1882-port-application-preferences

Conversation

@shaunandrews

@shaunandrews shaunandrews commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

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 /settings route. 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

  • Adds a dedicated app settings route with URL-addressable tabs.
  • Ports general app preferences into the agentic UI, including appearance, language, editor, terminal, default site directory, and Studio CLI settings.
  • Adds Usage, Keyboard, Skills, and MCP tabs for account usage, shortcuts, WordPress agent skills, and MCP setup.
  • Moves Settings access into sidebar/user-row navigation and removes the prominent theme toggle from the sidebar footer.
  • Adds connector/query plumbing for app globals, snapshot usage, WordPress skills, shared copy text, offline guards, and settings events.
  • Updates sidebar and site-list behavior so opening Settings does not accidentally expand the first site group.
  • Adds focused unit coverage around preferences, settings behavior, user-menu navigation, and site-list expansion behavior.

Review guide

Please review carefully:

  • Settings UX and product fit: Does this feel like the right permanent home for app-level settings in the agentic UI?
  • Desktop vs hosted gating: Native controls should only appear when appGlobals.platform !== 'browser'; hosted/browser mode should not briefly expose unavailable native controls.
  • Preference persistence: diffPreferencesFromSaved() should only send changed fields, preserve null/unset behavior for editor and terminal, and handle unsupported saved locales safely.
  • Navigation behavior: User-row Settings navigation, root-level settings events, tab URL state, and clean default URLs should all behave consistently.
  • Connector contract additions: New connector methods should be additive, typed clearly, and implemented safely in both IPC and hosted connectors.
  • Destructive preview-site action: Delete-all preview-site behavior should be disabled offline, confirmed before mutation, and keyed by user where relevant.
  • Copy behavior: MCP copy should only show success after copyText() resolves and should handle failures without unhandled rejections.
  • Dark-mode styling: apps/ui should use --wpds-color-* tokens, not Studio legacy --color-frame-* tokens.

Diff breakdown

Settings surface:

  • apps/ui/src/components/settings-view/index.tsx
  • apps/ui/src/components/settings-view/style.module.css
  • apps/ui/src/components/settings-view/preferences.ts

Navigation and sidebar:

  • apps/ui/src/ui-classic/router/route-settings/index.tsx
  • apps/ui/src/ui-classic/router/layout-root/index.tsx
  • apps/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.ts
  • apps/ui/src/data/core/connectors/ipc/index.ts
  • apps/ui/src/data/core/connectors/hosted/index.ts
  • apps/ui/src/data/queries/use-app-globals.ts
  • apps/ui/src/data/queries/use-snapshots.ts
  • apps/ui/src/data/queries/use-wordpress-skills.ts
  • apps/ui/src/hooks/use-offline.ts

Tests:

  • apps/ui/src/components/settings-view/index.test.tsx
  • apps/ui/src/components/settings-view/preferences.test.ts
  • apps/ui/src/components/user-menu/index.test.tsx
  • apps/ui/src/components/site-list/index.test.tsx

Screenshots

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

Settings tab, light mode

Settings tab, dark mode

Usage

Usage tab, light mode

Usage tab, dark mode

Keyboard

Keyboard tab, light mode

Keyboard tab, dark mode

Skills

Skills tab, light mode

Skills tab, dark mode

MCP

MCP tab, light mode

MCP tab, dark mode

Known tradeoffs and follow-ups

  • This is a broad UI PR, but the scope is intentionally limited to apps/ui; it does not migrate legacy apps/studio renderer settings.
  • Hosted/browser mode uses safe defaults or no-op behavior for capabilities that only make sense in the desktop app.
  • Skills and MCP get the UI/data plumbing here; reviewers should confirm whether any remaining product copy or behavior belongs in a follow-up.
  • The UI should still receive human visual review in light and dark mode before merge.

Safety checklist

  • No data migration.
  • No direct config-file writes introduced in the renderer.
  • Connector additions are additive to the existing Connector contract.
  • Native-only settings are gated by app globals.
  • Preview-site destructive action requires confirmation and is disabled while offline.
  • Snapshot usage query is user-keyed to avoid cross-account quota bleed.
  • MCP copy avoids exposing secrets; it copies the local MCP config text only.
  • Human visual review completed in both light and dark mode.
  • Final CI/checks are green before merge.

Testing Instructions

  1. Open the app and click the sidebar user row. Confirm it opens Settings directly and the row highlights while in Settings.
  2. In Settings, switch through Settings, Usage, Keyboard, Skills, and MCP. Confirm tab alignment, focus rings, selected states, and panel spacing in light and dark mode.
  3. Edit a preference, then navigate away without saving. Confirm the unsaved changes dialog appears.
  4. Confirm dropdowns, segmented controls, the directory picker field, and the Studio CLI switch match the WordPress UI-style input treatment in both themes.
  5. Confirm hosted/browser mode hides native-only settings.
  6. Confirm the Usage tab shows AI credits and preview-site usage with full-width meters.
  7. Confirm preview-site delete-all is disabled offline and asks for confirmation before deleting.
  8. Confirm the Keyboard tab lists only currently supported shortcuts.
  9. Confirm the MCP copy button copies the configuration and only shows success after the copy succeeds.

Pre-merge Checklist

  • Typecheck passes.
  • Relevant unit tests pass.
  • Light-mode visual review completed.
  • Dark-mode visual review completed.
  • Reviewer agrees the connector additions are the right boundary for this settings surface.

@shaunandrews shaunandrews changed the title Port application settings to agentic UI Agentic UI: Application Settings Jun 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread apps/ui/src/ui-classic/router/layout-root/index.tsx Outdated
Comment thread apps/ui/src/components/settings-view/index.tsx
Comment thread apps/ui/src/components/settings-view/index.tsx
Comment thread apps/ui/src/components/settings-view/index.tsx Outdated
Comment thread apps/ui/src/components/settings-view/index.test.tsx
Comment thread apps/ui/src/data/core/connectors/hosted/index.ts
Comment thread apps/ui/src/components/settings-view/index.tsx Outdated
@shaunandrews shaunandrews marked this pull request as ready for review June 29, 2026 18:25
@wpmobilebot

Copy link
Copy Markdown
Collaborator

📊 Performance Test Results

Comparing 0f64d77 vs trunk

app-size

Metric trunk 0f64d77 Diff Change
App Size (Mac) 1315.63 MB 1315.75 MB +0.12 MB ⚪ 0.0%

site-editor

Metric trunk 0f64d77 Diff Change
load 1114 ms 1118 ms +4 ms ⚪ 0.0%

site-startup

Metric trunk 0f64d77 Diff Change
siteCreation 6597 ms 6500 ms 97 ms 🟢 -1.5%
siteStartup 6057 ms 6557 ms +500 ms 🔴 8.3%

Results are median values from multiple test runs.

Legend: 🟢 Improvement (faster) | 🔴 Regression (slower) | ⚪ No change (<50ms diff)

@shaunandrews shaunandrews requested review from a team and bcotrim June 30, 2026 00:28

fireEvent.click( screen.getByRole( 'button', { name: 'Install' } ) );
fireEvent.click( screen.getByRole( 'button', { name: 'Remove' } ) );
fireEvent.click( screen.getByRole( 'button', { name: 'Install all' } ) );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not specifically comment for the test but in general to Install all option - I am finding it hard to differentiate that title against all the options that it offers:

Image

async confirmDeleteAllPreviewSites(): Promise< boolean > {
const CANCEL_BUTTON_INDEX = 0;
const DELETE_BUTTON_INDEX = 1;
const { response } = ( await ipcApi.showMessageBox( {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That option was not working for me as I could not trigger the delete model from this ellipsis:

Image

At the moment, clicking there does nothing for me. Is it working on your end?

@katinthehatsite katinthehatsite left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 issue and Docs - 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 bcotrim left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 ) ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isColorScheme can’t fire — colorScheme is already typed ColorScheme and the only caller passes a literal from colorSchemeElements(). Drop the function + guard.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants