Add OS notifications when an agent needs an approval#122
Open
germanescobar wants to merge 1 commit into
Open
Conversation
Agents that block on a tool/plan approval were only surfaced through the per-turn, per-session SSE, so the user got no signal while viewing another session or with the app backgrounded — exactly when it matters. Add an app-wide notification path: - session-runtime emits a `needs_input` RuntimeNotification when an agent records a pending approval, via a module EventEmitter. - New `GET /api/events` SSE endpoint bridges those events to the renderer, independent of which session view is mounted. - `useApprovalNotifications` opens one EventSource for the app lifetime and raises an OS Notification, suppressing the alert when the target session is already foreground and focused. Clicking focuses the window and opens it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Agents that block on a tool/plan approval were only surfaced through the per-turn, per-session SSE in the sessions route. That stream only reaches the client currently watching that session — so if the user was on another session or had the app backgrounded (exactly when an alert is useful), they got no signal.
This adds an app-wide notification path for
needs_input(approval) transitions, raising an OS notification.How
server/lib/session-runtime.ts— moduleEventEmitter+RuntimeNotificationtype +onRuntimeNotification(listener)subscriber.recordPendingApprovalemits aneeds_inputevent (sessionId, projectId, worktreeId, provider, toolName, requestId) the moment an agent blocks.server/index.ts— newGET /api/eventsSSE endpoint bridging emitter events to any connected renderer, with a 15s heartbeat and clean unsubscribe on disconnect. Independent of which session view is mounted.client/src/lib/useApprovalNotifications.ts— opens oneEventSource("/api/events")for the app lifetime, raises an OSNotification, suppresses the alert when the target session is already foreground and focused (document.hasFocus()), dedupes per session viatag, and on click focuses the window (controller.showWindow()) and opens the session.client/src/App.tsx— wires the hook in, passing the foreground session id and routing clicks through the existinghandleSelectSession.Scope
First cut is approval/needs-input only, notifications only (no dock badge). The emitter is generic, so "turn finished" / "errors" can be added later as a one-line emit at the completion path plus a
kindin the hook — no new plumbing.Notes
Test plan
tsc -p server/tsconfig.json)vite build)sessions.test.ts16/16 pass🤖 Generated with Claude Code