# Reference Settings — full reverse-engineer (2026-06-23) > Archived on 2026-07-13. This reverse-engineering snapshot is provenance, not the current Settings contract. Cross-checked by 4 parallel Explore agents on the extracted bundle at `/tmp/qoder-asar/out/renderer/assets/`. This note captures the reference's Settings module so future Maka PRs can align without re-doing the dig. Naming hygiene applies: do not surface the reference product name in code, commits, or end-user copy. --- ## 1. Shell shape Settings is a **full-pane modal** that takes over the workspace area. It is NOT a small overlay sheet. - `role="dialog"` + `aria-modal="true"` - Marker attributes: `data-modal="agents-settings"`, `data-canvas-dialog="true"`, `data-settings-layout="page"` - Outer shell: ``` flex h-full min-h-0 w-full flex-col overflow-hidden bg-background select-none ``` - The rest of the chat surface stays visible behind a subtle backdrop; the modal does not float over a blurred mask — it occupies the canvas. ### Two-rail layout | Region | Width / sizing | Notes | |----------|--------------------------------------|------------------------------------------| | Nav rail | `w-[256px] shrink-0` | Left side, `bg-transparent`, full height | | Content | `flex-1 min-w-0 overflow-hidden` | Right side, scrolls on the inner column | | Gap | `var(--agents-content-area-gap)` 4px | Margin between rail and content plate | Content pane class: `agents-settings-wide-content`: ```css .agents-settings-wide-content { background: var(--agents-content-area-bg); margin: var(--agents-content-area-gap) var(--agents-content-area-gap) var(--agents-content-area-gap) 0; border-radius: var(--agents-content-area-radius); /* 6px */ } ``` Content body inner wrapper (where the page lives): ``` mx-auto min-h-[200px] max-w-3xl pb-16 pt-10 ``` `max-w-3xl` = 48rem / 768px. That's the optical reading column for any settings page body. ### Responsive | Breakpoint | Behavior | |------------|-------------------------------------------------------| | ≥ 1200px | Two-rail (256px rail + content) | | 900–1199 | Two-rail, tightened | | < 900px | Compact: rail collapses; header shows back-arrow + title | --- ## 2. Nav rail The rail is a flat vertical list (no group headings — purely flat). ### Items shown to the end user (in order) 1. `preferences` — **Preferences** (the big aggregator) 2. `profile` — Profile / account 3. `system` — **System** (intentionally near-empty placeholder) 4. `keyboard` — Keyboard shortcuts 5. `vm` — Secure workspace / VM mode 6. `experimental` — Experimental flags 7. `permissions` — System capability toggles 8. `connector` — Integrations / connectors 9. `appshot` — App snapshot (macOS only, gated by `platforms: ["darwin"]`) ### Hidden / dev-only tabs `appearance` (handled via the Preferences page itself), `privacy`, `debug`, `hiddenConnector`, `awareness`, `appUpdate`, `models`, `customModels`, `commands`, `agents`, `worktrees`, `quickpick`, `voiceInput`, `wechat`, `beta`, `channels`, `legokit`, `archived` — all `exposed: false`. Tab registry lives in `index-C02cm0ok.js` around offset ~213400 (look for `Su=[]`). ### Nav-row recipe ```html ``` - Icon library: Lucide - Active state is a **fill** (not border / left-bar), with `--settings-nav-row-selected-bg` = `var(--color-fill-secondary)` - Typography: text-sm (14px), normal weight at rest; no weight bump on active (color/background carry the state) - Padding (educated from sibling rows): `px-4 py-3` - Gap between glyph + label: `gap-3` - Border radius: `squircle-md` (custom corner, not pure rounded-md) --- ## 3. Per-tab content inventory ### 3.1 Preferences (the kitchen sink) Globals offset ~76380–80000. This single tab carries the bulk of the end-user controls: | Control | Type | Notes | |----------------------------------|-----------------|-------------------------------------------------------------| | Language | select | UI locale | | Extended Thinking | switch | Bigger reasoning budget, disables streaming | | Launch at Login (autoLaunch) | switch | Auto-start | | Close Window Behavior | radio / select | Ask / Minimize-to-tray / Quit | | Desktop Notifications | switch | Native OS notifications | | Sound Notifications | switch | Audio on task completion | | Include Co-Authored-By | switch | Adds `Co-authored-by:` trailer to git commits | | Quick Switch (Ctrl/Cmd+Tab) | radio | Workspaces vs Agents | | Auto-advance after archive | radio | Next / Prev / Close | | Default Mode (new agent) | radio | Agent / Plan | | Preview Mode (artifactPreview) | radio | New window / Right sidebar | | Expand tool calls by default | switch | Tool-block collapsed vs expanded | | Show tool steps in IM channels | switch | Whether bot-reply surfaces include tool-call sub-steps | | Tool execution limit | number input | Soft pause when one turn exceeds N tool calls | | Keep System Awake (preventSleep) | switch | While Agent works | | Network Proxy | proxy block | System / Manual; URL input + test button + scheme validation | | Chat Settings (sub-section) | composite | Theme brightness, interface style, glass effects, font face, font size, chat width | **Key insight**: reference does NOT split "system-level" toggles (autoLaunch / preventSleep / notifications / proxy / closeWindowAction) into a separate System tab. They live alongside chat/agent toggles in ONE long Preferences page. ### 3.2 System Title only. No fields. Placeholder for future use. The page exists in the nav but its body is intentionally empty / "to be defined." Confirmed by walking the bundle. ### 3.3 Profile Two sections: - **Avatar**: glyph (first char or emoji) + background color (preset palette of ~11 tones) - **Account & Subscription**: email (copy), Account UID (copy), product UUID (copy), subscription tier (read-only), pricing-page link, logout ### 3.4 Appearance (`appearance` i18n key — actually rendered inside Preferences in production) | Control | Type | Options | |--------------------------|----------|-----------------------------------------------------------------| | Interface theme | select | System pref / Light / Dark / Light Glass / Light Clear (win) / Dark Glass / Dark Clear (win) / Classic Dark / Parchment Light / Parchment Dark / From editors | | Light variant | select | Per-mode theme | | Dark variant | select | Per-mode theme | | Workspace icon in sidebar| switch | Project glyph in the sidebar workspace list | | Always expand to-do list | switch | Full vs compact to-do view | ### 3.5 Keyboard - Search field across all shortcuts - Per-action row with primary + alternative binding - "Reset all to defaults" - Categories: General / Chats (workspaces) / Agents - General: Show shortcuts / Open settings / Toggle sidebar / Undo archive - Chats: Quick switch - Agents: Create new task / Search all tasks / Search in current task / Prev tab / Next tab / Focus input / Toggle input focus / Send / New line ### 3.6 VM (Secure workspace) Brief description: "dedicated space on your computer for running tasks — faster, more reliable, on-device." Enable/disable toggle. ### 3.7 Experimental Beta feature toggles. Per-flag rows; roster managed in the renderer component, not visible as a literal array in the bundle. ### 3.8 Permissions "System permissions QoderWork needs on this Mac." Capability rows (filesystem / network / mic / screen recording / accessibility) with "granted / not granted" status and a "request" CTA. ### 3.9 Connector Integrations with external apps. Builtin connectors / market connectors / custom connectors. Each row: brand glyph, status, enable toggle, "configure" button. ### 3.10 App Snapshot macOS-only. Frontmost-app screenshot capture for chat context. Needs Accessibility + Screen Recording perms. Permission status row + capture preview. --- ## 4. Repeating visual patterns inside a page Reference does NOT use bordered card containers around groups of controls. The default presentation is a **flat row list inside the `max-w-3xl` column**. ### 4.0 Content-column padding — WAWQAQ msg `2c810f2d` 2026-06-23 WAWQAQ called out the left/right whitespace as visibly wider in reference than in Maka. Concrete numbers from a second RE pass: - The content column is `mx-auto max-w-3xl pt-10 pb-16` (= 768px wide, 40px top, 64px bottom). No explicit `px-N` is applied inside the column — the side whitespace comes from the column NOT filling the right pane. - At the typical desktop window width (~1280px viewport, 256px nav rail), the right pane is ~1024px. A 768px centered column leaves ~128px of whitespace on each side. That's the "wider padding" effect. - Inside each row, padding is `px-5 py-4` (20px / 16px). Rows do NOT carry their own border, background plate, or shadow — separation is pure spacing. **Maka delta found 2026-06-23**: - `.settingsStructuredPage` had `gap: 16px` but NO `max-width` / `margin: 0 auto` — rows stretched to fill the right pane. Fixed to `max-width: 768px; margin: 0 auto; padding: 40px 24px 64px`. - `.settingsFormRow` had `border-bottom: 1px solid var(--border)` and `padding: 6px 0` — both wrong. Reference uses spacing-only and `px-5 py-4`. Fixed to `padding: 16px 20px`, no border-bottom. - `.settingsRow` was sharing `.providerCard` chrome (bordered, tinted, lifted). Provider cards keep their chrome (they ARE cards); `.settingsRow` flattened to a flex row. - Label was 12px / 600 weight; bumped to 14px / 500. Sub-text 11px → 12px. Matches reference `text-sm font-medium` + `text-xs text-text-quaternary`. ### 4.1 Row ``` flex items-center gap-3 px-4 py-3 /* group */ ├── label column │ ├── truncate text-sm font-medium text-text (title) │ └── mt-0.5 truncate text-xs text-text-quaternary (hint) └── control (right-aligned) ``` - No border / no card background per row by default - Visual separation between rows is achieved by spacing alone (no border-bottom) - Hover state moves via the parent `.group` (e.g., shows a kebab menu) ### 4.2 Sub-section heading inside a tab ``` text-sm font-semibold text-text mb-4 ``` ### 4.3 Switch - ~20×20px wrapper, `rounded-md` - On: `bg-primary/20 ring-1 ring-primary/40 scale-[0.97]` - Off: subtle gray fill (`bg-gray-100 dark:bg-neutral-600`) with inset shadow - Transition: `transition-all duration-200` ### 4.4 Input ``` w-full px-3 py-2 text-sm bg-background border rounded-md border-border-tertiary/80 focus:outline-none focus:ring-2 focus:ring-primary/50 ``` - Error: `border-error-border` - Password / icon suffix: `pr-9` ### 4.5 Button - Primary: `bg-primary text-primary-foreground` - Secondary: `bg-muted text-foreground` - Outline: `border border-border text-foreground hover:bg-muted` - Destructive: `text-error hover:bg-error-bg` - Icon-only sizes: `size-7 rounded-md` (28px square), `size-8 rounded-full` (32 round) ### 4.6 Chip / badge ``` rounded bg-fill-tertiary px-1.5 py-0.5 text-[10px] font-medium text-text-tertiary ``` ### 4.7 Content scroll The page body owns its scroll: ``` min-h-0 flex-1 overflow-y-auto scrollbar-none ``` Custom scrollbar is hidden. The inner content column has `pb-16` bottom padding so the last row never hugs the modal edge. --- ## 5. Tokens used inside Settings | Token | Value | |----------------------------------|----------------------------------------------------------------| | `--agents-content-area-bg` | `var(--color-bg-container)` | | `--agents-content-area-gap` | `4px` | | `--agents-content-area-radius` | `12px` | | `--agents-layout-bg` | `var(--surface-canvas)` (flat neutral shell — **DO NOT** paint a 172deg gradient here, see warning below) | | `--settings-nav-row-selected-bg` | `var(--color-fill-secondary)` | > ⚠️ **DO NOT paint a 172deg gradient on the layout/shell background.** > > The RE notes here historically said `--agents-layout-bg` is > `linear-gradient(172deg, var(--color-fill-tertiary) 19.61%, var(--color-bg-container) 81.35%)`. That value was an **artifact of the bundle CSS we copied**, not what the live reference product actually paints. > WAWQAQ has called this out four times in a row (msgs `1e693dee` / > `5d3b10e5` / `486b5611` / `4a1b8c13`) — "谁让你他妈的用渐变的啊? > 参考实现就没有啊". Every time we re-added the gradient because > some atlas/RE note claimed it was canon. > > Source-side enforcement: `apps/desktop/src/main/__tests__/chat-chrome-no-gradient-contract.test.ts` fails if any of `.appFrame`, `html[data-os="darwin"] .maka-session-panel`, or the floating panel reintroduces a gradient / border-right / smaller-than-12px radius. If a future RE iteration finds a *new* place where the reference product genuinely does paint a gradient, please update the contract test with the new exception in the same PR, don't silently lift the assertion. > > Use a **flat neutral shell** (`var(--surface-canvas)`) behind the > white content surface. Do not collapse the shell to the same white > as the content card: that removes the visible lower radius and lets > the bug come back even without a border or gradient. > > Rendered-pixel enforcement: after capturing > `sidebar-long-sessions/light-1280-motion`, run > `npm --workspace @maka/desktop run screenshots:chat-chrome:check`. > It verifies the actual PNG has a visible shell/content delta, no dark > one-pixel seam, and readable bottom surface corners. > > Surface radius is **12px** (was historically noted as 6px). 6px was > geometrically there but optically invisible — bottom corners of the > floating content card didn't read against a same-color shell. Color tokens consumed inside settings: - `--color-text` (primary text) - `--color-text-secondary` - `--color-text-tertiary` (hints) - `--color-text-quaternary` (de-emphasized) - `--color-border` (strong divider) - `--color-border-tertiary` (input borders) - `--color-fill-secondary` (active row fill) - `--color-fill-tertiary` (chip background) - `--color-bg-container` (page surface) - `--color-primary`, `--color-primary/20`, `--color-primary/40` (focus, switch on, ring) --- ## 6. Routing, state, behaviors - Active tab is stored in the URL: `?view=settings&tab=preferences`. No localStorage for the active tab — round-tripping the URL restores the page. - Deeplink scheme: external triggers can deep-link to a specific tab: `qoder-work://settings/preferences`. Maka's equivalent could be `maka://settings/`. - Default tab when opened with no `tab` param: `preferences`. - Modal close is escape-key + click-outside backdrop; focus is trapped inside `[role="dialog"]`. - Telemetry: `settings_tab_view` fires when a tab is selected; `settings_heartbeat` ticks every 300s with a feature-flag snapshot. - Saves: per-control, no explicit batch / "save" button visible. Renderer dispatches IPC writes per change; toasts surface failures. --- ## 7. Implications for Maka This RE matters because WAWQAQ's ask — "add a 系统设置 section" — is ALMOST CORRECT but the deeper truth from the reference is: **Reference does NOT scatter system-level toggles into their own narrow pages.** It collapses them into ONE long `Preferences` page, and reserves a near-empty `system` tab for future expansion. Maka today has 17 nav items in Settings (some of them — `网络`, `健康`, `开放网关`, `语音模型`, `每日回顾`, `记忆` — are single-purpose pages that mirror exactly the "wasteful single-purpose page" pattern WAWQAQ flagged for `网络`). The closer-to-reference move is to **consolidate**, not add another section. Concrete proposal: ### Proposed consolidated Maka Settings nav (target: ~9 items) | Group | Item | Holds | |-------------|-------------|------------------------------------------------------------| | 基础 | 通用 | Aggregator: 隐身模式, 启动行为, 新对话模式, 默认模型, 通知, 网络代理, 保持唤醒, 自动更新, 关闭窗口行为 | | 基础 | 外观 | 个性化 + theme + palette + font (merge 主题 + 个性化) | | AI | 模型 | Provider connections + OAuth + per-model config | | AI | 记忆与回顾 | Merge `记忆` + `每日回顾` | | AI | 语音与网关 | Merge `语音模型` + `开放网关` | | 集成 | 机器人对话 | Telegram / WeChat / Slack bot config | | 集成 | 联网搜索 | Tavily provider config | | 数据/系统 | 数据 | Export / import / wipe | | 数据/系统 | 权限与能力 | Capability toggles + filesystem allowlist | | 其他 | 健康 | Diagnostic / status / logs | | 其他 | 关于 | Version + license + acknowledgements | Specifically: **drop the standalone `网络` page; move proxy into 通用**. That's the minimum WAWQAQ asked for, but ride the same PR to merge `主题 + 个性化` into `外观` per reference, since 外观 is reference's canonical name for that grouping. ### Settings page-body recipe to copy For ANY settings page body, switch to: - `max-w-3xl mx-auto pt-10 pb-16` inner column - Flat row list (`flex items-center gap-3 px-4 py-3` per row) - `text-sm font-medium` title + `text-xs text-text-quaternary` hint - No bordered card around row groups - Sub-section heading: `text-sm font-semibold mb-4` - Switches / inputs / chips per §4 above This is the visual "reference 真好看" pattern WAWQAQ asked us to study — the page is uncluttered because rows have NO chrome, only spacing. --- ## 8. PR plan suggestion Two PRs, ship in sequence: **PR-SETTINGS-ALIGN-IA-0** — Information architecture consolidation - Drop standalone `网络` page; fold proxy into a "网络代理" sub-section of 通用 - Merge `主题 + 个性化` → `外观` - Merge `记忆 + 每日回顾` → `记忆与回顾` - Merge `语音模型 + 开放网关` → `语音与网关` - Update SETTINGS_NAV + section render switch + all deeplinks (`maka://settings/...`) - Pin via contract test: nav id allowlist + deeplink mapping **PR-SETTINGS-PAGE-BODY-0** — Visual pattern conversion - Convert every page body from `settingsStructuredPage / SettingRow` card chrome to the flat-row + `max-w-3xl` recipe - Add `.maka-settings-row`, `.maka-settings-page` primitives in styles.css - Sweep all SettingsPage components to use them Tackle them in this order so the IA stops shifting while we're polishing the bodies.