Skip to content

feat: browser-tab notification for a parked approval (goal 0132 slice A) - #361

Merged
alicoding merged 1 commit into
mainfrom
feat/0132-tab-notification
Aug 22, 2026
Merged

feat: browser-tab notification for a parked approval (goal 0132 slice A)#361
alicoding merged 1 commit into
mainfrom
feat/0132-tab-notification

Conversation

@alicoding

Copy link
Copy Markdown
Owner

Summary

  • Adds a generic browser-tab notification seam (app/useBrowserNotify.ts + shared/browserNotify.ts, {dedupeKey, title, body, onClick}) that raises a Notifications-API banner from a live, server-mode tab when something needs action and that tab isn't focused -- gated by a pure, unit-tested predicate (shouldNotifyBrowserTab).
  • Wires exactly one consumer this slice: a parked guardrail approval (App.tsx), reusing the existing pendingApprovalDescription copy and in-app setView({kind:'review'}) navigation on click. A future "run finished"/"agent acted while away" notification is a new call site, not a change to the seam.
  • Opt-in control ("Notify me on this device") in Settings > Remote access, requesting permission on click only, with honest default/granted/denied copy.
  • Adds the real-OS-banner entry to .claude/rules/testing.md's manual-only registry (no CI surface can raise or click a real system notification).
  • Documents the control in userdocs/reference/settings.md, regenerated llms-full.txt via go generate ./internal/docsgen.

Test plan

  • frontend/src/app/browserNotifyPredicate.test.ts -- 8 cases covering the predicate's full input range (Vitest).
  • frontend/e2e/remote-access.spec.ts -- opt-in control presence, default/granted/denied states, and the click -> requestPermission -> granted transition (Playwright, real mill-server binary).
  • Full local lefthook suite green (tsc, eslint, vitest+coverage floors, boundaries, comment-hygiene, ui-copy, docsgen-freshness, file-loc-limit).
  • Manual (documented in testing.md, not CI-provable): a real system notification banner appearing and click-to-focus-and-navigate, verified against a real browser tab reaching a server-mode instance.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FW5GkkAG8du7tNdYLk2zSd

Adds a generic browser-notification seam (app/useBrowserNotify.ts +
shared/browserNotify.ts) that raises a Notifications-API banner from a
live, server-mode tab when a decision needs action and that tab isn't
focused -- the tap on the shoulder the goal names as its whole value.
The parked-guardrail-approval call in App.tsx is the seam's first
consumer, not the only one it's built for: a future event just calls
it with different copy and a different click target.

Opt-in lives in Settings > Remote access ("Notify me on this device"),
requesting permission on click only, and states its own
default/granted/denied state honestly. Clicking a raised notification
focuses the tab and lands on the Review queue via existing in-app
navigation.

- shouldNotifyBrowserTab is a pure, unit-tested predicate (server mode
  AND unfocused AND unseen dedupe key).
- remote-access.spec.ts covers the opt-in control's presence and its
  default/granted/denied states, plus the click -> requestPermission ->
  granted round trip.
- testing.md's manual-only registry gets the real-OS-banner entry (no
  CI surface can raise or click a real system notification).
- userdocs/reference/settings.md documents the control; llms-full.txt
  regenerated via go generate ./internal/docsgen.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FW5GkkAG8du7tNdYLk2zSd
@alicoding
alicoding enabled auto-merge (squash) August 22, 2026 20:54
@alicoding
alicoding merged commit 26d5932 into main Aug 22, 2026
27 checks passed
@alicoding
alicoding deleted the feat/0132-tab-notification branch August 22, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant