App Icon & Dev App-Name — Session Notes
Session record. Shipped: the dev app icon is now the Tranquil node-graph mark. Not shipped: the dev menu-bar/dock name — it stays “Electron” and cannot be reliably changed in dev. Read the distributable checklist before packaging. See ADR-0020 for the decision.
Status
- Icon — implemented (dev).
scripts/dev.jspatches the Electron bundle on every launch; confirmed the green Tranquil icon shows in the dock. - Name — not fixed (dev), by decision. Everything on disk says “Tranquil”; macOS still shows “Electron”. Deferred to packaged builds.
- Nothing committed in
tranquil-clientyet at time of writing.
The icon (works)
Artwork. The Tranquil node-graph mark from www-tranquil/static/favicon.svg — a square glyph
with a rounded dark backing plate, genuine Tranquil brand art (the leftover resources/app-icons/beta.* set is Pulsar’s purple logo, not ours). Its colors are authored in oklch(), which SVG rasterizers don’t reliably support, so they were converted to sRGB hex:
| Role | oklch | sRGB hex |
|---|---|---|
| accent glyph | oklch(0.8 0.17 145) | #6fda75 |
| backing plate | oklch(0.17 0.012 240) | #0b1014 |
Assets built (in tranquil-client):
resources/app-icons/tranquil.svg— the favicon mark with hex colors.resources/app-icons/tranquil.icns— built viarsvg-convert -w 1024→ a.iconsetof the standard sizes downscaled withsips→iconutil -c icns.
Launcher patch — scripts/dev.js patchMacAppIcon(electronBin), modeled on the existing patchMacAppName(): macOS-only, best-effort, idempotent. It copies tranquil.icns into the
bundle’s Contents/Resources, sets CFBundleIconFile to tranquil via PlistBuddy (Set,
falling back to Add), and bumps the bundle’s mtime so macOS’s icon services cache re-reads it. main() runs it after patchMacAppName(); a shared reregisterMacBundle() runs lsregister -f only when a patch changed the bundle. If the Dock still shows the old icon, killall Dock forces a
refresh.
The name (does NOT work in dev)
Symptom. In yarn start, the bold application menu and the dock/⌘-Tab label read “Electron”,
not “Tranquil”.
This corrects the earlier macOS App Name in Dev — Build Notes, which
claimed the Info.plist CFBundleName patch fixes the visible name “on the very next yarn start.” It does not. That patch fixes Finder / LaunchServices metadata only; the menu-bar/dock
name is unaffected.
What is provably correct on disk yet still displays “Electron”:
CFBundleName=CFBundleDisplayName=Tranquilapp.getName()="Tranquil"(frompackage.jsonproductName; logged from the main process)- LaunchServices record
name/LSDisplayName=Tranquil(lsregister -dump,lsappinfo)
Everything tried that did not change the visible name:
patchMacAppName(CFBundleName+CFBundleDisplayName→ Tranquil).lsregister -f <bundle>re-registration.killall Dock.argv0: 'Tranquil'on the spawn.- Renamed the launcher executable to
Contents/MacOS/Tranquiland spawned that. - Ad-hoc re-sign (
codesign --force --deep --sign -). The bundle’s signature was in fact broken by our plist edits (“code has no resources but signature indicates they must be present”); re-signing made it valid again but the name still showed “Electron”. - A unique
CFBundleIdentifier(dev.tranquil.app) + re-sign + re-register.
Root cause (as far as it could be established). The machine had 6 registered Electron.app bundles (from other projects under Archive/, experiments/, apm-help/, plus ours). Five are
named “Electron” and all share CFBundleIdentifier = com.github.Electron — every npm i electron ships the identical stock bundle id. macOS keys app identity (and its display name) by bundle id, so
the colliding “Electron” registrations win. But giving our bundle a unique id still didn’t
visibly fix it, so there is an additional OS-level name cache/fallback that piecemeal steps couldn’t
clear remotely.
Trap — programmatic readouts lie here. lsappinfo info -only name and System Events name of process both reported “Tranquil” for the running instance while the visible menu
bar still said “Electron”. Do not trust them as a proxy; only a human looking at the menu
bar/dock/⌘-Tab is authoritative (osascript can’t read the menu bar without Accessibility grant).
Bundle left clean. The experimental unique id was reverted to stock com.github.Electron, the
bundle re-signed valid, the stray renamed binary removed, and the temporary start.js diagnostic
removed. Kept: CFBundleName/DisplayName = Tranquil and the tranquil.icns + CFBundleIconFile.
Distributable-binary checklist
Packaged builds get the correct name and icon because electron-builder does the full
rebrand as one operation (rename main executable and helper apps, set the plist, assign a unique
bundle id, embed the icon, re-sign). That’s why the packaged path is the source of truth and the
dev hacks aren’t. Before shipping Tranquil binaries, in script/electron-builder.js (config is in
that JS file, not a package.json build block):
- Icon set — replace the Pulsar “beta” artwork with the Tranquil node-graph icon. Point the
mac
iconat a Tranquil.icns, the Windowsiconat a.ico, and regenerate the Linuxresources/icons/PNG set (16→512). Reuseresources/app-icons/tranquil.svgas the master. - App id — change
appIdfromdev.pulsar-edit.pulsarto a Tranquil identifier (e.g.dev.tranquil.app). A unique, stable id also avoids thecom.github.Electroncollision class seen in dev. - Product name —
electron-builder.jsoverridesextraMetadata.productNameto “Pulsar”; set it to “Tranquil” so the packagedCFBundleName/menu name is correct. - Crash reporter —
src/main-process/start.jsstartscrashReporterwithproductName: 'Pulsar'; rename to “Tranquil”. - Signing/notarization (macOS) — a real distributable needs a Developer ID signature + notarization, not the ad-hoc signing used while debugging.
- Verify, don’t trust readouts: install the packaged
.appand look at the dock/menu with your eyes.
Verification (dev)
yarn start → the dock and ⌘-Tab icon show the green Tranquil mark (name will read “Electron”, as
documented). If the icon is stale after an Electron reinstall, it self-heals on the next launch
(the mtime bump + lsregister -f); a stubborn Dock clears with killall Dock.