Merge upstream/main into ralph/tool-result-refactor
Resolved conflicts: - pkg/heartbeat/service.go: merged both 'started' field and 'onHeartbeatWithTools' - pkg/tools/edit.go: use validatePath() with ToolResult return - pkg/tools/filesystem.go: fixed return values to use ToolResult - cmd/picoclaw/main.go: kept active setupCronTool, fixed toolsPkg import - pkg/tools/cron.go: fixed Execute return value handling Fixed tests for new function signatures (NewEditFileTool, NewAppendFileTool, NewExecTool) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -8,10 +8,12 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
type ExecTool struct {
|
||||
workingDir string
|
||||
timeout time.Duration
|
||||
@@ -20,14 +22,14 @@ type ExecTool struct {
|
||||
restrictToWorkspace bool
|
||||
}
|
||||
|
||||
func NewExecTool(workingDir string) *ExecTool {
|
||||
func NewExecTool(workingDir string, restrict bool) *ExecTool {
|
||||
denyPatterns := []*regexp.Regexp{
|
||||
regexp.MustCompile(`\brm\s+-[rf]{1,2}\b`),
|
||||
regexp.MustCompile(`\bdel\s+/[fq]\b`),
|
||||
regexp.MustCompile(`\brmdir\s+/s\b`),
|
||||
regexp.MustCompile(`\b(format|mkfs|diskpart)\b\s`), // Match disk wiping commands (must be followed by space/args)
|
||||
regexp.MustCompile(`\bdd\s+if=`),
|
||||
regexp.MustCompile(`>\s*/dev/sd[a-z]\b`), // Block writes to disk devices (but allow /dev/null)
|
||||
regexp.MustCompile(`>\s*/dev/sd[a-z]\b`), // Block writes to disk devices (but allow /dev/null)
|
||||
regexp.MustCompile(`\b(shutdown|reboot|poweroff)\b`),
|
||||
regexp.MustCompile(`:\(\)\s*\{.*\};\s*:`),
|
||||
}
|
||||
@@ -37,7 +39,7 @@ func NewExecTool(workingDir string) *ExecTool {
|
||||
timeout: 60 * time.Second,
|
||||
denyPatterns: denyPatterns,
|
||||
allowPatterns: nil,
|
||||
restrictToWorkspace: false,
|
||||
restrictToWorkspace: restrict,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +93,12 @@ func (t *ExecTool) Execute(ctx context.Context, args map[string]interface{}) *To
|
||||
cmdCtx, cancel := context.WithTimeout(ctx, t.timeout)
|
||||
defer cancel()
|
||||
|
||||
cmd := exec.CommandContext(cmdCtx, "sh", "-c", command)
|
||||
var cmd *exec.Cmd
|
||||
if runtime.GOOS == "windows" {
|
||||
cmd = exec.CommandContext(cmdCtx, "powershell", "-NoProfile", "-NonInteractive", "-Command", command)
|
||||
} else {
|
||||
cmd = exec.CommandContext(cmdCtx, "sh", "-c", command)
|
||||
}
|
||||
if cwd != "" {
|
||||
cmd.Dir = cwd
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user