内容
# ilmari
[](https://crates.io/crates/ilmari)
[](https://github.com/bnomei/ilmari/actions/workflows/ci.yml)
[](https://crates.io/crates/ilmari)
[](https://crates.io/crates/ilmari)
[](https://discordapp.com/users/bnomei)
[](https://www.buymeacoffee.com/bnomei)
最小的 tmux 弹出式雷达,可以作为独立的侧边栏或 tmux 弹出窗口使用。
支持的代理 CLI:Antigravity CLI (`agy`),Gemini CLI (`gemini`),Codex (`codex`),Amp (`amp`),Claude Code (`claude`),OpenCode (`opencode`),Pi (`pi`,`pi-agent`),Auggie (`auggie`),Grok (`grok`),GitHub Copilot CLI (`copilot`),和 Kiro CLI (`kiro-cli`)。
计划支持的代理 CLI:[Cursor CLI](https://github.com/bnomei/ilmari/issues/11) (`cursor`),[Aider](https://github.com/bnomei/ilmari/issues/12) (`aider`),[Cline CLI](https://github.com/bnomei/ilmari/issues/13) (`cline`),[Goose CLI](https://github.com/bnomei/ilmari/issues/14) (`goose`),和 [OpenHands CLI](https://github.com/bnomei/ilmari/issues/16) (`openhands`)。欢迎拉取请求:每个链接的 CLI 名称都打开了其跟踪问题。
## 平台支持
Ilmari 是为类 Unix tmux 环境构建的。支持的发布工件是 Linux 和 macOS 二进制文件,运行时使用环境假设有一个可用的 Unix 类 shell 和 tmux。Windows 目前不在考虑范围内:由于 Windows tmux 行为未实现和测试,因此不发布 Windows 发布工件。
Ilmari 适用于当 tmux 工作区有多个代理窗格时,您需要快速回答三个问题:
- 哪个窗格仍在运行
- 哪个窗格正在等待您
- 该窗格属于哪个工作区
它作为 tmux 弹出窗口打开,检查您已经运行的窗格,将它们按工作区分组,显示代理状态和可见的输出摘录,并直接跳转到选定的窗格。
Ilmari 优先考虑弹出窗口,并且仅作为观察者。它不启动代理,不管理工作流程,也不拥有您的 tmux 布局。它为您提供了一个现有的代理会话的快速索引。
<a title="点击打开" target="_blank" style="cursor: zoom-in;" href="https://raw.githubusercontent.com/bnomei/ilmari/main/screenshot.png"><img src="https://raw.githubusercontent.com/bnomei/ilmari/main/screenshot.png" alt="截图" style="width: 100%;" /></a>
## Ilmari 解决了什么问题
当多个代理同时运行时,通常的 tmux 工作流程会变得杂乱:
- 等待窗格容易被忽略
- 已完成窗格和仍在运行的窗格混在一起
- 工作区跨会话和窗口分散
- 您最终手动循环窗格,只需找到重要的那一个
Ilmari 将其减少到一个弹出窗口:
- 从 tmux 元数据和输出中检测支持的代理窗格
- 将窗格分类为正在运行、等待、已完成、已终止或未知
- 按工作区路径分组窗格
- 显示每个工作区的轻量级 git 更改上下文
- 跳转到选定的窗格并离开
## 安装
### Cargo (crates.io)
```sh
cargo install ilmari
```
### Homebrew
```bash
brew install bnomei/ilmari/ilmari
```
### GitHub Releases
从 GitHub Releases 页面下载预先构建的 Linux 或 macOS 存档,解压并将 `ilmari` 放在您的 `PATH` 上。Windows 存档不发布,因为 Windows 运行时行为暂不支持。
### 从源码
```bash
git clone https://github.com/bnomei/ilmari.git
cd ilmari
cargo build --release
```
## 弹出式首选项设置
tmux 弹出窗口支持需要 tmux 3.2 或更新版本。
### 1. 添加 tmux 绑定
假设 `ilmari` 已经安装并在您的 `PATH` 上可用:
```tmux
bind-key i display-popup -E -w 90% -h 85% "ilmari"
```
在编辑 `~/.tmux.conf` 后重新加载 tmux:
```sh
tmux source-file ~/.tmux.conf
```
### 2. 打开弹出窗口
按下 tmux 前缀键,然后按下绑定的键。
典型的弹出窗口流程:
- 打开 `ilmari`
- 使用 `j` / `k` 或箭头键移动选择
- 按 `Enter` 跳转到选定的窗格
- 按 `q` 或 `Esc` 退出
当 `ilmari` 作为 tmux 弹出窗口启动时,激活返回到目标窗格并关闭弹出窗口。
## 配置
Ilmari 通过命令行标志和环境变量进行配置。它首先读取环境默认值,然后命令行标志覆盖同一设置的默认值。
| 标志 | 目的 | 环境变量 |
| --- | --- | --- |
| `--refresh-seconds <SECONDS>` | 主要 tmux 扫描节奏 | `ILMARI_REFRESH_SECONDS` |
| `--process-refresh-seconds <SECONDS>` | CPU 和内存采样节奏 | `ILMARI_PROCESS_REFRESH_SECONDS` |
| `--palette <CSV>` | 18 槽调色板覆盖 | `ILMARI_TUI_PALETTE`,然后 `ILMARI_PALETTE` |
| `--no-tui` | 在没有终端 UI 的情况下运行 | `ILMARI_TUI=0` |
| `--no-git` | 以隐藏的 git 摘要启动 | 无 |
| `--no-output-tail` | 跳过窗格输出尾部捕获 | `ILMARI_OUTPUT_TAIL=0` |
| `--no-bell` | 禁用终端铃声警报 | 无 |
| `--socket` | 启用本地 JSON 套接字发布 | `ILMARI_SOCKET=1` |
| `--no-socket` | 禁用本地 JSON 套接字发布 | `ILMARI_SOCKET=0` |
| `--socket-path <PATH>` | 本地 JSON 套接字路径覆盖 | `ILMARI_SOCKET_PATH` |
| `--mcp` | 启用环回 MCP 资源服务器 | `ILMARI_MCP=1` |
| `--no-mcp` | 禁用环回 MCP 资源服务器 | `ILMARI_MCP=0` |
| `--mcp-port <PORT>` | 环回 MCP 端口,默认为 `62778`;`0` 选择一个空闲端口 | `ILMARI_MCP_PORT` |
| `--help` / `-h` | 打印帮助 | 无 |
| `--version` / `-V` | 打印版本 | 无 |
| 变量 | 目的 | 默认值 | 备注 |
| --- | --- | --- | --- |
| `ILMARI_REFRESH_SECONDS` | 主要 tmux 扫描节奏 | `5` | 正整数秒。空值,无效值或非正值会回退到默认值。 |
| `ILMARI_PROCESS_REFRESH_SECONDS` | CPU 和内存采样节奏 | `15` | 与主要刷新分开,以便 `ilmari` 不会在每次重绘时调用 `ps`。空值,无效值或非正值会回退到默认值。 |
| `ILMARI_TUI` | 终端 UI | 编译时启用 `tui` 功能 | 设置为 `0`,`false`,`no` 或 `off` 以无头运行。 |
| `ILMARI_OUTPUT_TAIL` | 窗格输出尾部捕获 | 启用 | 设置为 `0`,`false`,`no` 或 `off` 以跳过 `tmux capture-pane` 输出尾部捕获。 |
| `ILMARI_SOCKET` | 本地 JSON 套接字发布者 | 禁用 | 设置为 `1`,`true`,`yes` 或 `on` 以启用。 |
| `ILMARI_SOCKET_PATH` | 本地 JSON 套接字路径 | 用户和 tmux 套接字作用域的临时目录路径 | 设置路径会在除 `ILMARI_SOCKET=0` 外启用套接字。 |
| `ILMARI_MCP` | 环回 MCP 资源服务器 | 禁用 | 设置为 `1`,`true`,`yes` 或 `on` 以启用。 |
| `ILMARI_MCP_PORT` | 环回 MCP 端口 | `62778` | 设置端口会在除 `ILMARI_MCP=0` 外启用 MCP。使用 `0` 向操作系统请求一个空闲端口。 |
| `ILMARI_TUI_PALETTE` | 主要调色板覆盖 | 终端 ANSI 主题 | 采用 18 槽 CSV 调色板。优先于 `ILMARI_PALETTE`。 |
| `ILMARI_PALETTE` | 调色板覆盖的兼容别名 | 终端 ANSI 主题 | 仅在 `ILMARI_TUI_PALETTE` 未设置时使用。 |
示例:
```sh
ILMARI_REFRESH_SECONDS=10 ilmari
ILMARI_PROCESS_REFRESH_SECONDS=30 ilmari
ILMARI_OUTPUT_TAIL=0 ilmari
ilmari --no-tui --socket
ilmari --socket
ILMARI_SOCKET_PATH=/tmp/ilmari.sock ilmari
ilmari --no-tui --mcp
ilmari --no-tui --mcp --mcp-port 0
```
### 构建时功能
默认 Cargo 构建包括 TUI 和两个端点实现:
```sh
cargo build
```
可以在构建时删除功能:
```sh
cargo build --no-default-features
cargo build --no-default-features --features tui
cargo build --no-default-features --features socket
cargo build --no-default-features --features mcp
cargo build --no-default-features --features rmcp
cargo build --no-default-features --features socket,mcp
cargo build --no-default-features --features tui,socket,mcp
```
功能含义:
| 功能 | 效果 |
| --- | --- |
| `tui` | 构建终端 UI 并引入 `ratatui` 和 `crossterm`。 |
| `socket` | 构建本地 Unix 域 JSON 套接字端点。 |
| `mcp` | 构建环回 MCP 资源端点并引入 `rmcp`,`axum`,`tokio` 和 `tokio-util`。 |
| `rmcp` | `mcp` 的别名,用于显式命名底层 crate 的构建。 |
当编译掉某个端点时,运行时标志仍然可解析。启用编译掉的端点会报告状态警告,例如 `socket support was not compiled in` 或 `MCP support was not compiled in`。没有 `tui` 功能的构建以无头模式运行。
### 本地 JSON 套接字
启用时,Ilmari 在运行时发布一个本地 Unix 域套接字。该套接字不是网络监听器。它接受一行命令并为每个请求返回一个 JSON 对象:
```text
ping
list
ls
detail 12
detail %12
detail ilmari://1/7/12
```
`detail` 接受裸露的窗格编号,如 `12`,tmux 窗格 ID,如 `%12`,以及前缀 ID,如 `tmux:%12`,以及 Ilmari 资源 URI。响应使用规范的 tmux 窗格 ID 形式。
当 Ilmari 成功拥有套接字时,它还会将路径写入 tmux 全局选项 `@ilmari_socket_path`,以便连接器进程可以从 tmux 中发现它。如果另一个 Ilmari 进程已经拥有相同的套接字,则后一个进程继续运行而不会接管该端点。
`list` 返回一个紧凑的动作队列,供消费者使用。项目包括窗格 ID,资源 URI,消费者状态,代理 slug,当前工作区路径和预构建的 tmux `argv` 命令,其中一个即时的 tmux 动作是有用的。已完成的会话使用 `result` 意图:
```json
{
"ok": true,
"type": "list",
"schema_version": 1,
"revision": 42,
"resource": "ilmari://list",
"observed_at": "2026-06-21T16:40:12.123Z",
"ttl_ms": 15000,
"items": [
{
"resource": "ilmari://1/7/12",
"id": "%12",
"state": "needs-input",
"agent": "codex",
"cwd": "/Users/bnomei/PROJECTS/ilmari",
"next": {
"intent": "inspect",
"kind": "tmux",
"argv": ["tmux", "capture-pane", "-p", "-J", "-t", "%12", "-S", "-80"]
}
},
{
"resource": "ilmari://1/7/13",
"id": "%13",
"state": "done",
"agent": "claude-code",
"cwd": "/Users/bnomei/PROJECTS/site",
"next": {
"intent": "result",
"kind": "tmux",
"argv": ["tmux", "capture-pane", "-p", "-J", "-t", "%13", "-S", "-200"]
}
}
],
"warnings": []
}
```
### MCP 资源
使用 `--mcp` 或 `ILMARI_MCP=1` 启用时,Ilmari 默认在 `127.0.0.1:62778` 上启动一个本地的 MCP 流式 HTTP 服务器。 `--mcp-port <PORT>` 或 `ILMARI_MCP_PORT` 选择另一个端口, `--mcp-port 0` 请求操作系统提供一个空闲端口。服务器将其 URL 发布到 tmux 全局选项 `@ilmari_mcp_url`,例如 `http://127.0.0.1:62778/mcp`。
MCP 服务器仅公开资源。它不公开工具。资源描述符保持为纯文本以兼容客户端,而资源内容带有 `_meta.readOnly = true`。
可用资源:
| 资源 | 形状 |
| --- | --- |
| `ilmari://list` | 与套接字 `list` 相同。 |
| `ilmari://<session>/<window>/<pane>` | 与套接字 `detail` 相同,使用无符号 tmux ID,如 `ilmari://1/7/12`。 |
通过 MCP `resources/subscribe` 支持资源订阅。订阅某个窗格 URI 的用户在该窗格资源更改时接收 `notifications/resources/updated`。订阅 `ilmari://list` 的用户在列表 JSON 更改时接收 `notifications/resources/updated`,在可见资源集更改时接收 `notifications/resources/list_changed`。
状态映射:
| Ilmari 状态 | 消费者状态 | 下一步意图 |
| --- | --- | --- |
| `running` | `running` | `wait` |
| `waiting-input` | `needs-input` | `inspect` |
| `finished` | `done` | `result` |
| `terminated` | `gone` | `cleanup` |
| `unknown` | `unknown` | `inspect` |
### 窗格输出隐私
默认情况下,Ilmari 使用 `tmux capture-pane` 从支持的代理窗格中捕获一个小的最近尾部,以便它可以分类等待状态并显示最新的输出摘录。该窗格缓冲区/历史文本可能包含提示、命令输出、文件路径、令牌或其他敏感信息。如果您不希望 Ilmari 读取窗格内容,请使用 `ILMARI_OUTPUT_TAIL=0` 禁用输出尾部捕获;除非将该变量设置为 `0`、`false`、`no` 或 `off`,否则窗格尾部默认启用。
Ilmari 在代码中使用语义颜色角色,但默认情况下这些角色会通过终端的当前 ANSI 调色板解析。如果您想要显式颜色,请使用 `ILMARI_TUI_PALETTE` 或 `ILMARI_PALETTE` 提供 18 槽 CSV 调色板覆盖。
插槽顺序:
```text
fg,bg,black,red,green,yellow,blue,magenta,cyan,white,bright_black,bright_red,bright_green,bright_yellow,bright_blue,bright_magenta,bright_cyan,bright_white
```
接受的颜色格式:
- `#RRGGBB`
- `0xRRGGBB`
- `0XRRGGBB`
- `RRGGBB`
- `rgb:RR/GG/BB`
- `rgb:RRRR/GGGG/BBBB`
行为:
- `ILMARI_TUI_PALETTE` 优先于 `ILMARI_PALETTE`
- 空或格式错误的调色板值被忽略
- 如果两者都未设置,`ilmari` 使用终端的默认 ANSI 主题