From b913fcc644dfcb553dbf84cd42d531866da96d96 Mon Sep 17 00:00:00 2001 From: Levi Neely Date: Fri, 6 Mar 2026 17:02:57 +0100 Subject: [PATCH] Fix elevated bash execution --- cfg/sandbox/anvilmcp.yaml | 4 +++ cfg/sandbox/default.yaml | 1 + cmd/anvilmcp/execute.go | 44 +++---------------------------- internal/sandbox/wrapper.go | 31 ++++++++++++++++++++++ kiro-cli/agent/anvillm-agent.json | 8 ++++-- kiro-cli/install-mcp.sh | 15 +++-------- kiro-cli/mcp/anvilmcp.json | 10 +++++-- 7 files changed, 56 insertions(+), 57 deletions(-) diff --git a/cfg/sandbox/anvilmcp.yaml b/cfg/sandbox/anvilmcp.yaml index d96fb18..923738e 100644 --- a/cfg/sandbox/anvilmcp.yaml +++ b/cfg/sandbox/anvilmcp.yaml @@ -20,6 +20,7 @@ filesystem: - "/dev/null" - "/tmp" - "{NAMESPACE}" + - "{XDG_RUNTIME_DIR}/superpowerd" rwx: - "{CWD}" env: @@ -31,5 +32,8 @@ env: - WAYLAND_DISPLAY - USER - AGENT_ID + - SUPERPOWERD_SESSION_TOKEN + - SUPERPOWERD_SOCKET_DIR + - XDG_RUNTIME_DIR network: unrestricted: true diff --git a/cfg/sandbox/default.yaml b/cfg/sandbox/default.yaml index f1c60f7..b720a43 100644 --- a/cfg/sandbox/default.yaml +++ b/cfg/sandbox/default.yaml @@ -111,5 +111,6 @@ env: - PCLOUD_USER - EDITOR - GIT_SEQUENCE_EDITOR + - SUPERPOWERD_SESSION_TOKEN network: unrestricted: true diff --git a/cmd/anvilmcp/execute.go b/cmd/anvilmcp/execute.go index 9c5d519..30f2e19 100644 --- a/cmd/anvilmcp/execute.go +++ b/cmd/anvilmcp/execute.go @@ -214,53 +214,15 @@ func executeCode(code, language string, timeout int, sandboxName string, trusted ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second) defer cancel() - landrunPath, err := exec.LookPath("landrun") - if err != nil { - return "", fmt.Errorf("landrun not found: %v", err) - } - var cmd *exec.Cmd switch language { case "bash", "": - args := []string{} - - // Add filesystem permissions from config - addPaths := func(flag string, paths []string) { - for _, p := range paths { - expanded := sandbox.ExpandPath(p, workDir) - if expanded == "" || strings.Contains(expanded, "{") { - continue // Skip unexpanded templates - } - if _, err := os.Stat(expanded); err == nil { - args = append(args, flag, expanded) - } - } - } - - addPaths("--ro", cfg.Filesystem.RO) - addPaths("--rox", cfg.Filesystem.ROX) - addPaths("--rw", cfg.Filesystem.RW) - addPaths("--rwx", cfg.Filesystem.RWX) - - // Network - if cfg.Network.Unrestricted { - args = append(args, "--unrestricted-network") - } - - // Environment variables - for _, env := range cfg.Env { - if os.Getenv(env) != "" || env == "HOME" || env == "USER" || env == "PATH" { - args = append(args, "--env", env) - } - } - - args = append(args, "--", "bash", "-c", code) - - cmd = exec.CommandContext(ctx, landrunPath, args...) + wrapped := sandbox.WrapCommand(cfg, []string{"bash", "-c", code}, workDir) + cmd = exec.CommandContext(ctx, wrapped[0], wrapped[1:]...) cmd.Dir = workDir // Add new language cases here: // case "python": - // args = append(args, "--", "python3", "-c", code) + // wrapped := sandbox.WrapCommand(cfg, []string{"python3", "-c", code}, workDir) default: return "", fmt.Errorf("unsupported language: %s (supported: bash)", language) } diff --git a/internal/sandbox/wrapper.go b/internal/sandbox/wrapper.go index 61805c9..8e52032 100644 --- a/internal/sandbox/wrapper.go +++ b/internal/sandbox/wrapper.go @@ -2,7 +2,10 @@ package sandbox import ( "fmt" + "net" "os" + "os/exec" + "path/filepath" "sort" "strings" ) @@ -107,6 +110,16 @@ func WrapCommand(cfg *Config, originalCmd []string, cwd string) []string { args = append(args, "--") args = append(args, originalCmd...) + // Wrap with superpowers run-session if superpowerd is running + if IsSuperpowerdRunning() { + if superpowersPath, err := exec.LookPath("superpowers"); err == nil { + // Insert --env SUPERPOWERD_SESSION_TOKEN after landrun + args = append([]string{args[0], "--env", "SUPERPOWERD_SESSION_TOKEN"}, args[1:]...) + // Wrap: superpowers run-session -- landrun ... + args = append([]string{superpowersPath, "run-session", "--"}, args...) + } + } + return args } @@ -168,3 +181,21 @@ func pathExists(path string) bool { _, err := os.Stat(path) return err == nil } + +// IsSuperpowerdRunning checks if superpowerd daemon is running by testing socket connectivity +func IsSuperpowerdRunning() bool { + socketDir := os.Getenv("SUPERPOWERD_SOCKET_DIR") + if socketDir == "" { + socketDir = os.Getenv("XDG_RUNTIME_DIR") + if socketDir == "" { + return false + } + socketDir = filepath.Join(socketDir, "superpowerd") + } + conn, err := net.Dial("unixpacket", filepath.Join(socketDir, "superpowerd.sock")) + if err != nil { + return false + } + conn.Close() + return true +} diff --git a/kiro-cli/agent/anvillm-agent.json b/kiro-cli/agent/anvillm-agent.json index 3cf672b..b3287a9 100644 --- a/kiro-cli/agent/anvillm-agent.json +++ b/kiro-cli/agent/anvillm-agent.json @@ -15,7 +15,9 @@ "aws", "subagent", "web_fetch", - "@anvilmcp/execute_code" + "@anvilmcp/execute_code", + "@superpowers-mcp-server/execute_elevated_bash", + "@superpowers-mcp-server/request_file" ], "allowedTools": [ "code", @@ -30,7 +32,9 @@ "aws", "subagent", "web_fetch", - "@anvilmcp/execute_code" + "@anvilmcp/execute_code", + "@superpowers-mcp-server/execute_elevated_bash", + "@superpowers-mcp-server/request_file" ], "toolsSettings": { "shell": { diff --git a/kiro-cli/install-mcp.sh b/kiro-cli/install-mcp.sh index ad64f62..5851341 100755 --- a/kiro-cli/install-mcp.sh +++ b/kiro-cli/install-mcp.sh @@ -1,14 +1,7 @@ #!/bin/bash -SETTINGS_FILE="$HOME/.kiro/settings/cli.json" -MCP_CONFIG='{ - "mcpServers": { - "anvilmcp": { - "command": "anvilmcp", - "args": [] - } - } -}' +SETTINGS_FILE="$HOME/.kiro/settings/mcp.json" +MCP_CONFIG='{"mcpServers":{"anvilmcp":{"command":"anvilmcp","args":[]},"superpowers-mcp-server":{"command":"superpowers-mcp-server","args":[],"env":{"SUPERPOWERD_SESSION_TOKEN":"${SUPERPOWERD_SESSION_TOKEN}"},"autoApproveTools":["execute_elevated_bash","request_file"]}}}' if ! command -v jq &> /dev/null; then echo "Error: jq is required but not installed. Please install jq first." >&2 @@ -17,12 +10,10 @@ fi mkdir -p "$HOME/.kiro/settings" -if [ -f "$SETTINGS_FILE" ]; then - # Merge with existing settings +if [ -f "$SETTINGS_FILE" ] && [ -s "$SETTINGS_FILE" ]; then jq -s '.[0] * .[1]' "$SETTINGS_FILE" <(echo "$MCP_CONFIG") > "$SETTINGS_FILE.tmp" mv "$SETTINGS_FILE.tmp" "$SETTINGS_FILE" else - # Create new settings file echo "$MCP_CONFIG" | jq '.' > "$SETTINGS_FILE" fi diff --git a/kiro-cli/mcp/anvilmcp.json b/kiro-cli/mcp/anvilmcp.json index e34483a..570774f 100644 --- a/kiro-cli/mcp/anvilmcp.json +++ b/kiro-cli/mcp/anvilmcp.json @@ -2,9 +2,15 @@ "mcpServers": { "anvilmcp": { "command": "anvilmcp", - "autoApproveTools": ["execute_code"], + "args": [] + }, + "superpowers-mcp-server": { + "command": "superpowers-mcp-server", "args": [], - "env": {} + "env": { + "SUPERPOWERD_SESSION_TOKEN": "${SUPERPOWERD_SESSION_TOKEN}" + }, + "autoApproveTools": ["execute_elevated_bash", "request_file"] } } }