mirocode 0.0.0-stage → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.zh.md ADDED
@@ -0,0 +1,372 @@
1
+ <p align="center">
2
+ <img src="logo.png" alt="Miro" width="120" height="120">
3
+ </p>
4
+
5
+ <h1 align="center">Miro</h1>
6
+
7
+ <p align="center">
8
+ 面向 ACP 兼容编程智能体的终端客户端。<br>
9
+ 支持交互式 TUI 与一次性打印模式,基于 Bun、React 与 Ink。
10
+ </p>
11
+
12
+ <p align="center">
13
+ <a href="./README.md">English</a>
14
+ ·
15
+ 中文
16
+ </p>
17
+
18
+ ---
19
+
20
+ **miro-cli** 自带直接调用 Chat Completions、OpenAI Responses 或 Anthropic Messages 的 agent 和工具循环。只有显式传入 `--acp <provider-id>` 时,才会将 [Agent Client Protocol](https://agentclientprotocol.com/) 提供方作为子进程启动,并通过 stdio JSON-RPC 通信。
21
+
22
+ ## 环境要求
23
+
24
+ - [Bun](https://bun.sh/) **>= 1.4.3**;装 npm 包时只需 Node **>= 22.7**
25
+ - 为 Miro 自带 agent 准备一个兼容的 API 端点;仅在使用 `--acp` 时才需要 `PATH` 上的 ACP 提供方二进制(见 [ACP 提供方](#acp-提供方))
26
+
27
+ ## 安装与运行
28
+
29
+ 安装已发布的 npm 包;`miro` 命令跑在 Node **>= 22.7** 上,不需要 Bun:
30
+
31
+ ```bash
32
+ npm install -g mirocode
33
+ npx mirocode
34
+ ```
35
+
36
+ 从源码运行:
37
+
38
+ ```bash
39
+ bun install
40
+ bun start
41
+ ```
42
+
43
+ `npm publish` 发布的是 Node 单体产物 `dist/cli.js` 加 codemode Worker 与 QuickJS WASM;`prepack` 会按当前源码重新构建它们。
44
+
45
+ 为当前平台编译独立二进制:
46
+
47
+ ```bash
48
+ bun run build
49
+ ./dist/miro
50
+ ```
51
+
52
+ `bun run build:js` 会生成可检查的 ESM 包,而不是编译后的二进制。
53
+
54
+ 带 `v*` 的发布标签会构建 Linux / macOS(x64 与 arm64)二进制。本地交叉编译与 CI 使用相同参数:
55
+
56
+ ```bash
57
+ bun run scripts/build.ts --target bun-linux-x64 --outfile dist/miro-linux-amd64
58
+ ```
59
+
60
+ ## 用法
61
+
62
+ ```bash
63
+ miro
64
+ miro --version
65
+ miro -p "Analyze this project"
66
+ echo "Summarize this input" | miro -p
67
+ miro -p --output-format json "Fix the tests"
68
+ miro --model hy3
69
+ miro --effort high
70
+ miro --acp claude
71
+ miro --continue
72
+ miro --resume <session-id>
73
+ ./dist/miro -c <session-id>
74
+ ```
75
+
76
+ 从源码运行时,在 `--` 之后传递参数:
77
+
78
+ ```bash
79
+ bun start -- -c <session-id>
80
+ bun start -- -p "Analyze this project"
81
+ ```
82
+
83
+ ### 选项
84
+
85
+ | 参数 | 说明 |
86
+ |------|------|
87
+ | `-p`, `--print` | 非交互执行一次请求后退出 |
88
+ | `--output-format <text\|json>` | 打印模式输出格式(需配合 `--print`) |
89
+ | `--acp <provider-id>` | 按 id 启动可用的 ACP 提供方;不传时始终启动 miro |
90
+ | `--model <model>` | 按值或显示名选择模型(交互与打印模式均可用) |
91
+ | `--effort <level>` | 按值或显示名选择思考强度(交互与打印模式均可用,不保存) |
92
+ | `-c`, `--continue [id]` | 继续会话;省略 `id` 则使用当前项目最近一次会话 |
93
+ | `--resume <id>` | 按指定会话 id 恢复 |
94
+ | `--permission-mode <m>` | miro 权限模式:`auto`(默认)或 `manual` |
95
+ | `--mode <mode>` | 交互模式:`default` 或 `plan` |
96
+ | `-h`, `--help` | 打印帮助 |
97
+
98
+ `--output-format` 仅能与 `-p` / `--print` 同时使用;`--acp`、`--model`、`--effort` 也可在启动交互式 TUI 时使用,且只影响本次运行。`--acp` 只接受可用 ACP 提供方的 id,不能传 `miro`;已移除的 `--provider` 会报迁移错误。不带 `--print` 的裸提示会报错。`-c` 不带 id 只继续本次启动模式下最近的会话(ACP 还限定为同一 id);`--resume` 必须提供 id。
99
+
100
+ ## 命令
101
+
102
+ 在交互式输入框中使用:
103
+
104
+ | 命令 | 说明 |
105
+ |------|------|
106
+ | `/init [extra]` | 分析代码库并创建或改进 `AGENTS.md` |
107
+ | `/model [model]` | 选择或切换模型 |
108
+ | `/effort [level]` | 设置当前模型的努力程度 |
109
+ | `/config [id] [val]` | 查看或修改 ACP 会话配置项 |
110
+ | `/thinking [mode]` | 设置思考呈现为 `compact`(默认)、`full` 或 `hidden`;不带参数打开选择器 |
111
+ | `/permissions [mode]` | miro 权限模式:`auto`(默认)或 `manual`;不带参数打开选择器 |
112
+ | `/plan [on\|off\|status]` | 进入、退出或查看 Plan 模式(仅 miro) |
113
+ | `/statusline [reset]` | 配置状态栏项目、顺序与颜色 |
114
+ | `/review [text]` | 审查代码改动;不带参数打开选择器(未提交、分支、commit 或自定义指令) |
115
+ | `/goal [text]` | 朝一个目标持续工作,直到模型报告完成或受阻;回复运行中输入新目标会安全中断当前回合并接管。不带参数查看当前目标,另有 `replace`、`status`、`pause`、`resume` / `cancel` 子命令(仅 miro) |
116
+ | `/simplify [text]` | 在保持行为不变的前提下简化代码;可传路径或自由指令 |
117
+ | `/commit [text]` | 为当前改动创建一个提交;可用文本指导提交信息 |
118
+ | `/commit-push-pr` | 创建一个提交、把分支推送到 `origin`,并用该远端平台的 CLI(`gh`、`glab` 或 `tea`)创建拉取请求 |
119
+ | `/resume [id]` | 恢复已保存会话;不带 id 打开选择器 |
120
+ | `/continue [id]` | `/resume` 的别名 |
121
+ | `/new` | 新建会话,不清除终端 |
122
+ | `/sessions` | 列出当前项目已保存的会话 |
123
+ | `/clear` | 新建会话并清除终端与可见记录 |
124
+ | `/compact [text]` | 摘要较早的上下文并保留最近历史;可选文本用于指定摘要侧重点 |
125
+ | `/export [file]` | 导出对话(剪贴板或 `.txt` 文件) |
126
+ | `/help` | 显示帮助 |
127
+ | `/exit` | 退出(`exit`、`/quit`、`quit`),并打印会话累计用量 |
128
+ | `!<command>` | 在本地执行 shell 命令,输出会附到下一次普通提示 |
129
+
130
+ ACP 声明的提供方专用斜杠命令会原样转发。
131
+
132
+ `/commit-push-pr` 会先读 `origin` 远端再挑对应的 CLI:GitHub 用 `gh`,GitLab 用 `glab`,Gitea / Forgejo 用 `tea`。该 CLI 缺失、未认证,或平台本身没有 CLI(Bitbucket、无法识别的自建实例)时,它仍会提交并推送,然后给出手动创建拉取请求的 URL,而不是编造一个。仓库没有 `origin` 远端时,本地提交完就停下。
133
+
134
+ 回合进行中时,Enter 引导内置 Miro agent,Tab 将提示排入下一轮队列。引导会等待当前模型响应和工具执行收尾,再继续同一任务;进入模型历史前会显示为待生效。普通、Plan 和 Goal 对话支持引导;ACP、`/review`、`/commit` 等隔离工作流和独立压缩回退为 FIFO 排队。中断、故障或恢复会话后的未生效引导会暂停发送:打开 Ctrl+Q 后按 `r` 恢复,也可以编辑或删除消息。斜杠命令沿用原有分派规则。忙碌时拒绝 `!command`。
135
+
136
+ ## 快捷键
137
+
138
+ | 按键 | 作用 |
139
+ |------|------|
140
+ | Enter | 发送提示;当前任务支持时引导正在进行的任务 |
141
+ | Tab | 运行时排队发送;补全优先 |
142
+ | Shift+Enter | 插入换行(Miro 会启用 Kitty 与 xterm 扩展键上报;不支持的终端仍无法将它与 Enter 区分) |
143
+ | `?` | 快捷键速查(输入框为空时) |
144
+ | ↑ / ↓ | 输入历史或补全 |
145
+ | Ctrl+M | 选择或切换模型(需要终端支持 kitty 键盘协议,否则该键与 Enter 相同) |
146
+ | Shift+Tab | 循环交互模式(`Default` / `Plan`) |
147
+ | Ctrl+O | 打开整屏的 Review 窗口:实时与已保留的思考、shell 输出与工具详情 |
148
+ | Ctrl+Q | 查看待生效引导,编辑、重排或删除排队消息;`r` 恢复暂停发送 |
149
+ | Ctrl+L | 清除终端显示(不结束 ACP 会话) |
150
+ | Ctrl+C | 清空输入框;输入框为空时中断当前回合,2 秒内再按一次退出。任何正常退出方式(Ctrl+C、`/exit`、裸 `exit`/`quit`)都会打印同一行会话累计用量,形如 `Stat ↑12.4k ↓2.1k R84.3k W6.2k CH81.9% $0.018`:↑/↓ 是输入与输出的会话累计值,`R`/`W` 是缓存读/写(本会话出现过缓存读数后整段出现,没有读数的一侧补 0),`CH` 是缓存命中率(命中 /(未命中输入 + 命中 + 写入)),末段是会话累计成本(不足 1 时保留三位小数,不足 0.001 时保留四位;miro 累加主循环与压缩摘要请求,ACP 直接用 agent 上报的累计 `usage_update` 成本);提供方从未上报过用量与成本时这一行整体不打印 |
151
+ | Esc | 关闭快捷键帮助,或中断当前回合 |
152
+
153
+ `@` 补全文件路径(优先 `git ls-files`,否则回退到文件系统)。多行粘贴会作为一次提交保留:编辑时折叠显示,发送后在会话记录中还原为原文。
154
+
155
+ ## 渲染
156
+
157
+ 智能体回复会在终端里按 Markdown 渲染:标题、列表、表格、围栏代码块与行内代码都会着色,行内 `$...$` 与块级 `$$...$$` 数学公式会以 Unicode 字形呈现。流式过程中未闭合的数学分隔符会原样输出,直到回合结束;不支持的 LaTeX 语法保留为纯文本。这仅影响显示,你发送的消息文本不会被改动。
158
+
159
+ 思考内容使用三层披露方式。流式阶段若存在开头的 `**粗体标题**`,miro 会提取它并维持稳定的活动状态行;这一行还会带上计时,提供方上报过用量之后再加上 token 数,例如 `Thinking… (12s · ↑5 ↓2.9k)`:↑/↓ 是提供方最近一次读数里的输入与输出(miro 是每次 LLM 调用,ACP 是回合结束时 `PromptResponse` 的用量),不上报用量的提供方不会显示这一段。定稿后按持久化的 `thinkingDisplay` 设置呈现:`compact` 只保留标题与耗时摘要,`full` 额外打印 Markdown 正文,`hidden` 不进入可见 transcript。`/thinking` 打开选择器,`/thinking compact|full|hidden` 可直接切换。Ctrl+O 打开整屏的 Review 窗口,浏览实时思考、实时 shell 输出以及 transcript 里保留的思考与工具详情:列表里用 ↑/↓ 选中、Enter 进入详情,详情里用左右键切换到该列表的上一条 / 下一条。
160
+
161
+ 可见思考块只保存元数据;miro 的模型上下文检查点同样不保存原始 reasoning 与 thinking 块。原始 ACP 流量日志现在默认也会省略 `agent_thought_chunk`;只有确实需要这些敏感调试信息时,才应在 `~/.miro/settings.json` 中显式设置 `"recordRawThinking": true`。
162
+
163
+ ## ACP 提供方
164
+
165
+ Miro 默认使用自带 agent。要进入 ACP,显式使用 `miro --acp <id>`;对应二进制必须在 `PATH` 上。也可以在 `~/.miro/settings.json` 的 `providers.<id>` = `{ command | bin, args, name }` 新增或覆盖 ACP 定义。Miro 会把 ACP 提供方上次 `/model` 与 `/effort` 的选择记在同一条目的 `model` / `effort` 里。
166
+
167
+ | Id | 名称 | 二进制 |
168
+ |----|------|--------|
169
+ | `pi` | Pi | `pi-acp` |
170
+ | `cursor` | Cursor | `cursor-agent` |
171
+ | `claude` | Claude | `claude-agent-acp` |
172
+ | `codex` | Codex | `codex-acp` |
173
+
174
+ ### 内置 agent
175
+
176
+ Miro 自带的 agent 不启动子进程、不走 ACP 协议,而是直接调用 LLM API,自己跑工具循环(`read_file`、`write_file`、`edit_file`、`terminal`、`grep`、`glob`、`spawn_agent`、`update_tasks`),并对外发出与 ACP client 相同的事件。它同时支持 OpenAI Chat Completions(默认)、OpenAI Responses 与 Anthropic Messages,无需安装任何二进制。长对话会自动压缩,压缩时 transcript 与模型都会看到一条 `Context compacted` 提示。
177
+
178
+ 以「产出报告」为目的的命令——`/review`、`/simplify`、`/commit`、`/commit-push-pr`、`/init`——跑在**独立上下文**里:命令的提示词(rubric、预读的 git 上下文、你的指令)以及模型为此读过的每个文件,都留在这次运行专用的历史里,只有一行命令记录(随回合开始即入会话)与最终结论并入会话。于是一次读了五十个文件的审查不再挤占对话上下文,而结论照样落在 transcript 上——之后说「把第 2 条修掉」仍有据可依。按 `Esc` 取消时,命令记录与已经流出的内容仍留在会话里,与 transcript 所见一致,恢复会话后看到的历史也相同。这条只在 miro 下成立:ACP 提供方的对话历史在它自己的进程里,miro 既无法隔离也无法修剪,那里这些命令照旧作为普通回合执行、留在对话中。
179
+
180
+ 空闲时使用 `/compact`,或用 `/compact 保留数据库迁移相关决策` 指定摘要侧重点。它使用当前模型,不清除可见聊天记录,并保存压缩后的模型上下文供恢复会话使用;关闭自动压缩也不影响手动命令。按 `Esc` 可取消而不替换历史,历史不足时只提示、不发摘要请求。有正在执行的 goal 时需先暂停。Print 模式也支持 `miro -c <session-id> -p "/compact"`,进度写入 stderr。ACP 下仅当提供方声明支持时才转发该命令。
181
+
182
+ miro 用到的上游写在 `~/.miro/models.json`。打开 `/model` 会重新读取该文件,改完不必重启:
183
+
184
+ ```json
185
+ {
186
+ "providers": {
187
+ "ollama": {
188
+ "baseUrl": "http://localhost:11434/v1",
189
+ "api": "openai-completions",
190
+ "apiKey": "ollama",
191
+ "models": [
192
+ { "id": "llama3.1:8b" },
193
+ { "id": "qwen2.5-coder:7b" }
194
+ ]
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
200
+ `api` 可以是 `openai-completions`、`openai-responses` 或 `anthropic-messages`(提供方或模型级)。`apiKey` 可以是字面量、`$ENV_VAR` / `${ENV_VAR}`,或发请求时执行的 `!command`。选中某个模型会同时带上该提供方的 `baseUrl` / `api` / `apiKey`。选择器的值与顶层记下的 `model` 偏好始终是 `provider/id`(例如 `ollama/llama3.1:8b`)。`/model llama3.1:8b` 与 `--model llama3.1:8b` 在该 id 唯一时仍可匹配。
201
+
202
+ 推理模型需设置 `"reasoning": true`。`thinkingLevelMap` 把 miro 的标准 effort 档位映射成上游值:字符串给出上游值,`null` 隐藏不支持的档位;缺省的 `minimal` 至 `high` 使用同名映射,缺省的 `xhigh` / `max` 视为不支持。`/effort` 只展示当前模型支持的档位。
203
+
204
+ `models.json` 缺失或没有可用条目时,回退到 `~/.miro/settings.json` 里的 `miro` 对象:
205
+
206
+ ```json
207
+ {
208
+ "miro": {
209
+ "baseUrl": "https://api.openai.com/v1",
210
+ "models": [
211
+ { "id": "gpt-4o-mini", "name": "GPT-4o mini", "contextWindow": 128000 }
212
+ ],
213
+ "model": "gpt-4o-mini",
214
+ "protocol": "chat-completions",
215
+ "effort": "medium",
216
+ "thinking": true,
217
+ "sandbox": { "enabled": false },
218
+ "codemode": { "enabled": false }
219
+ }
220
+ }
221
+ ```
222
+
223
+ | 字段 | 默认值 | 说明 |
224
+ |------|--------|------|
225
+ | `protocol` | `chat-completions` | 仅在未使用 `models.json` 时生效:`chat-completions`、`openai-responses` 或 `anthropic-messages`;也可用 `$MIRO_PROTOCOL`。目录里的模型自带 `api`。 |
226
+ | `baseUrl` | 按协议决定 | Chat Completions / Responses 默认 `https://api.openai.com/v1`;Anthropic Messages 默认 `https://api.anthropic.com`。`$MIRO_BASE_URL` 优先。`models.json` 里的 `baseUrl` 对目录模型优先。 |
227
+ | `apiKey` | `$MIRO_API_KEY`,再按协议回退 | Anthropic Messages 使用 `$ANTHROPIC_API_KEY`,两个 OpenAI 协议使用 `$OPENAI_API_KEY`。在 `models.json` 里还可以写 `$ENV` 或 `!command`。 |
228
+ | `models` | `gpt-4o-mini`、`gpt-4o`、`deepseek-chat` | 仅当 `~/.miro/models.json` 没有可用条目时使用。字符串,或 `{ id, name, contextWindow }` 形式。 |
229
+ | `model` / `effort` / `thinking` | 首个模型 / `medium` / `true` | 回退默认值;顶层 `model` / `effort` 偏好匹配到可用选项时优先。与 ACP 提供方共用 `/model`、`/effort`、`/config` 流程。 |
230
+ | `maxToolRounds` | 不限 | 每个回合工具循环的最大轮数。默认不设上限,因为上下文已由自动压缩兜底;写入数字可为失控的回合兜底。 |
231
+ | `temperature` | 不设置 | 传给 API 的采样温度。 |
232
+ | `permissionMode` | `auto` | `auto` 全程不询问用户;仅 `risk_level: high` 或 `sandbox: false` 的 Terminal 调用由隔离模型自动审查,其余工具直接执行。`manual` 对写入和命令请求确认。未知值及旧 `ask`、`plan`、`yolo` 配置回退为 `auto`。 |
233
+ | `sandbox.enabled` | `false` | 为 `true` 时 `terminal` 工具在 `@anthropic-ai/sandbox-runtime` 的网络沙箱里执行命令:默认断网,只有 `allowedDomains` 能为单次调用放行网络。两种模式下工具同名,沙箱模式只是多出沙箱专属参数。文件系统仍使用宿主权限。需要满足 `@anthropic-ai/sandbox-runtime` 的平台前置条件,失败不会回退为未受限 shell。 |
234
+
235
+ 可用 `/config sandbox on` 或 `/config sandbox off` 持久化修改这个开关,并立即切换当前会话命令工具的沙箱状态。
236
+
237
+ `/model` 与 `/effort` 的选择按提供方分别记忆。`miro` 使用 `settings.json` 顶层的 `model` / `effort`,其中 `model` 记为 `provider/id`;ACP 提供方则存在自己的 `providers.<id>` 条目里。`miro` 对象里的 `model` / `effort` 只在顶层偏好缺省或匹配不到时作为回退默认值。miro 的 `Default` / `Plan` 交互模式与 `Auto` / `Manual` 权限模式相互独立;`Shift+Tab` 循环交互模式。
238
+
239
+ ### Codemode(实验性)
240
+
241
+ Codemode 默认关闭,仅适用于内置 Miro agent。用 `/config codemode on` 开启、`/config codemode off` 关闭,两者都会修改 `settings.json` 的 `miro.codemode.enabled`。Print 模式需在启动前将它设为 `true`。普通工具仍然保留。
242
+
243
+ 模型可在独立 QuickJS Worker 内用一段 JavaScript 组合读取、搜索、分页和聚合,只把选定输出交回上下文。脚本能调用 `read_file`、`grep`、`glob` 和已配置的 MCP 桥接;没有宿主 `process`、`fetch`、写文件、Terminal 或 subagent 能力。每次实际 MCP 调用仍遵循普通权限策略,非交互 Manual 会拒绝调用,内部调用保留在 transcript 中。
244
+
245
+ 每段脚本的 VM 时限为 60 秒、QuickJS 堆为 64 MiB,最多调用 64 次工具、并发读取 8 条,另有工具数据和输出预算。脚本必须 await 工具调用。取消与超时会等待宿主收尾,但不能撤销远端副作用;失败脚本不会自动重放。精确 API 和限制见[工具参考](./docs/tools/codemode.md)。它与 Terminal 沙箱相互独立,不改变 ACP 提供方行为。
246
+
247
+ ### MCP
248
+
249
+ 将可信服务写入 `~/.miro/settings.json` 顶层的 `mcpServers`:
250
+
251
+ ```json
252
+ {
253
+ "mcpServers": {
254
+ "local-tools": {
255
+ "command": "node",
256
+ "args": ["/absolute/path/server.js"],
257
+ "env": { "SERVICE_TOKEN": "your-token" }
258
+ },
259
+ "remote-tools": {
260
+ "type": "http",
261
+ "url": "https://example.com/mcp",
262
+ "headers": { "Authorization": "Bearer your-token" },
263
+ "connectTimeoutMs": 10000,
264
+ "timeoutMs": 60000
265
+ }
266
+ }
267
+ }
268
+ ```
269
+
270
+ 请将示例路径、URL 和凭据替换为真实服务的值。Stdio 直接启动 `command`,不经过 shell;HTTP 使用 Streamable HTTP,不支持旧 SSE。command、args、env、URL 和 headers 中的 `${NAME}` 从环境变量读取。设置 `"enabled": false` 可停用服务。超时使用正整数毫秒,默认连接 10 秒、请求 60 秒;只适用于内置 agent。
271
+
272
+ 项目服务写在 `<cwd>/.miro/mcp.json` 的同名 `mcpServers` 字段中,同名时覆盖全局服务。审阅文件后通过终端的 `miro mcp trust` 或 TUI 的 `/mcp trust` 授权;文件变化会撤销信任。`miro mcp add <名称> -- <命令> [参数...]`、`miro mcp add <名称> --url <URL>`、`miro mcp remove <名称>` 和 `miro mcp list` 管理服务;`--local` 作用于项目文件。修改后重启或通过 `/mcp` 重新加载。`/mcp` 还可查看连接状态、工具列表与登录操作。
273
+
274
+ 内置 agent 只提供两个 MCP 工具:`mcp_list_tools` 发现工具及参数 schema,`mcp_call` 执行调用。远端工具统一按需发现,不再单独声明为模型工具。连接跨回合复用,会话关闭时清理;工具目录变化通知会刷新缓存。工具返回的文本、嵌入文本资源和结构化 JSON 复用工具输出预算;资源链接仅保留元数据,图片、音频及二进制块以说明代替。不支持资源列举、URI 模板、资源读取、Prompts 和任务型执行。
275
+
276
+ 没有 Authorization 请求头的 HTTP 服务可使用 OAuth。运行 `miro mcp login <名称>` 或在 `/mcp` 中选择 Sign in;凭据保存在 `~/.miro/mcp-auth.json`。`miro mcp logout <名称>` 或 TUI 选项可注销。浏览器必须能访问本机回调端口(默认 8765,可用 `oauth.callbackPort` 设置)。在 TUI 登录面板按 Esc 或 Ctrl+C 可取消;关闭会话同样会取消登录并释放回调端口,整个 OAuth 流程超时为三分钟。
277
+
278
+ 登录会采用服务端 `WWW-Authenticate` 指定的资源元数据地址。权限优先取认证挑战或资源元数据(`scopes_supported`,也兼容部分网关的 `resource_scopes`),缺省时回退到已保存客户端的注册权限。需要覆盖登录请求的权限时,在 HTTP 服务条目中设置非空、以空格分隔的字符串,例如 `"oauth": { "scope": "openid profile offline_access" }`;只填写该服务支持的权限。令牌响应中的空字符串或 null 权限视为缺省,缺省时保留请求权限。回调带有 `iss` 或授权服务器声明要求它时,登录会校验授权服务器身份。OAuth 失败会标明阶段和错误码,不打印令牌响应。
279
+
280
+ **只配置可信服务。** 即使在 Manual 模式,发现工具也可能启动本地进程。实际 MCP 调用在 Manual 下需审批,授权绑定服务、工具和完整参数;非交互 Manual 会拒绝实际调用。Auto 不询问,也不对 MCP 执行 Terminal 安全审查。MCP 不受 Terminal 沙箱保护。取消或超时不代表远端副作用已撤销,调用不会自动重放。请妥善保管 `settings.json`;工具参数和结果仍属于会话数据。
281
+
282
+ ACP 会话透传已信任的服务配置,但由外部 agent 管理连接、权限与 OAuth。外部 agent 未声明支持 HTTP 时,会提示并跳过 HTTP 条目。miro 的 ACP 流量日志会隐去 MCP 连接配置,但外部 agent 仍会收到真实凭据,并可能有自己的日志。
283
+
284
+ ### Skill
285
+
286
+ Miro 支持 `SKILL.md` 约定(Agent Skills)。启动时从 `<cwd>/.miro/skills`、`<cwd>/.agents/skills`、`~/.miro/skills`、`~/.agents/skills` 扫描,优先级依次递减;额外目录写进 `~/.miro/settings.json` 顶层的 `skills` 数组,`"skills": false` 则整体关闭。含 `SKILL.md` 的目录就是一个 skill,不再向下扫描;裸 `*.md` 文件只有在 frontmatter 里带 `description` 时才算。同名时优先级更高的根目录胜出(显式路径高于默认目录),被遮住的文件会记在 client 的诊断里。
287
+
288
+ Frontmatter 使用 YAML core 语法,顶层必须是映射,且 `description` 必须为非空字符串。看起来像数字或布尔值的文本请加引号。支持 Unicode 转义、块标量和有限的别名引用,不支持自定义标签或合并键展开。YAML 语法错误、重复键、过量别名展开或超过 64 KiB 的 frontmatter 都会使该 skill 被跳过并留下诊断。
289
+
290
+ 只有每个 skill 的 name / description / 文件路径会写进系统提示的 `<available_skills>`,正文由模型按需用 `read_file` 读取。`/skill:<name> [args]` 则把该 skill 的正文直接注入本轮消息,`-p` 运行同样可用:
291
+
292
+ ```bash
293
+ /skill:pdf 提取 invoice.pdf 里的表格
294
+ miro -p "/skill:pdf 提取 invoice.pdf 里的表格"
295
+ ```
296
+
297
+ `disable-model-invocation: true` 只让 skill 不进模型可见的目录,手动 `/skill:` 仍可用。skill 只增加指令、**不增加能力**:Manual 的审批策略与 Auto 的 Terminal 自动审查策略都不会因 skill 改变。
298
+
299
+ 这只对 miro 生效。ACP 提供方自己管 skill,它广播出来的任何命令(例如 `skill:<name>`)都以普通提供方命令的形式进入 miro。
300
+
301
+ ## 会话与上下文
302
+
303
+ miro 会在可见聊天记录之外保存模型上下文检查点,包含压缩摘要及完整配对的工具调用与结果。恢复时优先使用最新合法检查点,不会重新回灌压缩前的可见记录;没有检查点的会话仍回退到可见消息。检查点包含对话和工具数据,请妥善保管会话文件。
304
+
305
+ 可见对话记录保存在 `~/.miro/sessions/<拍平后的 cwd>/<acp|miro>/<sessionId>.jsonl`,可通过 `/resume`、`--continue` 或 `--resume` 恢复。ACP 原始流量隔离在 `<拍平后的 cwd>/acp/raw/`,不会再与相同 session ID 的可恢复 transcript 冲突。项目目录名是把 cwd 里所有非字母数字字符折成 `-`(不掺哈希,保持可读)。除非显式开启 `recordRawThinking`,否则会省略原始思考 chunk。持久化失败不会导致程序退出;旧版 transcript 布局不再读取。可见会话的身份是运行方式 + session ID。`/resume`、`/sessions` 与 `--continue` 只显示当前启动模式的会话;要恢复 ACP transcript,须以该 transcript 的 `--acp <id>` 重启。空对话不留下任何东西:transcript 文件(连同它的运行方式目录)只在录到第一条 user/assistant 消息时才创建,零消息的 transcript 也不会被 `/resume`、`/sessions` 或 `--continue` 列出(ACP 原始流量日志不在此列,它仍在会话建立时开写)。
306
+
307
+ 启动时会加载 `~/.miro/AGENTS.md` 与 `./AGENTS.md`(跳过空白或不可读文件,相同文本去重),并在**第一次普通提示**时注入。恢复的会话跳过 AGENTS.md 的重复注入。若第一次请求失败,会恢复注入状态以便重试。
308
+
309
+ 输入框历史独立于对话记录,保存在 `~/.miro/history.jsonl`。
310
+
311
+ ## 配置
312
+
313
+ 模型、努力程度、提示词语言、状态栏和自定义 ACP 提供方偏好保存在 `~/.miro/settings.json`;其中遗留的顶层 `provider` 会被忽略。miro 的上游与模型列表只从 `~/.miro/models.json` 导入。`/config` 既可修改 ACP 以 `configOptions` 声明的实时选项,也可修改 miro 自己的 `language` 选项。
314
+
315
+ ### 权限模式
316
+
317
+ miro 提供 `Auto` 与 `Manual` 两档,默认 `Auto`。`/permissions` 可直接指定或打开选择器;它与 Plan 模式相互独立。
318
+
319
+ | 模式 | 行为 |
320
+ |------|------|
321
+ | `auto` | 默认。全程不弹人工审批;非 Terminal 工具直接执行,Terminal 仅在 `risk_level: high` 或 `sandbox: false` 时由隔离模型自动审查 |
322
+ | `manual` | 写入、编辑、删除、移动与命令需确认;读取、搜索和任务更新直接执行 |
323
+
324
+ `Auto` 不解析 Terminal 命令文本,因此 `rm`、`curl`、重定向、解释器与 heredoc 都没有特殊规则;`low` 与 `medium` 直接执行。只有 `high` 或 `sandbox: false` 会把用户意图、此前工具调用与本次动作(含模型可选填写、按不可信自述对待的 `risk_reason`)投影给隔离、无工具的分类器,绝不传入工具结果。分类器明确批准才执行;阻断、异常或不确定都直接拒绝并把理由交给下一轮模型,不会回退询问用户。工具行下会写明审查结论,被拦下时直接给出理由。
325
+
326
+ ```bash
327
+ miro --permission-mode auto
328
+ miro --permission-mode manual
329
+ /permissions manual
330
+ ```
331
+
332
+ `/permissions` 和启动参数只影响当前运行,不写入配置;持久化默认值可配置 `miro.permissionMode`。旧配置 `ask`、`plan`、`yolo` 和未知值回退到 `auto`,但显式的非法 `--permission-mode` 值会报错。
333
+
334
+ 配置 `permission-mode` 状态栏项后,分别显示 `AUTO`、`MANUAL`。非交互 miro 运行会按实际档位向 stderr 打印说明,stdout 保持纯结果。
335
+
336
+ ### Plan 模式
337
+
338
+ Plan 模式把调查与设计同实现分开。可通过 `/plan`、`/plan on` 或 Shift+Tab 进入;模型也能请求进入,但必须由用户确认。该模式保留普通的 Terminal、文件写入、子智能体及本地命令能力;专注规划是行为指令,而不是运行时只读限制。规范计划文件保存在 `~/.miro/sessions/<project>/miro/plans/<session>/<plan-id>.md`。
339
+
340
+ 在任一交互模式中,agent 最多可提出四个结构化问题,支持单选、多选、Markdown 选项预览、自定义文本和备注;在 Plan 模式中随后会提交规范计划文件供审阅。批准会冻结当时的精确文本、返回 Default 模式,并从该冻结快照开启一个全新的实现回合;要求修改会留在 Plan 模式;拒绝则退出且不实现。Plan 状态随会话持久化。目标正在运行时不能进入 Plan 模式。非交互运行与子智能体不会暴露提问界面。
341
+
342
+ `miro -p --mode plan "设计这项改动"` 刻意采用非交互语义:打印计划后退出,不提问、不打开审批界面、也不实现。ACP 提供方继续使用自己的模式行为。
343
+
344
+ ### 等待动词
345
+
346
+ 状态栏上的等待动词动画可通过 `~/.miro/settings.json` 的 `spinnerVerbs` 自定义:
347
+
348
+ ```json
349
+ {
350
+ "spinnerVerbs": { "mode": "append", "verbs": ["thinking", "planning", "searching"] }
351
+ }
352
+ ```
353
+
354
+ `mode` 为 `append`(追加到内置动词表)或 `replace`(只使用你的列表)。`verbs` 为空或非法时回落为默认值。
355
+
356
+ ### 提示词语言
357
+
358
+ `/config language English`(或 `en`、`en-us`)、`/config language Chinese`(或 `zh`、`zh-cn`、`中文`)或 `/config language Cantonese`(或 `yue`、`zh-hk`、`zh-yue`、`粤语`、`粵語`)用于设置 miro 内置工作流提示词(`/init`、`/review`、`/simplify`、`/commit` 与 `/commit-push-pr`)的语言,结果写入 `~/.miro/settings.json` 的 `language` 字段。默认英文,未知取值回落为英文。该设置不影响 ACP 会话配置与你自己发送的消息;提示词文本本身放在 `src/commands/prompts/<language>/`,新增一门语言即新增一个目录。
359
+
360
+ ### 状态栏
361
+
362
+ `/statusline` 可交互选择项目、顺序与颜色。`/statusline reset` 恢复默认。确认时会一并写入 `statusLine` 与 `statusLineUseColors`。
363
+
364
+ 默认项目:`["model-with-reasoning", "current-dir"]`。空数组隐藏状态栏。未知 id 会被忽略(一次性警告);没有数据的项目会被跳过。
365
+
366
+ 存在目标时,同一行的右侧会常驻 `◎ /goal active (4s)`:目标状态加上它**实际推进**了多久(暂停期间与结束之后都不计入,与预算同一口径)。它不是可配置项,随目标出现与消失;ACP 提供方没有目标机制,那里永不出现。整条状态栏被配置成空数组时,它与状态栏一起隐藏。
367
+
368
+ 可用 id 包括 `model`、`model-with-reasoning`、`reasoning`、`mode`、`permission-mode`、`current-dir`、`project-name`、`hostname`、`git-branch`、`run-state`、`provider`、`session-id`、`session-title`、`miro-version`、`context-used`、`context-remaining`、`context-window-size`、`task-progress`、`goal`、`used-tokens`、`input-tokens`、`output-tokens`、`thought-tokens`、`session-cost`。上下文、token、费用与会话标题类项目需要提供方上报,否则省略。`used-tokens`、`input-tokens`、`output-tokens`、`thought-tokens`、`session-cost` 都是会话累计值:miro 累加主循环的每一次 LLM 请求与压缩摘要请求(子智能体不计入),ACP 直接采用 agent 上报的会话累计快照(成本则用 `usage_update` 的累计值);因此它们可能大于活动槽思考行里的「最近一次读数」。`permission-mode` 在 miro 下显示 `AUTO` 或 `MANUAL`;无 miro 权限模式时隐藏。`goal` 显示当前目标的状态与进度,没有目标时隐藏——ACP 提供方没有目标机制,那里恒为隐藏。这些 id 也接受简写别名:`model-name`(`model`)、`permissions`(`permission-mode`)、`project` / `project-root`(`project-name`)、`status`(`run-state`)、`thread-id` / `thread-title`(`session-id`)、`version`(`miro-version`)、`context-usage`(`context-used`)、`goal-status`(`goal`)。
369
+
370
+ ## 许可证
371
+
372
+ ISC