-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Labels
P1: Post-Launch Week 1Ship within one week after launchShip within one week after launchenhancementNew feature or requestNew feature or request
Description
Feature Description
Add a macOS menu bar (system tray) icon in the top-right corner of the status bar to display real-time Agent status. Users can monitor task progress at a glance even when the main window is minimized or another app is in focus.
Requirements
Icon States
| State | Icon Appearance | Trigger |
|---|---|---|
| Idle | Static ClawWork icon (muted / low-saturation) | No Agent running |
| Running | Animated pulse/spin icon (accent green) | ≥1 Task with active Agent streaming |
| Unread | Icon with small green dot badge | Agent completed but user hasn't viewed result |
| Disconnected | Icon with orange exclamation badge | Gateway WS connection lost |
Click Behavior
- Single click → Show mini status popover (see below)
- Click outside popover → Dismiss popover
- Double-click / click "Open ClawWork" inside popover → Focus / restore main window
Mini Status Popover
Lists all running Tasks with:
- Task name (truncated + tooltip)
- Latest streaming message snippet (≤ 60 chars)
- Running duration (relative time, e.g. "3 min ago")
Popover footer:
- "Open ClawWork" button → focus main window
- "Quit" button →
app.quit()
When no tasks are running, show an empty state: "No active tasks".
Implementation Notes
Electron Tray API
// packages/desktop/src/main/tray.ts
import { Tray, Menu, nativeImage } from 'electron'
let tray: Tray | null = null
export function initTray(mainWindow: BrowserWindow): void {
const icon = nativeImage.createFromPath(/* @2x icon path */)
tray = new Tray(icon)
tray.setToolTip('ClawWork')
tray.on('click', () => showTrayPopover(mainWindow))
}
export function updateTrayStatus(
status: 'idle' | 'running' | 'unread' | 'disconnected'
): void {
// Swap template icon or overlay badge
}State Synchronization
Two viable approaches:
- Renderer (
taskStore/messageStore) detects state changes and notifies main process via IPC. - Main process subscribes directly to Gateway WS events in
gateway-client.ts(already has awareness of active sessions).
Icon Assets
- Provide
tray-icon.png(16×16) andtray-icon@2x.png(32×32) as macOS template images (setTemplateImage: true) so they automatically adapt to Dark / Light mode. - For the "running" animation, either draw rotating frames dynamically with
nativeImage+ canvas, or cycle frames viatray.setImage()on a timer.
Acceptance Criteria
- ClawWork icon appears in the menu bar on app launch
- Icon shows animated state when ≥1 Agent is streaming
- Icon shows "unread" badge after Agent completes; badge clears when the user views the result in the main window
- Icon shows disconnection badge when the Gateway WS connection is lost
- Clicking the icon opens a popover listing running Tasks (shows "No active tasks" when idle)
- "Open ClawWork" in the popover focuses the main window
- Closing the main window (window
closeevent) hides it instead of quitting — the app stays alive in the tray; "Quit" in the popover exits cleanly
Related Files
| File | Notes |
|---|---|
packages/desktop/src/main/index.ts |
Call initTray() here |
packages/desktop/src/main/ws/gateway-client.ts |
Subscribe to connection state for tray badge |
packages/desktop/src/renderer/stores/taskStore.ts |
Task running state |
packages/desktop/src/renderer/stores/messageStore.ts |
Streaming message snippets |
packages/desktop/src/preload/index.ts |
Add tray.updateStatus IPC bridge |
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P1: Post-Launch Week 1Ship within one week after launchShip within one week after launchenhancementNew feature or requestNew feature or request