Skip to content

Commit da40c51

Browse files
committed
feat: workspace bash background parameter
1 parent 070178c commit da40c51

File tree

2 files changed

+54
-3
lines changed

2 files changed

+54
-3
lines changed

codersdk/toolsdk/bash.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package toolsdk
22

33
import (
44
"context"
5+
_ "embed"
6+
"encoding/base64"
57
"errors"
68
"fmt"
79
"io"
@@ -15,18 +17,23 @@ import (
1517
"github.com/coder/coder/v2/cli/cliui"
1618
"github.com/coder/coder/v2/codersdk"
1719
"github.com/coder/coder/v2/codersdk/workspacesdk"
20+
"github.com/coder/coder/v2/cryptorand"
1821
)
1922

2023
type WorkspaceBashArgs struct {
21-
Workspace string `json:"workspace"`
22-
Command string `json:"command"`
24+
Workspace string `json:"workspace"`
25+
Command string `json:"command"`
26+
Background bool `json:"background"`
2327
}
2428

2529
type WorkspaceBashResult struct {
2630
Output string `json:"output"`
2731
ExitCode int `json:"exit_code"`
2832
}
2933

34+
//go:embed resources/background.sh
35+
var backgroundScript string
36+
3037
var WorkspaceBash = Tool[WorkspaceBashArgs, WorkspaceBashResult]{
3138
Tool: aisdk.Tool{
3239
Name: ToolNameWorkspaceBash,
@@ -45,6 +52,7 @@ The workspace parameter supports various formats:
4552
4653
Examples:
4754
- workspace: "my-workspace", command: "ls -la"
55+
- workspace: "my-workspace", command: "npm run dev", background: true
4856
- workspace: "john/dev-env", command: "git status"
4957
- workspace: "my-workspace.main", command: "docker ps"`,
5058
Schema: aisdk.Schema{
@@ -57,6 +65,10 @@ Examples:
5765
"type": "string",
5866
"description": "The bash command to execute in the workspace.",
5967
},
68+
"background": map[string]any{
69+
"type": "boolean",
70+
"description": "Whether to run the command in the background.",
71+
},
6072
},
6173
Required: []string{"workspace", "command"},
6274
},
@@ -119,8 +131,24 @@ Examples:
119131
}
120132
defer session.Close()
121133

134+
command := args.Command
135+
if args.Background {
136+
encodedCommand := base64.StdEncoding.EncodeToString([]byte(args.Command))
137+
encodedScript := base64.StdEncoding.EncodeToString([]byte(backgroundScript))
138+
commandID, err := cryptorand.StringCharset(cryptorand.Human, 8)
139+
if err != nil {
140+
return WorkspaceBashResult{}, xerrors.Errorf("failed to generate command ID: %w", err)
141+
}
142+
command = fmt.Sprintf(
143+
"ARG_COMMAND=\"$(echo -n %s | base64 -d)\" ARG_COMMAND_ID=%s bash -c \"$(echo -n %s | base64 -d)\"",
144+
encodedCommand,
145+
commandID,
146+
encodedScript,
147+
)
148+
}
149+
122150
// Execute command and capture output
123-
output, err := session.CombinedOutput(args.Command)
151+
output, err := session.CombinedOutput(command)
124152
outputStr := strings.TrimSpace(string(output))
125153

126154
if err != nil {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
3+
# This script is used to run a command in the background.
4+
5+
set -o errexit
6+
set -o pipefail
7+
8+
set -o nounset
9+
10+
COMMAND="$ARG_COMMAND"
11+
COMMAND_ID="$ARG_COMMAND_ID"
12+
13+
set +o nounset
14+
15+
LOG_DIR="/tmp/mcp-bg"
16+
LOG_PATH="$LOG_DIR/$COMMAND_ID.log"
17+
mkdir -p "$LOG_DIR"
18+
19+
nohup bash -c "$COMMAND" > "$LOG_PATH" 2>&1 &
20+
COMMAND_PID="$!"
21+
22+
echo "Command started with PID: $COMMAND_PID"
23+
echo "Log path: $LOG_PATH"

0 commit comments

Comments
 (0)