Repository navigation
How Notifications Work
Every message the app shows (a push, a failed pull, an Undo after a discard) goes through one toast store. The store pops it up as a balloon and records it in a history that the Notifications panel lists. The look: balloons in the bottom right corner and a Notifications tool window on the right.
A message that pops up and fades is easy to miss, especially git's error text after a failed pull. In a workspace with many repositories, a bare "Pushed" also does not say where. The old toasts had a colored edge and a button, and the history lived in a small popup on the status bar. Users asked for the IDE layout: readable balloons, and a panel in the right sidebar where every event stays until it is cleared.
flowchart TD
A[repoStore.run / runOp, other callers] --> B[toast.show: kind, title, detail, options]
B --> C[notifications.record: history entry with source]
B --> D{notifications.popsUp}
D -- panel shown, or Do Not Disturb and not an error --> E[History only]
D -- yes --> F[toast.items, at most 4]
F --> G[ToastHost: Notification balloons]
G -- pointer over --> H[toast.hold: timer stops]
C --> I[NotificationsPanel: Notification rows]
I --> J[remove, clear, runNotificationAction]
- A caller says what happened:
toast.success(title, detail, source), ortoast.show(kind, title, detail, { timeoutMs, action, source }).repoStore.runandrunOppassnotificationSource(repoPath), the repository's name. Git operations write their text withgitReport.ts(see below). - The store records every message in the history first (
notifications.record), so Do Not Disturb never loses one. -
shouldPopUpdecides whether a balloon shows. It says no while the Notifications panel is shown, since the message is already in view (the IDE does the same). With Do Not Disturb on, it lets only errors through. - A balloon closes after its timeout: 9 s for errors, 6 s for warnings, 8 s with a link, 3.5 s otherwise.
ToastHostcallsonholdwhen the pointer or the focus enters a balloon, which stops the timer. Leaving starts a 2.5 s timer. With more thanMAX_TOASTS(4) balloons up, the oldest close early. - The panel draws
notifications.itemsas rows.editorSettingsSynckeepsnotifications.openequal to "the right sidebar shows the Notifications panel". Opening it marks everything read, and the ids that were unread go intonotifications.fresh, which the rows show as a dot until the panel closes. Messages that arrive while it is open are read at once and joinfresh.
The bells in the right activity bar and the status bar both call settings.toggleRightPanel("notifications"), and so does View > Notifications. They count unread errors and warnings (unreadAlerts), and turn red when one is an error (hasUnreadError).
A list of messages that all read "Pushed" or "Pulled" says nothing, so src/lib/notifications/gitReport.ts words each git operation from the branch state before it and git's own output:
-
refUpdatesreads the<flag> <summary> <from> -> <to>lines that fetch and push print (a..b main -> origin/main,* [new branch],- [deleted],+forced,!rejected). -
outputSummaryturns the output into one fact per line: those refs (at most 6, then "and N more"),Updating a..b, Fast-forward, a merge commit, Rebased, the files-changed line, a new commit ([main 74dae5f] subject) and the new upstream. Progress lines that end in a carriage return are dropped. -
fetchReport,pullReport,pushReport,pushTagsReport,syncReport,commitReportandoperationReportbuild the title from theHeadInfocopied before the work (headOfingitActions.ts): the branch, its upstream and how many commits it was ahead. "Already up to date" and "Everything up-to-date" become an info message instead of a success.
runOp takes either a fixed title, which gets outputSummary as its detail, or a function from the OpOutcome to a report. run's success may return a report too, and both take a failure title such as "Could not push main".
-
ui/web/src/lib/components/Notification.svelte: one message, as aballoon(a toast) or arow(the list). It has the kind's icon, title, source, time, detail, action link and close button. -
ui/web/src/lib/components/ToastHost.svelte: the fixed stack of balloons. It sits above the status bar and beside the right activity bar (--toast-offset-right,--toast-offset-bottom). -
ui/web/src/lib/logic/toastModel.ts: kinds, timeouts,kindIcon,kindTone,kindLabel. -
ui/web/src/lib/icons.ts: theinfo,circle-checkandcircle-alerticons. -
ui/design-tokens/components-2.json(notification) andcomponents.json(toast): sizes. -
src/lib/ui/toast.svelte.ts: the app's toast store: options, timers, hold, the cap. -
src/lib/notifications/gitReport.ts: the titles and details of git operations. -
src/lib/notifications/notificationModel.ts: pure list operations such asaddNotification,removeNotification,shouldPopUp,unreadAlertsandhasUnreadError. -
src/lib/notifications/notifications.svelte.ts: the history store (items,open,fresh,remove,clear). -
src/lib/notifications/NotificationsPanel.svelte: the panel.NotificationBell.svelteis the status bar bell. -
src/lib/views/RightActivityBar.svelteandWorkspace.svelte: the bell item and the third right panel (RightPanelinsettingsData.ts).
-
One component for both looks. A balloon and a list row show the same parts, so
Notificationhas avariantinstead of two components. A future native app draws the same thing from the same tokens. - Links, not buttons. IDE balloons show their actions as links. A link is lighter and keeps a short message from looking like a dialog.
- No balloons while the panel is shown. Two copies of the same message on screen are noise. Errors are not an exception, because the panel is in view.
- Always the repository, and the branch in the title. At first the repository was shown only with several, and titles were bare ("Pushed", "Fetched"). Every entry in the list then looked the same, so now each one says where it ran and what moved.
- Read git's output instead of asking git again. The ref lines and summaries are already in the output, so a message costs no extra git call.
- Hold on hover and focus. A long git error needs time to read and select. Keyboard focus counts too, so the close button can be reached.
-
The history is not saved. Messages are about this session, and their links capture closures (an Undo's patch) that cannot outlive it.
dropStaleActionslets go of those after 2 or 30 minutes. - The status bar bell stays. The right activity bar can be hidden, and the status bar bell still opens the panel then.
-
src/lib/notifications/notificationModel.test.ts: the cap of 200, unread counts, link lifetimes,shouldPopUpwith Do Not Disturb and with the panel shown,removeNotificationandhasUnreadError. It also tests the toast store with the history: records every toast,freshdots, source, hold on hover and the four-balloon cap. -
src/lib/notifications/gitReport.test.ts: git output recorded from real fetches, pulls (fast-forward, merge, rebase), pushes and commits, read into facts and titles, including up to date and the "and N more" cut. -
ui/web/src/lib/logic/toastModel.test.ts: timeouts, and each kind's icon, color and name. - The look, the hover close button and the panel layout need a check in the app or in the showcase (
bun run ui, Notification and ToastHost). See Testing.
- Update this page when a timeout, the cap or the pop-up rule changes, when the panel moves, or when
Notificationgains a part. - Retake
notification-toasts.pngandnotifications-panel.png(bun scripts/screenshots.ts notification-toasts notifications-panel) when their look changes. - The user page is Notifications.
These pages are generated from docs/wiki. To correct something, open a pull request against the source file; edits made here are overwritten.
Using Nibtree
- Getting Started
- Welcome Screen
- Workspaces
- Files Panel
- File Operations
- File Icons
- Rounded Panels
- Editor and Tabs
- Pin Reorder and Wrap Tabs
- Single Tab Title
- Split Editor
- New File and Unsaved Changes
- Unload Hidden Tabs
- Editing Code
- Code Appearance
- Markdown Editor
- Image and PDF Preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and Replace
- Changes and Commits
- Sign In Prompts
- Commit Box Layout
- Repository Actions
- Commit Options
- Ignoring Files
- Diffs
- Inline Diffs
- Staging View
- Revert a Change
- Resolving Conflicts
- Merge Tool
- Blame
- History and Log
- Merge Commits
- Branches and Tags
- Branches Popup
- Remotes
- Stashes
- Shelf
- Git Menu
- Git Dialogs
- Interactive Rebase
- Worktrees
- AI Agents
- AI Tasks
- AI Usage
- Keep Computer Awake
- Submodules
- Git LFS
- GitHub
- Git Console
- Terminal
- Terminal Features
- Scripts
- Navigation
- Menus
- Settings
- Settings Search
- Color Themes
- Settings Terminal and Automation
- Settings Files
- Updates
- Status Bar and Help
- Notifications
- Memory Use
- Clear Cache
- MCP and CLI
- Git Mergetool
- Keyboard Shortcuts
- Keyboard Shortcuts Editor
- Troubleshooting
- Troubleshooting Git
Developers
- Developer Guide
- Architecture
- Project Layout
- Backend
- How Folder Watching Works
- Folder Watching Bugs We Fixed
- How Workspace Files Work
- How the Preview Scheme Works
- Backend Services
- How Terminal Features Work
- Terminal Bugs We Fixed
- Frontend
- How the Rich Markdown Editor Works
- Rich Markdown Bugs We Fixed
- Git Menu Links
- Menu Keys and Routing
- Frontend Modules
- Blame Bugs We Fixed
- Project Color And Title Bar
- One Diff View
- Diff Bugs We Fixed
- Merge Tool Layouts
- Merge Tool Bugs We Fixed
- Color Theme Bugs We Fixed
- How the Connected Diff Works
- Rounded Panels Bugs We Fixed
- Update Bugs We Fixed
- Status Bar Bugs We Fixed
- MCP and CLI Bugs We Fixed
- Repository Actions Bugs We Fixed
- How the Changes Tab Works
- CodeMirror Patterns
- How the Cursor Works
- How Editor Features Work
- How the Path Bar Works
- Commands and Events
- Settings Reference
- Commands Workspace and Changes
- Commands Branches and Remotes
- Commands History and Extras
- Commands App and Tools
- Testing
- Test Suites
- Debugging
- Debugging with MCP
- Measuring Setting Memory
- How Terminal Memory Is Measured
- How Markdown Diagrams Work
- Releases and CI
- Publishing the Wiki
- Versioning and Changelog
- Browser Version Packages
- Browser Release Checks
- Docker Image
- Platforms and Signing
- Windows Support
- Windows Bugs We Fixed
- Windows MCP and CLI
- Docs and Screenshots
- UI Library
- UI Library MCP
- UI Library Bugs
- UI Library Migration
- Contributing
How features work
- Welcome screen
- Workspaces and folders
- Files panel
- File operations
- File icons
- Editor and tabs
- Pin, reorder and wrap tabs
- Single tab title
- Split editor
- New File and unsaved changes
- Unload hidden tabs
- Editing code
- Code appearance
- Markdown editor
- Image and PDF preview
- Search Everywhere
- Recent Files
- Navigation Bar
- Find and replace
- Changes and commits
- Sign-in prompts
- Commit box layout
- Repository actions
- Commit options
- Ignoring files
- Diffs
- Inline diffs
- Staging view
- Revert a change
- Resolving conflicts
- Merge tool
- Blame
- History and log
- Merge commits
- Commit tabs
- Branches and tags
- Branches popup
- Remotes
- Stashes
- Shelf
- Git menu
- Git dialogs
- Interactive rebase
- Worktrees
- AI agents
- AI usage
- Keep computer awake
- AI tasks
- Submodules
- Git LFS
- GitHub account
- Git Console
- Back and Forward
- Integrated terminal
- Scripts tool window
- Menu bar
- Settings
- Search in Settings
- Color themes
- Rounded panels
- Updates and release channels
- Status bar and help links
- Notifications
- Memory readout and memory log
- Clear Cache
- MCP server and command line tool
- git mergetool mode