Desktop app
How the Nib desktop app runs the daemon, stores keys in the OS keychain, handles deep links and integrates with your system.
The desktop app is a native shell built on Tauri 2. It hosts the Nib workspace UI in the system webview (WKWebView on macOS, WebView2 on Windows, WebKitGTK on Linux) and supervises the agent runtime. The shell itself is small: it adds only what a browser can't do, such as running the daemon, the keychain, the menu bar and tray, deep links, a global shortcut and notifications.
The desktop app is a preview. The native shell, daemon supervision, keychain and deep links described here are in place; the workspace UI is still evolving.
The daemon
When Nib starts, it launches nib-daemon as a child process and waits for it to report ready.
- The daemon binds
127.0.0.1on a random port and generates a fresh bearer token. It writes both to a discovery file only you can read (daemon.jsonin its data folder), so the CLI and editor extensions can find it, and never to logs. - It prints a single ready line with the port and token, which the shell passes to the UI. Every request from the UI carries the token.
- The shell checks the daemon's health every 10 seconds. After three failed checks in a row, it restarts the daemon.
- If the daemon crashes, it restarts with exponential backoff, from 0.5 s up to 30 s. After 8 failed launches in a row, Nib stops trying and shows an error with a Restart button. A daemon that stays up for a minute resets the count.
- Each restart gets a new port and token. The UI reconnects on its own, and sessions resume from the last event it saw.
- On quit, the shell closes the daemon's input so it can close its sessions and database. If it's still running 4 seconds later, the shell sends it
SIGTERM, and 2 seconds after that kills it. If the shell itself crashes, the daemon notices that its parent is gone and exits.
The daemon's data lives in the app data folder: ~/Library/Application Support/gg.nib.desktop/daemon on macOS.
Using the CLI alongside the app
The CLI's default mode looks for a running daemon before starting its own, so nib in a terminal can share sessions with the app when they use the same data directory. To connect to a specific daemon, pass --daemon-url and put its token in NIB_DAEMON_TOKEN. See CLI.
Keys and the keychain
API keys you paste into Nib are stored in the operating system's credential store, under the service name gg.nib.desktop:
| Platform | Store |
|---|---|
| macOS | Keychain |
| Windows | Credential Manager |
| Linux | Secret Service (GNOME Keyring, KWallet) |
The daemon's database stores only a reference to each key, never the key itself. Key values never appear in logs or error messages. To remove a key, delete the provider in Nib's settings, or remove the entry in your OS's credential manager.
Deep links
Nib registers the nib:// URL scheme. After the scheme, a link is one of:
| Link | Opens |
|---|---|
session/<sessionId> | The session, bringing the window to the front |
inbox/<itemId> | The Inbox on that item. System notifications link here |
open/<target> | A page of the app, such as settings:appearance or inbox:needs-you. The agent links here when no window is open to show the page |
auth/callback?code=…&state=… | Completes signing in to your account in the browser |
auth/callback/<provider>?code=…&state=… | Completes connecting a model provider you sign in to in the browser |
Links that arrive before the window is ready, for example when a link launches Nib, are held and delivered once the UI loads. Unknown links are passed to the app, which ignores what it doesn't understand.
Use session links to jump from a notification, a chat message or a script straight to a session:
open "nib://session/ses_01JCQ8Z4X9T5V2M3N7K1P6R0WA" # macOS
xdg-open "nib://session/ses_01JCQ8Z4X9T5V2M3N7K1P6R0WA" # LinuxMenu actions
On macOS, Nib's menu bar contains these actions.
| Action | Menu item | Shortcut |
|---|---|---|
session.new | New Session | ⌘N |
window.new | New Window | ⌘⇧N |
workspace.open | Open Folder… | ⌘O |
settings.open | Settings… | ⌘, |
update.check | Check for Updates… | — |
account.sign-out | Sign Out… | — |
palette.open | Command Palette… | ⌘K |
sidebar.toggle | Toggle Sidebar | ⌘B |
terminal.toggle | Toggle Terminal | ⌃` |
help.shortcuts | Keyboard Shortcuts | ⌘/ |
help.docs | Nib Documentation | — |
help.report-issue | Report an Issue… | — |
See Keyboard shortcuts for everything else.
System integration
- Tray. The tray icon offers Show, New Session and Quit.
- Global shortcut. ⌘⇧Space (Ctrl+Shift+Space on Windows and Linux) shows or hides Nib from any app. Change it or turn it off in Settings → This computer.
- Notifications. When a session needs your input or finishes while the window isn't focused, Nib sends a system notification. It asks for permission the first time.
- Launch at login. Off by default. When on, Nib starts hidden.
- Open in editor. File paths in the transcript open in your editor through its URL scheme (VS Code, Zed and others) or in the system's default app. An app, a script or another executable file is shown in Finder (or your file manager) instead of being run. Nib never starts editor processes itself.
- Drag and drop. Drop files onto the window to attach them.
- Window state. Size and position are remembered between launches. The minimum window size is 760 × 520.
- Background streaming. Sessions keep streaming while the window is hidden.
Windows and platform differences
| macOS | Windows | Linux | |
|---|---|---|---|
| Title bar | Inset traffic lights over a translucent sidebar | Native caption with Mica | Native decorations |
| Menu bar | Yes | No; shortcuts are bound in the app | No; shortcuts are bound in the app |
| Closing the window | Hides Nib | Quits | Quits |
Security
- No remote content. The app loads only its bundled UI. It never navigates to web pages inside its own window.
- Strict content security policy. The UI can connect only to itself, the loopback daemon, and Nib's own cloud and Hub. Besides its own pages, it can frame only pages served on this computer, which is how the built-in browser shows your local dev server.
- Isolated IPC. Every message from the UI to the native shell passes through an isolation layer that allows only the commands the app declares, and each command needs an explicit permission.
- Loopback daemon with a token. Other programs on your machine can't use the daemon without the per-launch token, and the daemon accepts browser requests only from the app's own origin.
See Security and privacy.
Updates
Nib checks for updates at launch and every 4 hours, and when you choose Check for Updates…. Updates are signed, and the app verifies the signature against a public key compiled into it before installing.