Preferences
The Preferences panel centralizes your personal settings — appearance, notifications, and model visibility. Open it from the user menu (avatar icon) → Preferences on both desktop and mobile.
Most preferences are stored locally in your browser (localStorage) and persist across sessions. They are not tied to any specific runner. The exception is model visibility, which also syncs to your account on the server so hidden-model choices stay consistent across devices.
Appearance
Section titled “Appearance”Theme mode
Section titled “Theme mode”PizzaPi supports three theme modes:
- Auto — follows your operating system’s
prefers-color-schemesetting and updates automatically if you switch system themes. - Light — forces light mode regardless of system preference.
- Dark — forces dark mode regardless of system preference.
On desktop, the header toolbar has a dedicated theme button that cycles through all three modes without opening Preferences. On mobile, the same cycle lives inside the user dropdown menu.
Theme switches use a smooth 200ms transition to avoid jarring color flashes. A blocking inline script prevents flash of unstyled content (FOUC) on page load — your theme is applied before React hydrates.
Accent colors
Section titled “Accent colors”Choose an accent color that overrides the primary and ring colors throughout the UI. The default is the built-in PizzaPi palette (no override). A Reset color button restores that default.
The picker shows eight preset swatches:
| Accent | Description |
|---|---|
| Blue | Blue primary tones |
| Green | Green primary tones |
| Orange | Warm orange primary tones |
| Purple | Purple primary tones |
| Red | Red primary tones |
| Pink | Pink primary tones |
| Teal | Teal primary tones |
| Yellow | Yellow primary tones |
You can also pick any custom color with the native color picker. The selection is applied by setting --primary and --ring CSS variables on the <html> element; a data-accent="custom" marker is set for styling hooks. Accents compose with light/dark modes — every combination works.
High contrast
Section titled “High contrast”Enable High contrast mode for improved readability. This mode:
- Increases all text/background contrast ratios to 7:1+ (WCAG AAA)
- Switches border colors to maximum-contrast black/white
- Enlarges focus outlines (
3pxoutline with2pxoffset) - Disables decorative animations when
prefers-reduced-motionis active
PizzaPi also respects the prefers-contrast: more media query — if your OS requests higher contrast, it’s enabled automatically.
Font size
Section titled “Font size”Adjust the chat message text size. Choose from Small, Default, or Large. This only affects message content — UI chrome stays at its standard size.
UI density
Section titled “UI density”Controls spacing and padding for message content and headers:
- Compact — tighter padding on messages and headers, ideal for seeing more content
- Default — standard spacing
- Comfortable — more breathing room between messages and headers
Border radius
Section titled “Border radius”Controls the roundness of UI elements (buttons, cards, inputs):
| Option | Value |
|---|---|
| None | Sharp corners (0) |
| Small | Subtle rounding (0.375rem) |
| Default | Standard (0.625rem) |
| Large | Pill-like (1rem) |
Code font
Section titled “Code font”Choose the monospace font used for code blocks, inline code, and the terminal. Options include System (your OS default monospace), JetBrains Mono, Fira Code, and Source Code Pro.
All non-system fonts are bundled with PizzaPi (self-hosted woff2 files, ~500KB total) — no external requests to Google Fonts or CDNs. Fonts load on demand with font-display: swap so there’s no layout shift.
Runner terminal preferences
Section titled “Runner terminal preferences”Runner Settings → TUI Preferences configures the runner’s terminal interface, separately from browser appearance. These settings are saved to ~/.pizzapi/settings.json and apply to new terminal sessions.
| Control | Setting | Default |
|---|---|---|
| Terminal Mode | tuiMode: fullscreen or regular |
Fullscreen; choose Regular for normal terminal scrollback |
| Terminal Theme | theme: system, dark, light, or an existing custom theme |
System, using the terminal palette |
| Startup Display | quietStartup: true, "header", or false |
Quiet in PizzaPi; Header only shows version and key hints |
| Steering Mode | steeringMode: one-at-a-time or all |
One at a time |
| Provider Transport | transport: auto, sse, websocket, or websocket-cached |
Auto; this controls AI provider connections, not MCP |
| Double-Escape Action | doubleEscapeAction: tree, fork, or none |
Session tree |
Saving preserves terminal options this panel does not edit. Older UI values such as steeringMode: "manual", transport: "stdio", and doubleEscapeAction: "abort" are replaced with supported defaults when you save. Existing valid preferences are retained.
From the terminal, use /settings or set "tuiMode": "regular" in ~/.pizzapi/settings.json to keep normal terminal scrollback.
Notifications
Section titled “Notifications”Browser push notifications
Section titled “Browser push notifications”On the web, enable push from the notification settings and grant browser permission. Browser push uses the service worker and requires HTTPS (localhost is treated as secure by browsers). The relay must have stable VAPID keys; pizzapi web generates and persists these. If you self-host manually, configure VAPID_PUBLIC_KEY, VAPID_PRIVATE_KEY, and VAPID_SUBJECT consistently across restarts. See self-hosting.
When the web app is open, in-app attention indicators work without browser push permission. Notification preferences apply separately from native Android push.
Native Android push
Section titled “Native Android push”The Android app uses the relay’s optional ntfy integration for background push; it is not the browser Web Push path and is not available in ordinary desktop browsers. The server publishes through PIZZAPI_NTFY_URL; if that variable is unset, /api/push/register-native returns 503 and the Android UI reports the native push path as unconfigured.
PIZZAPI_NTFY_PUBLIC_URL can be set separately when devices need a public subscribe URL that differs from the server’s internal publish URL. Registration returns a per-device ntfy topic, optional future ntfyUser/ntfyPass fields, and the current child-session suppression preference.
Native push is started only in the bundled Android app. The UI preference stores two local flags:
| Preference | Local key | Server sync |
|---|---|---|
| Native push disabled | pizzapi.ntfyPushDisabled |
Registration/unregistration calls /api/push/register-native and /api/push/unregister-native. |
| Suppress child session notifications | pizzapi.ntfySuppressChild |
PUT /api/push/child-notifications-native updates native registrations for the user. |
Native ntfy notifications are sent for the same server push events as browser push:
| Event | Notification |
|---|---|
agent_end |
“Agent finished”, with the last assistant reply when available. |
AskUserQuestion tool start |
“Input needed”; single-question collab prompts may include quick-reply actions. |
plan_mode tool start |
“Input needed” with “Plan ready for review”. |
cli_error |
“Agent error”. |
| Trigger escalation to a human viewer | “Trigger awaiting your response”. |
Native push is suppressed only when a viewer for that session has explicitly reported its tab as visible. A connected but hidden tab still allows native push, so the Android device can alert you while the browser is in the background. Child-session notifications are suppressed by default for native registrations unless you turn off Suppress child session notifications.
See mobile push setup in the self-hosting guide and the native notification implementation.
Child-session notifications
Section titled “Child-session notifications”The child-session suppression preference affects notifications from spawned child sessions. It appears when push is supported and currently subscribed. For native Android push, the preference is cached in localStorage and written to the server so ntfy fan-out can skip or deliver child-session notifications per registration.
Haptic feedback
Section titled “Haptic feedback”On devices that support the Vibration API (primarily Android), PizzaPi can provide haptic feedback as agent text streams in. iOS Safari ignores navigator.vibrate(); haptics are not available there.
Models
Section titled “Models”Model visibility
Section titled “Model visibility”Control which models appear in the model selector dropdown. Hidden models won’t show up when switching models in any session, reducing clutter if you have many providers configured.
Click Manage model visibility to open the model list. Models are grouped by provider and can be toggled individually or by provider. Use the search box to filter by name or provider.