---
title: Agent 终端协议
description: ATP 是 Termio 托管任意 Agent 命令行工具的方式——一份 JSON 清单声明如何启动它、它如何汇报状态、如何精确恢复那段对话。Agent 自己的 TUI 始终留在真实终端里。
x-i18n:
  source_path: atp.mdx
  source_hash: cc00b0a0dda4c1c7626a24427f92833ae369bb83598583123ef554236d37d563
  generated_at: 2026-08-10
---

编辑器类协议把你的 Agent 重新渲染进编辑器面板。ATP 押的是相反的注：Agent 自己的 TUI
本身就是界面，所以它留在真实终端里，协议只标准化它周围那薄薄一层——**启动**、**实时
状态** 和 **精确恢复**。Termio 附带的每个 Agent 都由这同一份清单定义；不存在特权的内部
API。

## 清单

每个 Agent 一个 JSON 文件。下面是 Termio 内置的 Grok 清单，原文照录：

```json
{
  "id": "grok",
  "order": 95,
  "name": "Grok",
  "wire": "grok",
  "command": "grok",
  "permissionBypassFlag": "--yolo",
  "resume": {
    "create": "--session-id {id}",
    "resume": "--resume {id}",
    "storeRoot": "~/.grok/sessions",
    "storeMatch": "dir:{id}"
  },
  "icon": { "vector": "grok" },
  "install": "https://x.ai/cli",
  "titleStatus": {
    "attention": ["Action Required"]
  },
  "hooks": {
    "type": "json",
    "file": "~/.grok/hooks/termio.json",
    "dialect": "grok",
    "conversation": "sessionId",
    "events": [
      { "on": "SessionStart", "state": "idle" },
      { "on": "UserPromptSubmit", "state": "working" },
      { "on": "PreToolUse", "state": "working" },
      { "on": "PostToolUse", "state": "working" },
      { "on": "Stop", "state": "done" }
    ]
  }
}
```

| 字段 | 含义 |
| --- | --- |
| `id` | 稳定标识。会话会持久化它，所以一旦发布就不再更改。 |
| `name` | 选择器和侧栏里显示的名字。 |
| `command` | 要启动的命令行，在你登录 shell 的 `PATH` 上解析。 |
| `permissionBypassFlag` | 厂商的跳过权限参数，接到一个一键开关上。可选。 |
| `icon` | `vector`（内置品牌标记）、`path`（你自己的 PNG/SVG 文件）或 `symbol`（一个 SF Symbol），可附带 `tint`。 |
| `install` | 厂商的安装页面，在找不到该命令时提示。可选。 |
| `order` | 在 Agent 选择器里的位置。可选；未声明的清单排在最后。 |

## 状态

会话始终处于四种状态之一——`working`、`attention`（被你挡住）、`done` 或 `idle`——显示在
侧栏、菜单栏和你的 iPhone 上。清单声明 Agent 通过哪三条通道汇报它们：

| 通道 | 作用 |
| --- | --- |
| `hooks` | 精确通道：Termio 安装 Agent 自己的 hook 配置（按 `dialect` 为 JSON、TOML 或插件），让 Agent 自己汇报每个 `on → state` 事件。声明了 hooks 时，它就是唯一的事实来源。 |
| `titleStatus` | 针对 Agent 实时终端标题（OSC 0/2）的正则规则——这是部分 Agent 会广播的带内信号。它与 hooks 并存，并在标题翻转的瞬间纠正漏掉的事件。 |
| `status` | 面向完全没有 hook 机制的 Agent 的屏幕分类正则。声明了 hooks 时会被忽略。 |

`hooks.conversation` 指出 Agent 自己的会话 id 出现在它 hook 载荷的哪个位置（shell hooks
是 stdin JSON 的某个字段，插件是事件的键路径）。有了它，每次状态汇报也一并带上对话*身份*
——于是当 Agent 在会话中途切到新对话（`/new`、`/clear`）时，Termio 会在下一个事件到达的
瞬间把标签重新绑定到活着的那一段。

## 恢复 [#resume]

重新打开一个会话，会把 Agent 重新启动进同一段对话。恢复是 **要么精确、要么不做**：Termio
要么恢复到某个标签所绑定的那段确切对话，要么全新启动——它绝不猜。根据出现了哪些字段，分成
两类：

**固定 id** —— 命令行接受在启动时指定会话 id。`create` 用 Termio 生成的 id 开启一段新对话，
`resume` 续上它；`storeRoot` + `storeMatch` 描述 Agent 在磁盘上的会话存储，好让 Termio 分清
两者（创建重复 id 会报错，恢复不存在的 id 也会）。

**发现式 id** —— id 由 Agent 自己生成。`discover` 描述的是机制，而不是某个 Agent：会话记录
存在哪里、一条记录怎么读（`jsonl` —— 日志的第一行，而这份日志本身就是对话记录；或 `json`
—— 一个独立的元数据文件），以及指向 id 和工作目录的键路径。Termio 找回这个 id，把它绑定到
标签上，从此精确恢复。

```json
"resume": {
  "resume": "resume {id}",
  "discover": {
    "root": "~/.codex/sessions",
    "format": "jsonl",
    "id": "payload.id",
    "cwd": "payload.cwd"
  }
}
```

## 添加你自己的 Agent

把清单放在 `~/.termio/config/agents/<id>.json` 并重启 Termio——它就会和内置 Agent 一起出现在
选择器里，拥有同样的状态点和恢复行为。最小的清单只是一个 id、一个名字和一条命令；命令行
支持到哪一步，就把 status 和 resume 加到哪一步。

<Callout type="tip">
  [自定义 Agent](/zh-CN/docs/custom-agents) 指南把这件事从头到尾讲了一遍——图标、扫屏状态
  规则，以及如何覆盖一个内置 Agent。
</Callout>
