Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions modules/Shmuelie.Copilot/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
48 changes: 45 additions & 3 deletions modules/Shmuelie.Copilot/Public/Get-CopilotLaunchPlan.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -150,13 +150,34 @@ 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. 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
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). 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.
Expand Down Expand Up @@ -414,6 +435,12 @@ function Get-CopilotLaunchPlan {

[switch]$ScreenReader,

[switch]$AssistedApproval,

[switch]$AllowAllTools,

[string]$UsageOutputFile,

[string[]]$DisableMcpServer,

[string[]]$EnableMcpServer,
Expand Down Expand Up @@ -508,7 +535,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) {
Expand Down Expand Up @@ -561,6 +589,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' } }
Expand All @@ -585,6 +620,13 @@ 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) {
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 }
if ($AvailableTool) { foreach ($t in $AvailableTool) { $copilotArgs += '--available-tools', $t } }
Expand Down
31 changes: 29 additions & 2 deletions modules/Shmuelie.Copilot/Public/Start-Copilot.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,34 @@ 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. 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
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). 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.
Expand Down Expand Up @@ -430,6 +451,12 @@ function Start-Copilot {

[switch]$ScreenReader,

[switch]$AssistedApproval,

[switch]$AllowAllTools,

[string]$UsageOutputFile,

[string[]]$DisableMcpServer,

[string[]]$EnableMcpServer,
Expand Down
11 changes: 9 additions & 2 deletions modules/Shmuelie.Copilot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -76,7 +81,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 <name>` to force a server on regardless of its
`autoConnect` policy, or `-DisableMcpServer <name>` 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 <name>` to force one off.

## Requirements

Expand Down
91 changes: 91 additions & 0 deletions tests/Shmuelie.Copilot.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -1212,3 +1212,94 @@ 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'
$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'
}
}