From c7821c649093035ae645e296e80815cc8069c3ab Mon Sep 17 00:00:00 2001 From: "Kai Tao (from Dev Box)" Date: Tue, 28 Jul 2026 09:48:32 +0800 Subject: [PATCH 1/6] Implement yolo mode auto-approve (recovered) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- doc/specs/Multi-window-agent-pane.md | 43 ++++++ src/cascadia/TerminalApp/TerminalPage.cpp | 20 +++ .../TerminalSettingsEditor/AIAgents.xaml | 20 +++ .../AIAgentsViewModel.cpp | 25 ++++ .../AIAgentsViewModel.h | 5 + .../AIAgentsViewModel.idl | 9 ++ .../Resources/en-US/Resources.resw | 10 ++ .../GlobalAppSettings.cpp | 14 ++ .../TerminalSettingsModel/GlobalAppSettings.h | 2 + .../GlobalAppSettings.idl | 3 + .../TerminalSettingsModel/MTSMSettings.h | 1 + .../CustomAgentAndPolicyTests.cpp | 52 +++++++- src/cascadia/inc/AgentPolicy.h | 17 +++ tools/wta/locales/af-ZA.yml | 6 + tools/wta/locales/am-ET.yml | 6 + tools/wta/locales/ar-SA.yml | 6 + tools/wta/locales/as-IN.yml | 6 + tools/wta/locales/az-Latn-AZ.yml | 6 + tools/wta/locales/bg-BG.yml | 6 + tools/wta/locales/bn-IN.yml | 6 + tools/wta/locales/bs-Latn-BA.yml | 6 + tools/wta/locales/ca-ES.yml | 6 + tools/wta/locales/ca-Es-VALENCIA.yml | 6 + tools/wta/locales/cs-CZ.yml | 6 + tools/wta/locales/cy-GB.yml | 6 + tools/wta/locales/da-DK.yml | 6 + tools/wta/locales/de-DE.yml | 6 + tools/wta/locales/el-GR.yml | 6 + tools/wta/locales/en-GB.yml | 6 + tools/wta/locales/en-US.yml | 6 + tools/wta/locales/es-ES.yml | 6 + tools/wta/locales/es-MX.yml | 6 + tools/wta/locales/et-EE.yml | 6 + tools/wta/locales/eu-ES.yml | 6 + tools/wta/locales/fa-IR.yml | 6 + tools/wta/locales/fi-FI.yml | 6 + tools/wta/locales/fil-PH.yml | 6 + tools/wta/locales/fr-CA.yml | 6 + tools/wta/locales/fr-FR.yml | 6 + tools/wta/locales/ga-IE.yml | 6 + tools/wta/locales/gd-gb.yml | 6 + tools/wta/locales/gl-ES.yml | 6 + tools/wta/locales/gu-IN.yml | 6 + tools/wta/locales/he-IL.yml | 6 + tools/wta/locales/hi-IN.yml | 6 + tools/wta/locales/hr-HR.yml | 6 + tools/wta/locales/hu-HU.yml | 6 + tools/wta/locales/hy-AM.yml | 6 + tools/wta/locales/id-ID.yml | 6 + tools/wta/locales/is-IS.yml | 6 + tools/wta/locales/it-IT.yml | 6 + tools/wta/locales/ja-JP.yml | 6 + tools/wta/locales/ka-GE.yml | 6 + tools/wta/locales/kk-KZ.yml | 6 + tools/wta/locales/km-KH.yml | 6 + tools/wta/locales/kn-IN.yml | 6 + tools/wta/locales/ko-KR.yml | 6 + tools/wta/locales/kok-IN.yml | 6 + tools/wta/locales/lb-LU.yml | 6 + tools/wta/locales/lo-LA.yml | 6 + tools/wta/locales/lt-LT.yml | 6 + tools/wta/locales/lv-LV.yml | 6 + tools/wta/locales/mi-NZ.yml | 6 + tools/wta/locales/mk-MK.yml | 6 + tools/wta/locales/ml-IN.yml | 6 + tools/wta/locales/mr-IN.yml | 6 + tools/wta/locales/ms-MY.yml | 6 + tools/wta/locales/mt-MT.yml | 6 + tools/wta/locales/nb-NO.yml | 6 + tools/wta/locales/ne-NP.yml | 6 + tools/wta/locales/nl-NL.yml | 6 + tools/wta/locales/nn-NO.yml | 6 + tools/wta/locales/or-IN.yml | 6 + tools/wta/locales/pa-IN.yml | 6 + tools/wta/locales/pl-PL.yml | 6 + tools/wta/locales/pt-BR.yml | 6 + tools/wta/locales/pt-PT.yml | 6 + tools/wta/locales/qps-ploc.yml | 6 + tools/wta/locales/qps-ploca.yml | 6 + tools/wta/locales/qps-plocm.yml | 6 + tools/wta/locales/quz-PE.yml | 6 + tools/wta/locales/ro-RO.yml | 6 + tools/wta/locales/ru-RU.yml | 6 + tools/wta/locales/sk-SK.yml | 6 + tools/wta/locales/sl-SI.yml | 6 + tools/wta/locales/sq-AL.yml | 6 + tools/wta/locales/sr-Cyrl-BA.yml | 6 + tools/wta/locales/sr-Cyrl-RS.yml | 6 + tools/wta/locales/sr-Latn-RS.yml | 6 + tools/wta/locales/sv-SE.yml | 6 + tools/wta/locales/ta-IN.yml | 6 + tools/wta/locales/te-IN.yml | 6 + tools/wta/locales/th-TH.yml | 6 + tools/wta/locales/tr-TR.yml | 6 + tools/wta/locales/tt-RU.yml | 6 + tools/wta/locales/ug-CN.yml | 6 + tools/wta/locales/uk-UA.yml | 6 + tools/wta/locales/ur-PK.yml | 6 + tools/wta/locales/uz-Latn-UZ.yml | 6 + tools/wta/locales/vi-VN.yml | 6 + tools/wta/locales/zh-CN.yml | 6 + tools/wta/locales/zh-TW.yml | 6 + tools/wta/src/app.rs | 90 ++++++++++++- tools/wta/src/app_events.rs | 5 + tools/wta/src/app_tests.rs | 15 +++ tools/wta/src/commands.rs | 11 ++ tools/wta/src/main.rs | 28 +++- tools/wta/src/protocol/acp/client.rs | 63 ++++++++- .../wta/src/protocol/acp/mock_agent_tests.rs | 122 ++++++++++++++++++ 109 files changed, 1083 insertions(+), 6 deletions(-) diff --git a/doc/specs/Multi-window-agent-pane.md b/doc/specs/Multi-window-agent-pane.md index e1bd6d79d9..2faa4fa29f 100644 --- a/doc/specs/Multi-window-agent-pane.md +++ b/doc/specs/Multi-window-agent-pane.md @@ -905,6 +905,49 @@ work: - **Pre-warming**: not implemented. First user toggle creates the helper on demand. +### Z-R9. Yolo mode (auto-approve tool-call permission requests) + +Implements GitHub issue #326 ("Allow agent pane to run with options such +as `--allow-all`"). Rather than passing agent-CLI-specific flags +(`--allow-all`/`--yolo`, which differ per agent and don't exist for all +of them), auto-approve is implemented once at the ACP client layer +(`WtaClient::request_permission` in `tools/wta/src/protocol/acp/client.rs`), +so it works uniformly across Copilot/Claude/Gemini/Codex/custom agents +without depending on each CLI's own flag surface. + +Two independent, additive enable paths, both gated by the same +`AllowYoloMode` admin policy (`src/cascadia/inc/AgentPolicy.h`): + +1. **Global Settings toggle** — "Auto-approve tool calls" in the Settings + UI (`AIAgents.xaml`, backed by `agentPane.yoloMode` / + `GlobalAppSettings::EffectiveAgentPaneYoloMode()`). When on (and not + policy-blocked), `TerminalPage.cpp` appends `--auto-approve-tools` to + the helper's command line, which every ACP session on every tab of + every window inherits for the lifetime of the setting. +2. **Per-session `/yolo` slash command** — scoped to the *current tab's + current* ACP `session_id` only. Implemented as a shared + `Arc>>` (`App::yolo_sessions`, also held by + `WtaClient`'s `ClientState`): `/yolo` inserts the active session_id; + `request_permission` checks membership. Keying by `session_id` rather + than `tab_id` means the override does **not** persist across `/new` + (a fresh session_id is simply absent from the set) — the user must + run `/yolo` again after starting a new conversation. `/restart` clears + the whole set (every session is being torn down anyway). + +Policy enforcement on the Rust side: since wta has no direct registry +access, `TerminalPage.cpp` also passes `--yolo-command-blocked` whenever +`AllowYoloMode` is `Blocked`, independent of whatever the global toggle +happens to be — this lets `/yolo` itself refuse with a clear +"disabled by your organization's policy" message (`cmd_yolo` in +`tools/wta/src/app.rs`) even when the global setting is off. + +When either path is active for a given request, `request_permission` +skips the blocking `PermissionRequest` UI event entirely, picks the best +"allow" option (`allow_always` preferred over `allow_once` — see +`pick_allow_option`), responds immediately, and posts a passive +`AppEvent::SessionSystemMessage` to that session's tab chat so the user +still sees what was approved. + ## What this does NOT solve (out of scope) - **Cross-process Terminal instances**: if WT is configured for diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 376d088953..69348d738c 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -2172,6 +2172,26 @@ namespace winrt::TerminalApp::implementation { helperCmd.append(L" --no-autofix"); } + // Global "Yolo mode" — auto-approve every ACP permission request on + // this pane without prompting. Policy-gated via + // EffectiveAgentPaneYoloMode() (AgentPolicy::IsYoloModeAllowed()), so + // a GPO-blocked org never spawns a helper with this flag set even if + // the user's settings.json has agentPane.yoloMode: true. This is + // independent from the per-session `/yolo` slash command, which the + // helper enforces itself at runtime against the same policy. + if (globals.EffectiveAgentPaneYoloMode()) + { + helperCmd.append(L" --auto-approve-tools"); + } + // Independent of the global toggle above: tell the helper whether + // org policy blocks yolo mode outright, so its own `/yolo` slash + // command (a per-session override the user can flip at runtime) can + // refuse and explain why, instead of silently enabling unattended + // tool-call approval in a GPO-managed environment. + if (globals.IsYoloModePolicyLocked()) + { + helperCmd.append(L" --yolo-command-blocked"); + } if (const auto lang = _ResolveEffectiveLanguage(globals); !lang.empty()) { appendHelperFlagValue(L"--language", lang); diff --git a/src/cascadia/TerminalSettingsEditor/AIAgents.xaml b/src/cascadia/TerminalSettingsEditor/AIAgents.xaml index 7ef021fb83..777c6e2bdd 100644 --- a/src/cascadia/TerminalSettingsEditor/AIAgents.xaml +++ b/src/cascadia/TerminalSettingsEditor/AIAgents.xaml @@ -9,6 +9,7 @@ xmlns:local="using:Microsoft.Terminal.Settings.Editor" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:muxc="using:Microsoft.UI.Xaml.Controls" + xmlns:mtu="using:Microsoft.Terminal.UI" mc:Ignorable="d"> @@ -178,6 +179,25 @@ Style="{StaticResource ComboBoxSettingStyle}" /> + + + + + + + +