Cross-platform settings audit · web ↔ iOS

Which settings actually
belong on mobile.

The web app exposes 10 settings tabs; iOS ships 4. This audit maps every setting on both platforms, names what's shared, web-only, and native-only — then applies a least-bloat lens to decide what the phone should really carry. The short version: iOS already dropped the right tabs, but its one remaining tab is overloaded, and it's missing the single setting mobile needs more than the desktop.

10
web settings tabs
(8 functional + guide/roadmap)
4
iOS settings tabs
+ account + native server config
4
functional web tabs correctly dropped from iOS
1
setting mobile needs that iOS lacks (notifications)
How to read this document

Two color systems run through the diagrams. Platform is coded in each platform's own real brand primary — web in its blue (--primary-color #2f5fba), iOS in its teal (brand #0d9488). Separately, every setting carries a verdict about whether it belongs on the phone:

WEB iOS KEEP ADD DEFER NATIVE
  • KEEPOn mobile and correct to be there — a real on-the-go need with light interaction cost.
  • ADDNot on mobile, but should be — the phone has a genuine need the current build doesn't meet.
  • DEFERDeliberately keep off mobile — authoring- or analysis-heavy; belongs on desktop where the keyboard and screen are.
  • NATIVEExists only because iOS is a native app — no web equivalent is needed (e.g. telling the app which backend to talk to).
01 · the big picture

The settings map

Both platforms use the same architecture — a SettingsTab enum driving a detail pane. Web declares ten tabs; iOS declares four. Here is every tab and where it lands (or doesn't) on the phone.

WEB / DESKTOP /settings · 10 tabs iOS WorkspaceSettingsView · 4 tabs ▲ NOT ON MOBILE — desktop authoring / analytics 1 · Defaultsagent · theme · skills · tools · notifications 2 · Spokesconnected devices · pairing 3 · CodexChatGPT / OpenAI account auth 4 · Costscodex cost analysis report 5 · MCPserver management · custom · hot 6 · Heartbeatstrigger hooks · webhooks · fanout 7 · Automationsscheduled turns · cron 8 · Usagecredits · metrics · links out 9 · Guidestatic FAQ (no settings) 10 · Roadmapstatic planning display Defaults + Codex account folded inbackend · defaults · skills · tools · auth Spokestarget device · pairing · devices MCPservers · custom · config sheet ★ Server config (native only)host / port — modal off Defaults account — Log out Roadmapstatic planning display no web peer

Reading the lines. Solid green = present on both. Dashed teal = present on iOS but folded into another screen (web's standalone Codex tab becomes a section inside iOS Defaults). Dashed amber ✗ = the web tab stops at the desktop and never crosses to mobile. Violet = a mobile-native surface with no web counterpart.

4 kept

Defaults, Spokes, MCP, Roadmap cross to iOS intact. Codex auth crosses too, folded into Defaults.

4 dropped

Costs, Heartbeats, Automations, Usage never shipped to iOS — and that's the correct call. All four are desktop authoring/analytics.

1 native

Server config (host/port) exists only on iOS — a native client has to be told which backend to reach.

02 · the mapping

Tab by tab, web → iOS

Every top-level web settings tab, what it controls, where it lands on iOS, and the least-bloat verdict. Order follows the web router: defaults · spokes · codex · costs · mcp · heartbeats · automations · usage · guide · roadmap.

Web tabWhat it controlsOn iOSVerdict
1 · Defaults
/settings
Global defaults applied to new threads: agent template, theme, core-context toggle, per-skill & per-tool modes, plugin toggles, cloud-chat custom instructions, desktop notifications, log out. Defaults
Present, but overloaded — see §3. Missing custom instructions, plugins, notifications.
KEEP
2 · Spokes
/settings/spokes
Manage connected "spoke" devices (remote Codex hosts): pair, rename, ping, read logs, remove; choose the active target device. Spokes
Present. Target-picker + pairing + device list. This device (local) is compiled out on iOS.
KEEP
3 · Codex
/settings/codex
Connect / disconnect the ChatGPT / OpenAI account (OAuth or device-code); shows 5-hour & weekly usage meters. Defaults ▸ codex account
Folded into Defaults. Connect/paste-token/remove present; usage meters not ported.
KEEP
relocate — see §5
4 · Costs
/settings/costs
Ephemeral cost-analysis report generator: pick targets, project-path filters, date range, per-target limit; breakdown by project/model/thread. Absent
Not on iOS.
DEFER
5 · MCP
/settings/mcp
Add / connect / delete MCP servers; add "hot" recommended servers; author custom servers (name, slug, URL, auth type, discovery URL, description). MCP
Present with near-full parity, including the custom-server form and per-server config sheet.
KEEP
trim authoring — §5
6 · Heartbeats
/settings/heartbeats
Author trigger-hooks: adapters, transports, poll intervals, push webhooks, fanout, attached automations, raw metadata JSON. The most complex surface in the app. Absent
Not on iOS.
DEFER
7 · Automations
/settings/automations
Schedule recurring Codex/web thread turns: cron schedule, thread type, target spoke, model, effort, approval behavior, prompt body. Absent
Not on iOS.
DEFER
8 · Usage
/settings/usage
Read-only metrics (active threads, messages, credits) and links out to account settings & cost analysis. Absent
Not on iOS.
DEFER
9 · Guide
/settings/guide
Static FAQ accordions. No configurable setting. Absent
Not on iOS.
DEFER
link out
10 · Roadmap
/settings/roadmap
Static, hardcoded roadmap viewer. No configurable setting. Roadmap
Present — same static content, hardcoded in Swift.
DEFER
questionable keep

Note on verdicts vs. reality. A DEFER verdict on an absent row means iOS made the right choice by leaving it off. The only mismatch: Roadmap is present on iOS but arguably shouldn't be a first-class settings tab on either platform (it's marketing, not configuration).

03 · the overloaded tab

Inside "Defaults" — where the divergence really lives

The tab counts hide the real story. iOS kept the Defaults tab, but it quietly turned it into a catch-all: backend configuration, global agent defaults, skill & tool matrices, and the entire OpenAI account section all live on one scrolling screen. Meanwhile three web Defaults items never made the trip.

Setting inside "Defaults"WebiOSNotes
Default agent template balanced/builder/researchParity. Segmented picker on iOS, dropdown on web.
Theme system/light/darkParity. Both persist to backend key dark_mode; web also writes localStorage ai_library_dark_mode_preference.
Include core thread contextParity.
Per-skill default modeParity — a potentially long list of pickers on both.
Per-tool default approval modeParity — another long matrix of pickers.
Allow tools / task-writes / workspace-writes / subagents (4 global toggles)per-thread✓ globaliOS surfaces MORE here. Web exposes these permission toggles only in per-thread Thread Controls; iOS promotes them to global Defaults.
Cloud-chat custom instructions (8000-char system prompt)Missing on iOS. Affects every cloud chat, including mobile ones — so there's a real argument to expose it (read-mostly).
Plugin enable/disable togglesMissing on iOS. Set-once, rarely-changed — low priority to add.
Desktop notifications toggleWeb-only as built (browser Notification API), but the concept is exactly what mobile needs — see §5.
Backend server config host / portn/aiOS-native. The web app is served by its backend; a native app must be told where the backend is.
Codex / OpenAI account status · connect · token · removeown tab✓ hereOn web this is the standalone Codex tab; iOS crams it into the bottom of Defaults. Reorganize (§5).
Core finding iOS "Defaults" is doing five jobs

Backend config, global agent behavior, skill/tool policy matrices, notifications-shaped gaps, and account auth are all one screen. On a phone that's a long, mode-switching scroll. The fix isn't to remove settings — it's to split this one tab into a few small, purpose-named ones (§5), which also makes room to add the notification toggle mobile actually wants.

04 · exclusives

What's exclusive to each platform

Separating the settings that exist on only one side — and why they're one-sided — is what tells you whether an omission is a gap or a good decision.

WEB-ONLY

Only on web/desktop

  • Costs, Heartbeats, Automations, Usage tabs — heavy authoring & analytics. correct to omit
  • Guide (static FAQ) — belongs behind a help link, not a settings tab.
  • Cloud-chat custom instructions — affects mobile chats too; a candidate to add.
  • Plugin toggles — low-frequency workspace config.
  • Spoke "connect this computer" — Electron-only (window.innoisoDesktop.*); can't exist on iOS.
  • Account / Team / Admin routes (name, email, password, members, roles) — separate web pages, not the settings panel even on web.
  • Code sidebar ordering — a desktop-workspace nicety.
iOS-ONLY

Only on iOS (native necessities)

  • Server config — host / port (ServerConfigView). A native client must know its backend endpoint. Persisted to UserDefaults, defaults to api.innoiso.ai. keep, but bury
  • "Check backend now" / connection health — native connectivity affordance web never needs.
  • 4 global permission toggles in Defaults — iOS promotes what web keeps per-thread.
  • Composer "web search" toggle — present in the iOS composer; not surfaced the same way on web.
Notably absent on iOS

There is no notifications settings UI at all — no @AppStorage anywhere in the app, and push is requested silently at the OS level. For a phone, that's the one meaningful hole. ADD

05 · the decision lens

Which settings belong on a phone?

A settings screen bloats when it inherits everything the desktop has. The least-bloat test is two questions: does someone need to change this while mobile? and how heavy is the interaction? Plot every setting on those two axes and the mobile set falls out naturally.

AUTHORING WEIGHT → (light · glance/tap ————— heavy · forms/typing) MOBILE NEED → (low ————— high) BELONGS ON MOBILE MOBILE — BUT SIMPLIFY OPTIONAL / LOW PRIORITY DESKTOP ONLY Theme Log out Model default Codex connect Notifications * Spoke target MCP: connect / manage existing Spoke pairing MCP: author custom server Agent template Include core context Plugin toggles Custom instructions Server host/port ★ Per-skill / per-tool matrices Costs analysis Automations (cron) Heartbeats Team / Admin

* Notifications is the telling outlier — high mobile need, light interaction, yet currently absent on iOS. Everything in the bottom-right (heavy authoring, low on-the-go need) is exactly what iOS already declined to build. Points colored by verdict: keep, add, defer, native.

The principle

Mobile is a consumption & light-steering device. You'll flip a theme, connect an account, point Codex at your desk machine, approve a run, and want a push when it's done. You will not hand-write an 8000-character system prompt or a cron expression on a phone keyboard.

The corollary

Don't mirror the desktop's information architecture. Parity of capability ≠ parity of settings surface. The heavy authoring surfaces should stay one deep-link away ("Manage on web"), not be rebuilt as cramped mobile forms.

06 · the catalog

Verdict for every setting

The full list, grouped by verdict. This is the checklist a mobile build should be measured against.

KEEP — on mobile, correct
  • Theme (system / light / dark)
  • Log out / account session
  • Codex / ChatGPT account connect & disconnect
  • Model default (composer)
  • Spoke target selection (which device runs Codex)
  • Auto-review approvals toggle
  • MCP — connect / disconnect existing servers
  • Agent template (light; keep but demote)
ADD — mobile needs it, iOS lacks it
  • Notifications toggle — top priority. Push arrives via FCM; give users control before it ships loud.
  • Cloud-chat custom instructions (read-mostly; affects mobile chats)
  • Codex usage meters (read-only; genuinely useful on the go)
  • Plugin toggles (low priority)
NATIVE — keep, but out of the way
  • Server host / port — move under an "Advanced" disclosure
  • Backend health check
DEFER — leave off mobile (link to web where useful)
  • Heartbeats (all of it)
  • Automations (cron scheduling)
  • Costs analysis reports
  • Usage metrics (link out)
  • Guide / FAQ (help link)
  • Per-skill / per-tool matrices (collapse or defer)
  • Team management
  • Account name / email / password
  • Administration (super-admin)

Custom-server authoring in MCP is a borderline DEFER — keep the ability to connect existing servers on mobile, but the multi-field create form is a desktop task.

07 · the recommendation

A cleaner mobile settings structure

The goal isn't fewer capabilities — it's a smaller, more scannable surface. Split the overloaded Defaults tab into a handful of purpose-named groups (the native iOS Settings idiom), bury the developer-only pieces, and add the one thing mobile is missing.

TODAY

4 tabs, one of them a catch-all

  • Defaults — backend · agent · theme · permissions · skills · tools · Codex account5 jobs, 1 screen
  • Spokesdevice mgmt
  • MCPfull CRUD
  • Roadmapstatic
  • account — Log out
  • Server config — modal off Defaultsexposed
PROPOSED

Grouped, scannable, one addition

Account
  • Account — email · Log out · Connected accounts (Codex/ChatGPT + usage meters)
Preferences
  • Appearance — Theme
  • Notifications — new setting (push controls)
  • Chat defaults — agent template · model · core context custom instructions optional
  • Permissions — 4 allow-toggles · skill/tool matrices behind "Advanced"
Connections
  • Spokes — target + pairing
  • MCP servers — manage; author on web
Advanced / About
  • Advanced — Server host/port · health check
  • Manage on web — Usage · Team · Billing · Automations
  • Help & Roadmap — demoted from a tab to About

What actually changes

  • 1Split "Defaults" into Appearance, Chat defaults, and Permissions. Same settings, three short screens instead of one long one.
  • 2Move Codex account into an "Account" group as "Connected accounts," and port the read-only usage meters while you're there.
  • 3Add a Notifications screen. This is the one genuine gap — and it's more important on mobile than it ever was on web. Wire it to the FCM push work already on the roadmap.
  • 4Bury Server host/port under "Advanced." It defaults to api.innoiso.ai; 99% of users never touch it. It shouldn't sit next to Theme.
  • 5Collapse the skill/tool matrices behind a disclosure and keep the 4 coarse permission toggles up front.
  • 6Keep deferring Costs, Heartbeats, Automations, Usage. Replace them with a single "Manage on web" deep-link row. Demote Roadmap from a tab to About.
Net effect

The phone gains one setting it was missing (notifications), loses zero capability, and trades a single overloaded tab for a handful of glanceable ones — the native iOS Settings shape users already expect. The desktop stays the home for authoring and analytics.

08 · appendix

Persistence & flagged issues

Where settings are stored differs by platform and even by setting — worth knowing before any consolidation, plus a few loose threads the audit surfaced.

Where settings live

StoreWebiOSExamples
Backend user_settingsworkspace_activation_defaults, dark_mode, cloud instructions, notifications
Local device storelocalStorageUserDefaults (no @AppStorage anywhere)selected model, server host/port (iOS), per-thread auto-review, drafts
Per-thread (backend)Thread Controls runtime/skills/tools/memory
Per-thread (local)localStorage key/threadUserDefaults key/threadthinking effort (web), model/auto-review map (both)

Consolidation watch-out: theme is dual-persisted on web (backend dark_mode + localStorage ai_library_dark_mode_preference); iOS persists theme to the backend only. Per-thread model/thinking/auto-review are local-only on both — they won't follow a user across devices.

Loose threads to clean up

Dead web control

TopHeader.vue carries a full theme dropdown but is imported nowhere — a legacy component. The live theme control is the Defaults tab.

Orphaned key

sidebar_pinned is read & normalized in the web store but has no UI writer. Either wire it or remove it.

Compiled-out control

iOS Spokes has a This device (local) button gated #if !os(iOS) — it never renders on iPhone/iPad. Dead code on the mobile target.

Misleading filename

Sources/App/AppSettings.swift is not user settings — it's the typography token system. Worth a rename to avoid future confusion.

Settings that live outside "/settings" (both platforms)

Several user-configurable controls aren't in the settings panel on either platform — they're per-thread or in the composer. These already have rough parity and are not part of the settings-surface bloat question, but they matter for a full picture:

  • Composer: model picker (both) · thinking/effort level (web; verify iOS) · web-search toggle (iOS) · auto-review (both) · cwd + target spoke (both, Codex mode).
  • Thread Controls panel (per-thread runtime/skills/tools/memory/context): present on both, backend-persisted per thread.
  • Pin / unpin thread, mode switch (Chat ↔ Codex): both.