feature/recipe_implementation #5
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gmgauthier.com/grokkit/internal/grok"
|
"gmgauthier.com/grokkit/internal/grok"
|
||||||
@ -49,9 +50,8 @@ func (r *Runner) Run() error {
|
|||||||
r.handleApplyStep(refactorJSONs)
|
r.handleApplyStep(refactorJSONs)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
// Explicit trigger for read-only shell commands
|
// Explicit trigger for read-only shell
|
||||||
case strings.Contains(titleLower, "read-only shell") ||
|
case strings.Contains(titleLower, "read-only shell") || strings.Contains(titleLower, "shell read-only"):
|
||||||
strings.Contains(titleLower, "shell read-only"):
|
|
||||||
r.executeReadOnlyShell(step, previousResults)
|
r.executeReadOnlyShell(step, previousResults)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ func createUnifiedPatch(changes []FileChange, patchPath string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// executeReadOnlyShell — safe, whitelisted, read-only shell execution with user confirmation
|
// executeReadOnlyShell — now handles numbers in args (like tree -L 3)
|
||||||
func (r *Runner) executeReadOnlyShell(step Step, previousResults []string) {
|
func (r *Runner) executeReadOnlyShell(step Step, previousResults []string) {
|
||||||
prompt := fmt.Sprintf(`You need additional context from the filesystem for this step.
|
prompt := fmt.Sprintf(`You need additional context from the filesystem for this step.
|
||||||
|
|
||||||
@ -281,7 +281,7 @@ Return ONLY a JSON array of read-only commands. Example:
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"command": "tree",
|
"command": "tree",
|
||||||
"args": ["."]
|
"args": [".", "-L", 3]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -308,11 +308,11 @@ Only use safe read-only commands from the allowed list.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
jsonStr := response[start:end]
|
jsonStr := response[start:end]
|
||||||
jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"") // fix escaped quotes
|
jsonStr = strings.ReplaceAll(jsonStr, "\\\"", "\"")
|
||||||
|
|
||||||
type ShellCommand struct {
|
type ShellCommand struct {
|
||||||
Command string `json:"command"`
|
Command string `json:"command"`
|
||||||
Args []string `json:"args"`
|
Args []interface{} `json:"args"` // allows strings and numbers
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmds []ShellCommand
|
var cmds []ShellCommand
|
||||||
@ -322,9 +322,24 @@ Only use safe read-only commands from the allowed list.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, cmd := range cmds {
|
for _, cmd := range cmds {
|
||||||
|
// Build argument list, converting numbers to strings
|
||||||
|
args := make([]string, len(cmd.Args))
|
||||||
|
for i, arg := range cmd.Args {
|
||||||
|
switch v := arg.(type) {
|
||||||
|
case string:
|
||||||
|
args[i] = v
|
||||||
|
case float64:
|
||||||
|
args[i] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
|
case int, int64:
|
||||||
|
args[i] = fmt.Sprintf("%v", v)
|
||||||
|
default:
|
||||||
|
args[i] = fmt.Sprintf("%v", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fullCmd := cmd.Command
|
fullCmd := cmd.Command
|
||||||
if len(cmd.Args) > 0 {
|
if len(args) > 0 {
|
||||||
fullCmd += " " + strings.Join(cmd.Args, " ")
|
fullCmd += " " + strings.Join(args, " ")
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf(" Grok wants to run: %s\n Allow this command? [y/N] ", fullCmd)
|
fmt.Printf(" Grok wants to run: %s\n Allow this command? [y/N] ", fullCmd)
|
||||||
@ -353,7 +368,7 @@ Only use safe read-only commands from the allowed list.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run with strict cwd
|
// Run with strict cwd
|
||||||
execCmd := exec.Command(cmd.Command, cmd.Args...)
|
execCmd := exec.Command(cmd.Command, args...)
|
||||||
execCmd.Dir = r.resolveWorkDir()
|
execCmd.Dir = r.resolveWorkDir()
|
||||||
output, err := execCmd.CombinedOutput()
|
output, err := execCmd.CombinedOutput()
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user