@@ -2,6 +2,8 @@ package toolsdk
2
2
3
3
import (
4
4
"context"
5
+ _ "embed"
6
+ "encoding/base64"
5
7
"errors"
6
8
"fmt"
7
9
"io"
@@ -15,18 +17,23 @@ import (
15
17
"github.com/coder/coder/v2/cli/cliui"
16
18
"github.com/coder/coder/v2/codersdk"
17
19
"github.com/coder/coder/v2/codersdk/workspacesdk"
20
+ "github.com/coder/coder/v2/cryptorand"
18
21
)
19
22
20
23
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"`
23
27
}
24
28
25
29
type WorkspaceBashResult struct {
26
30
Output string `json:"output"`
27
31
ExitCode int `json:"exit_code"`
28
32
}
29
33
34
+ //go:embed resources/background.sh
35
+ var backgroundScript string
36
+
30
37
var WorkspaceBash = Tool [WorkspaceBashArgs , WorkspaceBashResult ]{
31
38
Tool : aisdk.Tool {
32
39
Name : ToolNameWorkspaceBash ,
@@ -45,6 +52,7 @@ The workspace parameter supports various formats:
45
52
46
53
Examples:
47
54
- workspace: "my-workspace", command: "ls -la"
55
+ - workspace: "my-workspace", command: "npm run dev", background: true
48
56
- workspace: "john/dev-env", command: "git status"
49
57
- workspace: "my-workspace.main", command: "docker ps"` ,
50
58
Schema : aisdk.Schema {
@@ -57,6 +65,10 @@ Examples:
57
65
"type" : "string" ,
58
66
"description" : "The bash command to execute in the workspace." ,
59
67
},
68
+ "background" : map [string ]any {
69
+ "type" : "boolean" ,
70
+ "description" : "Whether to run the command in the background." ,
71
+ },
60
72
},
61
73
Required : []string {"workspace" , "command" },
62
74
},
@@ -119,8 +131,24 @@ Examples:
119
131
}
120
132
defer session .Close ()
121
133
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
+
122
150
// Execute command and capture output
123
- output , err := session .CombinedOutput (args . Command )
151
+ output , err := session .CombinedOutput (command )
124
152
outputStr := strings .TrimSpace (string (output ))
125
153
126
154
if err != nil {
0 commit comments