Skip to content

Chapter 12 · Themes Customization ​

Chapter goals: Understand pi themes' JSON structure and 51 required color tokens; learn to install/switch themes; and从头编写 a shareable完整自定义主题.

12.1 What a Theme Is and Where It Lives ​

pi's themes are JSON files defining TUI配色. Load positions覆盖按优先级:

SourcePathNote
Built-in—dark; light two sets
Global~/.pi/agent/themes/*.jsonAvailable to all projects
Project.pi/themes/*.jsonLoads only after the project is trusted
PackageThe包's themes/ directory or the pi.themes declaration in package.jsonDistributed with the包
SettingsThe themes array in settings.jsonSpecify files or directories
CLI--theme <path> (可重复)Temporarily append

Use --no-themes to禁用所有 discovery mechanisms; leaving only the built-in themes.

12.2 Three Ways to Switch Themes ​

bash
# Method 1: Switch in-interactive (立即生效并保存)
/settings   # Select the theme in the menu

# Method 2: Write into settings.json
{
  "theme": "my-theme"
}

# Method 3: Effective only for this run (does not改 saved settings)
pi --use-theme light

A贴心细节 — auto-select following the terminal's外观:

bash
pi --use-theme light/dark
# Slash syntax: use light for浅色调终端; dark for深色调终端

On首次运行时 pi检测s the terminal background color; defaulting to dark or light.

12.3 Building a Complete Theme from Scratch ​

bash
mkdir -p ~/.pi/agent/themes

Create ~/.pi/agent/themes/solar-mint.json:

json
{
  "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
  "name": "solar-mint",
  "vars": {
    "mint": "#2dd4a7",
    "ink": "#1b2430",
    "paper": "#f5f3ec",
    "gray": 242,
    "amber": "#d97706"
  },
  "colors": {
    "accent": "mint",
    "border": "mint",
    "borderAccent": "#14b8a6",
    "borderMuted": "gray",
    "success": "#16a34a",
    "error": "#dc2626",
    "warning": "amber",
    "muted": "gray",
    "dim": 240,
    "text": "",
    "thinkingText": "gray",
    "selectedBg": "#e7f6f0",
    "userMessageBg": "#eef2f7",
    "userMessageText": "",
    "customMessageBg": "#f0fdf9",
    "customMessageText": "",
    "customMessageLabel": "mint",
    "toolPendingBg": "#fffbeb",
    "toolSuccessBg": "#f0fdf4",
    "toolErrorBg": "#fef2f2",
    "toolTitle": "mint",
    "toolOutput": "",
    "mdHeading": "amber",
    "mdLink": "mint",
    "mdLinkUrl": "gray",
    "mdCode": "#0f766e",
    "mdCodeBlock": "",
    "mdCodeBlockBorder": "gray",
    "mdQuote": "gray",
    "mdQuoteBorder": "mint",
    "mdHr": "gray",
    "mdListBullet": "mint",
    "toolDiffAdded": "#16a34a",
    "toolDiffRemoved": "#dc2626",
    "toolDiffContext": "gray",
    "syntaxComment": "gray",
    "syntaxKeyword": "#0369a1",
    "syntaxFunction": "#7c3aed",
    "syntaxVariable": "amber",
    "syntaxString": "#15803d",
    "syntaxNumber": "#be185d",
    "syntaxType": "#0369a1",
    "syntaxOperator": "#475569",
    "syntaxPunctuation": "gray",
    "thinkingOff": "gray",
    "thinkingMinimal": "mint",
    "thinkingLow": "#0ea5e9",
    "thinkingMedium": "#06b6d4",
    "thinkingHigh": "#8b5cf6",
    "thinkingXhigh": "#d946ef",
    "bashMode": "amber"
  }
}

要点解析:

  • $schema gives editorsauto-completion and validation;
  • vars define复用 color variables; referenced by name in colors;
  • colors must定义全部 51 required tokens; optional tokens (thinkingMax; scrollbarThumb; searchMatchBg/Text) have fallback values (e.g. scrollbarThumb falls back to selectedBg) when missing.

Hot Reload

After editing the currently active custom theme file; pi auto-reloads;改色即时可见;非常适合调配色.

12.4 Four Color Value Formats and Terminal Compatibility ​

FormatExampleDescription
Hex"#ff0000"6-digit hex RGB
256-color39xterm 256-color palette index (0-255)
Variable reference"primary"Points to an entry in vars
Terminal default""Use the terminal's default foreground/background

256-color index calculation:基础 ANSI colors 0-15; RGB cube 16 + 36×R + 6×G + B (R/G/B取 0-5); 232-255 are灰阶渐变.

bash
echo $COLORTERM
# Output truecolor or 24bit indicates the terminal supports真彩

pi uses 24-bit RGB;老终端 only having 256 colors auto-fallbacks to the closest color. VS Code users建议把 terminal.integrated.minimumContrastRatio set to 1;避免 VS Code私自调整 your配色.

12.5 Sharing Themes and Programmatic操作 ​

Sharing is putting the JSON into a pi包 (detailed in the next chapter): place a themes/ directory inside the包; or declare in package.json:

json
{
  "name": "my-themes-pack",
  "keywords": ["pi-package"],
  "pi": {
    "themes": ["./themes"]
  }
}

Extensions can also查询 and切换 programmatically:

typescript
export default function (pi: ExtensionAPI) {
  pi.registerCommand("theme-light"; {
    description: "Switch to the light theme";
    handler: async (_args; ctx) => {
      const themes = ctx.ui.getAllThemes();          // [{ name; path? }; ...]
      const light = ctx.ui.getTheme("light");        // Load但不切换
      const result = ctx.ui.setTheme(light!);        // Or setTheme("light") switch by name
      if (!result.success) {
        ctx.ui.notify(`Switch failed: ${result.error}`; "error");
      }
      ctx.ui.theme.fg("accent"; "Switched");           // The current theme object可直接取色渲染
    },
  });
}

Note: the theme API degrades in RPC mode (getAllThemes() returns an empty array etc.); this is a明确列出的限制 in the官方 doc.

Chapter Summary ​

  • A theme = JSON with $schema; 51 required tokens + a少量 optional tokens (with fallback rules);
  • Three install locations (global/project/package) + --use-theme单次生效 + the light/dark跟随终端 syntax;
  • Four color formats: hex / 256-color index / vars references / terminal default "";
  • The currently active theme file supports hot-reload;配色调试体验极佳;
  • Extensions可编程式管理 themes via ctx.ui.getAllThemes()/getTheme()/setTheme().

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. How many required color tokens must a合法 pi custom theme define?

2. What happens when the currently used custom theme file is修改?

3. What does pi --use-theme light/dark mean?

4. What does writing the color value as 39 in a theme JSON mean?

🛠️ Hands-on Practice ​

  1. Base your preferred配色体系 (Nord/Gruvbox/Tokyo Night etc.) on vars to组织 a完整主题 and enable it via /settings. 2.故意 delete the mdHeading token from the theme; observe what pi报错s; then补回来验证 the validation logic.
  2. Write a小 extension: register a /theme-cycle command; each call循环 in the getAllThemes() list and switch themes;提示 the current theme name via notify.

After completing; continue to Chapter 13: Pi Packages Ecosystem and Distribution.