From 76f2018b251e7737186132f1340580e10af44a82 Mon Sep 17 00:00:00 2001 From: Bo Zhang Date: Wed, 26 Aug 2026 09:14:54 +0800 Subject: [PATCH] Show "Ness" instead of "harness" in the macOS app menu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The app menu's About / Hide / Quit items read "harness" because they derive from app.name, which Electron takes from package.json's top-level "name" — still "harness". The menu bar title is already correct since macOS reads that from CFBundleName (build.productName). Renaming the package or calling app.setName() is not an option: app.name keys both the userData directory and the macOS Safe Storage keychain item, and the keychain is case-sensitive, so either would break secrets.enc decryption. Instead, set explicit labels from a new APP_DISPLAY_NAME constant, and set the About panel's applicationName so the dialog behind the About item matches too. --- src/main/desktop-shell.ts | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/desktop-shell.ts b/src/main/desktop-shell.ts index 691ebc895..0fda4e136 100644 --- a/src/main/desktop-shell.ts +++ b/src/main/desktop-shell.ts @@ -68,6 +68,12 @@ export interface DesktopShellEarlyHandle { transport: ElectronServerTransport } +/** User-facing product name. Deliberately NOT `app.name` — package.json's + * `name` stays "harness" because it keys the userData directory and the + * macOS Safe Storage keychain item (see CLAUDE.md), so renaming it or + * calling `app.setName()` would break secrets.enc decryption. */ +const APP_DISPLAY_NAME = 'Ness' + /** Where the web-client bundle lives at runtime. Differs between * packaged builds (asar-relative) and dev / unpacked (sibling of the * main bundle output). Lives here so index.ts doesn't need to call @@ -378,9 +384,9 @@ export function startDesktopShell(deps: DesktopShellStartDeps): DesktopShellStar function buildMenu(): void { const template: Electron.MenuItemConstructorOptions[] = [ { - label: app.name, + label: APP_DISPLAY_NAME, submenu: [ - { role: 'about' }, + { role: 'about', label: `About ${APP_DISPLAY_NAME}` }, { type: 'separator' }, { label: 'Settings…', @@ -388,7 +394,7 @@ export function startDesktopShell(deps: DesktopShellStartDeps): DesktopShellStar click: () => transport.sendSignal('app:openSettings') }, { type: 'separator' }, - { role: 'hide' }, + { role: 'hide', label: `Hide ${APP_DISPLAY_NAME}` }, { role: 'hideOthers' }, { role: 'unhide' }, { type: 'separator' }, @@ -411,7 +417,7 @@ export function startDesktopShell(deps: DesktopShellStartDeps): DesktopShellStar // AND keyup) flows to our handlers, where the hold gesture lives. // Menu click still quits immediately. { - label: `Quit ${app.name}`, + label: `Quit ${APP_DISPLAY_NAME}`, click: () => app.quit() } ] @@ -769,6 +775,12 @@ export function startDesktopShell(deps: DesktopShellStartDeps): DesktopShellStar log('app', 'failed to set dock icon', err instanceof Error ? err.message : err) } } + if (process.platform === 'darwin') { + app.setAboutPanelOptions({ + applicationName: APP_DISPLAY_NAME, + applicationVersion: app.getVersion() + }) + } buildMenu() void runBoot() createWindow()