From 115e89cae0bc8ee2e34381a9b8fe75495db132ce Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:05:56 -0300 Subject: [PATCH 1/8] feat(code): system tray with running-agent badge Adds a system tray icon (menu bar on macOS, tray on Windows/Linux) that displays the count of currently running agent sessions. On macOS the count is shown via `Tray.setTitle()` next to the icon; on Windows and Linux the icon is swapped between pre-rendered overlays in `apps/code/build/tray/`. Tooltip is always set to `"N running agent(s)"`, so the count is at least hover-discoverable on every platform until the designed overlay PNGs land. - New `ITray` platform port + `ElectronTray` adapter - New `TrayService` listens to a new `AgentService.RunningCountChanged` event and refreshes the badge live - Click on the tray icon restores and focuses the main window - Tray is initialized after services come up and disposed in graceful exit Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/build/tray/README.md | 14 +++ apps/code/build/tray/badge-0.png | Bin 0 -> 74537 bytes apps/code/forge.config.ts | 6 +- apps/code/src/main/di/container.ts | 4 + apps/code/src/main/di/tokens.ts | 2 + apps/code/src/main/index.ts | 3 + .../main/platform-adapters/electron-tray.ts | 90 ++++++++++++++++++ apps/code/src/main/services/agent/schemas.ts | 6 ++ apps/code/src/main/services/agent/service.ts | 22 +++++ .../main/services/app-lifecycle/service.ts | 8 ++ apps/code/src/main/services/tray/service.ts | 64 +++++++++++++ packages/platform/package.json | 4 + packages/platform/src/tray.ts | 8 ++ packages/platform/tsup.config.ts | 1 + 14 files changed, 231 insertions(+), 1 deletion(-) create mode 100644 apps/code/build/tray/README.md create mode 100644 apps/code/build/tray/badge-0.png create mode 100644 apps/code/src/main/platform-adapters/electron-tray.ts create mode 100644 apps/code/src/main/services/tray/service.ts create mode 100644 packages/platform/src/tray.ts diff --git a/apps/code/build/tray/README.md b/apps/code/build/tray/README.md new file mode 100644 index 0000000000..4656caa0ad --- /dev/null +++ b/apps/code/build/tray/README.md @@ -0,0 +1,14 @@ +# Tray icons + +Pre-rendered icons used by the system tray on Windows and Linux. On macOS the +count is shown via `Tray.setTitle()` so only `badge-0.png` is needed. + +Files: + +- `badge-0.png` — base icon, shown when no agents are running. +- `badge-1.png` … `badge-9.png` — base icon with the digit overlaid in a badge. +- `badge-9plus.png` — base icon with "9+" overlaid for ten or more. + +If a specific badge variant is missing the tray falls back to `badge-0.png` so +the count is still discoverable via the tooltip while the assets are being +designed. diff --git a/apps/code/build/tray/badge-0.png b/apps/code/build/tray/badge-0.png new file mode 100644 index 0000000000000000000000000000000000000000..41f42876eb3c7e8605bd2e074804b1c27d692bbe GIT binary patch literal 74537 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 z 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 RRs{U9vatK5!u-;${{!`Psowwq literal 0 HcmV?d00001 diff --git a/apps/code/forge.config.ts b/apps/code/forge.config.ts index f52736bf2e..22dc64d55a 100644 --- a/apps/code/forge.config.ts +++ b/apps/code/forge.config.ts @@ -151,7 +151,11 @@ const config: ForgeConfig = { icon: "./build/app-icon", // Forge adds .icns/.ico/.png based on platform appBundleId: "com.posthog.array", appCategoryType: "public.app-category.productivity", - extraResource: existsSync("build/Assets.car") ? ["build/Assets.car"] : [], + extraResource: [ + "build/tray", + "build/app-icon.png", + ...(existsSync("build/Assets.car") ? ["build/Assets.car"] : []), + ], extendInfo: existsSync("build/Assets.car") ? { CFBundleIconName: "Icon", diff --git a/apps/code/src/main/di/container.ts b/apps/code/src/main/di/container.ts index b2e2379419..5a8c963309 100644 --- a/apps/code/src/main/di/container.ts +++ b/apps/code/src/main/di/container.ts @@ -23,6 +23,7 @@ import { ElectronNotifier } from "../platform-adapters/electron-notifier"; import { ElectronPowerManager } from "../platform-adapters/electron-power-manager"; import { ElectronSecureStorage } from "../platform-adapters/electron-secure-storage"; import { ElectronStoragePaths } from "../platform-adapters/electron-storage-paths"; +import { ElectronTray } from "../platform-adapters/electron-tray"; import { ElectronUpdater } from "../platform-adapters/electron-updater"; import { ElectronUrlLauncher } from "../platform-adapters/electron-url-launcher"; import { AgentAuthAdapter } from "../services/agent/auth-adapter"; @@ -65,6 +66,7 @@ import { SlackIntegrationService } from "../services/slack-integration/service"; import { SleepService } from "../services/sleep/service"; import { SuspensionService } from "../services/suspension/service"; import { TaskLinkService } from "../services/task-link/service"; +import { TrayService } from "../services/tray/service"; import { UIService } from "../services/ui/service"; import { UpdatesService } from "../services/updates/service"; import { UsageMonitorService } from "../services/usage-monitor/service"; @@ -91,6 +93,7 @@ container.bind(MAIN_TOKENS.Notifier).to(ElectronNotifier); container.bind(MAIN_TOKENS.ContextMenu).to(ElectronContextMenu); container.bind(MAIN_TOKENS.BundledResources).to(ElectronBundledResources); container.bind(MAIN_TOKENS.ImageProcessor).to(ElectronImageProcessor); +container.bind(MAIN_TOKENS.Tray).to(ElectronTray); container.bind(MAIN_TOKENS.DatabaseService).to(DatabaseService); container @@ -150,6 +153,7 @@ container.bind(MAIN_TOKENS.UIService).to(UIService); container.bind(MAIN_TOKENS.UpdatesService).to(UpdatesService); container.bind(MAIN_TOKENS.UsageMonitorService).to(UsageMonitorService); container.bind(MAIN_TOKENS.TaskLinkService).to(TaskLinkService); +container.bind(MAIN_TOKENS.TrayService).to(TrayService); container.bind(MAIN_TOKENS.InboxLinkService).to(InboxLinkService); container.bind(MAIN_TOKENS.NewTaskLinkService).to(NewTaskLinkService); container.bind(MAIN_TOKENS.WatcherRegistryService).to(WatcherRegistryService); diff --git a/apps/code/src/main/di/tokens.ts b/apps/code/src/main/di/tokens.ts index 69ea894b37..aa607c458c 100644 --- a/apps/code/src/main/di/tokens.ts +++ b/apps/code/src/main/di/tokens.ts @@ -21,6 +21,7 @@ export const MAIN_TOKENS = Object.freeze({ ContextMenu: Symbol.for("Platform.ContextMenu"), BundledResources: Symbol.for("Platform.BundledResources"), ImageProcessor: Symbol.for("Platform.ImageProcessor"), + Tray: Symbol.for("Platform.Tray"), // Stores SettingsStore: Symbol.for("Main.SettingsStore"), @@ -84,4 +85,5 @@ export const MAIN_TOKENS = Object.freeze({ WorkspaceService: Symbol.for("Main.WorkspaceService"), EnrichmentService: Symbol.for("Main.EnrichmentService"), UsageMonitorService: Symbol.for("Main.UsageMonitorService"), + TrayService: Symbol.for("Main.TrayService"), }); diff --git a/apps/code/src/main/index.ts b/apps/code/src/main/index.ts index 6a005d365e..b329a173d2 100644 --- a/apps/code/src/main/index.ts +++ b/apps/code/src/main/index.ts @@ -28,6 +28,7 @@ import type { PosthogPluginService } from "./services/posthog-plugin/service"; import type { SlackIntegrationService } from "./services/slack-integration/service"; import type { SuspensionService } from "./services/suspension/service"; import type { TaskLinkService } from "./services/task-link/service"; +import type { TrayService } from "./services/tray/service"; import type { UpdatesService } from "./services/updates/service"; import type { WorkspaceService } from "./services/workspace/service"; import { ensureClaudeConfigDir } from "./utils/env"; @@ -170,6 +171,8 @@ async function initializeServices(): Promise { ); suspensionService.startInactivityChecker(); + container.get(MAIN_TOKENS.TrayService).initialize(); + // Track app started event trackAppEvent(ANALYTICS_EVENTS.APP_STARTED); } diff --git a/apps/code/src/main/platform-adapters/electron-tray.ts b/apps/code/src/main/platform-adapters/electron-tray.ts new file mode 100644 index 0000000000..44939852ba --- /dev/null +++ b/apps/code/src/main/platform-adapters/electron-tray.ts @@ -0,0 +1,90 @@ +import { existsSync } from "node:fs"; +import path from "node:path"; +import type { ITray } from "@posthog/platform/tray"; +import { app, nativeImage, Tray } from "electron"; +import { injectable } from "inversify"; + +@injectable() +export class ElectronTray implements ITray { + private tray: Tray | null = null; + private clickHandler: (() => void) | null = null; + private readonly imageCache = new Map(); + + public isSupported(): boolean { + return true; + } + + public show(): void { + if (this.tray) return; + + const baseImage = this.loadImage(this.resolveBadgePath(0)); + this.tray = new Tray(baseImage); + this.tray.on("click", () => this.clickHandler?.()); + if (process.platform === "darwin") { + this.tray.on("right-click", () => this.clickHandler?.()); + } + } + + public hide(): void { + if (!this.tray) return; + this.tray.destroy(); + this.tray = null; + this.imageCache.clear(); + } + + public setBadgeCount(count: number): void { + if (!this.tray) return; + + if (process.platform === "darwin") { + this.tray.setTitle(count > 0 ? String(count) : ""); + return; + } + + const iconPath = this.resolveBadgePath(count); + this.tray.setImage(this.loadImage(iconPath)); + } + + public setTooltip(text: string): void { + this.tray?.setToolTip(text); + } + + public onClick(handler: () => void): void { + this.clickHandler = handler; + } + + private resolveBadgePath(count: number): string { + const bucket = + count <= 0 ? "0" : count >= 10 ? "9plus" : String(Math.floor(count)); + const dir = this.trayAssetDir(); + const candidate = path.join(dir, `badge-${bucket}.png`); + if (existsSync(candidate)) return candidate; + + // Fall back to the base app icon until designed badge overlays land. + const base = path.join(dir, "badge-0.png"); + if (existsSync(base)) return base; + + return this.appIconFallback(); + } + + private trayAssetDir(): string { + if (app.isPackaged) { + return path.join(process.resourcesPath, "tray"); + } + return path.join(app.getAppPath(), "build", "tray"); + } + + private appIconFallback(): string { + if (app.isPackaged) { + return path.join(process.resourcesPath, "app-icon.png"); + } + return path.join(app.getAppPath(), "build", "app-icon.png"); + } + + private loadImage(filePath: string): Electron.NativeImage { + const cached = this.imageCache.get(filePath); + if (cached) return cached; + const image = nativeImage.createFromPath(filePath); + this.imageCache.set(filePath, image); + return image; + } +} diff --git a/apps/code/src/main/services/agent/schemas.ts b/apps/code/src/main/services/agent/schemas.ts index 410d77ea59..4c37642661 100644 --- a/apps/code/src/main/services/agent/schemas.ts +++ b/apps/code/src/main/services/agent/schemas.ts @@ -204,8 +204,13 @@ export const AgentServiceEvent = { SessionIdleKilled: "session-idle-killed", AgentFileActivity: "agent-file-activity", LlmActivity: "llm-activity", + RunningCountChanged: "running-count-changed", } as const; +export interface RunningCountChangedPayload { + count: number; +} + export interface AgentSessionEventPayload { taskRunId: string; payload: unknown; @@ -236,6 +241,7 @@ export interface AgentServiceEvents { [AgentServiceEvent.SessionIdleKilled]: SessionIdleKilledPayload; [AgentServiceEvent.AgentFileActivity]: AgentFileActivityPayload; [AgentServiceEvent.LlmActivity]: undefined; + [AgentServiceEvent.RunningCountChanged]: RunningCountChangedPayload; } // Permission response input for tRPC diff --git a/apps/code/src/main/services/agent/service.ts b/apps/code/src/main/services/agent/service.ts index 1596f9ff5b..e20dbfed46 100644 --- a/apps/code/src/main/services/agent/service.ts +++ b/apps/code/src/main/services/agent/service.ts @@ -426,6 +426,22 @@ export class AgentService extends TypedEventEmitter { return false; } + public getRunningSessionCount(): number { + let count = 0; + for (const session of this.sessions.values()) { + if (session.promptPending || session.inFlightMcpToolCalls.size > 0) { + count++; + } + } + return count; + } + + private emitRunningCountChanged(): void { + this.emit(AgentServiceEvent.RunningCountChanged, { + count: this.getRunningSessionCount(), + }); + } + public recordActivity(taskRunId: string): void { if (!this.sessions.has(taskRunId)) return; @@ -919,6 +935,7 @@ When creating pull requests, add the following footer at the end of the PR descr session.promptPending = true; this.recordActivity(sessionId); this.sleepService.acquire(sessionId); + this.emitRunningCountChanged(); try { const result = await session.clientSideConnection.prompt({ @@ -934,6 +951,7 @@ When creating pull requests, add the following footer at the end of the PR descr session.lastActivityAt = Date.now(); this.recordActivity(sessionId); this.sleepService.release(sessionId); + this.emitRunningCountChanged(); if (!this.hasActiveSessions()) { this.emit(AgentServiceEvent.SessionsIdle, undefined); @@ -1218,6 +1236,8 @@ For git operations while detached: private async cleanupSession(taskRunId: string): Promise { const session = this.sessions.get(taskRunId); if (session) { + const wasRunning = + session.promptPending || session.inFlightMcpToolCalls.size > 0; this.cancelInFlightMcpToolCalls(session); this.sleepService.release(taskRunId); try { @@ -1234,6 +1254,8 @@ For git operations while detached: this.idleTimeouts.delete(taskRunId); } + if (wasRunning) this.emitRunningCountChanged(); + // When no sessions remain, tear down MCP Apps connections and cached resources if (this.sessions.size === 0) { this.mcpAppsService.cleanup().catch(() => { diff --git a/apps/code/src/main/services/app-lifecycle/service.ts b/apps/code/src/main/services/app-lifecycle/service.ts index 53f9c4f1dd..041df7be3a 100644 --- a/apps/code/src/main/services/app-lifecycle/service.ts +++ b/apps/code/src/main/services/app-lifecycle/service.ts @@ -10,6 +10,7 @@ import { shutdownOtelTransport } from "../../utils/otel-log-transport"; import { shutdownPostHog, trackAppEvent } from "../posthog-analytics"; import type { ProcessTrackingService } from "../process-tracking/service"; import type { SuspensionService } from "../suspension/service.js"; +import type { TrayService } from "../tray/service"; import type { WatcherRegistryService } from "../watcher-registry/service"; const log = logger.scope("app-lifecycle"); @@ -110,6 +111,13 @@ export class AppLifecycleService { log.warn("Failed to stop inactivity checker during shutdown", error); } + try { + const trayService = container.get(MAIN_TOKENS.TrayService); + trayService.dispose(); + } catch (error) { + log.warn("Failed to dispose tray during shutdown", error); + } + try { const db = container.get(MAIN_TOKENS.DatabaseService); db.close(); diff --git a/apps/code/src/main/services/tray/service.ts b/apps/code/src/main/services/tray/service.ts new file mode 100644 index 0000000000..689a14c3c9 --- /dev/null +++ b/apps/code/src/main/services/tray/service.ts @@ -0,0 +1,64 @@ +import type { IMainWindow } from "@posthog/platform/main-window"; +import type { ITray } from "@posthog/platform/tray"; +import { inject, injectable } from "inversify"; +import { MAIN_TOKENS } from "../../di/tokens"; +import { logger } from "../../utils/logger"; +import { + AgentServiceEvent, + type RunningCountChangedPayload, +} from "../agent/schemas"; +import type { AgentService } from "../agent/service"; + +const log = logger.scope("tray"); + +@injectable() +export class TrayService { + private initialized = false; + private readonly onRunningCountChanged = ( + payload: RunningCountChangedPayload, + ) => this.refresh(payload.count); + + constructor( + @inject(MAIN_TOKENS.Tray) private readonly tray: ITray, + @inject(MAIN_TOKENS.AgentService) private readonly agents: AgentService, + @inject(MAIN_TOKENS.MainWindow) private readonly window: IMainWindow, + ) {} + + public initialize(): void { + if (this.initialized) return; + if (!this.tray.isSupported()) { + log.info("Tray not supported on this platform; skipping"); + return; + } + + this.tray.show(); + this.tray.onClick(() => this.handleClick()); + this.agents.on( + AgentServiceEvent.RunningCountChanged, + this.onRunningCountChanged, + ); + this.refresh(this.agents.getRunningSessionCount()); + this.initialized = true; + log.info("Tray initialized"); + } + + public dispose(): void { + if (!this.initialized) return; + this.agents.off( + AgentServiceEvent.RunningCountChanged, + this.onRunningCountChanged, + ); + this.tray.hide(); + this.initialized = false; + } + + private handleClick(): void { + if (this.window.isMinimized()) this.window.restore(); + this.window.focus(); + } + + private refresh(count: number): void { + this.tray.setBadgeCount(count); + this.tray.setTooltip(`${count} running agent${count === 1 ? "" : "s"}`); + } +} diff --git a/packages/platform/package.json b/packages/platform/package.json index 68916d1e20..9935ac81d9 100644 --- a/packages/platform/package.json +++ b/packages/platform/package.json @@ -63,6 +63,10 @@ "./image-processor": { "types": "./dist/image-processor.d.ts", "import": "./dist/image-processor.js" + }, + "./tray": { + "types": "./dist/tray.d.ts", + "import": "./dist/tray.js" } }, "scripts": { diff --git a/packages/platform/src/tray.ts b/packages/platform/src/tray.ts new file mode 100644 index 0000000000..bc6d28d4c4 --- /dev/null +++ b/packages/platform/src/tray.ts @@ -0,0 +1,8 @@ +export interface ITray { + isSupported(): boolean; + show(): void; + hide(): void; + setBadgeCount(count: number): void; + setTooltip(text: string): void; + onClick(handler: () => void): void; +} diff --git a/packages/platform/tsup.config.ts b/packages/platform/tsup.config.ts index 20fd8b4461..1cd9b5b92b 100644 --- a/packages/platform/tsup.config.ts +++ b/packages/platform/tsup.config.ts @@ -17,6 +17,7 @@ export default defineConfig({ "src/context-menu.ts", "src/bundled-resources.ts", "src/image-processor.ts", + "src/tray.ts", ], format: ["esm"], dts: true, From ebfb8e8530a347e72ec5121b448308d7792ad20c Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:10:24 -0300 Subject: [PATCH 2/8] fix(code): resize tray icon and mark template on macOS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 1024×1024 source PNG was being handed to `Tray` unmodified, so it overflowed the menu bar. Resize every loaded image to 22px tall on macOS and 16px elsewhere, and set the template flag on macOS so the icon adapts to light/dark menu bars. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- .../main/platform-adapters/electron-tray.ts | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/code/src/main/platform-adapters/electron-tray.ts b/apps/code/src/main/platform-adapters/electron-tray.ts index 44939852ba..9c66284a4b 100644 --- a/apps/code/src/main/platform-adapters/electron-tray.ts +++ b/apps/code/src/main/platform-adapters/electron-tray.ts @@ -4,6 +4,11 @@ import type { ITray } from "@posthog/platform/tray"; import { app, nativeImage, Tray } from "electron"; import { injectable } from "inversify"; +// macOS menu bar icons display at ~22pt; Windows/Linux trays render at ~16px. +// Source PNGs are 1024×1024 so they must be resized before handing to Tray, +// otherwise the icon overflows the menu bar. +const TRAY_ICON_SIZE = process.platform === "darwin" ? 22 : 16; + @injectable() export class ElectronTray implements ITray { private tray: Tray | null = null; @@ -83,8 +88,16 @@ export class ElectronTray implements ITray { private loadImage(filePath: string): Electron.NativeImage { const cached = this.imageCache.get(filePath); if (cached) return cached; - const image = nativeImage.createFromPath(filePath); - this.imageCache.set(filePath, image); - return image; + const resized = nativeImage + .createFromPath(filePath) + .resize({ height: TRAY_ICON_SIZE }); + if (process.platform === "darwin") { + // Template flag makes macOS render the icon as monochrome and adapt to + // light/dark menu bars. Falls back gracefully if a true template (single + // colour with alpha) asset is later supplied. + resized.setTemplateImage(true); + } + this.imageCache.set(filePath, resized); + return resized; } } From bf0b851df39907dcbf8da547a354014c0941b60c Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:12:57 -0300 Subject: [PATCH 3/8] fix(code): drop tray template flag, use 16px sizing `setTemplateImage(true)` on a fully-opaque colored PNG renders the silhouette as a solid block that's nearly invisible against the dark menu bar. Drop the template flag and resize to 16px (Electron's documented tray target) with the best quality filter. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- .../main/platform-adapters/electron-tray.ts | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/apps/code/src/main/platform-adapters/electron-tray.ts b/apps/code/src/main/platform-adapters/electron-tray.ts index 9c66284a4b..853dc5f974 100644 --- a/apps/code/src/main/platform-adapters/electron-tray.ts +++ b/apps/code/src/main/platform-adapters/electron-tray.ts @@ -4,10 +4,10 @@ import type { ITray } from "@posthog/platform/tray"; import { app, nativeImage, Tray } from "electron"; import { injectable } from "inversify"; -// macOS menu bar icons display at ~22pt; Windows/Linux trays render at ~16px. -// Source PNGs are 1024×1024 so they must be resized before handing to Tray, -// otherwise the icon overflows the menu bar. -const TRAY_ICON_SIZE = process.platform === "darwin" ? 22 : 16; +// Electron expects tray icons at 16×16 (32×32 for retina). Source PNGs are +// 1024×1024 so they must be resized before handing to Tray, otherwise the icon +// overflows the menu bar. +const TRAY_ICON_SIZE = 16; @injectable() export class ElectronTray implements ITray { @@ -88,15 +88,11 @@ export class ElectronTray implements ITray { private loadImage(filePath: string): Electron.NativeImage { const cached = this.imageCache.get(filePath); if (cached) return cached; + // The brand icon is full-color and opaque, so leave templateImage off — + // marking it template would render the silhouette as a solid block. const resized = nativeImage .createFromPath(filePath) - .resize({ height: TRAY_ICON_SIZE }); - if (process.platform === "darwin") { - // Template flag makes macOS render the icon as monochrome and adapt to - // light/dark menu bars. Falls back gracefully if a true template (single - // colour with alpha) asset is later supplied. - resized.setTemplateImage(true); - } + .resize({ height: TRAY_ICON_SIZE, quality: "best" }); this.imageCache.set(filePath, resized); return resized; } From 431744bec3b7b853a507982c6d294ec4ec8441ba Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:16:11 -0300 Subject: [PATCH 4/8] feat(code): monochrome template tray icon for macOS Adds a proper macOS template image (hedgehog silhouette extracted from the brand icon by alpha-thresholding the white background) at 22/44/66 px so Electron auto-picks the right scale. Template mode lets the icon adapt to light/dark menu bar like other system icons. Windows/Linux still use the colored `badge-N.png` set at 16 px. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/build/tray/icon.template.png | Bin 0 -> 523 bytes apps/code/build/tray/icon.template@2x.png | Bin 0 -> 1131 bytes apps/code/build/tray/icon.template@3x.png | Bin 0 -> 1679 bytes .../main/platform-adapters/electron-tray.ts | 39 ++++++++++++------ 4 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 apps/code/build/tray/icon.template.png create mode 100644 apps/code/build/tray/icon.template@2x.png create mode 100644 apps/code/build/tray/icon.template@3x.png diff --git a/apps/code/build/tray/icon.template.png b/apps/code/build/tray/icon.template.png new file mode 100644 index 0000000000000000000000000000000000000000..16385de95562084303da04a3db0a1be4f9558baa GIT binary patch literal 523 zcmV+m0`&cfP)dR* z$QcWVAp0=}UA;TZ&F-l8LQ%zZ^;=b4T|G=u*g1-(QJ}&eoWL@MA@k5fAHVS#TbZk< zksiY;-s49&SAUV=5)R=E-r`G6xWI1Q4E?`Y3XXj!%E;<0Ht;J-s~?dTyNLyjIpmdwLnc0si&7(x;sFjuiT9-|^+@W)KnHH%NZ1?FnN^|3VGlwo+zQ`*=-k*9 zT%-NG%8+5`!nFKe1bd9@5vbq7F}D$Ai(Q00#xq`@1$P zt329pAObFiZj)tPksAC8ubVtM`a^$M8r83O zho7de)-3d}UwY(E;!f-@o4+Qwj8jtAE8YLXE$JC})510Ruv1Jp{s4#raz7R8v)ljx N002ovPDHLkV1i!K?=k=Y literal 0 HcmV?d00001 diff --git a/apps/code/build/tray/icon.template@2x.png b/apps/code/build/tray/icon.template@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..db1cf01b9fd45690a79bd148d7f83c9445beb2ce GIT binary patch literal 1131 zcmV-x1eE)UP)OycvC4vMYif)7;=*E>x{{(R%DkvC5L@_8X z1T}~VPEi~-8gK+bH$v2eXiQ#Sw~IO__w?;~c%2U}-M8);zFT#wPMx|9(51VKe_b20Ytecuzpq=JFhQIMo@oWLBy*l+HoI7m5?YJNf zd=&rTU$ZgeDMArTSdU-v4h{?=-HR;TfnB&C=gffIFl@y=cplqpT>2t6*ol|0x%ND- zvsqqEotEB!XYkN4(%G?Yz+1&2i`FhW)KQXq4R`mDA4gL-)E-~7 zkA3Oki6q=g^M5ZQR72vJ31^jW!2Uv((a-6|m5+-*MXcVG$1Ow3CTtX&LW!mzUk^W7 zUU$rX@^O%rbwq4fOXcAG8fUaphis-sAzv>{)$Gx}E}xY6u~JYD*igL@m4@!a4|rJ> z=oj&%SYwYCBp2{hYX3-*FHT9iYk6hC8Q3f0UP<_Kl@snxva<_WJCTM9Yx0MaeA0wz z2_K4>e4J}P!dd$t3G*IKBwi3(_Ms$SN%9AU)2`IyJEtJsMR*i*HB`IcY9e-SB9vdQ zm0si`ktSxZUKPpAipWjYrTS;&;VMC>y+s zWpN^}N1ra#P0=d{uE*SI(8go2SrV52Ukv(_|z7nRQ$|b(&L3*vO zuWNG;-I^D5ADf=Vc}84gBOvdJWxkwqm8XYw9<(I#v1yku*ZRphj)Ws3p(^L@!YJXS znFcyEtlAs(&IgFXW|giO~ANByX35;YV!KdDuJ=$O_z+I8pPr9Aa)%ofz`IKX2p; z=@R}jp!Ax_?Gq_rZZyw=;DSn%&*3-K-q2<7EWBKpDGPpJ#NU{#Hy&NllTewmrBg-OL`4m5i+S_5%mtvbDWNjAp=xcEq zz7wT^y#<$ngw-0}jC+N7&QyIym_=-Eh%ZR{@g-gn8m@B~N|@fKV>oF@zj2Ub|EP11 xG;#je*XlRO43IxymNkyP4aXgLEim%(`XA147~iI7kd*)c002ovPDHLkV1k#v7oz|G literal 0 HcmV?d00001 diff --git a/apps/code/build/tray/icon.template@3x.png b/apps/code/build/tray/icon.template@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..629c7cd9edfa64b91fc563fbf6064faa90b0297e GIT binary patch literal 1679 zcmV;A25|X_P)@*pCjD1smeq7Q;p1RoTtSf64A zV?@FFps}SDwV`ibYV}2nij{;$N^8AUo6C3c;mpZSHoM=q`|a-c?Lz*r?9S}$?96}8 zoH=v$EG%OgHgXZ4wU17sZq7C9I#J|+0+4UV%UXoCG1TCMDO>=mR(dsXG0+cOfQ&>9 zsDx=i1Qe{}FmN3B9+-5MsV;qVDS{A@LnNRIbOZMQ8-X%#1eh|7_zRc^{tNQr7;w62 z!x=yyu+|(U;4|PI;2+cWIuWOgJ^$|mz6M?gHbkj3VXOmQ1iky47K>@VjfcLoXb!uxL%`?2ZXzi4oT(UKAF$WDS0w$)vS_78fe9SaLXlB0=k35( z)(Z;W#Zw8D7=Vv~UFJG)AGF|Yz$~x|M`30SI(S7yp+92s1Cfz86&wbhGnEXSx&X`TcgHP;OXS8whD-V5?TMxcFo2{>S`n@;sSFbzDw zQVpC{sHEQt{EZlf;3MhE&{|*)xZIVWWoRGHL$(0dnsmWk033EMGzET3x^-=Yn%BpH zQ^5Hqy&w@@qrD1|h?A~LvJCCREHHx%_9A#m#6`#kYqm+{K{sr1l!*iS9?wmomqau( zp7eel$L8>>w~oK@5~NHLn8l-iejT32e@dv|;WQkNkWEI;Jj4p;-Mw8~V0H-P(1ok@}5i&o}k1;+tXGU-jg zM@T1Uth#k8Tm?oDGIR>mt^0YCKZ=8}^dB6L^fJ>$&Yt+X>u(kkJ+e8t0N#Kt^-}&|~u4 zqYgsaR%DCsMh<7nypOCt71}^X+-tYabw6lFYYpD5l2b(V&ds!ej3kVhW_1Q}`zaY+ zz=yy!Buqw{x7aFOJ-{B|Y7!(P%|w8++Vmn`vvnjyM%sx0#}4TOK1B>VwPj*M7Ki|c zjB}A`GGx-Rk&zW5z#(G*`N%s!jAUeqh#J!AIbaZxjMc@Z1o`o>1OXLBrs&eocH0F^MQ~hB5nY_^ti8^y&)u02IS-QHbTTuc@a@V zyiHn(GON2sWw~8JV|Kgj-KiTD#6#VUY}B@esoYN@yxjCkz!(xx=CzIPG|J|@BkY4= zriMz#IB+8pS*LMJoempN2XF;(CQl%33amK8>Ij`8`^}M7gi@5ynzGa{Q=OIqKh$Yq z2@RtoY_zmicNi)m-FSG>ytMBuq6oV@?qwZ0q;Cz0P{t0KbFcMq)}eh^0h~!di8x`- z1FlN44DG`jM8D}^FDO(miTK5wuOuByV;oSOcbQ2~1$jurh9;~^vJTymjsgE7Qv@0e zvaTX;;dq0x8g;ACZ?I<}BO}g!0r(=Y+eJj$ZyG**N4W)YF8=RmI zyTU9%JG&kUewid-2r@WQu@NC+8o0#dm4Z}|66nD7BdbIm*kbZRN9aFqD)<%o?55Cv zHqu0j>M~p8hmr84I`Yc}wBX9q2VOB1%^+T)ZdW-C_9%Af@cQepgv4%Xc+wsme`ZU6 z@#qWexTzn3XOMZ9CNsQ@ICGys0@<{^+X?WOK{IyjXqTH1SC~CTrVs;c8ezYJ1brt7 z-D3A3quh&FjDv`~PH_+k8XI>#7YX*f+Kkv4KeIS0E)B;t@HP^9WQQ|0oeoicfGs1V z(2tDDV95HSLY+iM5byReWO+Pkm5KESST|HU((04Y_J#USJjw{V|E28YQtF-}%UDK4 Z{0}gtYi_5djXMAU002ovPDHLkV1lC8{)GSl literal 0 HcmV?d00001 diff --git a/apps/code/src/main/platform-adapters/electron-tray.ts b/apps/code/src/main/platform-adapters/electron-tray.ts index 853dc5f974..1b0f883d93 100644 --- a/apps/code/src/main/platform-adapters/electron-tray.ts +++ b/apps/code/src/main/platform-adapters/electron-tray.ts @@ -4,10 +4,11 @@ import type { ITray } from "@posthog/platform/tray"; import { app, nativeImage, Tray } from "electron"; import { injectable } from "inversify"; -// Electron expects tray icons at 16×16 (32×32 for retina). Source PNGs are -// 1024×1024 so they must be resized before handing to Tray, otherwise the icon -// overflows the menu bar. -const TRAY_ICON_SIZE = 16; +// macOS renders tray icons in points, and Electron auto-discovers @2x/@3x +// variants. The template PNGs are pre-rendered at 22/44/66 px, so on macOS we +// don't resize. Windows/Linux trays render around 16px and use the colored +// badge-N.png set, which are resized down from the 1024×1024 brand icon. +const NON_MAC_TRAY_ICON_SIZE = 16; @injectable() export class ElectronTray implements ITray { @@ -58,9 +59,17 @@ export class ElectronTray implements ITray { } private resolveBadgePath(count: number): string { + const dir = this.trayAssetDir(); + + if (process.platform === "darwin") { + // Monochrome silhouette that adapts to light/dark menu bar. The macOS + // count is rendered via setTitle, so a single template suffices. + const template = path.join(dir, "icon.template.png"); + if (existsSync(template)) return template; + } + const bucket = count <= 0 ? "0" : count >= 10 ? "9plus" : String(Math.floor(count)); - const dir = this.trayAssetDir(); const candidate = path.join(dir, `badge-${bucket}.png`); if (existsSync(candidate)) return candidate; @@ -88,12 +97,18 @@ export class ElectronTray implements ITray { private loadImage(filePath: string): Electron.NativeImage { const cached = this.imageCache.get(filePath); if (cached) return cached; - // The brand icon is full-color and opaque, so leave templateImage off — - // marking it template would render the silhouette as a solid block. - const resized = nativeImage - .createFromPath(filePath) - .resize({ height: TRAY_ICON_SIZE, quality: "best" }); - this.imageCache.set(filePath, resized); - return resized; + + const isMacTemplate = + process.platform === "darwin" && filePath.endsWith(".template.png"); + let image = nativeImage.createFromPath(filePath); + if (!isMacTemplate) { + image = image.resize({ + height: NON_MAC_TRAY_ICON_SIZE, + quality: "best", + }); + } + if (isMacTemplate) image.setTemplateImage(true); + this.imageCache.set(filePath, image); + return image; } } From d4fcaf41c12f5896c3bd26e01a657d212948fd61 Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:19:02 -0300 Subject: [PATCH 5/8] fix(code): flat-fill tray template silhouette The previous template kept the brand icon's internal white highlights as transparent cutouts, which read as a "bezelled" or carved hedgehog in the menu bar. Fill internal holes and slightly dilate the mask so the silhouette renders as one flat solid shape. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/build/tray/icon.template.png | Bin 523 -> 461 bytes apps/code/build/tray/icon.template@2x.png | Bin 1131 -> 953 bytes apps/code/build/tray/icon.template@3x.png | Bin 1679 -> 1614 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/code/build/tray/icon.template.png b/apps/code/build/tray/icon.template.png index 16385de95562084303da04a3db0a1be4f9558baa..c48bd71f1e90849452711a40a5c17474b1e33d33 100644 GIT binary patch delta 435 zcmV;k0Zjgj1kD4GB!84iL_t(|oTbz|ZWKWf#_``g7F!k%V+RC0Lf{BofdddBaRwtH zAwm*F1Q|IoA!k8C#7K}3fM8|3tcPH#*kd&EFRNR zpO&f)L*_E`n~;pFh)+`<;0kq`64c^aK$;@%aJ2xOR55vIU&}=_(ci}p+{K-UAK(JM z<5e+!PC5Q5yGJqeH@uB_9l$K57lmgMp5TMn#@Z&|T`|Eb;^%YW34R#HqX9hQu7E!s zcxQprJl696lYj6n49amh+Ym6OI^fUrm+Ix%z(w?rCssPvUgNf+blZSl!AHEqXY*gU zJk)!5gZJsFa1Q(U6ob#}>-4l#40UAl&a^R^Ccrt-S(V;>w5`6Jwoe#vR&8Nj>$iNU ze>#WNP|aux->yC_U7Bm$!VUAD$DwLm4@Qlu+;)ST*etWTZBxocHTZ%L=^M-Ej(IOw dmfLdp<2T-+djs*>TsZ&$002ovPDHLkV1g<**r)&i delta 497 zcmVa&(!RGfoPzZ90rQW84HIX`!NPxy*td!?x^=dQN?uiTUA|MJxo#9 zIf|xHpu!%Uz%qs*^Uy;dzwsGcnX9Og9>Xf$<3~7Gf05x54u9bc-r`G6xWI1Q4E?`Y z3XXj!%E;<0Ht;J-s~?dTyNLyjIpmdwLnc0si&7(x;sFjuiT9-|^+@W) zKnHH%NZ1?FnSWKG$6*gbD%=X+e(2oT6k+8m!ZEiIWs6;e zJ;pO!4f1Vg-qwUsWIOK$4Dk?8r2D%zE2})(a3BIMhHjH(T#*|53a^_yIpeZs-^S^V zj7g)r7DV4_-?v@2jF)rBx==_Bo)8bD=__NQ>s4zb9BKu}BGXd8@SOF2U=R@$LexSeqLm=n zT38BJR;Cav1Y50A*$Ebcjjdp1Z4)ePHEH|^BGDsiH0C~bE#4dV-P~>VE_ZX6KP)@@ zc4yyj-_Fd=yoF*#x`kHHe)1~!6Ta(v6;&7kCV+7u0sa8{fPb~F(OUhcz$8#rKaOPs zsBc#>4|EEs0h_>)ZtTUoL4SdUJBZ2PHjvKdYlQY4FwY+8 zxqc}@MvNv00O$P^o-AC{fxX@FP84Cdth4WAp|_4M0yD^yy2z!-1D-N=H#ANGm&|p& zLZ@U+HCGO7Q7cpw9ONMv)LsRyn>sVVCq4IEVeLrNSARv`J_bG@QBRTHIlBI%${0xyg`QRoZ66+Nz*I!{AGTj2NVv_Tf>&%lb7 z6JxIcPmJ9@=;M&kdB7IL-}3Ah`jOtZ)NknRfE`>rz{I<*9rR)d=px{qZZ+LMFwnai z*h1g$Cx3KEU^jxKz+Lsz^I{<+un)b^59rXq4!W-8TLyYZ9dQuAKJ*Razw4#hpnx5; zyZ3Em)zh_nU^ib#0&Vsyx<)pF#RNShgUGXPi(rp4b1f0Oycv zC4vMYif)7;=*E>x{{(R%DkvC5L@_8X1T}~VPEi~-8gK+bH$v2eXiQ#Sw~IO__w?;~ zc%2U}-M8);zFT#wPMx|9;;a{^c<0(QBOIVLz@eU3QBHfED+<{%V zALq<~+%Rm#J$N45Yh3ywH`s}nu(|d;ud`WRO`VqBfM@W~Fw)tvZopf`AdA*6I@D2; zdkuH@kRL}=IDgb0Ts)}Z8Y63bD?Y%f3Wa5@E{KS5mst2e3(bzS=x2;p;`0Z-!4Bcz zi&TX38{CHX)BVhX`2@%zZx3!NWXB0-O`eZ^>EVea+)DF*FCtV!;+P3%m2bfQLYC3b z>Bg0hi$6uI-jv5JL&_#>6q`bcrXXJrKUrRP%zpB5kbjkRL~K|~<>37qXS7m>Y^Fvb zUoTA6?9sk1pOpBqQcw=qP`weAhVH`;cv%(b7xAQ6V~-Xj7w}YS|45QAPD#3Jd1b*F z*el{*N%(V>6Yfs3vkO@}k%kLv@`sar(u8RVABvcKoNGVAS^FOe^BztlUJzUMp(I~P z@&|>}u7A|zJEtJsMR*i*HB`IcY9e-SB9vdQm0si`ktSxZUKPpAipWjYrTvK?38peP%>i)C>luScIQ)J@SV2d>B5Y0$=F_(i0R zt2j#>g?8gbe5MM8J&`?l3%(MjqRJ({=s|j|uCHrz58av zbAOemhjkvbB=WIomoV4*$vKXMBO;+H=kCHN;iQ=cIy9`|3{cKau@Msn^i{G}WOkS#gA~P@KrErPR`oSb` zmxSR*Y}0wzJQ2tW+?F^|^S2ygZd9EZ@_)WRZ{!N;68oF@zj2Ub|EP11G;#je*XlRO43IxymNkyP4aXgL dEim%(`XA147~iI7kd*)c002ovPDHLkV1h!e8W8{h diff --git a/apps/code/build/tray/icon.template@3x.png b/apps/code/build/tray/icon.template@3x.png index 629c7cd9edfa64b91fc563fbf6064faa90b0297e..d861e5bf4c4414095a3f0ec770170cc4f4f79469 100644 GIT binary patch delta 1597 zcmV-D2EzG|4bBXZB!3l2L_t(|ob8)kXdG1($A6jZw%w#j*^0rWextQkvG^n+D)=BM zSVdY|#DX71d=NxXd=Q^}^GWbY1Ph`lDyWE}RDAKJh$y0{_yuXOK~rnGiH$bNj1T9Y z+?%^Inc1(|nWcXiHhbsHoqPZHoO{kadjjXsF@~HA=QHmyxPN2G{l#TKOJmI{JOo6} z_Zlz;3qhPzTPMfh?Mro<+#{r_}*; zh!OMts<}3q&naLAm_m-_~l z0dZrx0N8_&(|=Zn+R4_K_Od|7TL*R^WMrO$3SMhE05OZQLgzDq%*kzAgFivt6Lun+ z@VAi(do#vd5FvB;6WKR*J8g*=Le%FjWcMwbDQpCt+g@Vk7I=aYa4GN`;*ST7h*jVx z;4(a|@QDDp2=T#CZjN$IPb(6JoHDnSU%rZI-(7m^SmgI2^vok0c} zC3z*LEq@OzC*4q$nF6+ZZT{bTfd?JAxLD+7;9=l$^L;o*rUu*x?8h!h;mu$9kH=g!*b4`>`%BBHjdM5xe*AyU+a$ zynp9C=U!?iZ(w7MLXeS#h@?sRSC~P@CF6*BchAY_rVR$92SjPnrlN|N$pgSk2+2Jq zquZNNmVx>kWfGK(M}QX)P3##Nh4j}Bl#Is_m)lb^(vWqJ=;fvH#&h17azzn{2(e^5 zNFpb)z-d1eizl>3=5GgiGgO^PXS+J7jHxO zMCc~tLN(wxa1V0unWC6gb!s9rz|+7VWGsEsiKy@`2$SE%bm0CHRqMv6dx$0Tne^+K z&U@{iuMyRlHbsQkTIjr}sBmM9IDa&eQ}J&6j;&ISV^TMqqM3vb^&CD_LnaWdp4K*h z_0NzkwkWE{$ch>;>Nfa9Y^F=c+7h7Qe(_g-30pN&boFlsZWZpj1y>?e)fcg4$AgS* zz=GT0*ETe;C5D4kW2w;Ku!fXZgHZyX2z8A+C}zOa33NV_$j_3iBvjt2d4GJ5{EtRg zPi_T(y3T8mQU-9mpHD=9J*1pZi)Z=*L$$q*6sydTa&T1j*$&)q+S>Zhmx4j(a1dGG zCbRe5r<%hlq%7zF)|Sec#BsCU_ac$=95H8*xXFd);bX|T{xCM_F`V#B(V$212qEDi z#2bE2f=ArQ{*}pnzzx7Fz<&?k{iah~pWu$eO~71%lsSF_yvYVf^0bXm$=Cxt3Y
7m!7nMmGLcNmB`Fd5N|W vP!4z6@}}NNu%uP`o%Yi$`04#~Xb1lTVxI}5jw20p00000NkvXXu0mjfOy3M2 delta 1662 zcmV-^27&p`437JMl^+k({m4rr0YrR#Q%XjhN z%*jqRyWh9_?e6#OLjJJq&g|^$%zw_DIdk?bEMplqauJ`kkAF_0Zq7C9I#J|+0+4UV z%UXoCG1TCMDO>=mR(dsXG0+cOfQ&>9sDx=i1Qe{}FmN3B9+-5MsV;qVDS{A@LnNRI zbOZMQ8-X%#1eh|7_zRc^{tNQr7;w62!x=yyu+|(U;4|PI;2+cWIuWOgJ^$|mz6M?g zHbkj3VXOmQ1b@B&9yfWB^q4)@b|56Ica~s8x>qFq%CcysM}Y|((n66@Fz4;SSJn#(-o;Z1l^B4JfnDZ0a38ebZNMzB3P)jP z4LW#5M4>-o@&l2PHx(QPo-}zy|Kh2Kw*7A44`2lW^nZmd4Sym_R2nSDs8DI11Rgcl z4F^|m?gHKm@<2wQeRv5tV6K}^^*k^QJit;7oK>i#-wOPV7>3{@>B`VrU=Fz4m7is3 zAI?Lz0N0vy!Ce3xb}lppeoMM_ZG@WF$AMG8`6j&}5niLc3XzDDu1c~D?ZYfEgADc} zcuB-X$bSZFwn^ndH*9f~i39o`&rPA1L^Ly=^nM-3=J2bxj=%8|q)ZZ+#iM_I9iGR3 zN~quAG#rnRO-9b-gX0fyzsD|<_bHPU8m<)Xyi+(14JAYkt6pFXI0U?F(kdM)DYpOz zfgcdFwuZ9|Ynjc!cZf6PL06fMLL2ccaJ0ew7k_XZ9d%$o&}HuB5J$;TR~hvSlyS&B z;VScxDN~B0GagV$_z8HJj z4p;-Mw8~V0H-P(1ok@}5i&o}k1;+tXGU-jgM@T1Uth#k8Tm?oDGIR>mt^0YCKZi}N3fxJX$%so+mynL$3w(e~0UP#` zyAybfrR%xvPTL9GfsoM_1sdm)RX|2`1JGmg+@lUc+E!$X??w)1%Dj)PJ{8(PM%-(+ z&UHU%M{5ntAR3_7)CVnY^)0Ediok!dny(y@_|6(YbPV*vTcJ3x$N zWQm9x(&;&15Rr`4#6(7xh|so{kpo8@^a18Nm^&tf5X74H_Fl5A> z_u-iHfsiF4ZUDaYxUZYNAtX`;Kxm`hHcDwA|sT&o< zL*0#R)V77G+)pCB-1JJo7!pwCwSSH7G|J|@BkY4=riMz#IB+8pS*LMJoempN2XF;( zCQl%33amK8>Ij`8`^}M7gi@5ynzGa{Q=OIqKh$Yq2@RtoY_zmicNi)m-FSG>ytMBu zq6oV@?qwZ0q;Cz0P{t0KbFcMq)}eh^0h~!di8x`-1FlN44DG`jM8D}^FMlXhFNyfY zoUbGuOJf{Rop+f@PX&2M!-giTO0o{!k&XfXB2xq!46?2wZ{c`@vKn=(&~LD3Atda! z@_nJqU58ASH%+?jU#DY)wtXwor@KtLsSTxi;TxQw54*xFK|8x134WO*Uzj@>#&5xZfSVZ9vpvWOMmg`3+%Y5AAx6(d6yJv18f>$zk&pPCkfqR_aLL(i+5OzgNVCMaS#a_ z8+Sby3HH3&jMy1Jvp6a)4aYR_HWGSdhch;v4pDx9EhD4QkBrJ-$oir}okT|v@Affd zc|2*AiS-9qH&i;(>XXp+h5AoC$_TpurR?NV>YgIYSVlzr4=|-`Zl|Sh($ From e552ba8344a87203037299a03c36b05b75545f05 Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:22:12 -0300 Subject: [PATCH 6/8] fix(code): count all live sessions for tray badge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `promptPending` is only true while the agent is actively generating — a quick prompt flickered the badge for under a second and a longer one hid it again the moment generation finished. Switch the running count to `sessions.size`, which stays stable from session creation through idle/cancellation. Emit `RunningCountChanged` when a session is added in `getOrCreateSession` (was previously only emitted around prompt()) and unconditionally on `cleanupSession`. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/src/main/services/agent/service.ts | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/apps/code/src/main/services/agent/service.ts b/apps/code/src/main/services/agent/service.ts index e20dbfed46..5b405deb1b 100644 --- a/apps/code/src/main/services/agent/service.ts +++ b/apps/code/src/main/services/agent/service.ts @@ -427,13 +427,7 @@ export class AgentService extends TypedEventEmitter { } public getRunningSessionCount(): number { - let count = 0; - for (const session of this.sessions.values()) { - if (session.promptPending || session.inFlightMcpToolCalls.size > 0) { - count++; - } - } - return count; + return this.sessions.size; } private emitRunningCountChanged(): void { @@ -867,6 +861,7 @@ When creating pull requests, add the following footer at the end of the PR descr this.sessions.set(taskRunId, session); this.recordActivity(taskRunId); + this.emitRunningCountChanged(); if (isRetry) { log.info("Session created after auth retry", { taskRunId }); @@ -935,7 +930,6 @@ When creating pull requests, add the following footer at the end of the PR descr session.promptPending = true; this.recordActivity(sessionId); this.sleepService.acquire(sessionId); - this.emitRunningCountChanged(); try { const result = await session.clientSideConnection.prompt({ @@ -951,7 +945,6 @@ When creating pull requests, add the following footer at the end of the PR descr session.lastActivityAt = Date.now(); this.recordActivity(sessionId); this.sleepService.release(sessionId); - this.emitRunningCountChanged(); if (!this.hasActiveSessions()) { this.emit(AgentServiceEvent.SessionsIdle, undefined); @@ -1236,8 +1229,6 @@ For git operations while detached: private async cleanupSession(taskRunId: string): Promise { const session = this.sessions.get(taskRunId); if (session) { - const wasRunning = - session.promptPending || session.inFlightMcpToolCalls.size > 0; this.cancelInFlightMcpToolCalls(session); this.sleepService.release(taskRunId); try { @@ -1254,7 +1245,7 @@ For git operations while detached: this.idleTimeouts.delete(taskRunId); } - if (wasRunning) this.emitRunningCountChanged(); + this.emitRunningCountChanged(); // When no sessions remain, tear down MCP Apps connections and cached resources if (this.sessions.size === 0) { From 2fbb72a62725a85d7e410d4ffd0750506ebd8c96 Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:24:08 -0300 Subject: [PATCH 7/8] fix(code): drop dilation ring on tray silhouette The 2-iteration binary_dilation I added to smooth anti-aliased edges also expanded the silhouette by ~2px on every side, which read as a visible border around the hedgehog. Generate the template from just the filled-holes mask with no dilation. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/build/tray/icon.template.png | Bin 461 -> 398 bytes apps/code/build/tray/icon.template@2x.png | Bin 953 -> 779 bytes apps/code/build/tray/icon.template@3x.png | Bin 1614 -> 1279 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/code/build/tray/icon.template.png b/apps/code/build/tray/icon.template.png index c48bd71f1e90849452711a40a5c17474b1e33d33..7b53775c59abd0b7381a97c676772d333b25560e 100644 GIT binary patch delta 371 zcmV-(0gV351C9fbB!5*&L_t(|oVArbPQySDM&GWj5QxhMIzc0t!GOcqu#+4;%lijrgSXj_sW{v*Xnm{z^87da9v$}gPmF~r;*HE;4xU8>qcSTFT`&|RF*hey!|G5fnNikz-?E?XDykwjXU5_vi1t}GOvLL;7Nk$ z5o}YStp6Oi2W%b{tP#9`0d@tN(%Doi%F_IjGui#6!>MluxSZ`CFcfZ^Sg`HV(|sDc zpj++N0eiq?08}**#-_8Wa$p}AQ+@3eWs>O!@QfUSx_WwGhxETnLDd2_`T=SuWBC2h R59d&EFRNR zpO&f)L*_E`n~;pFh)+`<;0kq`64c^aK$;@%aJ2xOR55vIU&}=_(ci}p+{K-UAK(JM z<5e+!PC5Q5yGJqeH@uB_9l$K57lmgMp5TMn#@Z&|T`|Eb;^%YW34R#HqX9hQu7E!s zcxQprJl696lYj6n49amh+Ym6OI^fUrm+Ix%z(w?rCssPvUgNf+blZSl!AHEqXY*gU zJk)!5gZJsFa1Q(U6ob#}>-4l#40UAl&a^R^Ccrt-S(V;>w5`6Jwoe#vR&8Nj>$iNU ze>#WNP|aux->yC_U7Bm$!VUAD$DwLm4@Qlu+;)ST*etWTZBxocHTZ%L=^M-Ej(IOw dmfLdp<2T-+djs*>TsZ&$002ovPDHLkV1g~5*s1^k diff --git a/apps/code/build/tray/icon.template@2x.png b/apps/code/build/tray/icon.template@2x.png index 51d23d0a20d12da8f41fe3ea2861a76d72ee8a53..09a23ef1c117f63ef84e0c015b10595040d18a01 100644 GIT binary patch delta 756 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 From 4056b7375323fd9616aeca51f5d74d3981747d1d Mon Sep 17 00:00:00 2001 From: Fernando Gomes Date: Tue, 26 May 2026 20:27:37 -0300 Subject: [PATCH 8/8] fix(code): invert tray template silhouette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Render the rounded-square area as the solid template and cut the hedgehog out of it instead of the other way around — the negative space reads cleaner at menu-bar size than a small lumpy hedgehog shape on its own. Generated-By: PostHog Code Task-Id: 01d444b5-b5d4-426a-9ae3-57ba28e54e09 --- apps/code/build/tray/icon.template.png | Bin 398 -> 477 bytes apps/code/build/tray/icon.template@2x.png | Bin 779 -> 975 bytes apps/code/build/tray/icon.template@3x.png | Bin 1279 -> 1419 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/code/build/tray/icon.template.png b/apps/code/build/tray/icon.template.png index 7b53775c59abd0b7381a97c676772d333b25560e..bdb41d5c90fca4abb8dc0e581ebb04ada6c2109f 100644 GIT binary patch delta 451 zcmV;!0X+VW1Kk6VB!8qyL_t(|oVC@zYE(fK2JqkATv5`9Mbt*3_zoh*RCd-DzJOS1 zm(JGCbapn{S=!i%1bhUs6BH~I)IyMunB99V?m6Ds^{%^7^T9BG&dhhteCIGz=`cbQ z<8_?I@t9YJ(MG?I&v-w}HHwAHc!6(WXqRkFoOy|jf?S15;eUBqvU%-C1o-Q!J7L&A zWVB_}8Q80o?;O5|aT2X9=6QIsz-be07w2o7!D@KPL^YvPRg5zit>J{`+6kN;;aIWw zL6_YTzT%BO%dexa^c69LDmYy&u5%41@ebRu={df{p_@y}vRTh~+tZcKbzF!|H*i;1 z*H5E=9ONn2Ab-k;H)b}LxhMIzc0t!GOcqu#+4;%lijrgSXj_sW{v*Xnm{z^87da9v$}gPmF~r;*HE;4xU8>qcSTFT`&|RF*hey!|G5fnNikz-?E?XDykwjXU5_vi1t}GOvLL;7Nk$ z5o}YStp6Oi2W%b{tP#9`0d@tN(%Doi%F_IjGui#6!>MluxSZ`CFcfZ^Sg`HV(|sDc zpj++N0eiq?08}**#-_8Wa$p}AQ+@3eWs>O!@QfUSx_WwGhxETnLDd2_`T=SuWBC2h R59t!)4R diff --git a/apps/code/build/tray/icon.template@2x.png b/apps/code/build/tray/icon.template@2x.png index 09a23ef1c117f63ef84e0c015b10595040d18a01..5bbf0608e575b98d2b797367bb952631564568a0 100644 GIT binary patch delta 954 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