mjakl-pi-dark-or-light

内容来源:README.md(说明文档) · 原始地址 · 查看安装指南

原始内容

pi-dark-or-light

Automatically switch Pi between configured dark and light themes.

pi-dark-or-light is a Pi extension for people who want Pi to follow the appearance of their system or terminal without hard-coding a single theme value in settings.json.

User Guide

Why pi-dark-or-light

Terminals, desktop environments, and multiplexers can change between dark and light appearances. This extension detects the current mode and applies the matching Pi theme.

In short: the extension decides dark vs light, and you optionally decide which theme name each mode should use.

Features

  • Dark/light detection — resolves the current appearance from OS, tmux, environment, terminal, or fallback signals.
  • Theme mapping — map detected dark and light modes to built-in or custom Pi theme names.
  • UI-only behavior — runs only in interactive UI sessions; headless/non-UI runs are left alone.
  • Live polling — re-checks every 5 seconds so appearance changes can be picked up while Pi is running.
  • Terminal background query — supports xterm-compatible OSC 11, useful in multiplexers such as Herdr when COLORFGBG is absent.
  • Project override support — reads global and project Pi settings.

Install

Install from npm:

pi install npm:@mjakl/pi-dark-or-light

Install from git:

pi install git:github.com/mjakl/pi-dark-or-light

Or install from a local checkout:

pi install /path/to/pi-dark-or-light

Package name: @mjakl/pi-dark-or-light.

Quick start

Minimal setup:

{
  "dark-or-light": {
    "dark": "dark",
    "light": "light"
  }
}

Example with custom themes:

{
  "dark-or-light": {
    "dark": "tokyo-night",
    "light": "github-light"
  }
}

If you do not configure a mapping, the extension uses Pi's built-in dark and light themes.

For Pi theme setup, including built-in and custom themes, see Pi's themes documentation.

Configuration

The extension reads settings from the same places Pi normally uses:

  • Global: ~/.pi/agent/settings.json
  • Project: .pi/settings.json

Project settings override global settings.

Use either config key:

  • dark-or-light (recommended)
  • darkOrLight (also accepted)

Supported config:

{
  "dark-or-light": {
    "dark": "theme-name-for-dark-mode",
    "light": "theme-name-for-light-mode",
    "default": "dark"
  }
}

All keys are optional:

  • dark — theme name to use when detection resolves to dark mode.
  • light — theme name to use when detection resolves to light mode.
  • default — fallback mode when no detector returns an answer; allowed values are dark and light.

Partial config is valid. For example:

{
  "dark-or-light": {
    "dark": "tokyo-night"
  }
}

In that case:

  • detected dark -> tokyo-night
  • detected light -> built-in light

You can also change the final fallback mode:

{
  "dark-or-light": {
    "default": "light",
    "light": "github-light"
  }
}

In that case, if no detector succeeds, the extension chooses light, which then maps to github-light.

If a mapped theme cannot be loaded

If you map dark or light to a custom theme name and Pi cannot apply it, the extension falls back to the built-in dark or light theme for that detected mode.

Recommended setup

If you want Pi to follow your environment automatically:

  1. Configure dark-or-light only if you want custom theme names.
  2. Let the extension choose the current mode from OS and terminal signals.

If you want a fixed theme instead, disable or remove this extension.


Technical Reference

These sections document config merging, detector order, and local development details.

When the extension is active

The extension manages the theme whenever it is loaded in a UI session.

If Pi or another workflow writes a top-level theme into settings.json, this extension still applies the detected dark/light result on startup and during polling.

Config merge behavior

Global and project dark-or-light settings are merged field-by-field, with project settings overriding global settings.

Use the same key spelling in both files if you rely on merging. Do not mix dark-or-light in one file with darkOrLight in the other.

Example global settings:

{
  "dark-or-light": {
    "dark": "tokyo-night",
    "light": "github-light"
  }
}

Example project settings:

{
  "dark-or-light": {
    "dark": "gruvbox-dark"
  }
}

Result for that project:

  • dark -> gruvbox-dark
  • light -> github-light

Detection order

The extension uses a fixed detector chain. The first detector that returns a clear answer wins.

Overall order:

  1. macOS native appearance
  2. Windows native appearance
  3. tmux client theme
  4. DARK_MODE environment variable
  5. terminal default background query (OSC 11)
  6. COLORFGBG heuristic
  7. configured default mode, defaulting to dark

Detectors that do not apply on the current platform are skipped.

Operating-system-specific order

macOS

On macOS, the extension first asks the OS directly by running osascript and querying System Events for the current dark mode setting.

  • true -> dark
  • false -> light

macOS order:

  1. Native macOS appearance via osascript
  2. tmux #{client_theme}
  3. DARK_MODE
  4. terminal default background query (OSC 11)
  5. COLORFGBG
  6. configured default mode, defaulting to dark

Windows

On Windows, the extension first checks:

HKCU:\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize

It reads AppsUseLightTheme:

  • 0 -> dark
  • 1 -> light

Windows order:

  1. Native Windows appearance via AppsUseLightTheme
  2. tmux #{client_theme}
  3. DARK_MODE
  4. terminal default background query (OSC 11)
  5. COLORFGBG
  6. configured default mode, defaulting to dark

Linux and other Unix-like systems

There is no desktop-environment-specific Linux detector. Linux appearance settings vary across GNOME, KDE, sway, Hyprland, remote shells, containers, and headless sessions, so the extension uses terminal-oriented signals instead.

Linux / other Unix order:

  1. tmux #{client_theme}
  2. DARK_MODE
  3. terminal default background query (OSC 11)
  4. COLORFGBG
  5. configured default mode, defaulting to dark

Shared detectors

tmux

If Pi is running inside tmux, the extension tries:

tmux display-message -p #{client_theme}

Accepted values are normalized case-insensitively:

  • dark
  • light
  • 1 / true -> dark
  • 0 / false -> light

This detector is attempted only when the environment suggests Pi is running in tmux (TMUX is set or TERM_PROGRAM=tmux).

DARK_MODE

If DARK_MODE is set, the extension accepts:

  • dark, 1, true -> dark
  • light, 0, false -> light

This is useful from shell profiles, wrapper scripts, launchers, or platform-specific automation.

Terminal default background (OSC 11)

If no explicit environment override is set, the extension asks the current terminal for its default background color:

ESC ] 11 ; ? ESC \\

Terminals that support this xterm-compatible query answer with an RGB color such as:

ESC ] 11 ; rgb:fafa/fafa/fafa ESC \\

The extension classifies bright backgrounds as light and dark backgrounds as dark.

If the terminal or multiplexer does not answer quickly, the detector times out and the chain continues.

Herdr note: Herdr 0.7.0 captures the host terminal background when the client attaches. If you change your terminal theme while keeping the same Herdr client attached, Herdr may keep answering with the old color until you detach and reattach.

COLORFGBG

If no stronger detector succeeds, the extension uses COLORFGBG, similar to Pi's built-in heuristic.

It parses the second ;-separated field. In the common two-part form, that field is the background color index.

  • background color index < 8 -> dark
  • background color index >= 8 -> light

Examples:

  • COLORFGBG=15;0 -> second field 0 -> dark
  • COLORFGBG=0;15 -> second field 15 -> light

Unusual multi-part COLORFGBG values may not apply and the detector chain will continue.

Final fallback

If none of the detectors produce an answer, the extension falls back to dark-or-light.default.

Default if unset: dark.

Allowed values: dark, light.

Local development

Install dependencies and run the type check:

npm install
npm run typecheck

One-off local testing:

pi -e /path/to/pi-dark-or-light/src/index.ts

Acknowledgements

This extension was influenced by Pi's own macOS theme example:

License

MIT