pi-theme-sync

Sync Pi theme with terminal appearance — works locally and over SSH via OSC 11 terminal queries

Package details

extension

Install pi-theme-sync from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-theme-sync
Package
pi-theme-sync
Version
0.3.1
Published
Mar 3, 2026
Downloads
46/mo · 11/wk
Author
mise42
License
MIT
Types
extension
Size
38.2 KB
Dependencies
0 dependencies · 0 peers
Pi manifest JSON
{
  "extensions": [
    "index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-theme-sync

Sync Pi theme with terminal appearance — works both locally and over SSH.

Terminal-first theme sync for Pi, with robust SSH support.

How it works

The extension uses a three-layer detection strategy (in priority order):

Priority Strategy When it helps
1 Override file (~/.pi/agent/theme-sync-override.json) Manual push from another machine
2 Terminal query (OSC 11 background-color) Preferred in interactive terminal sessions (local/SSH/tmux) for fast theme detection
3 OS-level detection (optional fallback) Disabled by default; can be enabled explicitly

Why it works over SSH

When you SSH into a remote machine, your local terminal (Ghostty) is still rendering everything. The extension sends an OSC 11 query (\033]11;?\033\\) to stdout. This travels through the SSH tunnel to Ghostty, which replies with the current background RGB. The extension parses the luminance to determine dark or light.

This means: when Ghostty switches theme = auto on your Laptop, the remote pi detects it within seconds — no push scripts needed.

The OSC 11 query runs in a short-lived subprocess that opens /dev/tty directly, so it doesn't interfere with pi's own terminal I/O.

Install

pi install npm:pi-theme-sync

Important: Remove pi-system-theme first to avoid two extensions fighting over setTheme:

pi remove npm:pi-system-theme

Package rename migration

This package was renamed from pi-system-theme-ssh-bridge / pi-sync-system-theme to pi-theme-sync.

If you installed the old package name, run:

pi remove npm:pi-system-theme-ssh-bridge
pi install npm:pi-theme-sync

Configuration

Use the /system-theme command inside pi to configure:

  1. Dark theme name (default: dark)
  2. Light theme name (default: light)
  3. Poll interval in ms (default: 4000)

Settings are saved to ~/.pi/agent/theme-sync-config.json.

Runtime commands

  • /system-theme — configure dark/light theme mapping and poll interval
  • /system-theme-refresh — manually re-run detection and apply mapped theme (best-effort)
  • /system-theme-debug — print detection trace (override / OSC11 / OS fallback) for troubleshooting
  • /system-theme-push dark|light|auto — write override appearance manually on the current machine

Reliable-first behavior (default)

To reduce input lag and TTY contention in long-running remote sessions:

  • Startup and /resume: performs an immediate OSC11 reconciliation attempt
  • Background polling:
    • Local sessions: OSC11 polling is enabled (with min-interval throttling)
    • Likely remote SSH sessions: OSC11 polling is disabled by default, preferring override + OS fallback
  • Manual fallback: /system-theme-refresh forces a one-shot OSC11 probe (may still fail in some remote TTY setups)

This restores local auto-switch behavior while keeping remote sessions stable by default.

Recommended remote workflow (stable)

When Pi runs on a remote host, the most reliable setup is:

  1. Run Pi remotely (SSH/tmux as usual)
  2. Push override updates from your local machine when local appearance changes
  3. Let remote Pi apply the override on next tick (or immediately on startup/resume)

Example local push:

./push-theme-override.sh user@remote-host

In practice, local push + remote reconcile is more stable than relying on continuous OSC11 probing during an active remote session.

Override file (optional)

For environments where neither OSC 11 nor OS detection works, you can push an override file manually:

# On your Laptop, push current appearance to Desktop:
./push-theme-override.sh user@desktop

# Or inside pi on any machine:
/system-theme-push dark
/system-theme-push light
/system-theme-push auto    # clears override, falls back to detection

Override file format

{
  "appearance": "dark",
  "updatedAt": "2026-02-22T07:00:00Z",
  "source": "my-laptop"
}

⚠️ Performance tuning notes (important)

This extension queries terminal background color (OSC 11) in interactive sessions (local/SSH/tmux). Aggressive polling can cause terminal artifacts (garbled startup output) or input lag on some terminal/SSH combinations.

Recommended ranges:

  • pollMs: 3000–8000 (default 4000)
  • PI_THEME_SYNC_OSC11_MIN_INTERVAL_MS: 4000–12000 (default 4000)

Avoid overly aggressive values unless you have tested your environment thoroughly:

  • pollMs < 2000
  • PI_THEME_SYNC_OSC11_MIN_INTERVAL_MS < 3000

If you notice lag, slash-command stutter, or startup artifacts:

  1. Increase pollMs
  2. Increase PI_THEME_SYNC_OSC11_MIN_INTERVAL_MS
  3. Temporarily disable OSC11 probing with:
export PI_THEME_SYNC_OSC11_ENABLED=0

Environment variables

Variable Default Description
PI_THEME_SYNC_OVERRIDE_FILE ~/.pi/agent/theme-sync-override.json Override file path
PI_THEME_SYNC_OVERRIDE_MAX_AGE_MS 60000 Max age before override is considered stale
PI_THEME_SYNC_OSC11_ENABLED 1 Enable/disable OSC 11 terminal query (0 to disable)
PI_THEME_SYNC_OSC11_MIN_INTERVAL_MS 4000 Minimum interval between OSC 11 probes in interactive sessions
PI_THEME_SYNC_BACKGROUND_OSC11 auto Background OSC11 policy: auto = local on / likely SSH off, 1 force on, 0 force off
PI_THEME_SYNC_OS_FALLBACK auto OS fallback policy: auto = local on / likely SSH off, 1 force on, 0 force off

Compatibility

  • Terminals: Any terminal supporting OSC 11 color queries (Ghostty, iTerm2, kitty, foot, WezTerm, xterm, etc.)
  • OS detection fallback: macOS, Linux (GNOME gsettings), Windows (PI_THEME_SYNC_OS_FALLBACK=auto locally by default; can force with 1)
  • SSH: Works transparently — no special setup required
  • tmux: Supported (including long-lived sessions where SSH_* env vars may be missing)
  • Ghostty theme = auto: Fully supported. When Ghostty switches colors, the next poll detects it.
  • Session resume: On /resume, the extension immediately re-checks appearance and reconciles the active theme.

Migrating from pi-system-theme

  1. pi remove npm:pi-system-theme
  2. pi install npm:pi-theme-sync
  3. Configure /system-theme as needed.

License

MIT