第 03 模块 · 2 节

创建自定义主题

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

动手:三行命令建一个主题

上一节懂了结构,这一节直接写一个能用的主题。先建文件:

mkdir -p ~/.pi/agent/themes
vim ~/.pi/agent/themes/my-theme.json

然后定义主题,包含所有必需的颜色。给一个完整可抄的模板(部分节选,完整要 51 个 token):

{
  "$schema": "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
  "name": "my-theme",
  "vars": {
    "primary": "#00aaff",
    "secondary": 242
  },
  "colors": {
    "accent": "primary",
    "border": "primary",
    "borderAccent": "#00ffff",
    "borderMuted": "secondary",
    "success": "#00ff00",
    "error": "#ff0000",
    "warning": "#ffff00",
    "muted": "secondary",
    "dim": 240,
    "text": "",
    "thinkingText": "secondary",
    "selectedBg": "#2d2d30",
    "userMessageBg": "#2d2d30",
    "userMessageText": "",
    "toolTitle": "primary",
    "mdHeading": "#ffaa00",
    "mdLink": "primary",
    "mdCode": "#00ffff",
    "syntaxKeyword": "primary",
    "syntaxString": "#00ff00",
    "thinkingOff": "secondary",
    "thinkingMax": "#ff0088",
    "bashMode": "#ffaa00"
  }
}

写完在 /settings 里选中它。

贯穿项目到这一节,给 md-tools 配主题可以正式做了:基于上面的模板,把 primary 换成 md-tools 的标识色,命名 md-tools,放进包的 themes/ 目录,再用 pi.themes 键声明。**这样一个「md-tools 主题」就跟着你的包一起分发出去了。** 别人装上包,就能在 /settings 里选到它。

热重载:改完立刻看效果

自定义主题的一个爽点:你编辑当前正在用的主题文件时,pi 会自动重载,马上看到视觉反馈。

这意味着你可以一边改色、一边看界面,不用反复重启。把「调色」这件事从「猜」变成「所见即所得」。


设计建议:按终端亮度配色

官方给了几条实用建议:

  • 深色终端:用明亮、饱和、高对比度的颜色
  • 浅色终端:用更暗、更柔和、低对比度的颜色
  • 色彩和谐:从一套基础色板起步(Nord、Gruvbox、Tokyo Night 等),在 vars 里定义,再统一引用
  • 测试:用不同消息类型、工具状态、markdown 内容、长文本换行都测一遍
  • VS Code:把 terminal.integrated.minimumContrastRatio 设为 1,得到准确颜色

vars 起步是养成好习惯:只改一处定义,整个主题同步变,不会改漏。


HTML 导出配色(可选)

主题还能控制 /export 的 HTML 输出配色。省略时,颜色从 userMessageBg 推导:

{
  "export": {
    "pageBg": "#18181e",
    "cardBg": "#1e1e24",
    "infoBg": "#3c3728"
  }
}

如果你的 md-tools 面向文档型工作流,导出的 HTML 好看不好看,也影响交付体验。


落地练习:给 md-tools 建一个主题

把主题真正做成 md-tools 的资产:

  1. 复制上面模板,命名 md-tools,把 primary 换成你想好的标识色
  2. /settings 里选中它,改几个色值,体验热重载(改了立刻变)
  3. 把它放进 md-tools 包的 themes/ 目录,并在 package.jsonpi.themes 里声明

怎么判断做对了?——主题在 /settings 可选、界面配色符合预期、热重载生效;并且 pi list(或包加载)后,md-tools 包里能看到这个主题。

卡住了怎么办? 主题加载失败?九成是少了必需 token——从内置主题复制完整模板再改。热重载不生效?确认你编辑的是「当前激活」的那个主题文件。


常见坑:主题 name 冲突或含 /

主题的 name 有两个硬约束,很容易踩:

  1. 必须唯一——和已存在主题重名,会被拒绝或互相覆盖
  2. 不能含 /——md-tools/blue 这种名字直接非法

很多人在命名上随手起,结果要么覆盖了别人的主题,要么加载报错。命名要刻意、要全局唯一,这是要分发的主题的基本素养。 起个有辨识度又不冲突的名字,比如 md-tools-dark


小结

  1. 三个命令建主题:mkdirvim/settings 选中
  2. 完整模板含 51 个 token,改色前先复制内置主题
  3. 热重载:编辑激活的主题文件立刻生效
  4. 深色终端用亮色,浅色终端用暗色,用 vars 统一管理
  5. 主题可放进包的 themes/ 随包分发,name 要唯一且不含 /

下一节,进入模块 04:程序化使用,先讲 JSON 模式。