From ad1047fde77d63f3a22ca3c49dbd2b094bbf1072 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:41:06 +0000 Subject: [PATCH 1/4] Initial plan From fc305aa4112ad758e4758a3e3e48d97a9a434c7b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:52:58 +0000 Subject: [PATCH 2/4] Add --cmd argument to agentic-workflows MCP server in dev mode - Add ActionMode field to MCPRendererOptions struct - Update renderAgenticWorkflowsMCPConfigWithOptions to add --cmd in dev mode - Update renderAgenticWorkflowsMCPConfigTOML to add --cmd in dev mode - Add ActionMode to WorkflowData and populate it from compiler - Update all engines (Copilot, Claude, Codex, Custom) to pass action mode - Add comprehensive tests for dev and release modes Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/claude_mcp.go | 5 + pkg/workflow/codex_mcp.go | 10 ++ .../compiler_orchestrator_workflow.go | 1 + pkg/workflow/compiler_types.go | 1 + pkg/workflow/copilot_mcp.go | 5 + pkg/workflow/custom_engine.go | 5 + pkg/workflow/mcp_config_builtin.go | 23 +++- pkg/workflow/mcp_config_refactor_test.go | 114 +++++++++++++----- pkg/workflow/mcp_renderer.go | 15 ++- 9 files changed, 139 insertions(+), 40 deletions(-) diff --git a/pkg/workflow/claude_mcp.go b/pkg/workflow/claude_mcp.go index f2064093a9..3ba217956a 100644 --- a/pkg/workflow/claude_mcp.go +++ b/pkg/workflow/claude_mcp.go @@ -15,11 +15,16 @@ func (e *ClaudeEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]a // Create unified renderer with Claude-specific options // Claude uses JSON format without Copilot-specific fields and multi-line args createRenderer := func(isLast bool) *MCPConfigRendererUnified { + actionMode := ActionModeDev // Default to dev mode + if workflowData != nil { + actionMode = workflowData.ActionMode + } return NewMCPConfigRenderer(MCPRendererOptions{ IncludeCopilotFields: false, // Claude doesn't use "type" and "tools" fields InlineArgs: false, // Claude uses multi-line args format Format: "json", IsLast: isLast, + ActionMode: actionMode, }) } diff --git a/pkg/workflow/codex_mcp.go b/pkg/workflow/codex_mcp.go index 09ab7f695c..26a119b936 100644 --- a/pkg/workflow/codex_mcp.go +++ b/pkg/workflow/codex_mcp.go @@ -18,11 +18,16 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an // Create unified renderer with Codex-specific options // Codex uses TOML format without Copilot-specific fields and multi-line args createRenderer := func(isLast bool) *MCPConfigRendererUnified { + actionMode := ActionModeDev // Default to dev mode + if workflowData != nil { + actionMode = workflowData.ActionMode + } return NewMCPConfigRenderer(MCPRendererOptions{ IncludeCopilotFields: false, // Codex doesn't use "type" and "tools" fields InlineArgs: false, // Codex uses multi-line args format Format: "toml", IsLast: isLast, + ActionMode: actionMode, }) } @@ -104,11 +109,16 @@ func (e *CodexEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]an // Use shared JSON renderer for gateway input createJSONRenderer := func(isLast bool) *MCPConfigRendererUnified { + actionMode := ActionModeDev // Default to dev mode + if workflowData != nil { + actionMode = workflowData.ActionMode + } return NewMCPConfigRenderer(MCPRendererOptions{ IncludeCopilotFields: false, // Gateway doesn't need Copilot fields InlineArgs: false, // Use standard multi-line format Format: "json", IsLast: isLast, + ActionMode: actionMode, }) } diff --git a/pkg/workflow/compiler_orchestrator_workflow.go b/pkg/workflow/compiler_orchestrator_workflow.go index 6a187607c7..2b353fd55b 100644 --- a/pkg/workflow/compiler_orchestrator_workflow.go +++ b/pkg/workflow/compiler_orchestrator_workflow.go @@ -132,6 +132,7 @@ func (c *Compiler) buildInitialWorkflowData( StrictMode: c.strictMode, SecretMasking: toolsResult.secretMasking, ParsedFrontmatter: toolsResult.parsedFrontmatter, + ActionMode: c.actionMode, } } diff --git a/pkg/workflow/compiler_types.go b/pkg/workflow/compiler_types.go index 867ce8fe5d..b48f469a0a 100644 --- a/pkg/workflow/compiler_types.go +++ b/pkg/workflow/compiler_types.go @@ -427,6 +427,7 @@ type WorkflowData struct { SecretMasking *SecretMaskingConfig // secret masking configuration ParsedFrontmatter *FrontmatterConfig // cached parsed frontmatter configuration (for performance optimization) ActionPinWarnings map[string]bool // cache of already-warned action pin failures (key: "repo@version") + ActionMode ActionMode // action mode for workflow compilation (dev, release, script) } // BaseSafeOutputConfig holds common configuration fields for all safe output types diff --git a/pkg/workflow/copilot_mcp.go b/pkg/workflow/copilot_mcp.go index 61a75239da..2840ce6906 100644 --- a/pkg/workflow/copilot_mcp.go +++ b/pkg/workflow/copilot_mcp.go @@ -18,11 +18,16 @@ func (e *CopilotEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string] // Create unified renderer with Copilot-specific options // Copilot uses JSON format with type and tools fields, and inline args createRenderer := func(isLast bool) *MCPConfigRendererUnified { + actionMode := ActionModeDev // Default to dev mode + if workflowData != nil { + actionMode = workflowData.ActionMode + } return NewMCPConfigRenderer(MCPRendererOptions{ IncludeCopilotFields: true, // Copilot uses "type" and "tools" fields InlineArgs: true, // Copilot uses inline args format Format: "json", IsLast: isLast, + ActionMode: actionMode, }) } diff --git a/pkg/workflow/custom_engine.go b/pkg/workflow/custom_engine.go index 834ddbb38f..bcd46ceeb4 100644 --- a/pkg/workflow/custom_engine.go +++ b/pkg/workflow/custom_engine.go @@ -253,11 +253,16 @@ func (e *CustomEngine) RenderMCPConfig(yaml *strings.Builder, tools map[string]a // Create unified renderer with Custom engine-specific options // Custom engine uses JSON format without Copilot-specific fields and multi-line args (like Claude) createRenderer := func(isLast bool) *MCPConfigRendererUnified { + actionMode := ActionModeDev // Default to dev mode + if workflowData != nil { + actionMode = workflowData.ActionMode + } return NewMCPConfigRenderer(MCPRendererOptions{ IncludeCopilotFields: false, // Custom engine doesn't use "type" and "tools" fields InlineArgs: false, // Custom engine uses multi-line args format Format: "json", IsLast: isLast, + ActionMode: actionMode, }) } diff --git a/pkg/workflow/mcp_config_builtin.go b/pkg/workflow/mcp_config_builtin.go index 0e4b1df40c..a856723385 100644 --- a/pkg/workflow/mcp_config_builtin.go +++ b/pkg/workflow/mcp_config_builtin.go @@ -158,7 +158,7 @@ func renderSafeOutputsMCPConfigWithOptions(yaml *strings.Builder, isLast bool, i // renderAgenticWorkflowsMCPConfigWithOptions generates the Agentic Workflows MCP server configuration with engine-specific options // Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. // Uses MCP Gateway spec format: container, entrypoint, entrypointArgs, and mounts fields. -func renderAgenticWorkflowsMCPConfigWithOptions(yaml *strings.Builder, isLast bool, includeCopilotFields bool) { +func renderAgenticWorkflowsMCPConfigWithOptions(yaml *strings.Builder, isLast bool, includeCopilotFields bool, actionMode ActionMode) { envVars := []string{ "GITHUB_TOKEN", } @@ -175,7 +175,15 @@ func renderAgenticWorkflowsMCPConfigWithOptions(yaml *strings.Builder, isLast bo // MCP Gateway spec fields for containerized stdio servers yaml.WriteString(" \"container\": \"" + constants.DefaultAlpineImage + "\",\n") yaml.WriteString(" \"entrypoint\": \"/opt/gh-aw/gh-aw\",\n") - yaml.WriteString(" \"entrypointArgs\": [\"mcp-server\"],\n") + + // In dev mode, add --cmd argument to specify the binary path + // This is required for the MCP server to execute commands like 'compile', 'status', etc. + if actionMode.IsDev() { + yaml.WriteString(" \"entrypointArgs\": [\"mcp-server\", \"--cmd\", \"/opt/gh-aw/gh-aw\"],\n") + } else { + yaml.WriteString(" \"entrypointArgs\": [\"mcp-server\"],\n") + } + // Mount gh-aw binary (read-only), gh CLI binary (read-only), workspace (read-write for status/compile), and temp directory (read-write for logs) yaml.WriteString(" \"mounts\": [\"" + constants.DefaultGhAwMount + "\", \"" + constants.DefaultGhBinaryMount + "\", \"" + constants.DefaultWorkspaceMount + "\", \"" + constants.DefaultTmpGhAwMount + "\"],\n") @@ -224,12 +232,19 @@ func renderSafeOutputsMCPConfigTOML(yaml *strings.Builder) { // renderAgenticWorkflowsMCPConfigTOML generates the Agentic Workflows MCP server configuration in TOML format for Codex // Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. // Uses MCP Gateway spec format: container, entrypoint, entrypointArgs, and mounts fields. -func renderAgenticWorkflowsMCPConfigTOML(yaml *strings.Builder) { +func renderAgenticWorkflowsMCPConfigTOML(yaml *strings.Builder, actionMode ActionMode) { yaml.WriteString(" \n") yaml.WriteString(" [mcp_servers.agentic_workflows]\n") yaml.WriteString(" container = \"" + constants.DefaultAlpineImage + "\"\n") yaml.WriteString(" entrypoint = \"/opt/gh-aw/gh-aw\"\n") - yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") + + // In dev mode, add --cmd argument to specify the binary path + if actionMode.IsDev() { + yaml.WriteString(" entrypointArgs = [\"mcp-server\", \"--cmd\", \"/opt/gh-aw/gh-aw\"]\n") + } else { + yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") + } + // Mount gh-aw binary (read-only), gh CLI binary (read-only), workspace (read-write for status/compile), and temp directory (read-write for logs) yaml.WriteString(" mounts = [\"" + constants.DefaultGhAwMount + "\", \"" + constants.DefaultGhBinaryMount + "\", \"" + constants.DefaultWorkspaceMount + "\", \"" + constants.DefaultTmpGhAwMount + "\"]\n") // Use env_vars array to reference environment variables instead of embedding secrets diff --git a/pkg/workflow/mcp_config_refactor_test.go b/pkg/workflow/mcp_config_refactor_test.go index 6c9b4fd61e..ae0ff30d99 100644 --- a/pkg/workflow/mcp_config_refactor_test.go +++ b/pkg/workflow/mcp_config_refactor_test.go @@ -93,13 +93,38 @@ func TestRenderAgenticWorkflowsMCPConfigWithOptions(t *testing.T) { name string isLast bool includeCopilotFields bool + actionMode ActionMode expectedContent []string unexpectedContent []string }{ { - name: "Copilot with type and escaped env vars", + name: "Copilot dev mode with --cmd", isLast: false, includeCopilotFields: true, + actionMode: ActionModeDev, + expectedContent: []string{ + `"agentic_workflows": {`, + `"type": "stdio"`, + `"container": "alpine:latest"`, + `"entrypoint": "/opt/gh-aw/gh-aw"`, + `"entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"]`, + `"/opt/gh-aw:/opt/gh-aw:ro"`, // gh-aw binary mount (read-only) + `"/usr/bin/gh:/usr/bin/gh:ro"`, // gh CLI binary mount (read-only) + `"${{ github.workspace }}:${{ github.workspace }}:rw"`, // workspace mount (read-write) + `"/tmp/gh-aw:/tmp/gh-aw:rw"`, // temp directory mount (read-write) + `"GITHUB_TOKEN": "\${GITHUB_TOKEN}"`, + ` },`, + }, + unexpectedContent: []string{ + `${{ secrets.`, + `"command":`, // Should NOT use command - must use container + }, + }, + { + name: "Copilot release mode without --cmd", + isLast: false, + includeCopilotFields: true, + actionMode: ActionModeRelease, expectedContent: []string{ `"agentic_workflows": {`, `"type": "stdio"`, @@ -114,19 +139,21 @@ func TestRenderAgenticWorkflowsMCPConfigWithOptions(t *testing.T) { ` },`, }, unexpectedContent: []string{ + `--cmd`, `${{ secrets.`, `"command":`, // Should NOT use command - must use container }, }, { - name: "Claude/Custom without type, with shell env vars", + name: "Claude/Custom dev mode with --cmd", isLast: true, includeCopilotFields: false, + actionMode: ActionModeDev, expectedContent: []string{ `"agentic_workflows": {`, `"container": "alpine:latest"`, `"entrypoint": "/opt/gh-aw/gh-aw"`, - `"entrypointArgs": ["mcp-server"]`, + `"entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"]`, `"/opt/gh-aw:/opt/gh-aw:ro"`, // gh-aw binary mount (read-only) `"/usr/bin/gh:/usr/bin/gh:ro"`, // gh CLI binary mount (read-only) `"${{ github.workspace }}:${{ github.workspace }}:rw"`, // workspace mount (read-write) @@ -149,7 +176,7 @@ func TestRenderAgenticWorkflowsMCPConfigWithOptions(t *testing.T) { t.Run(tt.name, func(t *testing.T) { var output strings.Builder - renderAgenticWorkflowsMCPConfigWithOptions(&output, tt.isLast, tt.includeCopilotFields) + renderAgenticWorkflowsMCPConfigWithOptions(&output, tt.isLast, tt.includeCopilotFields, tt.actionMode) result := output.String() @@ -212,40 +239,61 @@ func TestRenderSafeOutputsMCPConfigTOML(t *testing.T) { // TestRenderAgenticWorkflowsMCPConfigTOML verifies the Agentic Workflows TOML format helper // Per MCP Gateway Specification v1.0.0 section 3.2.1, stdio-based MCP servers MUST be containerized. func TestRenderAgenticWorkflowsMCPConfigTOML(t *testing.T) { - var output strings.Builder + tests := []struct { + name string + actionMode ActionMode + expectedArgs string + unexpectedContent []string + }{ + { + name: "dev mode with --cmd", + actionMode: ActionModeDev, + expectedArgs: `entrypointArgs = ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"]`, + unexpectedContent: []string{ + `entrypointArgs = ["mcp-server"]`, + }, + }, + { + name: "release mode without --cmd", + actionMode: ActionModeRelease, + expectedArgs: `entrypointArgs = ["mcp-server"]`, + unexpectedContent: []string{ + `--cmd`, + }, + }, + } - renderAgenticWorkflowsMCPConfigTOML(&output) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var output strings.Builder - result := output.String() + renderAgenticWorkflowsMCPConfigTOML(&output, tt.actionMode) - expectedContent := []string{ - `[mcp_servers.agentic_workflows]`, - `container = "alpine:latest"`, - `entrypoint = "/opt/gh-aw/gh-aw"`, - `entrypointArgs = ["mcp-server"]`, - `"/opt/gh-aw:/opt/gh-aw:ro"`, // gh-aw binary mount (read-only) - `"/usr/bin/gh:/usr/bin/gh:ro"`, // gh CLI binary mount (read-only) - `"${{ github.workspace }}:${{ github.workspace }}:rw"`, // workspace mount (read-write) - `"/tmp/gh-aw:/tmp/gh-aw:rw"`, // temp directory mount (read-write) - `env_vars = ["GITHUB_TOKEN"]`, - } + result := output.String() - unexpectedContent := []string{ - `env = {`, // Should use env_vars instead - `command = "gh"`, // Should NOT use command - must use container - `"aw"`, // Old arg format - `args = [`, // Old args format - } + expectedContent := []string{ + `[mcp_servers.agentic_workflows]`, + `container = "alpine:latest"`, + `entrypoint = "/opt/gh-aw/gh-aw"`, + tt.expectedArgs, + `"/opt/gh-aw:/opt/gh-aw:ro"`, // gh-aw binary mount (read-only) + `"/usr/bin/gh:/usr/bin/gh:ro"`, // gh CLI binary mount (read-only) + `"${{ github.workspace }}:${{ github.workspace }}:rw"`, // workspace mount (read-write) + `"/tmp/gh-aw:/tmp/gh-aw:rw"`, // temp directory mount (read-write) + `env_vars = ["GITHUB_TOKEN"]`, + } - for _, expected := range expectedContent { - if !strings.Contains(result, expected) { - t.Errorf("Expected content not found: %q\nActual output:\n%s", expected, result) - } - } + for _, expected := range expectedContent { + if !strings.Contains(result, expected) { + t.Errorf("Expected content not found: %q\nActual output:\n%s", expected, result) + } + } - for _, unexpected := range unexpectedContent { - if strings.Contains(result, unexpected) { - t.Errorf("Unexpected content found: %q\nActual output:\n%s", unexpected, result) - } + for _, unexpected := range tt.unexpectedContent { + if strings.Contains(result, unexpected) { + t.Errorf("Unexpected content found: %q\nActual output:\n%s", unexpected, result) + } + } + }) } } diff --git a/pkg/workflow/mcp_renderer.go b/pkg/workflow/mcp_renderer.go index 375f04b3cc..dce29007da 100644 --- a/pkg/workflow/mcp_renderer.go +++ b/pkg/workflow/mcp_renderer.go @@ -98,6 +98,8 @@ type MCPRendererOptions struct { Format string // IsLast indicates if this is the last server in the configuration (affects trailing comma) IsLast bool + // ActionMode indicates the action mode for workflow compilation (dev, release, script) + ActionMode ActionMode } // MCPConfigRendererUnified provides unified rendering methods for MCP configurations @@ -395,7 +397,7 @@ func (r *MCPConfigRendererUnified) renderSafeInputsTOML(yaml *strings.Builder, s // RenderAgenticWorkflowsMCP generates the Agentic Workflows MCP server configuration func (r *MCPConfigRendererUnified) RenderAgenticWorkflowsMCP(yaml *strings.Builder) { - mcpRendererLog.Printf("Rendering Agentic Workflows MCP: format=%s", r.options.Format) + mcpRendererLog.Printf("Rendering Agentic Workflows MCP: format=%s, action_mode=%s", r.options.Format, r.options.ActionMode) if r.options.Format == "toml" { r.renderAgenticWorkflowsTOML(yaml) @@ -403,7 +405,7 @@ func (r *MCPConfigRendererUnified) RenderAgenticWorkflowsMCP(yaml *strings.Build } // JSON format - renderAgenticWorkflowsMCPConfigWithOptions(yaml, r.options.IsLast, r.options.IncludeCopilotFields) + renderAgenticWorkflowsMCPConfigWithOptions(yaml, r.options.IsLast, r.options.IncludeCopilotFields, r.options.ActionMode) } // renderAgenticWorkflowsTOML generates Agentic Workflows MCP configuration in TOML format @@ -413,7 +415,14 @@ func (r *MCPConfigRendererUnified) renderAgenticWorkflowsTOML(yaml *strings.Buil yaml.WriteString(" [mcp_servers.agentic_workflows]\n") yaml.WriteString(" container = \"" + constants.DefaultAlpineImage + "\"\n") yaml.WriteString(" entrypoint = \"/opt/gh-aw/gh-aw\"\n") - yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") + + // In dev mode, add --cmd argument to specify the binary path + if r.options.ActionMode.IsDev() { + yaml.WriteString(" entrypointArgs = [\"mcp-server\", \"--cmd\", \"/opt/gh-aw/gh-aw\"]\n") + } else { + yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") + } + yaml.WriteString(" mounts = [\"" + constants.DefaultGhAwMount + "\"]\n") yaml.WriteString(" env_vars = [\"GITHUB_TOKEN\"]\n") } From adfa351cac453a8cd9568d514570a8a6c2ad3c09 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 18:56:49 +0000 Subject: [PATCH 3/4] Fix test to expect --cmd argument in dev mode for agentic-workflows MCP Update TestImportAgenticWorkflowsTool to check for the --cmd argument that is now added in dev mode. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/importable_tools_test.go | 5 +++-- pkg/workflow/mcp_config_builtin.go | 8 ++++---- pkg/workflow/mcp_renderer.go | 4 ++-- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/pkg/workflow/importable_tools_test.go b/pkg/workflow/importable_tools_test.go index 42194a92dc..f7d231288e 100644 --- a/pkg/workflow/importable_tools_test.go +++ b/pkg/workflow/importable_tools_test.go @@ -229,8 +229,9 @@ Uses imported agentic-workflows tool. workflowData := string(lockFileContent) // Verify containerized agentic_workflows server is present (per MCP Gateway Specification v1.0.0) - if !strings.Contains(workflowData, `"entrypointArgs": ["mcp-server"]`) { - t.Error("Expected compiled workflow to contain 'mcp-server' entrypointArgs") + // In dev mode (default), should include --cmd argument + if !strings.Contains(workflowData, `"entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"]`) { + t.Error("Expected compiled workflow to contain 'mcp-server' entrypointArgs with --cmd in dev mode") } // Verify container format is used (not command format) diff --git a/pkg/workflow/mcp_config_builtin.go b/pkg/workflow/mcp_config_builtin.go index a856723385..0611050204 100644 --- a/pkg/workflow/mcp_config_builtin.go +++ b/pkg/workflow/mcp_config_builtin.go @@ -175,7 +175,7 @@ func renderAgenticWorkflowsMCPConfigWithOptions(yaml *strings.Builder, isLast bo // MCP Gateway spec fields for containerized stdio servers yaml.WriteString(" \"container\": \"" + constants.DefaultAlpineImage + "\",\n") yaml.WriteString(" \"entrypoint\": \"/opt/gh-aw/gh-aw\",\n") - + // In dev mode, add --cmd argument to specify the binary path // This is required for the MCP server to execute commands like 'compile', 'status', etc. if actionMode.IsDev() { @@ -183,7 +183,7 @@ func renderAgenticWorkflowsMCPConfigWithOptions(yaml *strings.Builder, isLast bo } else { yaml.WriteString(" \"entrypointArgs\": [\"mcp-server\"],\n") } - + // Mount gh-aw binary (read-only), gh CLI binary (read-only), workspace (read-write for status/compile), and temp directory (read-write for logs) yaml.WriteString(" \"mounts\": [\"" + constants.DefaultGhAwMount + "\", \"" + constants.DefaultGhBinaryMount + "\", \"" + constants.DefaultWorkspaceMount + "\", \"" + constants.DefaultTmpGhAwMount + "\"],\n") @@ -237,14 +237,14 @@ func renderAgenticWorkflowsMCPConfigTOML(yaml *strings.Builder, actionMode Actio yaml.WriteString(" [mcp_servers.agentic_workflows]\n") yaml.WriteString(" container = \"" + constants.DefaultAlpineImage + "\"\n") yaml.WriteString(" entrypoint = \"/opt/gh-aw/gh-aw\"\n") - + // In dev mode, add --cmd argument to specify the binary path if actionMode.IsDev() { yaml.WriteString(" entrypointArgs = [\"mcp-server\", \"--cmd\", \"/opt/gh-aw/gh-aw\"]\n") } else { yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") } - + // Mount gh-aw binary (read-only), gh CLI binary (read-only), workspace (read-write for status/compile), and temp directory (read-write for logs) yaml.WriteString(" mounts = [\"" + constants.DefaultGhAwMount + "\", \"" + constants.DefaultGhBinaryMount + "\", \"" + constants.DefaultWorkspaceMount + "\", \"" + constants.DefaultTmpGhAwMount + "\"]\n") // Use env_vars array to reference environment variables instead of embedding secrets diff --git a/pkg/workflow/mcp_renderer.go b/pkg/workflow/mcp_renderer.go index dce29007da..f89665f8bf 100644 --- a/pkg/workflow/mcp_renderer.go +++ b/pkg/workflow/mcp_renderer.go @@ -415,14 +415,14 @@ func (r *MCPConfigRendererUnified) renderAgenticWorkflowsTOML(yaml *strings.Buil yaml.WriteString(" [mcp_servers.agentic_workflows]\n") yaml.WriteString(" container = \"" + constants.DefaultAlpineImage + "\"\n") yaml.WriteString(" entrypoint = \"/opt/gh-aw/gh-aw\"\n") - + // In dev mode, add --cmd argument to specify the binary path if r.options.ActionMode.IsDev() { yaml.WriteString(" entrypointArgs = [\"mcp-server\", \"--cmd\", \"/opt/gh-aw/gh-aw\"]\n") } else { yaml.WriteString(" entrypointArgs = [\"mcp-server\"]\n") } - + yaml.WriteString(" mounts = [\"" + constants.DefaultGhAwMount + "\"]\n") yaml.WriteString(" env_vars = [\"GITHUB_TOKEN\"]\n") } From acc472ea3cbf8b5cfd549957b2a354e51a762d31 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 5 Feb 2026 19:02:04 +0000 Subject: [PATCH 4/4] Complete implementation: --cmd argument for agentic-workflows MCP in dev mode All tests passing, code formatted and linted successfully. Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/agent-performance-analyzer.lock.yml | 2 +- .github/workflows/agent-persona-explorer.lock.yml | 2 +- .github/workflows/audit-workflows.lock.yml | 2 +- .github/workflows/cloclo.lock.yml | 2 +- .github/workflows/daily-firewall-report.lock.yml | 2 +- .github/workflows/daily-observability-report.lock.yml | 4 ++-- .github/workflows/daily-safe-output-optimizer.lock.yml | 2 +- .github/workflows/deep-report.lock.yml | 4 ++-- .github/workflows/dev-hawk.lock.yml | 2 +- .github/workflows/example-workflow-analyzer.lock.yml | 2 +- .github/workflows/mcp-inspector.lock.yml | 2 +- .github/workflows/metrics-collector.lock.yml | 2 +- .github/workflows/portfolio-analyst.lock.yml | 2 +- .github/workflows/prompt-clustering-analysis.lock.yml | 2 +- .github/workflows/python-data-charts.lock.yml | 2 +- .github/workflows/q.lock.yml | 2 +- .github/workflows/safe-output-health.lock.yml | 2 +- .github/workflows/security-review.lock.yml | 2 +- .github/workflows/smoke-claude.lock.yml | 2 +- .github/workflows/smoke-copilot.lock.yml | 2 +- .github/workflows/static-analysis-report.lock.yml | 2 +- .github/workflows/workflow-normalizer.lock.yml | 2 +- 22 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.github/workflows/agent-performance-analyzer.lock.yml b/.github/workflows/agent-performance-analyzer.lock.yml index 6eba39295d..70cd275845 100644 --- a/.github/workflows/agent-performance-analyzer.lock.yml +++ b/.github/workflows/agent-performance-analyzer.lock.yml @@ -546,7 +546,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/agent-persona-explorer.lock.yml b/.github/workflows/agent-persona-explorer.lock.yml index 503ca0e036..8630978822 100644 --- a/.github/workflows/agent-persona-explorer.lock.yml +++ b/.github/workflows/agent-persona-explorer.lock.yml @@ -440,7 +440,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/audit-workflows.lock.yml b/.github/workflows/audit-workflows.lock.yml index f221c5f0e2..2fa84985b3 100644 --- a/.github/workflows/audit-workflows.lock.yml +++ b/.github/workflows/audit-workflows.lock.yml @@ -507,7 +507,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/cloclo.lock.yml b/.github/workflows/cloclo.lock.yml index 544e46478d..3b8ea104b0 100644 --- a/.github/workflows/cloclo.lock.yml +++ b/.github/workflows/cloclo.lock.yml @@ -554,7 +554,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/daily-firewall-report.lock.yml b/.github/workflows/daily-firewall-report.lock.yml index 512117bea1..b54ea2e160 100644 --- a/.github/workflows/daily-firewall-report.lock.yml +++ b/.github/workflows/daily-firewall-report.lock.yml @@ -493,7 +493,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/daily-observability-report.lock.yml b/.github/workflows/daily-observability-report.lock.yml index 4b37309885..3f9d544643 100644 --- a/.github/workflows/daily-observability-report.lock.yml +++ b/.github/workflows/daily-observability-report.lock.yml @@ -495,7 +495,7 @@ jobs: [mcp_servers.agentic_workflows] container = "alpine:latest" entrypoint = "/opt/gh-aw/gh-aw" - entrypointArgs = ["mcp-server"] + entrypointArgs = ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"] mounts = ["/opt/gh-aw:/opt/gh-aw:ro"] env_vars = ["GITHUB_TOKEN"] @@ -522,7 +522,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/daily-safe-output-optimizer.lock.yml b/.github/workflows/daily-safe-output-optimizer.lock.yml index c30b9e3dc3..6fef4a9704 100644 --- a/.github/workflows/daily-safe-output-optimizer.lock.yml +++ b/.github/workflows/daily-safe-output-optimizer.lock.yml @@ -473,7 +473,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/deep-report.lock.yml b/.github/workflows/deep-report.lock.yml index b09d078ed9..2671be203f 100644 --- a/.github/workflows/deep-report.lock.yml +++ b/.github/workflows/deep-report.lock.yml @@ -569,7 +569,7 @@ jobs: [mcp_servers.agentic_workflows] container = "alpine:latest" entrypoint = "/opt/gh-aw/gh-aw" - entrypointArgs = ["mcp-server"] + entrypointArgs = ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"] mounts = ["/opt/gh-aw:/opt/gh-aw:ro"] env_vars = ["GITHUB_TOKEN"] @@ -596,7 +596,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/dev-hawk.lock.yml b/.github/workflows/dev-hawk.lock.yml index 1ce4c0b835..99a84fc310 100644 --- a/.github/workflows/dev-hawk.lock.yml +++ b/.github/workflows/dev-hawk.lock.yml @@ -414,7 +414,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/example-workflow-analyzer.lock.yml b/.github/workflows/example-workflow-analyzer.lock.yml index 9ccb2a7235..d38edc6017 100644 --- a/.github/workflows/example-workflow-analyzer.lock.yml +++ b/.github/workflows/example-workflow-analyzer.lock.yml @@ -430,7 +430,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 4a5c7f4656..6b0dc87ad7 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -508,7 +508,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/metrics-collector.lock.yml b/.github/workflows/metrics-collector.lock.yml index 57b56c0e90..2942ee74e4 100644 --- a/.github/workflows/metrics-collector.lock.yml +++ b/.github/workflows/metrics-collector.lock.yml @@ -211,7 +211,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/portfolio-analyst.lock.yml b/.github/workflows/portfolio-analyst.lock.yml index 8c74d3b349..aaef87ecb2 100644 --- a/.github/workflows/portfolio-analyst.lock.yml +++ b/.github/workflows/portfolio-analyst.lock.yml @@ -500,7 +500,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/prompt-clustering-analysis.lock.yml b/.github/workflows/prompt-clustering-analysis.lock.yml index 9e9841441f..c534ce2a49 100644 --- a/.github/workflows/prompt-clustering-analysis.lock.yml +++ b/.github/workflows/prompt-clustering-analysis.lock.yml @@ -497,7 +497,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/python-data-charts.lock.yml b/.github/workflows/python-data-charts.lock.yml index ac61c8da4f..5d0d1afba8 100644 --- a/.github/workflows/python-data-charts.lock.yml +++ b/.github/workflows/python-data-charts.lock.yml @@ -488,7 +488,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 410c210483..e9e4689ce4 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -537,7 +537,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/safe-output-health.lock.yml b/.github/workflows/safe-output-health.lock.yml index d0a0fd64be..ed078ce817 100644 --- a/.github/workflows/safe-output-health.lock.yml +++ b/.github/workflows/safe-output-health.lock.yml @@ -449,7 +449,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/security-review.lock.yml b/.github/workflows/security-review.lock.yml index 6bce31c825..355b375424 100644 --- a/.github/workflows/security-review.lock.yml +++ b/.github/workflows/security-review.lock.yml @@ -528,7 +528,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/smoke-claude.lock.yml b/.github/workflows/smoke-claude.lock.yml index 1b2e75a027..79434d98a1 100644 --- a/.github/workflows/smoke-claude.lock.yml +++ b/.github/workflows/smoke-claude.lock.yml @@ -1131,7 +1131,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index f176938575..dafd7709de 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -1120,7 +1120,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}" diff --git a/.github/workflows/static-analysis-report.lock.yml b/.github/workflows/static-analysis-report.lock.yml index 5c102382a8..c487a70604 100644 --- a/.github/workflows/static-analysis-report.lock.yml +++ b/.github/workflows/static-analysis-report.lock.yml @@ -448,7 +448,7 @@ jobs: "agentic_workflows": { "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "$GITHUB_TOKEN" diff --git a/.github/workflows/workflow-normalizer.lock.yml b/.github/workflows/workflow-normalizer.lock.yml index ebd4e3b914..c1d5dc6708 100644 --- a/.github/workflows/workflow-normalizer.lock.yml +++ b/.github/workflows/workflow-normalizer.lock.yml @@ -447,7 +447,7 @@ jobs: "type": "stdio", "container": "alpine:latest", "entrypoint": "/opt/gh-aw/gh-aw", - "entrypointArgs": ["mcp-server"], + "entrypointArgs": ["mcp-server", "--cmd", "/opt/gh-aw/gh-aw"], "mounts": ["/opt/gh-aw:/opt/gh-aw:ro", "/usr/bin/gh:/usr/bin/gh:ro", "${{ github.workspace }}:${{ github.workspace }}:rw", "/tmp/gh-aw:/tmp/gh-aw:rw"], "env": { "GITHUB_TOKEN": "\${GITHUB_TOKEN}"