Title: Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app by DragonnZhang · Pull Request #69 · modelstudioai/openwork · GitHub
Open Graph Title: Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app by DragonnZhang · Pull Request #69 · modelstudioai/openwork
X Title: Add interface zoom (⌘+ / ⌘- / ⌘0) to scale the whole app by DragonnZhang · Pull Request #69 · modelstudioai/openwork
Description: Closes #68 What & why Every desktop app OpenWork is benchmarked against — Claude Desktop, VS Code, Codex/ChatGPT desktop, Slack, Discord — exposes an interface zoom that scales the whole UI up or down via the platform-standard ⌘+ / ⌘- / ⌘0 (Ctrl on Windows/Linux). OpenWork had none: grep -rn "setZoomLevel\|zoomFactor\|webFrame\|zoom" apps/electron/src found nothing, and there was no such binding in the action registry. Users on high-DPI displays (or who want to fit more on screen) had no way to resize the whole app. This adds an app-wide interface-zoom preference — frontend-only, no backend / qwen-code change. Distinct from any per-surface "chat text size" / "conversation width" work: interface zoom scales the entire renderer (sidebar, navigator, chat, settings, dialogs, composer), not just message text. How context/ZoomContext.tsx (new) — ZoomProvider, mirroring the merged ReduceMotionProvider. Owns a discrete zoom factor from a Chrome-like step ladder (50%–200%), applies it by setting document.documentElement.style.zoom (a Chromium-native property that scales the whole tree, including portalled dialogs), and clears the inline style at 100%. Persists in localStorage (craft-zoom-level) via the existing lib/local-storage.ts helper — no IPC, no config.json. actions/definitions.ts — three new View actions: view.zoomIn (mod+=), view.zoomOut (mod+-), view.zoomReset (mod+0). Registering them means they appear automatically in the Command Palette (⌘K) and the Settings → Keyboard Shortcuts reference. components/ZoomHotkeys.tsx (new) — a render-null bridge mounted inside ActionRegistryProvider that wires those actions to the provider via useAction. main.tsx — mounts ZoomProvider at the renderer root (inside ReduceMotionProvider). pages/settings/AppearanceSettingsPage.tsx — a Zoom stepper (− / percentage / + with reset) in Appearance → Interface, for discoverability and mouse-only users. lib/local-storage.ts — new zoomLevel key. actions/action-i18n.ts + locales/*.json — 5 new i18n keys across all 7 locales. e2e/assertions/zoom.assert.ts (new) — CDP assertion (below). Verification (DoD) Run in this PR's sandbox; all checks that don't require launching Electron pass with zero delta vs main: bun run typecheck:all — no new errors. apps/electron reports exactly the 11 pre-existing errors (auto-update.ts owner/repo, a settings-default-thinking test tuple, two test files importing vitest) — none in files this PR touches; all other packages clean. bun test — the failing-test set is byte-for-byte identical to a clean main run in the same environment: 56 failing tests on both, diff empty. This change adds zero new failures. (The raw N fail line is order-dependent when the whole suite runs unisolated; the deterministic signal is the failing-test set.) bun run lint:i18n:parity — OK (1549 keys per locale, 7 locales). The 5 new keys are in every locale. eslint on all changed files — 0 errors. The new files add no warnings; the pre-existing no-localstorage / exhaustive-deps warnings are unchanged. Renderer build (bun run build:renderer, where this change lives) — ✅ built cleanly. CDP assertion transpiles (bun build e2e/assertions/zoom.assert.ts) — ✅. CDP e2e assertion (zoom.assert.ts) Drives the real built app over CDP entirely in the draft/no-session state (Settings only, no backend): Open Settings → Appearance → Interface; the Zoom control renders at 100%, with no inline zoom style on . Click Zoom in → the display reads 110%, document.documentElement.style.zoom === '1.1', and localStorage["craft-zoom-level"] is 1.1 — proving it applies and persists, not merely renders. Click Reset → back to 100%, the inline zoom style is cleared, and the persisted value returns to 1. ⚠️ Local CDP run was blocked by this sandbox's egress policy, not by the feature. The Electron binary download (GitHub release host) returns 403 from the org egress proxy — its allowlist covers npm/pypi/crates but not GitHub release hosts — so Electron can't be launched here (xvfb is present; only the binary fetch fails; the proxy README says to report such policy denials, not route around them). The assertion transpiles and is included so CI / a reviewer can run bun run e2e in an environment with normal network access. Everything that doesn't require launching Electron (typecheck, unit tests, i18n parity, lint, renderer build) passes with zero delta vs main. This is the same documented environment limitation as the merged reduce-motion PR (#51). Part of the autonomous desktop-feature loop (loop-bot). 🤖 Generated with Claude Code Generated by Claude Code
Open Graph Description: Closes #68 What & why Every desktop app OpenWork is benchmarked against — Claude Desktop, VS Code, Codex/ChatGPT desktop, Slack, Discord — exposes an interface zoom that scales the whole UI up ...
X Description: Closes #68 What & why Every desktop app OpenWork is benchmarked against — Claude Desktop, VS Code, Codex/ChatGPT desktop, Slack, Discord — exposes an interface zoom that scales the whole UI...
Opengraph URL: https://github.com/modelstudioai/openwork/pull/69
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:75c23515-2788-6d72-c9b3-6055132d9284 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | ECF2:2818E8:1170586:177016D:6A52A1CF |
| html-safe-nonce | b7b8fbd7c93d60a3175f1eb91bdcf4dbd49d0a8652b4d03cbff57160207b0046 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFQ0YyOjI4MThFODoxMTcwNTg2OjE3NzAxNkQ6NkE1MkExQ0YiLCJ2aXNpdG9yX2lkIjoiNTI2NzE3MjE2MDcxNjMxNzEzNSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | d4ee966b2190fe05a17d80857e745cda3922ff8b9779100f67d07e56fc8bd912 |
| hovercard-subject-tag | pull_request:4011056099 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/modelstudioai/openwork/pull/69/files |
| twitter:image | https://avatars.githubusercontent.com/u/52599892?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/52599892?s=400&v=4 |
| og:image:alt | Closes #68 What & why Every desktop app OpenWork is benchmarked against — Claude Desktop, VS Code, Codex/ChatGPT desktop, Slack, Discord — exposes an interface zoom that scales the whole UI up ... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| diff-view | unified |
| go-import | github.com/modelstudioai/openwork git https://github.com/modelstudioai/openwork.git |
| octolytics-dimension-user_id | 283556804 |
| octolytics-dimension-user_login | modelstudioai |
| octolytics-dimension-repository_id | 1256697754 |
| octolytics-dimension-repository_nwo | modelstudioai/openwork |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1256697754 |
| octolytics-dimension-repository_network_root_nwo | modelstudioai/openwork |
| turbo-body-classes | logged-out env-production page-responsive full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 07a982c1d40157c619b364352b704c3ce66bb332 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width