Files
Ben GotowandClaude Opus 5 7e80ff06b1 Disable developer mode and devtools in packaged builds (#2968)
* Refuse developer mode and devtools in packaged builds

A packaged release no longer honors --dev or --test: both flags are ignored, so
development mode cannot be switched on from the command line. The developer
console is unreachable as well — the menu items, the renderer command behind the
keybinding, and the IPC method allowlist that could open it are all omitted when
the app is packaged.

The tradeoff for plugin and theme authors is that release builds no longer offer
the developer console or "Run with Debug Flags". Both are still there when
Mailspring runs from a source checkout (npm start) or an unpackaged build, which
is also how npm test and the Playwright suite drive the app.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfkJHohJ9UZzAXheJ76tnC

* Show the startup error in the window when devtools are unavailable

handleSetupError opened devtools so a bootstrap failure's stack was readable.
A packaged build has no console, so paint the stack into the window instead —
selectable, so it can be pasted into a bug report.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfkJHohJ9UZzAXheJ76tnC

* Add a copy button to the startup error screen

The window that shows a bootstrap failure never loaded the app's menus, so it
has no Edit > Copy and the platform copy shortcut does nothing — selectable text
alone wasn't enough to get a stack into a bug report.

Writes through @electron/remote's clipboard: the renderer's own electron module
no longer exports `clipboard`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfkJHohJ9UZzAXheJ76tnC

* Withhold devTools from every window in a packaged build

The menu, keybinding and IPC allowlist gates removed the ways to ask for a
console, but any code in a Mailspring window could still reach its own
webContents through @electron/remote and call openDevTools(). Setting
devTools: false on the webPreferences removes the capability itself, and
Electron then treats those calls as silent no-ops.

Applied to every window the app creates — app windows and their <webview>
guests, the sync status window, both quickpreview windows, print, show
original, open-body-in-new-window and the account log viewer — all gated on
developerToolsAvailable(), so an unpackaged build is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LfkJHohJ9UZzAXheJ76tnC

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-10-11 20:39:38 -05:00
..