fix: small improvements around command execution

Carlos Alexandro Becker created

Change summary

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(-)

Detailed changes

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 {

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
 		}

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 {

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),