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
3 changes: 3 additions & 0 deletions internal/infrastructure/agents/copilot_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,9 @@ func appendCopilotOptions(args []string, options map[string]any) []string {
}
if allow, ok := getBoolOption(options, "allow_all"); ok && allow {
args = append(args, "--allow-all")
} else if skip, ok := getBoolOption(options, "dangerously_skip_permissions"); ok && skip {
// Alias for cross-provider compatibility: dangerously_skip_permissions maps to --allow-all
args = append(args, "--allow-all")
}
return args
}
Expand Down
43 changes: 43 additions & 0 deletions internal/infrastructure/agents/copilot_provider_unit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ func TestCopilotProvider_Execute_WithOptions(t *testing.T) {
mockStdout: `{"type":"assistant.message","data":{"content":"code","messageId":"m1"}}` + "\n" + `{"type":"result","sessionId":"s1","exitCode":0}`,
wantCLIArgs: []string{"-p", "test", "--output-format=json", "--silent", "--allow-all"},
},
{
name: "dangerously_skip_permissions alias",
prompt: "test",
options: map[string]any{"dangerously_skip_permissions": true},
mockStdout: `{"type":"assistant.message","data":{"content":"code","messageId":"m1"}}` + "\n" + `{"type":"result","sessionId":"s1","exitCode":0}`,
wantCLIArgs: []string{"-p", "test", "--output-format=json", "--silent", "--allow-all"},
},
{
name: "unknown options silently ignored",
prompt: "test",
Expand Down Expand Up @@ -477,6 +484,42 @@ func TestCopilotProvider_DeniedToolsMultiple(t *testing.T) {
assert.Contains(t, args, "--deny-tool=python")
}

func TestCopilotProvider_DangerouslySkipPermissions_AllowAllTakesPrecedence(t *testing.T) {
mockExec := mocks.NewMockCLIExecutor()
mockExec.SetOutput([]byte("{\"type\":\"assistant.message\",\"data\":{\"content\":\"code\",\"messageId\":\"m1\"}}\n{\"type\":\"result\",\"sessionId\":\"s1\",\"exitCode\":0}"), nil)
provider := NewCopilotProviderWithOptions(WithCopilotExecutor(mockExec))

options := map[string]any{"allow_all": true, "dangerously_skip_permissions": true}
_, err := provider.Execute(context.Background(), "test", options, nil, nil)

require.NoError(t, err)
calls := mockExec.GetCalls()
require.Len(t, calls, 1)
args := calls[0].Args
// allow_all takes precedence; --allow-all should appear exactly once
count := 0
for _, a := range args {
if a == "--allow-all" {
count++
}
}
assert.Equal(t, 1, count, "--allow-all should appear exactly once when both options are set")
}

func TestCopilotProvider_DangerouslySkipPermissions_FalseOmitsFlag(t *testing.T) {
mockExec := mocks.NewMockCLIExecutor()
mockExec.SetOutput([]byte("{\"type\":\"assistant.message\",\"data\":{\"content\":\"code\",\"messageId\":\"m1\"}}\n{\"type\":\"result\",\"sessionId\":\"s1\",\"exitCode\":0}"), nil)
provider := NewCopilotProviderWithOptions(WithCopilotExecutor(mockExec))

options := map[string]any{"dangerously_skip_permissions": false}
_, err := provider.Execute(context.Background(), "test", options, nil, nil)

require.NoError(t, err)
calls := mockExec.GetCalls()
require.Len(t, calls, 1)
assert.NotContains(t, calls[0].Args, "--allow-all")
}

func TestCopilotProvider_AllowAllFalseOmitsFlag(t *testing.T) {
mockExec := mocks.NewMockCLIExecutor()
mockExec.SetOutput([]byte("{\"type\":\"assistant.message\",\"data\":{\"content\":\"code\",\"messageId\":\"m1\"}}\n{\"type\":\"result\",\"sessionId\":\"s1\",\"exitCode\":0}"), nil)
Expand Down
Loading