agavra/tuicr
GitHub: agavra/tuicr
一个终端中的 GitHub 风格 diff 审查工具,专为审阅 AI 生成代码而设计,可将结构化评论导出为 LLM 友好的 Markdown 格式。
Stars: 886 | Forks: 90
# tuicr:用于代码审查的 TUI
像审查 GitHub Pull Request 一样,直接在你的终端中审查 AI 生成的 diffs。

## 我为什么开发这个工具
我经常使用 Claude,但在“审查每一处改动”和“接受所有编辑”之间没有中间地带。审查每一处改动会将速度拖慢到人类的节奏,而接受所有编辑会让最终的审查变得痛苦,因为我最终不得不逐一留下评论,并在每次修复后等待。
`tuicr` 就是这个中间地带。放开 Agent 的限制,像审查普通的 PR 一样审查这些改动,在需要的地方留下评论,并将所有内容导出为结构化的反馈,以便 Agent 可以一次性处理。
它让我的 AI 辅助开发飞速运转。
## 概述
一个位于你终端中的 GitHub 风格的 diff 查看器,支持 Vim 键绑定。滚动查看修改过的文件、留下评论、将文件标记为已审查,并将你的完整评论复制到剪贴板,格式已准备好直接粘贴回 Agent。
## 功能特性
- **无限滚动 diff 视图** - 所有修改过的文件在一个连续滚动视图中展示(GitHub 风格)
- **Vim 键绑定** - 使用 `j/k`、`Ctrl-d/u`、`g/G`、`{/}`、`[/]` 进行导航
- **可展开的上下文** - 在 "... expand (N lines) ..." 上按 Enter 键,以显示 hunk 之间隐藏的上下文
- **评论** - 添加审查级别、文件级别或行级别的带类型评论
- **可视模式** - 使用 `v` / `V` 选择行范围,并一次性对多行进行评论
- **审查跟踪** - 将文件标记为已审查,将进度持久化到磁盘
- **`.tuicrignore` 支持** - 从审查 diff 中排除匹配的文件
- **剪贴板导出** - 复制专为 LLM 消耗优化的结构化 Markdown
- **会话持久化** - 审查进度自动保存,并在重启时重新加载
- **Jujutsu 支持** - 内置 jj 支持(由于 jj 仓库以 Git 为后端,因此会优先尝试)
- **Mercurial 支持** - 内置 hg 支持
## 安装
### Homebrew (macOS/Linux)
```
brew install agavra/tap/tuicr
```
### 预编译二进制文件
从 [GitHub Releases](https://github.com/agavra/tuicr/releases) 下载适合您平台的最新版本。
### Mise (macOS/Linux/Windows)
```
mise use github:agavra/tuicr
```
### 通过 crates.io
```
cargo install tuicr
```
### 使用 Nix
```
# build tuirc (将二进制文件链接到 ./result/bin/tuirc)
nix build github:agavra/tuicr
# 或直接运行
nix run github:agavra/tuicr
```
### 从源码构建
```
git clone https://github.com/agavra/tuicr.git
cd tuicr
cargo install --path .
```
## 使用方法
在任何 git、jujutsu 或 mercurial 仓库中运行 `tuicr`:
```
cd /path/to/your/repo
tuicr
```
检测顺序:Jujutsu → Git → Mercurial。因为 jj 仓库以 Git 为后端,所以首先尝试 Jujutsu。
### 选项
| 标志 | 描述 |
|------|-------------|
| `-r` / `--revisions ` | 要审查的提交范围/版本集。确切语法取决于 VCS 后端 |
| `--theme ` | 颜色主题覆盖(`dark`、`light`、`ayu-light`、`onedark`、`github-light`、`github-dark`、`catppuccin-latte`、`catppuccin-frappe`、`catppuccin-macchiato`、`catppuccin-mocha`、`gruvbox-dark`、`gruvbox-light`、`nord-dark`、`nord-light`、`nord-dark-high-contrast`、`nord-light-high-contrast`、`solarized-light`、`solarized-dark`、`tokyo-night-storm`) |
| `--appearance ` | 默认主题的外观模式(`dark`、`light`、`system`) |
| `--stdout` | 导出时输出到标准输出而不是剪贴板 |
| `--no-update-check` | 启动时跳过更新检查 |
默认情况下,`tuicr` 以提交选择模式启动。
如果存在暂存或未暂存的更改,第一个可选择的条目是 `Staged changes` 和/或 `Unstaged changes`。
当提供 `-r` / `--revisions` 时,`tuicr` 会直接打开该版本范围。
在窄终端(少于 100 列)上,`tuicr` 启动时会隐藏文件列表;使用 `;e` 切换其可见性。
### 配置
在以下位置设置默认主题:
- Linux/macOS:`$XDG_CONFIG_HOME/tuicr/config.toml`(默认:`~/.config/tuicr/config.toml`)
- Windows:`%APPDATA%\tuicr\config.toml`
示例:
```
theme = "catppuccin-mocha"
appearance = "system"
theme_dark = "gruvbox-dark"
theme_light = "gruvbox-light"
show_file_list = false
diff_view = "side-by-side"
backend = "libgit2"
wrap = true
cursor_line = false
transparent_background = false
scroll_offset = 5
comment_types = [
{ id = "note", label = "question", definition = "ask for clarification", color = "yellow" },
{ id = "suggestion", definition = "possible improvements" },
{ id = "issue", definition = "problems to fix" },
{ id = "praise", definition = "positive feedback" },
{ id = "nit", label = "nitpick", definition = "small optional tweaks", color = "#d19a66" }
]
```
`show_file_list` 控制启动时文件列表面板是否可见(默认:`true`)。可在运行时使用 `;e` 切换。
`diff_view` 设置默认的 diff 布局:`"unified"`(默认)或 `"side-by-side"`。可在运行时使用 `:diff` 切换。
`backend` 选择 Git 实现:`"libgit2"`(普通 Git 仓库的默认值)或 `"cli"`。稀疏检出的仓库会自动路由到 Git CLI 后端,因为 libgit2 不能可靠地支持稀疏索引检出。
`wrap` 在 diff 视图中启用换行(默认:`false`)。可在运行时使用 `:set wrap!` 切换。
`cursor_line` 在 diff 视图中高亮显示当前光标行和可视选择区域(默认:`true`)。设置为 `false` 以禁用。
`transparent_background` 允许终端背景透过面板显示(默认:`true`)。设置为 `false` 以改为绘制主题的 `panel_bg` 颜色。
`scroll_offset` 在滚动时保持光标上下可见的最小行数(类似于 Vim 的 `scrolloff`)。默认:`0`(无边距)。
`comment_types` 替换默认列表并定义 Tab 键的循环顺序。
每个条目都需要 `id`,并可选择设置 `label`、`definition` 和 `color`。
颜色接受终端名称(例如 `yellow`、`light_red`)或十六进制代码(`#RRGGBB`)。
#### `comment_types` 的工作原理
- `id` 是保存在会话中并用于匹配的稳定内部值。
- `label` 是在 UI 和导出中显示的可见标签(`[QUESTION]`、`[NITPICK]` 等)。
- `definition` 是针对 LLM 的指导文本,包含在导出的 `Comment types:` 图例中。
- `color` 控制 TUI 中的评论徽章/边框颜色。
- 声明 `comment_types` 是一种完全替代,如果您定义了 2 种类型,则只有这 2 种可用。
- 如果缺少 `comment_types`,tuicr 使用默认值:`note`、`suggestion`、`issue`、`praise`。
- 无效的条目会被忽略并伴随启动警告,如果所有条目都无效,tuicr 会回退到默认值。
最小替换示例:
```
comment_types = [
{ id = "question", definition = "ask for clarification" },
{ id = "blocker", color = "red", definition = "must be fixed before merge" }
]
```
主题解析优先级:
1. `--theme `
2. 上述配置文件路径中的 `theme`(取决于操作系统)
3. 配置中的 `theme_dark` + `theme_light`(由外观决定)
4. 配置中仅 `theme_dark` 或仅 `theme_light`(忽略外观)
5. `--appearance `(仅在未设置显式主题或变体时)
6. 配置中的 `appearance`(仅在未设置显式主题或变体时)
7. 内置默认值(`system`)
注意:
- 无效的 `--theme` 值会导致立即以非零状态退出。
- `config.toml` 中的未知键会被忽略并伴随启动警告。
### 使用 `.tuicrignore` 忽略文件
`tuicr` 从仓库根目录读取 `.tuicrignore`,并将匹配的文件从所有审查 diff 中排除。
规则遵循 gitignore 风格的模式匹配,包括 `!` 取反。
示例:
```
target/
dist/
*.lock
!Cargo.lock
```
### 鼠标
鼠标支持**默认开启**。要在配置中禁用它,请设置:
```
mouse = false
```
| 操作 | 效果 |
|--------|--------|
| 滚轮上/下 | 滚动光标下的面板(文件列表、diff、提交列表或帮助弹窗),而不移动光标行 |
| 点击文件 | 跳转到该文件(lazygit 风格) |
| 点击目录 | 展开或折叠它 |
| 点击 diff 行 | 将光标定位到该行 |
| 点击提交 | 切换选择(或展开行以加载更多) |
| 在 diff 中拖动 | 高亮显示一个范围;按 `y` 复制选中的源码行 |
要在整个 UI 中进行完整的原生终端选择,请在拖动时按住终端的旁路修饰符(通常是 **Shift** 或 **Option/Alt**,取决于终端)。如果两者都不起作用,请查看您终端的文档。
### 键绑定
#### 导航
| 按键 | 操作 |
|-----|--------|
| `j` / `↓` | 向下滚动 |
| `k` / `↑` | 向上滚动 |
| `h` / `←` | 向左滚动 |
| `l` / `→` | 向右滚动 |
| `Ctrl-d` / `Ctrl-u` | 向下/向上滚动半页 |
| `Ctrl-f` / `Ctrl-b` | 向下/向上滚动整页 |
| `g` / `G` | 跳转到第一个/最后一个文件 |
| `{N}G` | 跳转到当前文件的第 N 行 |
| `{` / `}` | 跳转到上一个/下一个文件 |
| `[` / `]` | 跳转到上一个/下一个 hunk |
| `/` | 在 diff 中搜索 |
| `n` / `N` | 下一个/上一个搜索匹配项 |
| `Enter` | 展开/折叠 hunk 之间隐藏的上下文 |
| `zz` | 将光标居中到屏幕 |
#### 文件树
| 按键 | 操作 |
|-----|--------|
| `Space` | 切换展开目录 |
| `Enter` | 展开目录 / 跳转到 diff 中的文件 |
| `o` | 展开所有目录 |
| `O` | 折叠所有目录 |
#### 面板焦点
| 按键 | 操作 |
|-----|--------|
| `Tab` / `Shift-Tab` | 在文件列表、diff 和提交选择器之间向前/向后切换焦点 |
| `;h` | 聚焦文件列表(左面板) |
| `;l` | 聚焦 diff 视图(右面板) |
| `;k` | 聚焦提交选择器(顶部面板) |
| `;j` | 聚焦 diff 视图 |
| `;e` | 切换文件列表可见性 |
| `Enter` | 选择文件(当文件列表获得焦点时) |
#### 审查操作
| 按键 | 操作 |
|-----|--------|
| `r` | 切换文件的已审查状态 |
| `c` | 添加行评论(如果不在 diff 行上,则添加文件评论) |
| `C` | 添加文件评论 |
| `;c` | 添加审查评论 |
| `v` / `V` | 进入可视模式进行范围评论 |
| `dd` | 删除光标处的评论 |
| `i` | 编辑光标处的评论 |
| `y` | 将评论复制到剪贴板 |
#### 可视模式
| 按键 | 操作 |
|-----|--------|
| `j` / `k` | 向下/向上扩展选择范围 |
| `c` / `Enter` | 为选中范围创建评论 |
| `Esc` / `v` / `V` | 取消选择 |
#### 评论模式
| 按键 | 操作 |
|-----|--------|
| `Tab` / `Shift-Tab` | 向前/向后循环切换评论类型(根据 `comment_types` 顺序) |
| `Enter` / `Ctrl-Enter` / `Ctrl-s` | 保存评论 |
| `Shift-Enter` / `Ctrl` | 插入新行 |
| `←` / `→` | 移动光标 |
| `Ctrl-w` / `Alt-Backspace` / `Cmd-Backspace` | 删除单词 |
| `Ctrl-u` | 清除行 |
| `Esc` / `Ctrl-c` | 取消 |
#### 命令
| 命令 | 操作 |
|---------|--------|
| `:w` | 保存会话 |
| `:e` (`:reload`) | 重新加载 diff 文件 |
| `:clip` (`:export`) | 将评论复制到剪贴板 |
| `:diff` | 切换 diff 视图(unified / side-by-side) |
| `:commits` | 选择要审查的提交 |
| `:set wrap` | 在 diff 视图中启用换行 |
| `:set wrap!` | 在 diff 视图中切换换行 |
| `:set commits` | 显示内联提交选择器 |
| `:set nocommits` | 隐藏内联提交选择器 |
| `:set commits!` | 切换内联提交选择器 |
| `:clear` | 清除所有评论 |
| `:version` | 显示 tuicr 版本 |
| `:update` | 检查更新 |
| `:q` | 退出(如果有未保存的内容会警告) |
| `:q!` | 强制退出 |
| `:x` / `:wq` | 保存并退出(如果存在评论,会提示复制) |
| `?` | 切换帮助 |
| `q` | 快速退出 |
#### 提交选择(启动时)
| 按键 | 操作 |
|-----|--------|
| `j` / `k` | 移动选择 |
| `Space` | 切换提交选择 |
| `Enter` | 确认并加载 diff |
| `q` / `Esc` | 退出 |
#### 内联提交选择器(多提交审查)
当审查多个提交时,diff 视图顶部会出现一个内联提交选择器面板。使用 `;k` 或 `Tab` 聚焦它。
| 按键 | 操作 |
|-----|--------|
| `j` / `k` | 在提交之间导航 |
| `Space` / `Enter` | 切换提交选择(更新 diff) |
| `(` / `)` | 在各个提交之间循环切换 |
| `Esc` | 将焦点返回给 diff |
#### 确认对话框
| 按键 | 操作 |
|-----|--------|
| `y` / `Enter` | 是 |
| `n` / `Esc` | 否 |
## 审查输出
当您导出审查结果时(`:clip` 或在 `:wq` 时确认),`tuicr` 会将结构化的 Markdown 复制到您的剪贴板。该格式已优化,可直接粘贴到 AI Agent 对话中:
```
I reviewed your code and have the following comments. Please address them.
Comment types: ISSUE (problems to fix), SUGGESTION (improvements), NOTE (observations), PRAISE (positive feedback)
1. **[SUGGESTION]** `src/auth.rs` - Consider adding unit tests
2. **[ISSUE]** `src/auth.rs:42` - Magic number should be a named constant
3. **[NOTE]** `src/auth.rs:50-55` - This block could be refactored
```
每条评论都有编号且自包含,带有其文件路径和行号或范围(如果适用)。
如果配置了 `comment_types`,此图例和 `[TYPE]` 标签将反映您配置的标签和定义。
## 会话持久化
会话会自动保存到 `~/.local/share/tuicr/reviews/`(符合 XDG 规范)。当您在同一个仓库中重新打开 `tuicr` 时,您之前的审查进度(评论、审查状态)将会被恢复。
## Agent 集成
tuicr 在 `skills/tuicr/` 中提供了一个由仓库管理的技能包。
它会在一个 tmux 分屏中打开 tuicr,以便您可以交互式地审查更改并将评论反馈给您的编码 Agent。
**用法:** `/tuicr` 或要求您的编码 Agent “review my changes with tuicr”。
### Claude Code
**前置条件:** Claude Code 在 tmux 内运行,已安装 tuicr。
**安装**(选择其一):
```
# 将 shared skill 复制到 Claude 的本地 skills 目录
mkdir -p ~/.claude/skills
cp -r /path/to/tuicr/skills/tuicr ~/.claude/skills/tuicr
```
### Codex
**前置条件:** Codex 在 tmux 内运行,已安装 tuicr。
**安装**:
```
# 将 shared skill 复制到本地 agents 的 skills 目录
mkdir -p ~/.agents/skills
cp -r /path/to/tuicr/skills/tuicr ~/.agents/skills/tuicr
```
标签:AI编程, AI辅助开发, Claude, CLI, Code Review, CVE检测, Diff Viewer, Git, Markdown, Pull Request, Rust, TUI, Vim键绑定, WiFi技术, 代码审查, 代码管理, 剪贴板, 可视化界面, 可视化选择, 威胁情报, 差异分析, 差异查看器, 开发者工具, 批注, 效率工具, 终端应用, 终端用户界面, 网络流量审计, 通知系统