第 03 模块 · 1 节

理解主题与 color tokens

《Pi 生产级工程》03 主题与界面 · 本节时长 32 分钟

主题是什么

主题是定义 TUI 配色的 JSON 文件。你可能觉得「配色」跟生产级无关——但想想:一个要分发给团队的包,界面好不好看、可不可定制,直接决定别人愿不愿意用。主题,就是把「看起来舒服」变成可分发资产的第一步。

贯穿项目md-tools 既然要打包分发,顺手配一个配套主题是很自然的加分项——它让你的工具箱在别人终端里一眼可辨。**本节先读懂主题的结构和 color tokens 体系,下一节动手给 md-tools 建一个自定义主题。** 记住:主题也能作为资源装进 Pi Package(themes/pi.themes)。

主题从哪来、怎么选

pi 从这些地方加载主题:

位置 说明
内置 darklight
全局 ~/.pi/agent/themes/*.json
项目 .pi/themes/*.json(项目被信任后)
themes/ 目录或 package.jsonpi.themes
设置 themes 数组
CLI --theme(可重复)

首次运行时,pi 会检测你的终端背景,默认选 dark 或 light。选中主题,在 /settings 或 settings.json 里:

{
  "theme": "my-theme"
}

主题文件长什么样

一个主题文件的基本结构:

{
  "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
  "name": "my-theme",
  "vars": {
    "blue": "#0066cc",
    "gray": 242
  },
  "colors": {
    "accent": "blue",
    "muted": "gray",
    "text": "",
    "...": ""
  }
}

三个要点:

  • name 必填,必须唯一,且不能含 /
  • vars 可选:定义可复用颜色,之后在 colors 里引用
  • colors 必须定义全部 51 个必需的 color tokens

$schema 字段能让你在编辑器里获得自动补全和校验。


51 个 color tokens 分几类

color tokens 是主题的「变量名」,每个都代表界面上一类元素。它们分门别类:

类别 数量 例子
核心 UI 11 accentbordersuccesserrortext
背景与内容 11 必需 + 3 可选 selectedBguserMessageBgtoolTitle
Markdown 10 mdHeadingmdCodemdQuotemdHr
工具 Diff 3 toolDiffAddedtoolDiffRemoved
语法高亮 9 syntaxKeywordsyntaxStringsyntaxType
思考级别边框 6 必需 + 1 可选 thinkingOff ~ thinkingMax
Bash 模式 1 bashMode

几个可选的 token 有回退值:thinkingMax 回退到 thinkingXhighscrollbarThumbsearchMatchBg 回退到 selectedBgsearchMatchText 回退到 text这让老主题不用改也能用。


颜色值的四种写法

每个 token 的值支持四种格式:

格式 示例 说明
Hex "#ff0000" 6 位十六进制 RGB
256 色 39 xterm 256 色调色板索引(0-255)
变量 "primary" 引用 vars 里的一项
默认 "" 用终端默认色

text 通常用 ""(终端默认色)。256 色调色板里,16-231 是 6×6×6 RGB 立方体,232-255 是灰度梯度。


终端兼容性:24-bit vs 256 色

pi 用 24-bit RGB 颜色。多数现代终端支持(iTerm2、Kitty、WezTerm、Windows Terminal、VS Code)。老终端只支持 256 色时,pi 会回退到最近的近似值。

检查你的终端是否支持真彩:

echo $COLORTERM  # 应该输出 truecolor 或 24bit

如果你开发主题,记得在一个支持 truecolor 的终端里看效果。


落地练习:读一遍内置 dark 主题

不用写代码,先读一个现成主题理解 token 体系:

  1. 找到 pi 内置的 dark.json(或 light.json
  2. 对照本节的分类表,把每个 token 归到它属于哪一类
  3. 挑 3 个 token(比如 accentmdHeadingtoolDiffAdded),想清楚它们在界面上分别控制什么

怎么判断做对了?——你能不看分类表,说出 10 个以上 token 各自控制界面哪一块;并且明白「51 个 token 必须全定义」这个硬约束。

卡住了怎么办? 找不到内置主题文件?用主题的 $schema URL 也能看到 token 清单。分类记不住?先把核心 UI 那 11 个记住就够起步。


常见坑:以为只填 accent 就够

新手写主题最大的坑,是只填 accent 和几个高频色,然后发现主题加载失败或界面大片难看

因为 colors 必须定义全部 51 个必需 token。缺一个就加载不出来(或按回退值补)。正确做法:从内置主题复制一份完整模板,改你想改的,别从零手写漏字段。这也是下一节动手时我会带你走的路。


小结

  1. 主题是定义 TUI 配色的 JSON 文件
  2. name 必填且不能含 /vars 定义可复用色,colors 必须全定义
  3. 51 个必需 token 分 7 大类,几个可选 token 有回退值
  4. 颜色值支持 Hex / 256 色 / 变量 / 默认四种写法
  5. pi 用 24-bit RGB,老终端自动回退 256 色

下一节,动手创建你自己的自定义主题。