跳转到主要内容

14 主题

用 JSON 文件定义 pi TUI 的配色:主题格式、颜色令牌、取值方式与创建技巧。

pi 可以创建主题。让它为你的环境构建一个吧。

主题是定义 TUI 颜色的 JSON 文件。

目录

加载位置

Pi 从以下位置加载主题:

  • 内置:dark、light
  • 全局:~/.pi/agent/themes/*.json
  • 项目:.pi/themes/*.json(仅在项目被信任后)
  • 包:themes/ 目录或 package.json 中的 pi.themes 条目
  • 设置:包含文件或目录的 themes 数组
  • CLI:--theme <path>(可重复使用)

使用 --no-themes 禁用发现。

选择主题

通过 /settings 或在 settings.json 中选择主题:

{
  "theme": "my-theme"
}

首次运行时,pi 会检测你的终端背景,并默认使用 dark 或 light。

初始主题

以某个主题启动交互式运行,而不更改已保存的设置:

pi --use-theme light

若要跟随终端外观,请使用 lightTheme/darkTheme 语法:

pi --use-theme light/dark

CLI 传入的值是本次运行的初始主题。之后在 /settings 中选择其他主题会立即生效,并照常保存。

创建自定义主题

  1. 创建主题文件:
mkdir -p ~/.pi/agent/themes
vim ~/.pi/agent/themes/my-theme.json
  1. 定义包含所有必需颜色的主题(参见颜色令牌):
{
  "$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",
    "scrollbarTrack": "secondary",
    "scrollbarThumb": "",
    "searchMatchBg": "#2d2d30",
    "searchMatchText": "",
    "userMessageBg": "#2d2d30",
    "userMessageText": "",
    "customMessageBg": "#2d2d30",
    "customMessageText": "",
    "customMessageLabel": "primary",
    "toolPendingBg": "#1e1e2e",
    "toolSuccessBg": "#1e2e1e",
    "toolErrorBg": "#2e1e1e",
    "toolTitle": "primary",
    "toolOutput": "",
    "mdHeading": "#ffaa00",
    "mdLink": "primary",
    "mdLinkUrl": "secondary",
    "mdCode": "#00ffff",
    "mdCodeBlock": "",
    "mdCodeBlockBorder": "secondary",
    "mdQuote": "secondary",
    "mdQuoteBorder": "secondary",
    "mdHr": "secondary",
    "mdListBullet": "#00ffff",
    "toolDiffAdded": "#00ff00",
    "toolDiffRemoved": "#ff0000",
    "toolDiffContext": "secondary",
    "syntaxComment": "secondary",
    "syntaxKeyword": "primary",
    "syntaxFunction": "#00aaff",
    "syntaxVariable": "#ffaa00",
    "syntaxString": "#00ff00",
    "syntaxNumber": "#ff00ff",
    "syntaxType": "#00aaff",
    "syntaxOperator": "primary",
    "syntaxPunctuation": "secondary",
    "thinkingOff": "secondary",
    "thinkingMinimal": "primary",
    "thinkingLow": "#00aaff",
    "thinkingMedium": "#00ffff",
    "thinkingHigh": "#ff00ff",
    "thinkingXhigh": "#ff0000",
    "thinkingMax": "#ff0088",
    "bashMode": "#ffaa00"
  }
}
  1. 通过 /settings 选择主题。

热重载: 当你编辑当前启用的自定义主题文件时,pi 会自动重新加载它,以获得即时的视觉反馈。

主题格式

{
  "$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 必须定义全部 53 个必需令牌。thinkingMax 和两个搜索高亮令牌是可选的,使用下面列出的回退值。

$schema 字段可以启用编辑器自动补全和验证。

颜色令牌

每个主题都必须定义全部 53 个必需的颜色令牌。可选令牌用于保持与现有主题的兼容:thinkingMax 回退到 thinkingXhigh,searchMatchBg 回退到 selectedBg,searchMatchText 回退到 text。其他搜索匹配项在 searchMatchBg 背景上使用带下划线的 searchMatchText;当前匹配项则反转该前景/背景对并使用粗体文本。

核心 UI(13 色)

令牌用途
accent主强调色(徽标、选中项、光标)
border普通边框
borderAccent高亮边框
borderMuted弱化边框(编辑器)
success成功状态
error错误状态
warning警告状态
muted次要文本
dim三级文本
text默认文本(通常为 "")
thinkingText思考块文本
scrollbarTrack全屏滚动条轨道前景色
scrollbarThumb全屏滚动条滑块前景色,普通和展开状态共用

背景与内容(11 个必需,2 个可选)

令牌用途
selectedBg选中行背景
searchMatchBg对话记录搜索匹配背景及当前匹配文本;可选,回退到 selectedBg
searchMatchText对话记录搜索匹配文本及当前匹配背景;可选,回退到 text
userMessageBg用户消息背景
userMessageText用户消息文本
customMessageBg扩展消息背景
customMessageText扩展消息文本
customMessageLabel扩展消息标签
toolPendingBg工具框(等待中)
toolSuccessBg工具框(成功)
toolErrorBg工具框(错误)
toolTitle工具标题
toolOutput工具输出文本

Markdown(10 色)

令牌用途
mdHeading标题
mdLink链接文本
mdLinkUrl链接 URL
mdCode行内代码
mdCodeBlock代码块内容
mdCodeBlockBorder代码块围栏
mdQuote引用块文本
mdQuoteBorder引用块边框
mdHr水平分割线
mdListBullet列表符号

工具 Diff(3 色)

令牌用途
toolDiffAdded新增行
toolDiffRemoved删除行
toolDiffContext上下文行

语法高亮(9 色)

令牌用途
syntaxComment注释
syntaxKeyword关键字
syntaxFunction函数名
syntaxVariable变量
syntaxString字符串
syntaxNumber数字
syntaxType类型
syntaxOperator运算符
syntaxPunctuation标点符号

思考级别边框(6 个必需,1 个可选)

指示思考级别的编辑器边框颜色(视觉层级从弱到强):

令牌用途
thinkingOff关闭思考
thinkingMinimal极少思考
thinkingLow低思考
thinkingMedium中等思考
thinkingHigh高思考
thinkingXhigh超高思考
thinkingMax最高思考;可选,回退到 thinkingXhigh

Bash 模式(1 色)

令牌用途
bashModebash 模式下的编辑器边框(! 前缀)

HTML 导出(可选)

export 部分控制 /export HTML 输出的颜色。如果省略,颜色将从 userMessageBg 派生。

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

颜色取值

支持四种格式:

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

256 色调色板

  • 0-15:基本 ANSI 颜色(因终端而异)
  • 16-231:6×6×6 RGB 立方体(16 + 36×R + 6×G + B,其中 R、G、B 为 0-5)
  • 232-255:灰度渐变

终端兼容性

Pi 使用 24 位 RGB 颜色。大多数现代终端都支持(iTerm2、Kitty、WezTerm、Windows Terminal、VS Code)。对于只支持 256 色的旧终端,pi 会回退到最接近的近似值。

检查真彩色支持:

echo $COLORTERM  # Should output "truecolor" or "24bit"

技巧

深色终端: 使用明亮、饱和度高、对比更强的颜色。

浅色终端: 使用更暗、更柔和、对比更低的颜色。

颜色和谐: 从一个基础调色板(Nord、Gruvbox、Tokyo Night)开始,在 vars 中定义它,并保持一致的引用。

测试: 用不同的消息类型、工具状态、Markdown 内容和长换行文本检查你的主题。

VS Code: 将 terminal.integrated.minimumContrastRatio 设为 1 以获得准确的颜色。

示例

参见内置主题: