From c4d4bdeaf53cb2f1a7ec650ecdb36f569d607940 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 May 2026 22:16:47 +0000 Subject: [PATCH 1/4] Initial plan From c675bb53c85a61cab9bb1b3193319dbf45c3a046 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 May 2026 22:23:50 +0000 Subject: [PATCH 2/4] Plan serena removal consistency fix Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/smoke-claude.lock.yml | 26 +------------------------ 1 file changed, 1 insertion(+), 25 deletions(-) diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 9016509e6fd..dd8f4c825d9 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -867,31 +867,7 @@ jobs: fetch-depth: 0 - name: Clean git credentials after checkout continue-on-error: true - run: | - if [ -x "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials_checkout.sh" ]; then - bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials_checkout.sh" - else - echo "WARNING: Checkout cleanup helper missing. Running inline fallback." - cleaned_configs=0 - while IFS= read -r git_config; do - git config --file "${git_config}" --remove-section credential 2>/dev/null || true - sed -i '/^\[credential /,/^\[/{ /^\[credential /d; /^\[/!d; }' "${git_config}" 2>/dev/null || true - git config --file "${git_config}" --unset-all http.extraheader 2>/dev/null || true - git config --file "${git_config}" --get-regexp '^http\..*\.extraheader$' 2>/dev/null | while read -r key _; do - git config --file "${git_config}" --unset-all "${key}" || true - done || true - git config --file "${git_config}" --get-regexp '^remote\..*\.url$' 2>/dev/null | while read -r key url; do - clean_url=$(echo "${url}" | sed -E 's|(https?://)([^@]+@)?(.*)|\1\3|') - if [ "${url}" != "${clean_url}" ]; then - git config --file "${git_config}" "${key}" "${clean_url}" - fi - done || true - cleaned_configs=$((cleaned_configs + 1)) - done < <(find "${GITHUB_WORKSPACE}" /tmp -maxdepth 15 -type f -name "config" \( -path "*/.git/config" -o -path "*/.git/modules/*/config" \) 2>/dev/null | sort -u) - if [ "${cleaned_configs}" -eq 0 ]; then - echo "No git config files found for checkout cleanup fallback" - fi - fi + run: bash "${RUNNER_TEMP}/gh-aw/actions/clean_git_credentials_checkout.sh" - name: Fetch additional refs env: GH_AW_FETCH_TOKEN: ${{ secrets.GH_AW_GITHUB_MCP_SERVER_TOKEN || secrets.GH_AW_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} From 7e37172e359989fee7ec4b942d21dd07d427f201 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 May 2026 22:24:46 +0000 Subject: [PATCH 3/4] Reject removed tools.serena in parser Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/mcp.go | 75 ++++++++++-------------------------------- pkg/parser/mcp_test.go | 26 ++++++++++++--- 2 files changed, 38 insertions(+), 63 deletions(-) diff --git a/pkg/parser/mcp.go b/pkg/parser/mcp.go index 56d30d44a9c..3dce48df65c 100644 --- a/pkg/parser/mcp.go +++ b/pkg/parser/mcp.go @@ -15,6 +15,12 @@ import ( var mcpLog = logger.New("parser:mcp") +const serenaRemovedMessage = `tools.serena built-in support has been removed. Import shared/mcp/serena.md instead: + imports: + - uses: shared/mcp/serena.md + with: + languages: ["go", "typescript"]` + // ValidMCPTypes defines all supported MCP server types. // "local" is an alias for "stdio" and gets normalized during parsing. var ValidMCPTypes = []string{"stdio", "http", "local"} @@ -182,8 +188,11 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) ( if hasTools { if tools, ok := toolsSection.(map[string]any); ok { for toolName, toolValue := range tools { - // Only handle built-in MCP tools (github, playwright, and serena) - if toolName == "github" || toolName == "playwright" || toolName == "serena" { + if toolName == "serena" { + return nil, fmt.Errorf(serenaRemovedMessage) + } + // Only handle built-in MCP tools (github, playwright) + if toolName == "github" || toolName == "playwright" { config, err := processBuiltinMCPTool(toolName, toolValue, serverFilter) if err != nil { return nil, err @@ -210,8 +219,11 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) ( if hasTools { if tools, ok := toolsSection.(map[string]any); ok { for toolName, toolValue := range tools { - // Only handle built-in MCP tools (github, playwright, and serena) - if toolName == "github" || toolName == "playwright" || toolName == "serena" { + if toolName == "serena" { + return nil, fmt.Errorf(serenaRemovedMessage) + } + // Only handle built-in MCP tools (github, playwright) + if toolName == "github" || toolName == "playwright" { config, err := processBuiltinMCPTool(toolName, toolValue, serverFilter) if err != nil { return nil, err @@ -251,7 +263,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) ( return configs, nil } -// processBuiltinMCPTool handles built-in MCP tools (github, playwright, and serena) +// processBuiltinMCPTool handles built-in MCP tools (github and playwright) func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string) (*RegistryMCPServerConfig, error) { // Apply server filter if specified if serverFilter != "" && !strings.Contains(strings.ToLower(toolName), strings.ToLower(serverFilter)) { @@ -421,59 +433,6 @@ func processBuiltinMCPTool(toolName string, toolValue any, serverFilter string) } } - return &config, nil - } else if toolName == "serena" { - // Handle Serena MCP server - uses uvx to install and run from GitHub - config := RegistryMCPServerConfig{ - BaseMCPServerConfig: types.BaseMCPServerConfig{ - Type: "stdio", - Command: "uvx", - Args: []string{ - "--from", "git+https://github.com/oraios/serena", - "serena", "start-mcp-server", - "--context", "codex", - "--project", "${GITHUB_WORKSPACE}", - }, - Env: make(map[string]string), - }, - Name: "serena", - } - - // Check for custom Serena configuration - if toolConfig, ok := toolValue.(map[string]any); ok { - // Handle custom args - these would be appended to the default args - if argsValue, exists := toolConfig["args"]; exists { - // Handle []any format - if argsSlice, ok := argsValue.([]any); ok { - for _, arg := range argsSlice { - if argStr, ok := arg.(string); ok { - config.Args = append(config.Args, argStr) - } - } - } - // Handle []string format - if argsSlice, ok := argsValue.([]string); ok { - config.Args = append(config.Args, argsSlice...) - } - } - - // Handle allowed tools configuration - if allowed, hasAllowed := toolConfig["allowed"]; hasAllowed { - if allowedSlice, ok := allowed.([]any); ok { - for _, item := range allowedSlice { - if str, ok := item.(string); ok { - config.Allowed = append(config.Allowed, str) - } - } - } - } - } - - // If no specific allowed tools are configured, allow all tools (*) - if len(config.Allowed) == 0 { - config.Allowed = []string{"*"} - } - return &config, nil } diff --git a/pkg/parser/mcp_test.go b/pkg/parser/mcp_test.go index 5744c7b746d..5f1d683bbb8 100644 --- a/pkg/parser/mcp_test.go +++ b/pkg/parser/mcp_test.go @@ -5,6 +5,7 @@ package parser import ( "encoding/json" "reflect" + "strings" "testing" "github.com/github/gh-aw/pkg/types" @@ -16,11 +17,12 @@ import ( func TestExtractMCPConfigurations(t *testing.T) { tests := []struct { - name string - frontmatter map[string]any - serverFilter string - expected []RegistryMCPServerConfig - expectError bool + name string + frontmatter map[string]any + serverFilter string + expected []RegistryMCPServerConfig + expectError bool + expectedErrContains string }{ { name: "GitHub tool with read-only true", @@ -130,6 +132,16 @@ func TestExtractMCPConfigurations(t *testing.T) { }, expected: []RegistryMCPServerConfig{}, }, + { + name: "Serena tool is removed", + frontmatter: map[string]any{ + "tools": map[string]any{ + "serena": true, + }, + }, + expectError: true, + expectedErrContains: "tools.serena built-in support has been removed", + }, { name: "GitHub tool default configuration", frontmatter: map[string]any{ @@ -378,6 +390,10 @@ func TestExtractMCPConfigurations(t *testing.T) { if tt.expectError { if err == nil { t.Errorf("Expected error but got none") + return + } + if tt.expectedErrContains != "" && !strings.Contains(err.Error(), tt.expectedErrContains) { + t.Errorf("Expected error containing %q, got %q", tt.expectedErrContains, err.Error()) } return } From a942a2a17eb7e539c9a54b3883b288d97e532ba2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 17 May 2026 22:35:08 +0000 Subject: [PATCH 4/4] Simplify serena removal to plain error Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/parser/mcp.go | 10 ++-------- pkg/parser/mcp_test.go | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/pkg/parser/mcp.go b/pkg/parser/mcp.go index 3dce48df65c..27ad90cd53c 100644 --- a/pkg/parser/mcp.go +++ b/pkg/parser/mcp.go @@ -15,12 +15,6 @@ import ( var mcpLog = logger.New("parser:mcp") -const serenaRemovedMessage = `tools.serena built-in support has been removed. Import shared/mcp/serena.md instead: - imports: - - uses: shared/mcp/serena.md - with: - languages: ["go", "typescript"]` - // ValidMCPTypes defines all supported MCP server types. // "local" is an alias for "stdio" and gets normalized during parsing. var ValidMCPTypes = []string{"stdio", "http", "local"} @@ -189,7 +183,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) ( if tools, ok := toolsSection.(map[string]any); ok { for toolName, toolValue := range tools { if toolName == "serena" { - return nil, fmt.Errorf(serenaRemovedMessage) + return nil, fmt.Errorf("tools.serena is removed") } // Only handle built-in MCP tools (github, playwright) if toolName == "github" || toolName == "playwright" { @@ -220,7 +214,7 @@ func ExtractMCPConfigurations(frontmatter map[string]any, serverFilter string) ( if tools, ok := toolsSection.(map[string]any); ok { for toolName, toolValue := range tools { if toolName == "serena" { - return nil, fmt.Errorf(serenaRemovedMessage) + return nil, fmt.Errorf("tools.serena is removed") } // Only handle built-in MCP tools (github, playwright) if toolName == "github" || toolName == "playwright" { diff --git a/pkg/parser/mcp_test.go b/pkg/parser/mcp_test.go index 5f1d683bbb8..d3def3d698f 100644 --- a/pkg/parser/mcp_test.go +++ b/pkg/parser/mcp_test.go @@ -140,7 +140,7 @@ func TestExtractMCPConfigurations(t *testing.T) { }, }, expectError: true, - expectedErrContains: "tools.serena built-in support has been removed", + expectedErrContains: "tools.serena is removed", }, { name: "GitHub tool default configuration",