From 8c2aeb12aafcd8650ff529ed33b41113df2c27d7 Mon Sep 17 00:00:00 2001 From: Shmueli Englard Date: Tue, 25 Aug 2026 10:15:59 -0700 Subject: [PATCH 1/2] Start-Copilot: map more Copilot CLI launch flags Add first-class parameters for Copilot CLI flags that previously had no mapping (reachable only via -RemainingArgs): - -AssistedApproval -> --assisted-approval (assisted-approval safety judge) - -AllowAllTools -> --allow-all-tools (auto-approve tools while keeping path/URL verification; implies not passing --allow-all) - -UsageOutputFile -> --usage-output-file (write usage JSON) Also extend -EnableMcpServer to pass the CLI's native --enable-mcp-server, so a server disabled in the Copilot settings is enabled for the run, in addition to the existing path-based autoConnect override. Parameters are added to Get-CopilotLaunchPlan (the shared core) and surfaced on Start-Copilot, which auto-forwards them. Tests, README, and CHANGELOG updated. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b98f01a0-a039-492f-8576-b1917e54742d --- modules/Shmuelie.Copilot/CHANGELOG.md | 8 +++ .../Public/Get-CopilotLaunchPlan.ps1 | 39 ++++++++++++-- .../Shmuelie.Copilot/Public/Start-Copilot.ps1 | 27 +++++++++- modules/Shmuelie.Copilot/README.md | 4 +- tests/Shmuelie.Copilot.Tests.ps1 | 53 +++++++++++++++++++ 5 files changed, 125 insertions(+), 6 deletions(-) diff --git a/modules/Shmuelie.Copilot/CHANGELOG.md b/modules/Shmuelie.Copilot/CHANGELOG.md index 46f8fc3..77da524 100644 --- a/modules/Shmuelie.Copilot/CHANGELOG.md +++ b/modules/Shmuelie.Copilot/CHANGELOG.md @@ -6,6 +6,14 @@ Versions change only when a release is cut; unreleased work stays under ## [Unreleased] +### Added +- `Start-Copilot` / `Get-CopilotLaunchPlan` gained `-AssistedApproval` + (`--assisted-approval`), `-AllowAllTools` (`--allow-all-tools`, which implies + not passing `--allow-all`), and `-UsageOutputFile` (`--usage-output-file`). +- `-EnableMcpServer` now also passes the CLI's native `--enable-mcp-server`, so a + server disabled in the Copilot settings is enabled for the run — in addition + to overriding the path-based `autoConnect` policy. + ## [0.2.0] - 2026-08-21 ### Added diff --git a/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 b/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 index 25e4c7a..e4908e9 100644 --- a/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 +++ b/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 @@ -150,13 +150,30 @@ function Get-CopilotLaunchPlan { .PARAMETER ScreenReader Enable screen reader accessibility optimizations. + .PARAMETER AssistedApproval + Review tool-permission requests with the assisted-approval safety judge + instead of approving them outright. Takes precedence over allowing all + tools when the judge engages; requires experimental mode (on by default + unless -NoExperimental is set). + + .PARAMETER AllowAllTools + Allow all tools to run automatically without confirmation while keeping + file-path and URL verification (unlike --allow-all, which also disables + path/URL checks). Implies not passing --allow-all. + + .PARAMETER UsageOutputFile + Write final usage statistics as JSON to the specified file. Most useful + with -Prompt (non-interactive mode). + .PARAMETER DisableMcpServer One or more MCP server names to disable at startup, in addition to any servers disabled by path-based autoConnect policy in the config. .PARAMETER EnableMcpServer - One or more MCP server names to force-enable at startup, overriding - path-based autoConnect policy in the config. + One or more MCP server names to enable at startup. Overrides the + path-based autoConnect policy in the config and also passes the CLI's + native --enable-mcp-server so a server disabled in the Copilot settings + is enabled for this run only (nothing is persisted). .PARAMETER Name Set a name for the new session. Cannot be combined with session resume. @@ -414,6 +431,12 @@ function Get-CopilotLaunchPlan { [switch]$ScreenReader, + [switch]$AssistedApproval, + + [switch]$AllowAllTools, + + [string]$UsageOutputFile, + [string[]]$DisableMcpServer, [string[]]$EnableMcpServer, @@ -508,7 +531,8 @@ function Get-CopilotLaunchPlan { $copilotArgs = @() if (-not $NoExperimental) { $copilotArgs += '--experimental' } - if (-not $NoAllowAll) { $copilotArgs += '--allow-all' } + if (-not $NoAllowAll -and -not $AllowAllTools) { $copilotArgs += '--allow-all' } + if ($AllowAllTools) { $copilotArgs += '--allow-all-tools' } # Block destructive git force operations (--deny-tool takes precedence over --allow-all) if (-not $NoDefaultDenyTools) { @@ -561,6 +585,13 @@ function Get-CopilotLaunchPlan { } } + # Re-enable servers disabled in the CLI's own settings for this run only. + if ($EnableMcpServer) { + foreach ($s in $EnableMcpServer) { + $copilotArgs += '--enable-mcp-server', $s + } + } + # Named parameters mapped to CLI flags if ($Model) { $copilotArgs += '--model', $Model } if ($Version) { $copilotArgs += '--prefer-version', $Version; if ($copilotArgs -notcontains '--no-auto-update') { $copilotArgs += '--no-auto-update' } } @@ -585,6 +616,8 @@ function Get-CopilotLaunchPlan { if ($PluginDir) { foreach ($p in $PluginDir) { $copilotArgs += '--plugin-dir', $p } } if ($SecretEnvVars) { $copilotArgs += '--secret-env-vars', ($SecretEnvVars -join ',') } if ($ScreenReader) { $copilotArgs += '--screen-reader' } + if ($AssistedApproval) { $copilotArgs += '--assisted-approval' } + if ($UsageOutputFile) { $copilotArgs += '--usage-output-file', $UsageOutputFile } if ($PlainDiff) { $copilotArgs += '--plain-diff' } if ($Stream) { $copilotArgs += '--stream', $Stream } if ($AvailableTool) { foreach ($t in $AvailableTool) { $copilotArgs += '--available-tools', $t } } diff --git a/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 b/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 index 28cb964..f190b96 100644 --- a/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 +++ b/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 @@ -141,13 +141,30 @@ function Start-Copilot { .PARAMETER ScreenReader Enable screen reader accessibility optimizations. + .PARAMETER AssistedApproval + Review tool-permission requests with the assisted-approval safety judge + instead of approving them outright. Takes precedence over allowing all + tools when the judge engages; requires experimental mode (on by default + unless -NoExperimental is set). + + .PARAMETER AllowAllTools + Allow all tools to run automatically without confirmation while keeping + file-path and URL verification (unlike the default --allow-all, which + also disables path/URL checks). Implies not passing --allow-all. + + .PARAMETER UsageOutputFile + Write final usage statistics as JSON to the specified file. Most useful + with -Prompt (non-interactive mode). + .PARAMETER DisableMcpServer One or more MCP server names to disable at startup, in addition to any servers disabled by path-based autoConnect policy in the config. .PARAMETER EnableMcpServer - One or more MCP server names to force-enable at startup, overriding - path-based autoConnect policy in the config. + One or more MCP server names to enable at startup. Overrides the + path-based autoConnect policy in the config and also passes the CLI's + native --enable-mcp-server so a server disabled in the Copilot settings + is enabled for this run only (nothing is persisted). .PARAMETER Name Set a name for the new session. Cannot be combined with session resume. @@ -430,6 +447,12 @@ function Start-Copilot { [switch]$ScreenReader, + [switch]$AssistedApproval, + + [switch]$AllowAllTools, + + [string]$UsageOutputFile, + [string[]]$DisableMcpServer, [string[]]$EnableMcpServer, diff --git a/modules/Shmuelie.Copilot/README.md b/modules/Shmuelie.Copilot/README.md index ae3818a..80b85d7 100644 --- a/modules/Shmuelie.Copilot/README.md +++ b/modules/Shmuelie.Copilot/README.md @@ -76,7 +76,9 @@ The path-glob form is useful for MCP servers that are only relevant in certain repositories. For example, a server configured with `"autoConnect": ["D:\\work\\*"]` connects only when you launch from under `D:\work`. Use `-EnableMcpServer ` to force a server on regardless of its -`autoConnect` policy, or `-DisableMcpServer ` to force one off. +`autoConnect` policy — this also passes the CLI's native `--enable-mcp-server`, +so a server disabled in your Copilot settings is enabled for the run — or +`-DisableMcpServer ` to force one off. ## Requirements diff --git a/tests/Shmuelie.Copilot.Tests.ps1 b/tests/Shmuelie.Copilot.Tests.ps1 index 59c5925..105a44e 100644 --- a/tests/Shmuelie.Copilot.Tests.ps1 +++ b/tests/Shmuelie.Copilot.Tests.ps1 @@ -1212,3 +1212,56 @@ Describe 'Get-CopilotMcpServer' { @(Get-Content $script:CopilotTestLog | Where-Object { $_ -eq 'mcp list --json' }) | Should -HaveCount 2 } } + +Describe 'Get-CopilotLaunchPlan additional flag mappings' { + BeforeEach { + $testHome = Join-Path $TestDrive 'home' + $env:USERPROFILE = Join-Path $TestDrive 'legacy-userprofile' + New-Item -ItemType Directory -Path $testHome -Force | Out-Null + Mock -ModuleName Shmuelie.Copilot -CommandName Get-CopilotHome -MockWith { $testHome } + Add-FakeCopilot -Path (Join-Path $TestDrive 'bin') + } + + It 'emits --assisted-approval when -AssistedApproval is set' { + $plan = Get-CopilotLaunchPlan -DeferResume -AssistedApproval + $plan.Args | Should -Contain '--assisted-approval' + } + + It 'emits --usage-output-file with its value' { + $target = Join-Path $TestDrive 'usage.json' + $plan = Get-CopilotLaunchPlan -DeferResume -UsageOutputFile $target + $i = [array]::IndexOf($plan.Args, '--usage-output-file') + $i | Should -BeGreaterOrEqual 0 + $plan.Args[$i + 1] | Should -Be $target + } + + It 'emits --allow-all-tools and suppresses --allow-all' { + $plan = Get-CopilotLaunchPlan -DeferResume -AllowAllTools + $plan.Args | Should -Contain '--allow-all-tools' + $plan.Args | Should -Not -Contain '--allow-all' + } + + It 'emits --allow-all by default and not --allow-all-tools' { + $plan = Get-CopilotLaunchPlan -DeferResume + $plan.Args | Should -Contain '--allow-all' + $plan.Args | Should -Not -Contain '--allow-all-tools' + } + + It 'emits native --enable-mcp-server for each -EnableMcpServer name' { + $plan = Get-CopilotLaunchPlan -DeferResume -EnableMcpServer 'server-a', 'server-b' + $values = for ($j = 0; $j -lt $plan.Args.Count - 1; $j++) { + if ($plan.Args[$j] -eq '--enable-mcp-server') { $plan.Args[$j + 1] } + } + $values | Should -Contain 'server-a' + $values | Should -Contain 'server-b' + } + + It 'forwards the new flags from Start-Copilot -PassThru' { + $target = Join-Path $TestDrive 'usage2.json' + $plan = Start-Copilot -PassThru -DeferResume -AssistedApproval -AllowAllTools -UsageOutputFile $target + $plan.Args | Should -Contain '--assisted-approval' + $plan.Args | Should -Contain '--allow-all-tools' + $plan.Args | Should -Not -Contain '--allow-all' + $plan.Args | Should -Contain '--usage-output-file' + } +} From 1ebe17566a5bb425832b3cd6ef290c5affc08d95 Mon Sep 17 00:00:00 2001 From: Shmueli Englard Date: Tue, 25 Aug 2026 11:38:47 -0700 Subject: [PATCH 2/2] Address peer-review findings on the new Copilot flags - Warn when -AssistedApproval is combined with -NoExperimental (the CLI needs experimental mode for the assisted-approval judge to engage). - Document that -AllowAllTools keeps file-path/URL verification, so fully non-interactive (-Prompt) use may also need -AllowAllPaths / -AllowAllUrls. - Document that -EnableMcpServer's native --enable-mcp-server is a no-op for an already-enabled server; refresh the README feature list. - Add interaction tests: NoExperimental+AssistedApproval warning, NoAllowAll+AllowAllTools suppression, native enable with an mcp-config present (server enabled, not disabled), usage-output-file value adjacency, and -EnableMcpServer passthrough via Start-Copilot -PassThru. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: b98f01a0-a039-492f-8576-b1917e54742d --- .../Public/Get-CopilotLaunchPlan.ps1 | 15 +++++-- .../Shmuelie.Copilot/Public/Start-Copilot.ps1 | 8 +++- modules/Shmuelie.Copilot/README.md | 7 +++- tests/Shmuelie.Copilot.Tests.ps1 | 40 ++++++++++++++++++- 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 b/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 index e4908e9..87393c7 100644 --- a/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 +++ b/modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1 @@ -159,7 +159,10 @@ function Get-CopilotLaunchPlan { .PARAMETER AllowAllTools Allow all tools to run automatically without confirmation while keeping file-path and URL verification (unlike --allow-all, which also disables - path/URL checks). Implies not passing --allow-all. + path/URL checks). Implies not passing --allow-all. For fully + non-interactive use (-Prompt) where the agent may access paths outside + the working directory or external URLs, also pass -AllowAllPaths / + -AllowAllUrls so it does not stall on permission prompts. .PARAMETER UsageOutputFile Write final usage statistics as JSON to the specified file. Most useful @@ -173,7 +176,8 @@ function Get-CopilotLaunchPlan { One or more MCP server names to enable at startup. Overrides the path-based autoConnect policy in the config and also passes the CLI's native --enable-mcp-server so a server disabled in the Copilot settings - is enabled for this run only (nothing is persisted). + is enabled for this run only (nothing is persisted). Passing a name whose + server is already enabled is a no-op. .PARAMETER Name Set a name for the new session. Cannot be combined with session resume. @@ -616,7 +620,12 @@ function Get-CopilotLaunchPlan { if ($PluginDir) { foreach ($p in $PluginDir) { $copilotArgs += '--plugin-dir', $p } } if ($SecretEnvVars) { $copilotArgs += '--secret-env-vars', ($SecretEnvVars -join ',') } if ($ScreenReader) { $copilotArgs += '--screen-reader' } - if ($AssistedApproval) { $copilotArgs += '--assisted-approval' } + if ($AssistedApproval) { + if ($NoExperimental) { + Write-Warning '-AssistedApproval requires experimental mode; -NoExperimental will likely prevent the assisted-approval judge from engaging.' + } + $copilotArgs += '--assisted-approval' + } if ($UsageOutputFile) { $copilotArgs += '--usage-output-file', $UsageOutputFile } if ($PlainDiff) { $copilotArgs += '--plain-diff' } if ($Stream) { $copilotArgs += '--stream', $Stream } diff --git a/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 b/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 index f190b96..3e45b64 100644 --- a/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 +++ b/modules/Shmuelie.Copilot/Public/Start-Copilot.ps1 @@ -150,7 +150,10 @@ function Start-Copilot { .PARAMETER AllowAllTools Allow all tools to run automatically without confirmation while keeping file-path and URL verification (unlike the default --allow-all, which - also disables path/URL checks). Implies not passing --allow-all. + also disables path/URL checks). Implies not passing --allow-all. For + fully non-interactive use (-Prompt) where the agent may access paths + outside the working directory or external URLs, also pass -AllowAllPaths + / -AllowAllUrls so it does not stall on permission prompts. .PARAMETER UsageOutputFile Write final usage statistics as JSON to the specified file. Most useful @@ -164,7 +167,8 @@ function Start-Copilot { One or more MCP server names to enable at startup. Overrides the path-based autoConnect policy in the config and also passes the CLI's native --enable-mcp-server so a server disabled in the Copilot settings - is enabled for this run only (nothing is persisted). + is enabled for this run only (nothing is persisted). Passing a name whose + server is already enabled is a no-op. .PARAMETER Name Set a name for the new session. Cannot be combined with session resume. diff --git a/modules/Shmuelie.Copilot/README.md b/modules/Shmuelie.Copilot/README.md index 80b85d7..3229b3a 100644 --- a/modules/Shmuelie.Copilot/README.md +++ b/modules/Shmuelie.Copilot/README.md @@ -33,7 +33,12 @@ Start-Copilot auto-resumes. Control it with `-NoResume`, `-ResumeLatest`, `-ResumeSession`, `-NoAutoResume`, and `-IncludeUnnamed`. - **Sensible defaults** (`--allow-all --experimental`), each disablable with - `-NoAllowAll` / `-NoExperimental`. + `-NoAllowAll` / `-NoExperimental`. Use `-AllowAllTools` for a middle ground + that auto-approves tools while keeping file-path and URL verification. +- **More permission & scripting flags** — `-AssistedApproval` + (`--assisted-approval` safety judge), `-UsageOutputFile` (write usage JSON to + a file), and `-EnableMcpServer` (also re-enables a settings-disabled MCP + server for the run). - **Default deny rules** for destructive git operations (force push, hard reset, rebase, amend, `git pull`, and similar). - **Full flag mapping** — model, reasoning effort, MCP enable/disable, plan mode, diff --git a/tests/Shmuelie.Copilot.Tests.ps1 b/tests/Shmuelie.Copilot.Tests.ps1 index 105a44e..f3dda71 100644 --- a/tests/Shmuelie.Copilot.Tests.ps1 +++ b/tests/Shmuelie.Copilot.Tests.ps1 @@ -1262,6 +1262,44 @@ Describe 'Get-CopilotLaunchPlan additional flag mappings' { $plan.Args | Should -Contain '--assisted-approval' $plan.Args | Should -Contain '--allow-all-tools' $plan.Args | Should -Not -Contain '--allow-all' - $plan.Args | Should -Contain '--usage-output-file' + $usageIdx = [array]::IndexOf($plan.Args, '--usage-output-file') + $usageIdx | Should -BeGreaterOrEqual 0 + $plan.Args[$usageIdx + 1] | Should -Be $target + } + + It 'warns when -AssistedApproval is combined with -NoExperimental' { + Get-CopilotLaunchPlan -DeferResume -AssistedApproval -NoExperimental -WarningVariable warnings -WarningAction SilentlyContinue | Out-Null + ($warnings -join ' ') | Should -Match 'experimental' + } + + It 'suppresses --allow-all when both -NoAllowAll and -AllowAllTools are set' { + $plan = Get-CopilotLaunchPlan -DeferResume -NoAllowAll -AllowAllTools + $plan.Args | Should -Contain '--allow-all-tools' + $plan.Args | Should -Not -Contain '--allow-all' + } + + It 'enables a configured server via the native flag instead of disabling it' { + $mcpHome = Join-Path $TestDrive ([guid]::NewGuid()) + $cfgDir = Join-Path $mcpHome '.copilot' + New-Item -ItemType Directory -Path $cfgDir -Force | Out-Null + $config = @{ mcpServers = @{ srv = @{ command = 'x'; autoConnect = @('Z:\no-such-path\*') } } } | ConvertTo-Json -Depth 6 + Set-Content -Path (Join-Path $cfgDir 'mcp-config.json') -Value $config + Mock -ModuleName Shmuelie.Copilot -CommandName Get-CopilotHome -MockWith { $mcpHome } + + $plan = Get-CopilotLaunchPlan -DeferResume -EnableMcpServer 'srv' + + $plan.Args | Should -Contain '--enable-mcp-server' + $disabled = for ($j = 0; $j -lt $plan.Args.Count - 1; $j++) { + if ($plan.Args[$j] -eq '--disable-mcp-server') { $plan.Args[$j + 1] } + } + $disabled | Should -Not -Contain 'srv' + } + + It 'forwards -EnableMcpServer through Start-Copilot -PassThru' { + $plan = Start-Copilot -PassThru -DeferResume -EnableMcpServer 'server-a' + $values = for ($j = 0; $j -lt $plan.Args.Count - 1; $j++) { + if ($plan.Args[$j] -eq '--enable-mcp-server') { $plan.Args[$j + 1] } + } + $values | Should -Contain 'server-a' } }