Add stackable toast notifications #5

Merged
harry merged 1 commits from worktree-toast-notifications into main 2026-05-15 20:28:10 +01:00
Owner

Summary

  • Replaces the single-slot status-line flash with a top-right toast stack rendered over the focused pane.
  • flashError, flashTransient, and MCP request_human_attention now push onto the same stack (cap 5, oldest drops on overflow).
  • Ctrl-N dismisses the most recent toast. Empty stack lets Ctrl-N pass through to the focused PTY so readline / nano / emacs / opencode keep their bindings.
  • New "Clear notifications" palette command empties the stack.

Visual

Sample toast rendered by the new toast_dismiss harness scenario:

STEADY READY
                                       ╭────────────────────────────────────────────────╮
                                       │ ! steady — needs eyes on the deploy            │
                                       ╰────────────────────────────────────────────────╯

Test plan

  • go test ./...
  • go test -race ./internal/app/ ./internal/harness/
  • New unit tests in internal/app/toast_test.go cover push/cap/FIFO/dismissTop/clear/snapshot-copy
  • New harness scenario internal/harness/scenarios/toast_dismiss.json exercises attention toast → Ctrl-N → dismissed
  • Existing error_flash_preserves_focused_pane.json still passes (toast surface preserves focused pane content)

Notes

  • Ctrl-N was chosen over Ctrl-X because opencode and other terminal apps bind Ctrl-X heavily; falling-through when the stack is empty keeps it cooperative.
  • Toasts are deliberately not auto-dismissed — user explicitly requested manual control.
## Summary - Replaces the single-slot status-line flash with a top-right toast stack rendered over the focused pane. - `flashError`, `flashTransient`, and MCP `request_human_attention` now push onto the same stack (cap 5, oldest drops on overflow). - `Ctrl-N` dismisses the most recent toast. Empty stack lets `Ctrl-N` pass through to the focused PTY so readline / nano / emacs / opencode keep their bindings. - New "Clear notifications" palette command empties the stack. ## Visual Sample toast rendered by the new `toast_dismiss` harness scenario: ``` STEADY READY ╭────────────────────────────────────────────────╮ │ ! steady — needs eyes on the deploy │ ╰────────────────────────────────────────────────╯ ``` ## Test plan - [x] `go test ./...` - [x] `go test -race ./internal/app/ ./internal/harness/` - [x] New unit tests in `internal/app/toast_test.go` cover push/cap/FIFO/dismissTop/clear/snapshot-copy - [x] New harness scenario `internal/harness/scenarios/toast_dismiss.json` exercises attention toast → Ctrl-N → dismissed - [x] Existing `error_flash_preserves_focused_pane.json` still passes (toast surface preserves focused pane content) ## Notes - `Ctrl-N` was chosen over `Ctrl-X` because opencode and other terminal apps bind Ctrl-X heavily; falling-through when the stack is empty keeps it cooperative. - Toasts are deliberately *not* auto-dismissed — user explicitly requested manual control.
harry added 1 commit 2026-05-15 20:27:02 +01:00
Replaces the single-slot status-line flash with a top-right toast
stack over the focused pane. flashError, flashTransient, and
notifyAttention all push onto the same stack (cap 5, FIFO drop).
Ctrl-N dismisses the most recent toast; empty stack falls through to
the focused PTY so readline / nano / emacs / opencode bindings keep
working. A new "Clear notifications" palette item empties the stack.
harry merged commit e4ab8c2136 into main 2026-05-15 20:28:10 +01:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: harry/patterm#5