fix: unify YOLO and Auto permission mode descriptions across surfaces (#1867)
Some checks are pending
CI / test-windows (push) Waiting to run
CI / lint (push) Waiting to run
CI / test (1) (push) Waiting to run
CI / test (2) (push) Waiting to run
CI / test (3) (push) Waiting to run
CI / test (4) (push) Waiting to run
CI / test (5) (push) Waiting to run
CI / test-pi-tui (push) Waiting to run
CI / build (push) Waiting to run
CI / typecheck (push) Waiting to run
Nix Build / Check flake.nix workspace sync (push) Waiting to run
Nix Build / nix build .#kimi-code (push) Blocked by required conditions
Release / Release (push) Waiting to run
Release / Deploy docs (push) Blocked by required conditions
Release / Native release artifact (push) Blocked by required conditions
Release / Publish native release assets (push) Blocked by required conditions

* fix(tui): correct YOLO and Auto permission mode descriptions

* fix: unify YOLO and Auto permission mode descriptions across CLI, ACP, web, and docs

* docs: correct YOLO and Auto mode descriptions in the interaction guide

* fix: correct YOLO mode notices in session replay and vscode extension

* feat(vscode): rename /afk command to /auto, keeping afk as hidden alias

Also correct the stale 'afk' mode reference in the built-in MCP config
skill guidance of both agent engines.

* fix(vscode): forward engine approval requests instead of blanket-approving them

The extension-level approval handler auto-approved every request when
legacy yolo/afk was on, silently swallowing the sensitive-file,
plan-review, and ask-rule prompts the engine yolo mode still sends.
Forward every request to the user and let the engine permission mode do
the auto-approving, matching TUI and web behavior.
This commit is contained in:
Kai 2026-07-18 02:09:31 +08:00 committed by GitHub
parent 7d393b56fb
commit 3086e47039
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 97 additions and 62 deletions

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
Rename the stale "afk" reference to "auto" in the built-in MCP config skill guidance.

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
Correct the YOLO and Auto permission mode descriptions in CLI --help output and in the ACP session mode selector shown by IDE clients.

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
web: Correct the YOLO and Auto permission mode descriptions in the slash command list and the mobile permission sheet.

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
Fix the YOLO and Auto permission mode descriptions to match their actual behavior: YOLO auto-approves tool actions but the agent may still ask questions, while Auto is fully autonomous and never asks.

View file

@ -0,0 +1,5 @@
---
"@moonshot-ai/kimi-code": patch
---
Correct the YOLO mode notice shown when replaying a session: tool actions are auto-approved, but the agent may still ask questions.

View file

@ -46,8 +46,8 @@ export function createProgram(
)
.option('-c, --continue', 'Continue the previous session for the working directory.', false)
.addOption(new Option('-C').hideHelp().default(false))
.option('-y, --yolo', 'Automatically approve all actions.', false)
.option('--auto', 'Start in auto permission mode.', false)
.option('-y, --yolo', 'Auto-approve regular tool calls; the agent may still ask questions.', false)
.option('--auto', 'Start in auto permission mode: fully autonomous, the agent will not ask questions.', false)
.addOption(
new Option(
'-m, --model <model>',

View file

@ -130,7 +130,7 @@ export async function handleYoloCommand(host: SlashCommandHost, args: string): P
}
await session.setPermission('yolo');
host.setAppState({ permissionMode: 'yolo' });
host.showNotice('YOLO mode: ON', 'AI auto-approves safe actions, asks for approval on risky ones.');
host.showNotice('YOLO mode: ON', 'Tool actions auto-approved; the agent may still ask you questions.');
return;
}
@ -153,7 +153,7 @@ export async function handleYoloCommand(host: SlashCommandHost, args: string): P
} else {
await session.setPermission('yolo');
host.setAppState({ permissionMode: 'yolo' });
host.showNotice('YOLO mode: ON', 'AI auto-approves safe actions, asks for approval on risky ones.');
host.showNotice('YOLO mode: ON', 'Tool actions auto-approved; the agent may still ask you questions.');
}
}
@ -174,7 +174,7 @@ export async function handleAutoCommand(host: SlashCommandHost, args: string): P
}
await session.setPermission('auto');
host.setAppState({ permissionMode: 'auto' });
host.showNotice('Auto mode: ON', 'Run all actions automatically, including risky ones.');
host.showNotice('Auto mode: ON', 'All actions auto-approved; the agent will not ask you questions.');
return;
}
@ -197,7 +197,7 @@ export async function handleAutoCommand(host: SlashCommandHost, args: string): P
} else {
await session.setPermission('auto');
host.setAppState({ permissionMode: 'auto' });
host.showNotice('Auto mode: ON', 'Run all actions automatically, including risky ones.');
host.showNotice('Auto mode: ON', 'All actions auto-approved; the agent will not ask you questions.');
}
}

View file

@ -136,14 +136,14 @@ export const BUILTIN_SLASH_COMMANDS = [
{
name: 'yolo',
aliases: ['yes'],
description: 'Toggle YOLO mode: AI auto-approves safe actions, asks for approval on risky ones.',
description: 'Toggle YOLO mode: auto-approve tool actions, but the agent may still ask questions.',
priority: 101,
availability: 'always',
},
{
name: 'auto',
aliases: [],
description: 'Toggle Auto mode: run all actions automatically, including risky ones.',
description: 'Toggle Auto mode: fully autonomous, agent decides everything without asking.',
priority: 99,
availability: 'always',
},

View file

@ -8,15 +8,15 @@ const PERMISSION_OPTIONS: readonly ChoiceOption[] = [
label: 'Manual',
description: 'Approve every action yourself.',
},
{
value: 'auto',
label: 'Auto',
description: 'Run all actions automatically, including risky ones.',
},
{
value: 'yolo',
label: 'YOLO',
description: 'AI decides which actions need your approval.',
description: 'Auto-approve tool actions, but the agent may still ask questions.',
},
{
value: 'auto',
label: 'Auto',
description: 'Fully autonomous — agent decides everything without asking.',
},
];

View file

@ -569,7 +569,7 @@ export class SessionReplayRenderer {
if (mode === 'yolo') {
this.host.appendTranscriptEntry(
replayEntry(context, 'status', 'YOLO mode: ON', 'notice', {
detail: 'All actions will be approved automatically. Use with caution.',
detail: 'Tool actions auto-approved; the agent may still ask you questions.',
}),
);
return;

View file

@ -6,8 +6,8 @@ export default {
swarm: { desc: 'Toggle swarm mode; /swarm <task> runs a task in swarm' },
goal: { desc: 'Create/control a goal: /goal <objective>, /goal pause|resume|cancel' },
btw: { desc: 'Side chat: /btw <question> asks a forked side session' },
yolo: { desc: 'Auto-approve everything (yolo mode)' },
auto: { desc: 'Auto-approve safe edits/reads' },
yolo: { desc: 'Auto-approve tool actions; the agent may still ask questions' },
auto: { desc: 'Fully autonomous — the agent never asks questions' },
thinking: { desc: 'Set the thinking level' },
compact: { desc: 'Compact the conversation history' },
fork: { desc: 'Fork this session into a new one' },

View file

@ -12,8 +12,8 @@ export default {
sessionCount: '{n} sessions',
newSession: 'New session',
permManualSub: 'confirm every tool',
permAutoSub: 'auto-approve edits',
permYoloSub: 'auto-approve all',
permAutoSub: 'fully autonomous, never asks',
permYoloSub: 'auto-approve tools, may still ask',
planModeSub: 'Plan mode',
swarmModeSub: 'Swarm mode',
archivedSessions: 'Archived sessions',

View file

@ -6,8 +6,8 @@ export default {
swarm: { desc: '切换 swarm 模式;/swarm <任务> 直接在 swarm 下执行' },
goal: { desc: '创建/控制目标:/goal <目标>、/goal pause|resume|cancel' },
btw: { desc: '侧边聊天:/btw <问题> 向 fork 的侧边会话提问' },
yolo: { desc: '自动批准一切 (yolo 模式)' },
auto: { desc: '自动批准安全的读写' },
yolo: { desc: '自动批准工具操作Agent 仍可能提问' },
auto: { desc: '完全自主Agent 不再提问' },
thinking: { desc: '设置思考强度' },
compact: { desc: '压缩会话历史' },
fork: { desc: '把当前会话 fork 出一个新会话' },

View file

@ -12,8 +12,8 @@ export default {
sessionCount: '{n} 个会话',
newSession: '新建会话',
permManualSub: '每个工具都确认',
permAutoSub: '自动批准编辑',
permYoloSub: '全部自动批准',
permAutoSub: '完全自主,不再提问',
permYoloSub: '自动批准工具,仍可能提问',
planModeSub: '计划模式',
swarmModeSub: 'Swarm 模式',
archivedSessions: '已归档会话',

View file

@ -54,7 +54,7 @@
"kimi.yoloMode": {
"type": "boolean",
"default": false,
"description": "Auto-approve all tool calls"
"description": "Auto-approve regular tool calls; the agent may still ask questions"
},
"kimi.autosave": {
"type": "boolean",

View file

@ -20,11 +20,11 @@ const SLASH_COMMANDS: SlashCommandInfo[] = [
{ name: "init", aliases: [], description: "Analyze the codebase and generate AGENTS.md" },
{ name: "compact", aliases: [], description: "Compact the conversation context" },
{ name: "clear", aliases: ["reset"], description: "Clear the context" },
{ name: "yolo", aliases: [], description: "Toggle YOLO mode (auto-approve all actions)" },
{ name: "yolo", aliases: [], description: "Toggle YOLO mode (auto-approve tool actions; may still ask questions)" },
{
name: "afk",
aliases: [],
description: "Toggle afk mode (auto-dismiss questions and auto-approve tool calls)",
name: "auto",
aliases: ["afk"],
description: "Toggle Auto mode (fully autonomous; the agent will not ask questions)",
},
{ name: "plan", aliases: [], description: "Toggle plan mode. Usage: /plan [on|off|view|clear]" },
{

View file

@ -19,6 +19,7 @@ const HOST_COMMANDS = new Set([
"clear",
"reset",
"yolo",
"auto",
"afk",
"plan",
"add-dir",
@ -84,6 +85,7 @@ export async function runHostSlashCommand(
case "yolo":
await toggleLegacyPermission(runtime, "yolo", emit);
break;
case "auto":
case "afk":
await toggleLegacyPermission(runtime, "afk", emit);
break;
@ -120,17 +122,17 @@ async function toggleLegacyPermission(
if (kind === "yolo") {
emit(flags.yolo
? "You only live once! All actions will be auto-approved."
? "You only live once! Tool actions will be auto-approved; the agent may still ask questions."
: flags.afk
? "Yolo disabled, but afk is still on — tool calls remain auto-approved."
? "Yolo disabled, but Auto is still on — tool calls remain auto-approved."
: "You only die once! Actions will require approval.");
return;
}
emit(flags.afk
? "afk mode enabled. Questions will be auto-dismissed and tool calls auto-approved."
? "Auto mode enabled. Questions will be auto-dismissed and tool calls auto-approved."
: flags.yolo
? "afk mode disabled. You are back at the keyboard. Yolo is still on."
: "afk mode disabled. You are back at the keyboard.");
? "Auto mode disabled. You are back at the keyboard. Yolo is still on."
: "Auto mode disabled. You are back at the keyboard.");
}
async function runPlanCommand(

View file

@ -98,11 +98,11 @@ export class SessionRuntime {
this.legacyApproval = options.legacyApproval;
this.reverseRpc = new ReverseRpcController((event) => this.emitStreamEvent(event));
this.session.setApprovalHandler((request) =>
this.legacyApproval.yolo || this.legacyApproval.afk
? Promise.resolve({ decision: "approved" })
: this.reverseRpc.requestApproval(request),
);
// Forward every approval request to the user. The engine permission mode
// (mapped from the legacy flags) already auto-approves what yolo/auto
// allow internally; anything that reaches this handler is an exception
// (sensitive file, plan review, ask rule) the user must decide on.
this.session.setApprovalHandler((request) => this.reverseRpc.requestApproval(request));
this.session.setQuestionHandler((request) => this.reverseRpc.requestQuestion(request));
this.unsubscribe = this.session.onEvent((event) => this.onSdkEvent(event));
}

View file

@ -369,7 +369,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", ()
"compact",
"clear",
"yolo",
"afk",
"auto",
"plan",
"add-dir",
"export",

View file

@ -570,18 +570,24 @@ describe("session runtime (adapts one SDK session for subscribed Webviews)", ()
await expect(pending).resolves.toEqual(expected);
});
it("auto-approves SDK approval requests in legacy yolo mode", async () => {
const { sdk, broadcasts } = createRuntime({ yolo: true, afk: false });
await expect(sdk.requestApproval({
it("forwards SDK approval requests to the Webview in legacy yolo mode", async () => {
const { runtime, sdk, broadcasts } = createRuntime({ yolo: true, afk: false });
const pending = sdk.requestApproval({
toolCallId: "tool-yolo",
toolName: "Bash",
action: "Run command",
display: { kind: "command", command: "pnpm test" },
})).resolves.toEqual({ decision: "approved" });
expect(streamData(broadcasts)).not.toContainEqual(
expect.objectContaining({ type: "ApprovalRequest" }),
);
});
const request = streamData(broadcasts).find(
(event) =>
typeof event === "object" &&
event !== null &&
"type" in event &&
event.type === "ApprovalRequest",
) as { payload: { id: string } };
expect(runtime.respondApproval(request.payload.id, "approve")).toBe(true);
await expect(pending).resolves.toEqual({ decision: "approved" });
});
it("restores core permission when a legacy flag cannot be persisted", async () => {

View file

@ -98,7 +98,7 @@ Fields in the config file fall into two categories: **top-level scalars** that d
| Field | Type | Default | Description |
| --- | --- | --- | --- |
| `default_model` | `string` | — | Default model alias; must be defined in `models` |
| `default_permission_mode` | `string` | `manual` | Default permission mode for new sessions; one of `manual` (prompt each time), `auto` (auto-approve read operations), or `yolo` (auto-approve everything) |
| `default_permission_mode` | `string` | `manual` | Default permission mode for new sessions; one of `manual` (prompt each time), `yolo` (auto-approve tool actions, but the agent may still ask questions), or `auto` (fully autonomous — the agent decides everything without asking) |
| `default_plan_mode` | `boolean` | `false` | Whether new sessions start in Plan mode (produce a plan before executing) by default |
| `merge_all_available_skills` | `boolean` | `true` | Whether to merge Agent Skills from all available directories |
| `extra_skill_dirs` | `array<string>` | — | Extra skill search directories, layered on top of the default directories |

View file

@ -55,7 +55,8 @@ Options passed at startup have the highest priority and apply only to the curren
| --- | --- |
| `-S, --session [id]` | Resume a specific session; enters interactive selection when no id is given |
| `-c, --continue` | Resume the last session for the current working directory |
| `-y, --yolo` | Auto-approve all tool calls |
| `-y, --yolo` | Auto-approve regular tool calls; the agent may still ask questions |
| `--auto` | Start in auto permission mode: fully autonomous, the agent will not ask questions |
| `--plan` | Start in Plan mode |
| `-m, --model <model>` | Use a specific model alias for this session |
| `-p, --prompt <prompt>` | Run in non-interactive mode: execute a single prompt and exit |

View file

@ -37,7 +37,7 @@ Type `@` to trigger file-path completion. Selecting a path inserts its relative
## Approval flow
When the agent calls a tool that has side effects — modifying files, running commands — the TUI displays an approval panel for your confirmation. Approvals are not triggered in YOLO mode, nor for writes to plan files in Plan mode.
When the agent calls a tool that has side effects — modifying files, running commands — the TUI displays an approval panel for your confirmation. Approvals are not triggered for regular tool calls in YOLO mode, nor for writes to plan files in Plan mode.
Use the arrow keys to select an option and press `Enter` to confirm, or press `1` / `2` / `3` to select by number directly. `Esc`, `Ctrl-C`, and `Ctrl-D` are all equivalent to rejecting.
@ -56,9 +56,9 @@ After producing a plan the agent pauses for your review — you can approve it,
### YOLO / Auto mode
**YOLO mode** (`/yolo`) skips the approval confirmation for almost all tool calls, making it suitable for batch tasks you know are safe. The one exception is the exit-confirmation for Plan mode.
**YOLO mode** (`/yolo`) auto-approves regular tool calls, making it suitable for batch tasks you know are safe. It still asks before sensitive actions — accessing sensitive files such as `.env` or SSH keys, or exiting Plan mode — and the agent can still ask you questions.
**Auto mode** (`/auto`) is more restrained: tool approvals are handled automatically, but the agent does not ask the user clarifying questions — useful when you want unattended operation without fully disabling approvals.
**Auto mode** (`/auto`) is the fully unattended mode: every tool approval is handled automatically, including sensitive files and plan exits, and the agent never asks you questions — it decides everything on its own.
::: warning
YOLO mode skips confirmation for file writes and command execution. Only use it in working directories you trust.

View file

@ -98,7 +98,7 @@ timeout = 5
| 字段 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `default_model` | `string` | — | 默认模型别名,必须在 `models` 中定义 |
| `default_permission_mode` | `string` | `manual` | 新会话的默认权限模式,可选 `manual`(逐次询问)、`auto`(自动批准读操作)、`yolo`(全部自动批准 |
| `default_permission_mode` | `string` | `manual` | 新会话的默认权限模式,可选 `manual`(逐次询问)、`yolo`自动批准工具操作Agent 仍可能提问)、`auto`完全自主Agent 自己做决定,不再提问 |
| `default_plan_mode` | `boolean` | `false` | 新会话是否默认以 Plan 模式(先出计划再执行)启动 |
| `merge_all_available_skills` | `boolean` | `true` | 是否合并所有目录中的 Agent Skills |
| `extra_skill_dirs` | `array<string>` | — | 额外 Skill 搜索目录,叠加到默认目录之上 |

View file

@ -55,7 +55,8 @@ Kimi Code CLI 有三个地方可以影响运行参数:配置文件、命令行
| --- | --- |
| `-S, --session [id]` | 恢复指定会话;不带 id 时进入交互式选择 |
| `-c, --continue` | 续上当前目录的上一次会话 |
| `-y, --yolo` | 自动批准所有工具调用 |
| `-y, --yolo` | 自动批准普通工具调用Agent 仍可能提问 |
| `--auto` | 以 auto 权限模式启动完全自主Agent 不会向用户提问 |
| `--plan` | 以 Plan 模式启动 |
| `-m, --model <model>` | 指定本次使用的模型别名 |
| `-p, --prompt <prompt>` | 非交互模式:执行单条提示词后退出 |

View file

@ -37,7 +37,7 @@ Kimi Code CLI 支持在输入框中直接粘贴图片和视频,让 AI 结合
## 审批流程
Agent 调用会产生副作用的工具修改文件、执行命令等TUI 会弹出审批面板让你确认。YOLO 模式以及 Plan 模式下对计划文件的写入不触发审批。
Agent 调用会产生副作用的工具修改文件、执行命令等TUI 会弹出审批面板让你确认。YOLO 模式下的普通工具调用,以及 Plan 模式下对计划文件的写入不触发审批。
用方向键选择选项,`Enter` 确认;也可以按 `1`/`2`/`3` 数字键直接选择。`Esc``Ctrl-C``Ctrl-D` 等同于拒绝。
@ -56,9 +56,9 @@ Agent 输出方案后会等待你审批——可批准执行、拒绝、或要
### YOLO / Auto 模式
**YOLO 模式**`/yolo`跳过几乎所有工具调用的审批确认适合已知安全的批处理任务Plan 模式的退出审批除外
**YOLO 模式**`/yolo`自动批准普通工具调用,适合已知安全的批处理任务。敏感操作仍会询问——例如访问 `.env`、SSH 私钥等敏感文件,或退出 Plan 模式——Agent 也仍可能向你提问
**Auto 模式**`/auto`则更克制:工具审批自动处理,但 Agent 不会向用户提问,适合需要无人值守但又不想完全关闭审批的场景
**Auto 模式**`/auto`是完全无人值守模式:所有工具审批自动处理,包括敏感文件和计划退出,且 Agent 不会向你提问,完全由它自己做决定
::: warning 注意
YOLO 模式会跳过文件写入和命令执行的确认,请只在受信任的工作目录下使用。

View file

@ -39,12 +39,12 @@ export const ACP_MODES = [
{
id: 'auto',
name: 'Auto',
description: 'Auto-approve safe operations.',
description: 'Fully autonomous — agent decides everything without asking.',
},
{
id: 'yolo',
name: 'YOLO',
description: 'Auto-approve everything.',
description: 'Auto-approve tool actions, but the agent may still ask questions.',
},
] as const satisfies readonly SessionMode[];

View file

@ -1,7 +1,7 @@
/**
* `permissionMode` domain (L3) `IAgentPermissionModeService` implementation.
*
* Holds the agent's permission mode (`manual` / `auto`) in the `wire`
* Holds the agent's permission mode (`manual` / `yolo` / `auto`) in the `wire`
* `PermissionModeModel`, mutating it only through the `permission.set_mode` Op
* (`wire.dispatch(setMode({ mode }))`) and reading it through `wire.getModel`.
* `setMode` emits `onDidChangeMode` after an actual change, and mode-aware

View file

@ -108,7 +108,7 @@ For changes, the flow is:
currently in it, and the entry you're about to write or delete. This
is for transparency, not a confirmation gate — the Edit/Write
permission prompt is the real gate, and your message is what gives
the user context when that prompt appears. In yolo / afk modes there
the user context when that prompt appears. In yolo / auto modes there
is no prompt, which is those modes' explicit contract.
3. **Write and tell them how to reload MCP servers.** Preserve unrelated
entries and the `mcpServers` wrapper. MCP servers load at session

View file

@ -108,7 +108,7 @@ For changes, the flow is:
currently in it, and the entry you're about to write or delete. This
is for transparency, not a confirmation gate — the Edit/Write
permission prompt is the real gate, and your message is what gives
the user context when that prompt appears. In yolo / afk modes there
the user context when that prompt appears. In yolo / auto modes there
is no prompt, which is those modes' explicit contract.
3. **Write and tell them how to reload MCP servers.** Preserve unrelated
entries and the `mcpServers` wrapper. MCP servers load at session