Change summary
internal/fsext/expand.go | 29 +++++++++++++++++++++++++++++
internal/llm/tools/ls.go | 10 ++++------
2 files changed, 33 insertions(+), 6 deletions(-)
Detailed changes
@@ -0,0 +1,29 @@
+package fsext
+
+import (
+ "os"
+ "strings"
+
+ "mvdan.cc/sh/v3/expand"
+ "mvdan.cc/sh/v3/syntax"
+)
+
+// Expand is a wrapper around [expand.Literal]. It will escape the input
+// string, expand any shell symbols (such as '~') and resolve any environment
+// variables.
+func Expand(s string) (string, error) {
+ if s == "" {
+ return "", nil
+ }
+ p := syntax.NewParser()
+ word, err := p.Document(strings.NewReader(s))
+ if err != nil {
+ return "", err
+ }
+ cfg := &expand.Config{
+ Env: expand.FuncEnviron(os.Getenv),
+ ReadDir2: os.ReadDir,
+ GlobStar: true,
+ }
+ return expand.Literal(cfg, word)
+}
@@ -121,12 +121,10 @@ func (l *lsTool) Run(ctx context.Context, call ToolCall) (ToolResponse, error) {
searchPath = l.workingDir
}
- if searchPath == "~" {
- homeDir, err := os.UserHomeDir()
- if err != nil {
- return ToolResponse{}, fmt.Errorf("error resolving home directory: %w", err)
- }
- searchPath = homeDir
+ var err error
+ searchPath, err = fsext.Expand(searchPath)
+ if err != nil {
+ return ToolResponse{}, fmt.Errorf("error expanding path: %w", err)
}
if !filepath.IsAbs(searchPath) {