-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Description
Describe the feature or problem you'd like to solve
Copilot CLI repeatedly prompts for one-off approval to run common multi-statement PowerShell commands even within a trusted workspace, with no option to remember or persist that permission.
Proposed solution
Describe the feature or problem you'd like to solve
Copilot CLI frequently proposes PowerShell “scriptlets” (multi-statement commands containing variables, loops, conditionals, scriptblocks, and pipelines). Even when all referenced files are inside a trusted workspace, the approval prompt appears as a one-off:
Do you want to run this command?- Yes
- No, and tell Copilot what to do differently
There is no option to remember / allow for session / allow within this workspace, so routine analysis and small refactors become very prompt-heavy.
I’m not proposing a specific fix/implementation here—just reporting the behavior and the expectation that there should be some way to avoid repeatedly granting permission for these “same shape” commands within a trusted workspace.
What I expected
When commands only operate on files inside a trusted workspace, I expected Copilot CLI to provide some mechanism to reduce repeated prompts for common/repeated operations (e.g., remember for session/workspace, or another workflow that avoids repeated one-off approvals).
What happened instead
For PowerShell multi-statement “scriptlets”, Copilot CLI repeatedly shows a one-time approval prompt with only Yes/No choices and no apparent way to persist the approval, despite the paths being in a trusted workspace.
Environment
- GitHub Copilot CLI version: 0.0.406
- OS: Windows (PowerShell)
- All paths below refer to files within a trusted workspace
Example prompts or workflows
Examples that trigger one-off approval prompts (paths + values anonymized)
Example 1: Search for terms in a trace file (variable + loop)
# Search reasoning for "1234" or "1,234" or "SomeDomainTerm"
$trace = Get-Content "C:\Users\me\source\experiments\project-alpha\tests\traces\latest_run.json" -Raw
foreach ($term in @("1234", "1,234", "SomeDomainTerm")) {
$count = ([regex]::Matches($trace, $term)).Count
Write-Output "$term : $count occurrences"
}Example 2: Read JSON and print a summary (pipeline + scriptblock)
$trace = Get-Content "C:\Users\me\source\experiments\project-alpha\tests\traces\latest_run.json" |
ConvertFrom-Json;
$trace.result.issues |
ForEach-Object { "$($_.severity): $($_.description)" }Example 3: Update a fixture JSON in place (read + replace + write + verify)
# Update the fixture JSON directly - rename the fields
$fixture = Get-Content "C:\Users\me\source\experiments\project-alpha\tests\e2e\fixtures-json\2023-sample.fixture.json" -Raw
$fixture = $fixture -replace '"OriginalSomeField"', '"SomeField_Original"' -replace '"CorrectSomeField"', '"SomeField_Correct"'
Set-Content "C:\Users\me\source\experiments\project-alpha\tests\e2e\fixtures-json\2023-sample.fixture.json" $fixture
# Verify
Get-Content "C:\Users\me\source\experiments\project-alpha\tests\e2e\fixtures-json\2023-sample.fixture.json"Example 4: Update two fixtures (variables + pipeline + write + verify)
# Update both fixtures: Correct -> Corrected
$f1 = "C:\Users\me\source\experiments\project-alpha\tests\e2e\fixtures-json\2023-sample-a.fixture.json"
$f2 = "C:\Users\me\source\experiments\project-alpha\tests\e2e\fixtures-json\2023-sample-b.fixture.json"
(Get-Content $f1 -Raw) -replace '"SomeField_Correct"', '"SomeField_Corrected"' | Set-Content $f1
(Get-Content $f2 -Raw) -replace '"SomeField_Correct"', '"SomeField_Corrected"' | Set-Content $f2
# Verify
Select-String -Path $f1,$f2 -Pattern "SomeField" | Select-Object Filename, LineExample 5: Read-only analysis of trace JSON (nested loops + conditionals)
$trace = Get-Content "C:\Users\me\source\experiments\project-alpha\tests\traces\latest_run.json" -Raw | ConvertFrom-Json
# Check tool calls - what items were retrieved
$trace.turns | ForEach-Object {
if ($_.tool_calls) {
$_.tool_calls | ForEach-Object {
if ($_.function.name -eq "get_item") {
$args = $_.function.arguments | ConvertFrom-Json
"Retrieved: $($args.item_name)"
}
}
}
}
Write-Host "`nTotal turns: $($trace.turns.Count)"
Write-Host "Reasoning length: $($trace.reasoning.Length)"Example 6: Read Copilot tool output from temp file (temp path + string checks)
# The issues text is lowercased in the assertion. Check if "4567" or "1234" (without commas) appears
$output = Get-Content "C:\Users\me\AppData\Local\Temp\copilot-tool-output-1234567890000-abcdef.txt" -Raw
# The model outputs "1,234" and "4,567" with commas
# The test checks for "4567", "1234", "999" without commas
# That's why it fails - comma formatting
Write-Host "Contains '4,567': $($output.Contains('4,567'))"
Write-Host "Contains '1,234': $($output.Contains('1,234'))"
Write-Host "Contains '4567' (no comma): $($output.Contains('4567'))"
Write-Host "Contains '1234' (no comma): $($output.Contains('1234'))"Additional context
No response