From 1ad34859239311c5b9d0cd7f193cfae9d230b099 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Fri, 20 Jun 2025 10:07:22 -0300 Subject: [PATCH] fix: small improvements around command execution --- internal/fsext/fileutil.go | 20 +++++++++++++++----- internal/llm/tools/glob.go | 2 +- internal/llm/tools/grep.go | 14 +++----------- internal/llm/tools/shell/shell.go | 18 ++++++------------ 4 files changed, 25 insertions(+), 29 deletions(-) diff --git a/internal/fsext/fileutil.go b/internal/fsext/fileutil.go index a401e014ad3b85b91a6cdf1e0c3fa7f1b9420f74..8230e3a3c2f965bef22131678b146173d81935a1 100644 --- a/internal/fsext/fileutil.go +++ b/internal/fsext/fileutil.go @@ -25,12 +25,10 @@ func init() { rgPath, err = exec.LookPath("rg") if err != nil { logging.Warn("Ripgrep (rg) not found in $PATH. Some features might be limited or slower.") - rgPath = "" } fzfPath, err = exec.LookPath("fzf") if err != nil { logging.Warn("FZF not found in $PATH. Some features might be limited or slower.") - fzfPath = "" } } @@ -49,9 +47,21 @@ func GetRgCmd(globPattern string) *exec.Cmd { } rgArgs = append(rgArgs, "--glob", globPattern) } - cmd := exec.Command(rgPath, rgArgs...) - cmd.Dir = "." - return cmd + return exec.Command(rgPath, rgArgs...) +} + +func GetRgSearchCmd(pattern, path, include string) *exec.Cmd { + if rgPath == "" { + return nil + } + // Use -n to show line numbers and include the matched line + args := []string{"-n", pattern} + if include != "" { + args = append(args, "--glob", include) + } + args = append(args, path) + + return exec.Command("rg", args...) } type FileInfo struct { diff --git a/internal/llm/tools/glob.go b/internal/llm/tools/glob.go index f01620b38304a9bf3bce52a6941f8f6bf639d827..3a0adf0581b3ba75f4bd86e337ab355323a4f3e5 100644 --- a/internal/llm/tools/glob.go +++ b/internal/llm/tools/glob.go @@ -150,7 +150,7 @@ func runRipgrep(cmd *exec.Cmd, searchRoot string, limit int) ([]string, error) { } var matches []string - for _, p := range bytes.Split(out, []byte{0}) { + for p := range bytes.SplitSeq(out, []byte{0}) { if len(p) == 0 { continue } diff --git a/internal/llm/tools/grep.go b/internal/llm/tools/grep.go index b02e77469f164f2b2706272bc60e6a7d6869e608..b004e47fe5f13caa7bc22be304fd074b19658471 100644 --- a/internal/llm/tools/grep.go +++ b/internal/llm/tools/grep.go @@ -257,19 +257,11 @@ func searchFiles(pattern, rootPath, include string, limit int) ([]grepMatch, boo } func searchWithRipgrep(pattern, path, include string) ([]grepMatch, error) { - _, err := exec.LookPath("rg") - if err != nil { - return nil, fmt.Errorf("ripgrep not found: %w", err) - } - - // Use -n to show line numbers and include the matched line - args := []string{"-n", pattern} - if include != "" { - args = append(args, "--glob", include) + cmd := fsext.GetRgSearchCmd(pattern, path, include) + if cmd == nil { + return nil, fmt.Errorf("ripgrep not found in $PATH") } - args = append(args, path) - cmd := exec.Command("rg", args...) output, err := cmd.Output() if err != nil { if exitErr, ok := err.(*exec.ExitError); ok && exitErr.ExitCode() == 1 { diff --git a/internal/llm/tools/shell/shell.go b/internal/llm/tools/shell/shell.go index 6c94904c9584c8d1500130196fef10cad202620d..38c3021a89a33579f97ea2610a824ba0f5b40dfb 100644 --- a/internal/llm/tools/shell/shell.go +++ b/internal/llm/tools/shell/shell.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "io" "os" "os/exec" "path/filepath" @@ -17,7 +18,7 @@ import ( type PersistentShell struct { cmd *exec.Cmd - stdin *os.File + stdin io.WriteCloser isAlive bool cwd string mu sync.Mutex @@ -39,22 +40,15 @@ type commandResult struct { err error } -var ( - shellInstance *PersistentShell - shellInstanceOnce sync.Once -) +var shellInstance *PersistentShell func GetPersistentShell(workingDir string) *PersistentShell { - shellInstanceOnce.Do(func() { - shellInstance = newPersistentShell(workingDir) - }) - if shellInstance == nil { shellInstance = newPersistentShell(workingDir) - } else if !shellInstance.isAlive { + } + if !shellInstance.isAlive { shellInstance = newPersistentShell(shellInstance.cwd) } - return shellInstance } @@ -100,7 +94,7 @@ func newPersistentShell(cwd string) *PersistentShell { shell := &PersistentShell{ cmd: cmd, - stdin: stdinPipe.(*os.File), + stdin: stdinPipe, isAlive: true, cwd: cwd, commandQueue: make(chan *commandExecution, 10),