Skip to content

Agentic UI: Application Settings - #3979

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

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 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.

@fredrikekelund

Copy link
Copy Markdown
Contributor

Heads up: #4140 also touches the Agentic UI settings by adding a dropdown menu that lets users decide what happens to running sites when quitting Studio.

@bcotrim
bcotrim marked this pull request as draft July 14, 2026 16:21
bcotrim added a commit that referenced this pull request Jul 20, 2026
)

## Related issues

- Related to STU-1882

## How AI was used in this PR

Implemented with Claude Code (design ported from the settings redesign
explorations in #3975/#3979, adapted to auto-save). All changes were
reviewed, and behavior was verified manually in the app plus unit tests.

## Proposed Changes

First PR of the application-settings series for the new Studio
experience.

- **Settings now save instantly.** Changing any option persists it
immediately — no more Save button, dirty-state tracking, or losing
changes when navigating away. Per the settings design post: "options are
saved when changed."
- **Redesigned settings screen.** A title-bar-height header with a
centered tab list replaces the in-content title and tabs, and the
preferences are grouped into cards: a General section (Appearance as a
System/Light/Dark segmented control, Language, Preferred editor,
Preferred terminal, When quitting with running sites) and a Studio
experience section with the "Switch to classic" action. Save errors
surface inline in the affected section.
- **Settings no longer show stale values.** The screen previously
trusted a forever-fresh persisted cache, so preferences changed
elsewhere (or fields added since) could show wrong/empty values until
the cache expired. It now reconciles with the main process on
mount/focus.
- **Editor/terminal selections match the classic UI's behavior.** Only
installed apps are offered and the effective (fallback-resolved) app is
always shown, so a brand-new user sees a working "open in" option rather
than nothing. The site actions menu now names the apps ("Open in
Cursor", "Open in Terminal") and hides an action only when no supported
app is available.
- **"Stop, restart on next launch" now works in the new Studio
experience.** The relaunch half of that behavior only lived in the
classic UI; the new shell now restarts the flagged sites on boot too.

| Dark | Light |
|--------|--------|
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/9f95f2d0-1964-4c7f-8849-fffac00fe9f4"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/767a4950-8a6e-4216-9c9d-c2e612eadbe9"
/> |

**Note:** Some settings are intentionally left out and will be addressed
in follow-up PRs

## Testing Instructions

1. Enable the new Studio experience (beta feature flag) and open
**Settings**.
2. Change each preference (appearance, language, editor, terminal, quit
behavior) — each should apply immediately with no Save button. Language
reloads the app in the new locale.
3. Navigate away and back, and restart the app — values should persist
and match what the classic UI's settings dialog shows.
4. Right-click a site in the sidebar — the menu should read "Open in
<your editor>" / "Open in <your terminal>" and both should open.
5. Set "When quitting with running sites" to "Stop, restart on next
launch", start a site, quit Studio, relaunch — the site should start
again automatically.
6. Verify the settings screen 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)
bcotrim added a commit that referenced this pull request Jul 20, 2026
## Related issues

- Related to STU-1882

## How AI was used in this PR

Implemented with Claude Code (part of the STU-1882 settings series),
guided by the exploration in #3979. Code, styles, and tests were
reviewed before pushing;

## Proposed Changes

- Adds an **MCP** tab to the Agentic UI settings so users can connect
external AI assistants to Studio without hunting through docs: a short
explanation of what MCP is for, a "Learn more" link to the Studio MCP
docs, and the ready-to-paste `wordpress-studio` server configuration
JSON with a one-click copy button.
- The copy button now only shows "Copied" after the text has actually
landed on the clipboard, and announces it to screen readers. If copying
fails, the button no longer claims success — this also fixes the same
silent-failure behavior for copying chat messages and markdown code
blocks, which shared the button.

## Testing Instructions

1. Launch Studio with the Agentic UI enabled and open **Settings**.
2. Switch to the new **MCP** tab: verify the intro text, the "Learn
more" link (opens the MCP docs in your browser), and the config JSON
code block.
3. Click the copy icon over the code block: a "Copied" check state
should appear for ~2s, and pasting should produce the JSON.
4. Check the tab in both light and dark mode.
5. Copying a chat message or a markdown code block in a session should
still work as before.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?

🤖 Generated with [Claude Code](https://claude.com/claude-code)
bcotrim added a commit that referenced this pull request Jul 21, 2026
## Related issues

- Related to [STU-1882](https://linear.app/a8c/issue/STU-1882)

## How AI was used in this PR

Implemented with Claude Code following the auto-save settings patterns
from #4219, using the Save-button-era exploration in #3979 as a
reference. All code reviewed, linted, typechecked, and unit-tested
locally.

## Proposed Changes

- A new **Default site directory** row in Settings shows the current
folder and opens the native folder picker; picking a folder saves
immediately, matching the auto-save behavior of the other preferences.
The value is shared with the classic UI, so changes made in either stay
in sync.

| Light | Dark |
|--------|--------|
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/4e22e5f9-3232-4b93-9514-de67bf116d7d"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/1de28d2a-c9b8-4f91-b181-c8a10e94ac1c"
/> |


## Testing Instructions

1. Enable the new Studio experience and open **Settings**.
2. Verify the **Default site directory** row shows your current default
(or "Choose a folder…" if unset).
3. Click it, pick a folder — the choice should persist immediately (no
Save button), and survive an app restart.
4. Cancel the picker — nothing should change or save.
5. Switch to the classic UI → Preferences: the same directory should
appear there (and vice versa).
6. Create a new site in the agentic UI: the proposed path should live
under the chosen directory.
8. Check the settings screen 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)
bcotrim added a commit that referenced this pull request Jul 21, 2026
## Related issues

- Related to STU-1882 (PR 4 of the Agentic UI application-settings
series)

## How AI was used in this PR

Implemented with Claude Code, adapting the `AccountInformationSection`
from the #3979 exploration to trunk's current auto-save settings layout.
Code, styles, and tests reviewed and verified by me in the running app.

## Proposed Changes

- Adds an **Account** card to the Agentic UI Settings (preferences) tab,
so account state and quick help links are visible right where the rest
of the app configuration lives.
- The card header offers **Docs** and **Report an issue** shortcuts that
open in the browser.
- The sidebar user-menu is intentionally untouched — its dropdown keeps
offering the same actions.

| Light | Dark |
|--------|--------|
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/e33672f7-a2e2-42e8-841e-51f82fb133a9"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/8267c73a-77af-413a-9374-af045be7c415"
/> |
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/fd36d6bb-10e9-489a-af27-2c866f27c12d"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/91e3e19f-ef4f-490b-8662-76c6f717b52f"
/> |

## Testing Instructions

1. Launch Studio with the Agentic UI enabled and open **Settings**.
2. Signed out: the Account card shows the "WordPress.com account"
heading, the login blurb, and a **Log in** button that starts the OAuth
flow.
3. Signed in: the card shows your Gravatar, display name, and email;
**Log out** signs you out and the card flips back to the signed-out
state.
4. Click **Docs** and **Report an issue** — each opens the expected page
in your default browser.
5. Verify the card in both light and dark mode, and at a narrow window
width (the card stacks below 640px).

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?
@bcotrim bcotrim mentioned this pull request Jul 21, 2026
1 task
bcotrim added a commit that referenced this pull request Jul 21, 2026
## Related issues

- Related to STU-1882

## How AI was used in this PR

Implemented with Claude Code from the STU-1882 series plan, porting the
Skills panel from the exploration PR #3975/#3979 and reworking it per
review feedback (toggles instead of Install/Remove buttons, optimistic
updates). All code reviewed and visually verified in light + dark mode.

## Proposed Changes

Adds a **Skills** tab to the Agentic UI application settings, letting
users manage WordPress agent skills globally — applied to all existing
and future sites.

- Each skill is a single row with a toggle: on installs it to every
site, off removes it. State is optimistic, so toggles respond instantly
and roll back if the operation fails.
- An **Install all** button in the panel header installs every remaining
skill at once; it disappears once everything is installed (with reserved
space, so the layout doesn't jump).
- Intro copy explains what skills are, with a Learn more link to the
docs.

| Light | Dark |
|--------|--------|
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/184e9ba6-4b6b-4e18-9f9c-50e1101bb5df"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/fc435d36-f988-4519-a07f-e704afdecaac"
/> |

## Testing Instructions

1. Enable the Agentic UI and open **Settings → Skills**.
2. Toggle a skill on: within a moment, the skill appears under
`<site>/.agents/skills/<skill-id>/` for each site (e.g. `ls
~/Studio/<site>/.agents/skills/`) and its id is added to
`selectedSkills` in `~/.studio/shared.json`.
3. Toggle it off: the files and the `selectedSkills` entry are removed.
4. Click **Install all**: all remaining skills install sequentially;
toggles disable and the button shows a loading state while it runs; the
button disappears when everything is installed (no layout jump in the
header, no flashing on individual toggles).
5. Verify light + dark mode.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?

---------

Co-authored-by: Volodymyr Makukha <nei.css@gmail.com>
bcotrim added a commit that referenced this pull request Jul 22, 2026
## Related issues

- Related to STU-1882

## How AI was used in this PR

Implemented with Claude Code (connector contract, queries, panel UI, and
tests), following the patterns established in #3979 and reviewed by the
author.

## Proposed Changes

Adds a **Usage** tab to the agentic UI settings so users can see what
they're consuming without leaving Studio:

- An **AI credits** section explaining credits are free while Studio
Code is in Alpha, with a full placeholder meter.
- A **Preview sites** section showing "N of M active preview sites" with
a progress bar, backed by the WordPress.com usage endpoint (with a
fallback to counting local snapshots when usage isn't available). An
overflow menu offers **Delete all preview sites**, guarded by a native
confirmation dialog, with an inline error if deletion fails.
- The delete action is disabled when there's nothing to delete, while
loading, when the account can't create previews, or when offline (the
menu label explains the offline case).
- Signed-out users see a prompt to log in to view their usage.

## Testing Instructions

1. Enable the agentic UI and open **Settings → Usage**.
2. Signed out: verify the "Log in to view preview site usage for your
account." prompt and that the Log in button starts the OAuth flow.
3. Signed in with preview sites: verify the "N of M active preview
sites" count and progress bar match `studio preview list`.
4. Open the ⋯ menu → **Delete all preview sites** → verify the native
warning dialog; cancel leaves everything untouched, confirming deletes
all previews and the meter drops to 0.
5. With 0 preview sites (or offline via Network Link Conditioner / Wi-Fi
off): verify the menu action is disabled; when offline the label
explains why.
6. Check the tab in both light and dark mode.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?

---------

Co-authored-by: Antonio Sejas <antonio.sejas@automattic.com>
bcotrim added a commit that referenced this pull request Jul 22, 2026
## Related issues

- Related to STU-1882 (PR 3 of the agentic-UI application-settings
series; ported from #3979)

## How AI was used in this PR

Implemented with Claude Code from a scoped brief: it ported the
`StudioCliSection` from #3979 to the auto-save settings model, extended
the connector contract across the three connectors, and wrote the tests.
Two behaviors were hardened based on manual testing feedback: a "cancel
behind the native dialog leaves the toggle stale" bug (fixed by
refetching the installed state after saving) and standalone-CLI handling
(toggle disabled with an explanatory tooltip). All code was
human-reviewed and manually tested on macOS.

## Proposed Changes

Adds a **Studio CLI** section to the new (agentic UI) application
settings, so users can install or uninstall the `studio` terminal
command without switching back to the classic UI — the last preference
from the classic settings that had no equivalent in the new experience.

- The toggle saves immediately (same auto-save behavior as the rest of
the settings) and links to the CLI docs.
- Install/uninstall can be declined or fail behind native OS dialogs
(permissions, dev-build warnings) while the IPC call still resolves, so
after every change the UI re-checks the actual installed state and the
toggle settles on reality — cancelling the native dialog returns the
toggle to its saved position instead of showing a state that never
happened. Failures surface an inline error in the section.
- When the `studio` command is a standalone (curl) install, the app
never installs over or uninstalls it — previously the toggle would
appear to work but silently no-op. The toggle is now disabled in that
case, with a tooltip explaining that the CLI is managed outside the app
and pointing at `studio uninstall`. This exposes the existing
externally-managed detection from the installation managers over IPC
(`isStudioCliExternallyManaged`).
- The section is hidden where installing a CLI isn't possible: browser
hosts (`studio ui` / hosted) and Windows Store builds. This introduces a
minimal `getAppGlobals()` connector method (platform + Windows Store
flag) for that gating, since this part of #3979 hadn't landed with the
earlier settings PRs.

| Light | Dark |
|--------|--------|
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/40d2aa41-30a9-4e09-adb3-bcac072e856b"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/520e4452-cb26-4eee-b560-4a54108f26e3"
/> |
| <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/7510ed2c-ce07-46b4-a4b4-c970cc3b9506"
/> | <img width="3248" height="2122" alt="image"
src="https://github.com/user-attachments/assets/69dcf281-8ddd-4e67-9a34-081bb188a4eb"
/> |

## Testing Instructions

Note: this PR adds a main-process IPC handler, so a full app restart
(not hot reload) is required.

1. Enable the new Studio experience and open **Settings**.
2. Confirm a **Studio CLI** card appears below **Account**, with the
toggle reflecting whether `~/.local/bin/studio` exists (`where studio`).
3. Turn the toggle **on**, accept the dev-build warning → `studio`
resolves in a new terminal and the toggle stays on.
4. Turn it **off**, accept → the symlink is removed and the toggle stays
off.
5. Toggle again but press **Cancel** in the native dialog → the toggle
returns to its previous position (this was the stale-state bug fixed
here).
6. With a standalone curl-installed CLI (symlink at
`~/.local/bin/studio` pointing outside the app bundle): the toggle shows
on but is disabled. Hovering it shows a tooltip pointing at `studio
uninstall` — it should open quickly (~200ms, faster than the app's
default tooltip delay, since the disabled control gives no other
feedback) and wrap as a compact multi-line bubble (max width 280px)
instead of one long line.
7. Check both light and dark mode, including the toggle's
checked/unchecked, disabled, and focus styles, plus the tooltip in step
6.

## Pre-merge Checklist

- [x] Have you checked for TypeScript, React or other console errors?
@bcotrim bcotrim closed this Jul 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment