From 6e0ae8db584820d3bf71e9a5af6742bca9bcbc47 Mon Sep 17 00:00:00 2001 From: Ara Date: Mon, 18 May 2026 17:44:32 -0700 Subject: [PATCH] Add Hub Monitor UI to menubar example (#10688) * add menubar hub monitor dashboard * docs: add menubar preview screenshot --- sdk/apps/examples/menubar/README.md | 18 + .../menubar/assets/hub-monitor-preview.jpg | Bin 0 -> 72779 bytes sdk/apps/examples/menubar/package.json | 1 + sdk/apps/examples/menubar/sidecar/index.ts | 333 +++- .../examples/menubar/src-tauri/src/main.rs | 104 +- .../menubar/src-tauri/tauri.conf.json | 15 +- sdk/apps/examples/menubar/ui/index.html | 1341 +++++++++++++++++ 7 files changed, 1775 insertions(+), 37 deletions(-) create mode 100644 sdk/apps/examples/menubar/assets/hub-monitor-preview.jpg create mode 100644 sdk/apps/examples/menubar/ui/index.html diff --git a/sdk/apps/examples/menubar/README.md b/sdk/apps/examples/menubar/README.md index 7855a08d39..d81d085eef 100644 --- a/sdk/apps/examples/menubar/README.md +++ b/sdk/apps/examples/menubar/README.md @@ -1,3 +1,7 @@ +### Preview + +![Cline Hub Monitor preview](./assets/hub-monitor-preview.jpg) + ### Architecture Overview ``` @@ -14,6 +18,12 @@ Menu Bar Sidecar (apps/examples/menubar/sidecar/index.ts) ← TypeScript/Bun pr │ JSON lines on stdout: hub_state / notification / ready ▼ Rust Tauri App (apps/examples/menubar/src-tauri/src/main.rs) + │ + ├── Hub Monitor Window (ui/index.html) + │ ● Live hub status, uptime, clients, sessions + │ ● Running session tracker and inspector + │ ● Recent events and background-session launcher + │ │ ├── System Tray Icon with dynamic menu │ ● Hub Connected — 3 clients, 2 sessions @@ -24,3 +34,11 @@ Rust Tauri App (apps/examples/menubar/src-tauri/src/main.rs) │ └── Logs notifications to stderr (with severity) ``` + +### Dev Commands + +From `sdk/apps/examples/menubar/`: + +- `bun run dev:ui` - run only the Hub Monitor UI at `http://127.0.0.1:3466/` with preview data +- `bun run dev` - run the full Tauri app with the real hub sidecar +- `bun run typecheck` - TypeScript check diff --git a/sdk/apps/examples/menubar/assets/hub-monitor-preview.jpg b/sdk/apps/examples/menubar/assets/hub-monitor-preview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0bd2fec2227bf9ec8f354836f467ee9ab891aaaa GIT binary patch literal 72779 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 Y^M@tmR!Xv=#4&1=h}qMjfj<}i7cWCJHUIzs literal 0 HcmV?d00001 diff --git a/sdk/apps/examples/menubar/package.json b/sdk/apps/examples/menubar/package.json index 61ec00bd1b..b95c3fffc5 100644 --- a/sdk/apps/examples/menubar/package.json +++ b/sdk/apps/examples/menubar/package.json @@ -4,6 +4,7 @@ "private": true, "type": "module", "scripts": { + "dev:ui": "python3 -m http.server 3466 --bind 127.0.0.1 --directory ui", "dev": "tauri dev", "build": "tauri build", "build:sidecar:bin": "bun run scripts/build-sidecar-bin.ts", diff --git a/sdk/apps/examples/menubar/sidecar/index.ts b/sdk/apps/examples/menubar/sidecar/index.ts index 68460708ef..df0d42023f 100644 --- a/sdk/apps/examples/menubar/sidecar/index.ts +++ b/sdk/apps/examples/menubar/sidecar/index.ts @@ -23,8 +23,18 @@ interface TrackedSession { sessionId: string; status: string; workspaceRoot: string; + cwd?: string; createdAt: number; + updatedAt: number; createdByClientId?: string; + title?: string; + provider?: string; + model?: string; + prompt?: string; + inputTokens?: number; + outputTokens?: number; + totalCost?: number; + agentCount?: number; } interface ClientSummary { @@ -33,6 +43,33 @@ interface ClientSummary { sessionCount: number; } +interface SessionSummary { + sessionId: string; + title: string; + status: string; + workspaceRoot: string; + workspaceName: string; + cwd?: string; + model?: string; + provider?: string; + createdAt: number; + updatedAt: number; + createdByClientId?: string; + prompt?: string; + inputTokens?: number; + outputTokens?: number; + totalCost?: number; + agentCount: number; +} + +interface EventRecord { + id: string; + title: string; + body: string; + severity: "info" | "success" | "warn" | "error"; + timestamp: number; +} + type ClientSummaryGroup = { label: string; name: string; @@ -67,8 +104,9 @@ interface ProviderLaunchAuth { } interface SidecarCommand { - type: "new_chat" | "shutdown_hub"; + type: "new_chat" | "shutdown_hub" | "abort_session"; prompt?: string; + sessionId?: string; } function isVisibleClient(clientType: string): boolean { @@ -103,6 +141,70 @@ function emitNotification( }); } +function asRecord(value: unknown): Record | undefined { + return value && typeof value === "object" + ? (value as Record) + : undefined; +} + +function asString(value: unknown): string | undefined { + return typeof value === "string" && value.trim() ? value.trim() : undefined; +} + +function asNumber(value: unknown): number | undefined { + return typeof value === "number" && Number.isFinite(value) ? value : undefined; +} + +function basename(value: string | undefined): string { + const trimmed = value?.trim(); + if (!trimmed) { + return "workspace"; + } + const parts = trimmed.split(/[\\/]+/).filter(Boolean); + return parts.at(-1) ?? trimmed; +} + +function shortSessionId(sessionId: string): string { + return sessionId.length > 10 ? sessionId.slice(0, 10) : sessionId; +} + +function pushEvent( + events: EventRecord[], + title: string, + body: string, + severity: EventRecord["severity"] = "info", + timestamp = Date.now(), +): void { + events.unshift({ + id: `${timestamp}-${events.length}-${title}`, + title, + body, + severity, + timestamp, + }); + if (events.length > 30) { + events.length = 30; + } +} + +function metadataFor( + session: SessionRecord | Record, +): Record { + return asRecord(session.metadata) ?? {}; +} + +function usageFor( + session: SessionRecord | Record, +): Record { + return ( + asRecord(session.aggregateUsage) ?? + asRecord(session.usage) ?? + asRecord(metadataFor(session).aggregateUsage) ?? + asRecord(metadataFor(session).usage) ?? + {} + ); +} + function formatUptime(ms: number): string { const totalSeconds = Math.max(0, Math.floor(ms / 1000)); const days = Math.floor(totalSeconds / 86_400); @@ -169,6 +271,87 @@ function summarizeClient(client: TrackedClient): { }; } +function sessionTitle(session: SessionRecord | Record): string { + const raw = session as Record; + const metadata = metadataFor(session); + const title = asString(metadata.title); + if (title) { + return title; + } + const prompt = asString(raw.prompt) ?? asString(metadata.prompt); + if (prompt) { + return prompt.length > 34 ? `${prompt.slice(0, 31)}...` : prompt; + } + return basename(asString(raw.workspaceRoot) ?? asString(raw.cwd)); +} + +function trackedSessionFrom( + session: SessionRecord | Record, +): TrackedSession | undefined { + const raw = session as Record; + const sessionId = asString(raw.sessionId); + if (!sessionId) { + return undefined; + } + const metadata = metadataFor(session); + const usage = usageFor(session); + const createdAt = + asNumber(raw.createdAt) ?? + asNumber(raw.startedAt) ?? + asNumber(metadata.createdAt) ?? + Date.now(); + return { + sessionId, + status: asString(raw.status) ?? "running", + workspaceRoot: asString(raw.workspaceRoot) ?? asString(raw.cwd) ?? "", + cwd: asString(raw.cwd), + createdAt, + updatedAt: + asNumber(raw.updatedAt) ?? + asNumber(raw.endedAt) ?? + asNumber(metadata.updatedAt) ?? + createdAt, + createdByClientId: asString(raw.createdByClientId), + title: sessionTitle(session), + provider: asString(raw.provider) ?? asString(metadata.provider), + model: asString(raw.model) ?? asString(metadata.model), + prompt: asString(raw.prompt) ?? asString(metadata.prompt), + inputTokens: + asNumber(usage.inputTokens) ?? + asNumber(usage.input) ?? + asNumber(usage.totalInputTokens), + outputTokens: + asNumber(usage.outputTokens) ?? + asNumber(usage.output) ?? + asNumber(usage.totalOutputTokens), + totalCost: asNumber(usage.totalCost) ?? asNumber(metadata.totalCost), + agentCount: Array.isArray(raw.participants) + ? Math.max(1, raw.participants.length) + : 1, + }; +} + +function toSessionSummary(session: TrackedSession): SessionSummary { + return { + sessionId: session.sessionId, + title: session.title || basename(session.workspaceRoot), + status: session.status, + workspaceRoot: session.workspaceRoot, + workspaceName: basename(session.workspaceRoot || session.cwd), + cwd: session.cwd, + model: session.model, + provider: session.provider, + createdAt: session.createdAt, + updatedAt: session.updatedAt, + createdByClientId: session.createdByClientId, + prompt: session.prompt, + inputTokens: session.inputTokens, + outputTokens: session.outputTokens, + totalCost: session.totalCost, + agentCount: session.agentCount ?? 1, + }; +} + function parseLastSessionContext( session: SessionRecord | Record | undefined, ): LastSessionContext | undefined { @@ -267,6 +450,7 @@ async function main(): Promise { const clients = new Map(); const sessions = new Map(); + const events: EventRecord[] = []; let lastSessionContext: LastSessionContext | undefined; let hubStartedAt: string | undefined; @@ -316,13 +500,10 @@ async function main(): Promise { ) { continue; } - sessions.set(session.sessionId, { - sessionId: session.sessionId, - status: session.status, - workspaceRoot: session.workspaceRoot, - createdAt: session.createdAt, - createdByClientId: session.createdByClientId, - }); + const tracked = trackedSessionFrom(session); + if (tracked) { + sessions.set(tracked.sessionId, tracked); + } } const mostRecentContext = [...knownSessions] .sort((a, b) => b.updatedAt - a.updatedAt) @@ -331,6 +512,12 @@ async function main(): Promise { if (mostRecentContext) { lastSessionContext = mostRecentContext; } + pushEvent( + events, + "Hub monitor connected", + `${knownClients.length} clients and ${knownSessions.length} sessions discovered`, + "success", + ); }; function emitState(): void { @@ -378,6 +565,10 @@ async function main(): Promise { clients: Array.from(clients.values()), sessions: Array.from(sessions.values()), clientSummaries, + sessionSummaries: Array.from(sessions.values()) + .sort((a, b) => b.updatedAt - a.updatedAt) + .map(toSessionSummary), + events, lastWorkspaceRoot: lastSessionContext?.workspaceRoot, hubStartedAt, hubUptime: hubStartedAt @@ -455,6 +646,30 @@ async function main(): Promise { } } + async function abortBackgroundSession(sessionId: string): Promise { + const trimmedSessionId = sessionId.trim(); + if (!trimmedSessionId) { + return; + } + try { + await sessionClient.abortRuntimeSession(trimmedSessionId); + pushEvent( + events, + "Session abort requested", + `Requested stop for ${shortSessionId(trimmedSessionId)}`, + "warn", + ); + emitState(); + } catch (error) { + emit({ + type: "notification", + title: "Stop session failed", + body: error instanceof Error ? error.message : String(error), + severity: "error", + }); + } + } + const stdin = createInterface({ input: process.stdin, terminal: false }); stdin.on("line", (line) => { const trimmed = line.trim(); @@ -476,10 +691,25 @@ async function main(): Promise { if (command?.type === "shutdown_hub") { void shutdownHub(); } + if (command?.type === "abort_session") { + if (typeof command.sessionId === "string") { + void abortBackgroundSession(command.sessionId); + } + } }); uiClient.subscribeUI({ onNotify(payload: HubUINotifyPayload) { + pushEvent( + events, + payload.title, + payload.body, + payload.severity === "error" + ? "error" + : payload.severity === "warning" + ? "warn" + : "info", + ); emit({ type: "notification", title: payload.title, @@ -510,13 +740,26 @@ async function main(): Promise { : "unknown", connectedAt: Date.now(), }); + pushEvent( + events, + "Client connected", + `${formatClientLabel(typeof payload.clientType === "string" ? payload.clientType : "unknown")} joined the hub`, + "success", + ); emitState(); }, onClientDisconnected(payload) { const clientId = typeof payload.clientId === "string" ? payload.clientId : undefined; if (!clientId) return; + const client = clients.get(clientId); clients.delete(clientId); + pushEvent( + events, + "Client disconnected", + `${client?.displayName ?? client?.clientType ?? clientId} left the hub`, + "warn", + ); emitState(); }, onSessionCreated(payload) { @@ -543,19 +786,16 @@ async function main(): Promise { emitState(); return; } - sessions.set(sessionId, { - sessionId, - status, - workspaceRoot: - typeof session.workspaceRoot === "string" - ? session.workspaceRoot - : "", - createdAt: Date.now(), - createdByClientId: - typeof session.createdByClientId === "string" - ? session.createdByClientId - : undefined, - }); + const tracked = trackedSessionFrom({ ...session, status }); + if (!tracked) return; + sessions.set(sessionId, tracked); + pushEvent( + events, + `Started session "${tracked.title ?? shortSessionId(sessionId)}"`, + `${tracked.workspaceRoot || "workspace"} on ${tracked.model ?? "selected model"}`, + "success", + tracked.createdAt, + ); emitState(); }, onSessionUpdated(payload) { @@ -584,26 +824,42 @@ async function main(): Promise { return; } if (existing) { + const previousStatus = existing.status; existing.status = status; + existing.updatedAt = + asNumber(session.updatedAt) ?? asNumber(session.endedAt) ?? Date.now(); + existing.title = sessionTitle(session); + existing.workspaceRoot = + typeof session.workspaceRoot === "string" + ? session.workspaceRoot + : existing.workspaceRoot; + existing.cwd = + typeof session.cwd === "string" ? session.cwd : existing.cwd; + const metadata = metadataFor(session); + existing.provider = + asString(session.provider) ?? + asString(metadata.provider) ?? + existing.provider; + existing.model = + asString(session.model) ?? asString(metadata.model) ?? existing.model; existing.createdByClientId = typeof session.createdByClientId === "string" ? session.createdByClientId : existing.createdByClientId; sessions.set(sessionId, existing); + if (previousStatus !== status) { + pushEvent( + events, + `Session ${status}`, + `${existing.title ?? shortSessionId(sessionId)} changed from ${previousStatus}`, + status === "running" ? "success" : status === "idle" ? "info" : "warn", + ); + } } else { - sessions.set(sessionId, { - sessionId, - status, - workspaceRoot: - typeof session.workspaceRoot === "string" - ? session.workspaceRoot - : "", - createdAt: Date.now(), - createdByClientId: - typeof session.createdByClientId === "string" - ? session.createdByClientId - : undefined, - }); + const tracked = trackedSessionFrom({ ...session, status }); + if (tracked) { + sessions.set(sessionId, tracked); + } } emitState(); }, @@ -617,13 +873,20 @@ async function main(): Promise { ? session.sessionId : typeof payload.sessionId === "string" ? payload.sessionId - : undefined; + : undefined; if (!sessionId) return; const participantCount = Array.isArray(session?.participants) ? session.participants.length : 0; if (participantCount <= 0) { + const tracked = sessions.get(sessionId); sessions.delete(sessionId); + pushEvent( + events, + "Session detached", + `${tracked?.title ?? shortSessionId(sessionId)} has no active participants`, + "warn", + ); emitState(); } }, diff --git a/sdk/apps/examples/menubar/src-tauri/src/main.rs b/sdk/apps/examples/menubar/src-tauri/src/main.rs index 32721d61fd..a166141a62 100644 --- a/sdk/apps/examples/menubar/src-tauri/src/main.rs +++ b/sdk/apps/examples/menubar/src-tauri/src/main.rs @@ -23,6 +23,8 @@ struct HubState { hub_uptime: Option, last_error: Option, client_summaries: Vec, + session_summaries: Vec, + events: Vec, notifications: Vec, } @@ -34,6 +36,37 @@ struct ClientSummary { session_count: usize, } +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct SessionSummary { + session_id: String, + title: String, + status: String, + workspace_root: String, + workspace_name: String, + cwd: Option, + model: Option, + provider: Option, + created_at: u64, + updated_at: u64, + created_by_client_id: Option, + prompt: Option, + input_tokens: Option, + output_tokens: Option, + total_cost: Option, + agent_count: usize, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +struct HubEventRecord { + id: String, + title: String, + body: String, + severity: String, + timestamp: u64, +} + #[derive(Clone, Serialize, Deserialize)] struct NotificationRecord { title: String, @@ -53,6 +86,8 @@ struct SidecarMessage { clients: Option>, sessions: Option>, client_summaries: Option>, + session_summaries: Option>, + events: Option>, last_workspace_root: Option, hub_uptime: Option, title: Option, @@ -133,6 +168,13 @@ fn push_notification( fn resolve_sidecar_script(workspace_root: &str, launch_cwd: &str) -> Option { let candidates = [ + PathBuf::from(workspace_root) + .join("sdk") + .join("apps") + .join("examples") + .join("menubar") + .join("sidecar") + .join("index.ts"), PathBuf::from(workspace_root) .join("apps") .join("examples") @@ -161,6 +203,16 @@ fn resolve_sidecar_binary(workspace_root: &str) -> Option { let binary_name = sidecar_binary_name(); let current_exe = std::env::current_exe().ok(); let candidates = [ + Some( + PathBuf::from(workspace_root) + .join("sdk") + .join("apps") + .join("examples") + .join("menubar") + .join("src-tauri") + .join("bin") + .join(&binary_name), + ), Some( PathBuf::from(workspace_root) .join("apps") @@ -305,6 +357,8 @@ fn handle_sidecar_message(state: &Arc, msg: SidecarMessage, raw: &str) if let Ok(mut hub) = state.hub_state.lock() { hub.connected = connected; hub.client_summaries = msg.client_summaries.unwrap_or_default(); + hub.session_summaries = msg.session_summaries.unwrap_or_default(); + hub.events = msg.events.unwrap_or_default(); hub.last_workspace_root = msg .last_workspace_root .and_then(|value| if value.trim().is_empty() { None } else { Some(value) }); @@ -517,6 +571,9 @@ fn build_tray_menu( hub_state.last_workspace_root.is_some(), None::<&str>, )?; + let open_dashboard_item = + MenuItem::with_id(app, "open_dashboard", "Open Dashboard", true, None::<&str>)?; + items.push(Box::new(open_dashboard_item)); items.push(Box::new(new_chat_item)); items.push(Box::new(PredefinedMenuItem::separator(app)?)); @@ -554,6 +611,8 @@ fn get_hub_state(state: tauri::State<'_, Arc>) -> serde_json::Value { serde_json::json!({ "connected": hub.connected, "clientSummaries": hub.client_summaries, + "sessionSummaries": hub.session_summaries, + "events": hub.events, "lastWorkspaceRoot": hub.last_workspace_root, "hubUptime": hub.hub_uptime, "lastError": hub.last_error, @@ -562,6 +621,39 @@ fn get_hub_state(state: tauri::State<'_, Arc>) -> serde_json::Value { }) } +#[tauri::command] +fn start_new_session(prompt: String, state: tauri::State<'_, Arc>) -> Result<(), String> { + let prompt = prompt.trim().to_string(); + if prompt.is_empty() { + return Err("Prompt cannot be empty".to_string()); + } + send_sidecar_command( + state.inner(), + serde_json::json!({ + "type": "new_chat", + "prompt": prompt, + }), + ) +} + +#[tauri::command] +fn abort_session( + session_id: String, + state: tauri::State<'_, Arc>, +) -> Result<(), String> { + let session_id = session_id.trim().to_string(); + if session_id.is_empty() { + return Err("Session id cannot be empty".to_string()); + } + send_sidecar_command( + state.inner(), + serde_json::json!({ + "type": "abort_session", + "sessionId": session_id, + }), + ) +} + fn main() { let app_state = Arc::new(AppState::new()); let launch_cwd = std::env::current_dir() @@ -649,6 +741,12 @@ fn main() { thread::sleep(Duration::from_millis(300)); app.exit(0); } + "open_dashboard" => { + if let Some(window) = app.get_webview_window("main") { + let _ = window.show(); + let _ = window.set_focus(); + } + } "latest_error" => { let state = app.state::>(); let error = { @@ -709,7 +807,11 @@ fn main() { Ok(()) }) - .invoke_handler(tauri::generate_handler![get_hub_state]) + .invoke_handler(tauri::generate_handler![ + get_hub_state, + start_new_session, + abort_session + ]) .run(tauri::generate_context!()) .expect("error running menubar app"); } diff --git a/sdk/apps/examples/menubar/src-tauri/tauri.conf.json b/sdk/apps/examples/menubar/src-tauri/tauri.conf.json index d5c5dda37a..1a3b3312fc 100644 --- a/sdk/apps/examples/menubar/src-tauri/tauri.conf.json +++ b/sdk/apps/examples/menubar/src-tauri/tauri.conf.json @@ -6,10 +6,23 @@ "build": { "beforeDevCommand": "bun run build:sidecar:bin", "beforeBuildCommand": "bun run build:sidecar:bin", + "frontendDist": "../ui", "beforeBundleCommand": "[ \"$(uname)\" = \"Darwin\" ] && [ -e ./target/release/bundle/macos/Cline\\ Hub.app ] && xattr -d com.apple.quarantine ./target/release/bundle/macos/Cline\\ Hub.app || true" }, "app": { - "windows": [], + "withGlobalTauri": true, + "windows": [ + { + "label": "main", + "title": "Cline Hub Monitor", + "width": 1600, + "height": 900, + "minWidth": 1180, + "minHeight": 720, + "resizable": true, + "decorations": false + } + ], "security": { "csp": null } diff --git a/sdk/apps/examples/menubar/ui/index.html b/sdk/apps/examples/menubar/ui/index.html new file mode 100644 index 0000000000..8bc5f0042b --- /dev/null +++ b/sdk/apps/examples/menubar/ui/index.html @@ -0,0 +1,1341 @@ + + + + + + Cline Hub Monitor + + + +

+
+
+ + +
+ +
+ + +
+
+
Session Inspector
+
+ + + +
+
+ +
+
+ +
+ refactor-auth + Preview data +
+
Running
+
+
+ dev-studio - Started 8m ago - ID: sess_8f3c2a7d +
+ +
+ +
+
+
Overview
+
+
+ +
+
Live Transcript (preview)
+
+
+ +
+
+ Timeline + +
+
+
+
+ + +
+
+
+
+ + + +