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.
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:
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.
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.
Defaults, Spokes, MCP, Roadmap cross to iOS intact. Codex auth crosses too, folded into Defaults.
Costs, Heartbeats, Automations, Usage never shipped to iOS — and that's the correct call. All four are desktop authoring/analytics.
Server config (host/port) exists only on iOS — a native client has to be told which backend to reach.
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 tab | What it controls | On iOS | Verdict |
|---|---|---|---|
| 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).
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" | Web | iOS | Notes |
|---|---|---|---|
| Default agent template balanced/builder/research | ✓ | ✓ | Parity. Segmented picker on iOS, dropdown on web. |
| Theme system/light/dark | ✓ | ✓ | Parity. Both persist to backend key dark_mode; web also writes localStorage ai_library_dark_mode_preference. |
| Include core thread context | ✓ | ✓ | Parity. |
| Per-skill default mode | ✓ | ✓ | Parity — a potentially long list of pickers on both. |
| Per-tool default approval mode | ✓ | ✓ | Parity — another long matrix of pickers. |
| Allow tools / task-writes / workspace-writes / subagents (4 global toggles) | per-thread | ✓ global | iOS 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 toggles | ✓ | ✗ | Missing on iOS. Set-once, rarely-changed — low priority to add. |
| Desktop notifications toggle | ✓ | ✗ | Web-only as built (browser Notification API), but the concept is exactly what mobile needs — see §5. |
| Backend server config host / port | n/a | ★ | iOS-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 · remove | own tab | ✓ here | On web this is the standalone Codex tab; iOS crams it into the bottom of Defaults. Reorganize (§5). |
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.
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.
window.innoisoDesktop.*); can't exist on iOS.ServerConfigView). A native client must know its backend endpoint. Persisted to UserDefaults, defaults to api.innoiso.ai. keep, but buryThere 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
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.
* 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.
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.
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.
The full list, grouped by verdict. This is the checklist a mobile build should be measured against.
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.
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.
api.innoiso.ai; 99% of users never touch it. It shouldn't sit next to Theme.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.
Where settings are stored differs by platform and even by setting — worth knowing before any consolidation, plus a few loose threads the audit surfaced.
| Store | Web | iOS | Examples |
|---|---|---|---|
| Backend user_settings | ✓ | ✓ | workspace_activation_defaults, dark_mode, cloud instructions, notifications |
| Local device store | localStorage | UserDefaults (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/thread | UserDefaults key/thread | thinking 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.
TopHeader.vue carries a full theme dropdown but is imported nowhere — a legacy component. The live theme control is the Defaults tab.
sidebar_pinned is read & normalized in the web store but has no UI writer. Either wire it or remove it.
iOS Spokes has a This device (local) button gated #if !os(iOS) — it never renders on iPhone/iPad. Dead code on the mobile target.
Sources/App/AppSettings.swift is not user settings — it's the typography token system. Worth a rename to avoid future confusion.
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: