Repository: charmbracelet/crush

Issue:
LSP/MCP command paths don't resolve ~
### Describe the bug

The binary name in the LSP/MCP blocks don't resolve `~ `to `os.UserHomeDir` if I have a binary that isn't in my $PATH (i.e. mason install share)

### To Reproduce

Steps to reproduce the behavior:
1. set .crush.json or ~/.config/crush/crush.json to use a binary by ~
2. binary fails to run, as it tries to find a file with a literal ~ in the name

Hints from issue comments:
@meowgorithm: Solid DX issue. Will fix.@taigrr: I can do it the same way I did for #140 ?@caarlos0: is this still a problem? I seem to remember this was fixed... @caarlos0: I was remembering it wrong- https://github.com/charmbracelet/crush/pull/1105

Solution patch:
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 7c477b58..c0da1c50 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -67,8 +67,12 @@ builds:
         goarch: arm
       - goos: android
         goarch: "386"
+      - goos: windows
+        goarch: arm
     ldflags:
       - -s -w -X github.com/charmbracelet/crush/internal/version.Version={{.Version}}
+    flags:
+      - -trimpath
 
 archives:
   - name_template: >-
diff --git a/internal/config/load.go b/internal/config/load.go
index 9ac5411f..500fc236 100644
--- a/internal/config/load.go
+++ b/internal/config/load.go
@@ -41,13 +41,8 @@ func LoadReader(fd io.Reader) (*Config, error) {
 
 // Load loads the configuration from the default paths.
 func Load(workingDir, dataDir string, debug bool) (*Config, error) {
-	// uses default config paths
-	configPaths := []string{
-		globalConfig(),
-		GlobalConfigData(),
-		filepath.Join(workingDir, fmt.Sprintf("%s.json", appName)),
-		filepath.Join(workingDir, fmt.Sprintf(".%s.json", appName)),
-	}
+	configPaths := lookupConfigs(workingDir)
+
 	cfg, err := loadFromConfigPaths(configPaths)
 	if err != nil {
 		return nil, fmt.Errorf("failed to load config from paths %v: %w", configPaths, err)
@@ -316,7 +311,7 @@ func (c *Config) setDefaults(workingDir, dataDir string) {
 	if dataDir != "" {
 		c.Options.DataDirectory = dataDir
 	} else if c.Options.DataDirectory == "" {
-		if path, ok := fsext.SearchParent(workingDir, defaultDataDirectory); ok {
+		if path, ok := fsext.LookupClosest(workingDir, defaultDataDirectory); ok {
 			c.Options.DataDirectory = path
 		} else {
 			c.Options.DataDirectory = filepath.Join(workingDir, defaultDataDirectory)
@@ -357,7 +352,7 @@ func (c *Config) applyLSPDefaults() {
 	// Apply defaults to each LSP configuration
 	for name, cfg := range c.LSP {
 		// Try to get defaults from powernap based on command name
-		base, ok := configManager.GetServer(cfg.Command)
+		base, ok := configManager.GetServer(name)
 		if !ok {
 			continue
 		}
@@ -514,6 +509,28 @@ func (c *Config) configureSelectedModels(knownProviders []catwalk.Provider) erro
 	return nil
 }
 
+// lookupConfigs searches config files recursively from CWD up to FS root
+func lookupConfigs(cwd string) []string {
+	// prepend default config paths
+	configPaths := []string{
+		globalConfig(),
+		GlobalConfigData(),
+	}
+
+	configNames := []string{appName + ".json", "." + appName + ".json"}
+
+	foundConfigs, err := fsext.Lookup(cwd, configNames...)
+	if err != nil {
+		// returns at least default configs
+		return configPaths
+	}
+
+	// reverse order so last config has more priority
+	slices.Reverse(foundConfigs)
+
+	return append(configPaths, foundConfigs...)
+}
+
 func loadFromConfigPaths(configPaths []string) (*Config, error) {
 	var configs []io.Reader
 
diff --git a/internal/fsext/lookup.go b/internal/fsext/lookup.go
new file mode 100644
index 00000000..09842657
--- /dev/null
+++ b/internal/fsext/lookup.go
@@ -0,0 +1,141 @@
+package fsext
+
+import (
+	"errors"
+	"fmt"
+	"os"
+	"path/filepath"
+
+	"github.com/charmbracelet/crush/internal/home"
+)
+
+// Lookup searches for a target files or directories starting from dir
+// and walking up the directory tree until filesystem root is reached.
+// It also checks the ownership of files to ensure that the search does
+// not cross ownership boundaries. It skips ownership mismatches without
+// errors.
+// Returns full paths to fount targets.
+// The search includes the starting directory itself.
+func Lookup(dir string, targets ...string) ([]string, error) {
+	if len(targets) == 0 {
+		return nil, nil
+	}
+
+	var found []string
+
+	err := traverseUp(dir, func(cwd string, owner int) error {
+		for _, target := range targets {
+			fpath := filepath.Join(cwd, target)
+			err := probeEnt(fpath, owner)
+
+			// skip to the next file on permission denied
+			if errors.Is(err, os.ErrNotExist) ||
+				errors.Is(err, os.ErrPermission) {
+				continue
+			}
+
+			if err != nil {
+				return fmt.Errorf("error probing file %s: %w", fpath, err)
+			}
+
+			found = append(found, fpath)
+		}
+
+		return nil
+	})
+	if err != nil {
+		return nil, err
+	}
+
+	return found, nil
+}
+
+// LookupClosest searches for a target file or directory starting from dir
+// and walking up the directory tree until found or root or home is reached.
+// It also checks the ownership of files to ensure that the search does
+// not cross ownership boundaries.
+// Returns the full path to the target if found, empty string and false otherwise.
+// The search includes the starting directory itself.
+func LookupClosest(dir, target string) (string, bool) {
+	var found string
+
+	err := traverseUp(dir, func(cwd string, owner int) error {
+		fpath := filepath.Join(cwd, target)
+
+		err := probeEnt(fpath, owner)
+		if errors.Is(err, os.ErrNotExist) {
+			return nil
+		}
+
+		if err != nil {
+			return fmt.Errorf("error probing file %s: %w", fpath, err)
+		}
+
+		if cwd == home.Dir() {
+			return filepath.SkipAll
+		}
+
+		found = fpath
+		return filepath.SkipAll
+	})
+
+	return found, err == nil && found != ""
+}
+
+// traverseUp walks up from given directory up until filesystem root reached.
+// It passes absolute path of current directory and staring directory owner ID
+// to callback function. It is up to user to check ownership.
+func traverseUp(dir string, walkFn func(dir string, owner int) error) error {
+	cwd, err := filepath.Abs(dir)
+	if err != nil {
+		return fmt.Errorf("cannot convert CWD to absolute path: %w", err)
+	}
+
+	owner, err := Owner(dir)
+	if err != nil {
+		return fmt.Errorf("cannot get ownership: %w", err)
+	}
+
+	for {
+		err := walkFn(cwd, owner)
+		if err == nil || errors.Is(err, filepath.SkipDir) {
+			parent := filepath.Dir(cwd)
+			if parent == cwd {
+				return nil
+			}
+
+			cwd = parent
+			continue
+		}
+
+		if errors.Is(err, filepath.SkipAll) {
+			return nil
+		}
+
+		return err
+	}
+}
+
+// probeEnt checks if entity at given path exists and belongs to given owner
+func probeEnt(fspath string, owner int) error {
+	_, err := os.Stat(fspath)
+	if err != nil {
+		return fmt.Errorf("cannot stat %s: %w", fspath, err)
+	}
+
+	// special case for ownership check bypass
+	if owner == -1 {
+		return nil
+	}
+
+	fowner, err := Owner(fspath)
+	if err != nil {
+		return fmt.Errorf("cannot get ownership for %s: %w", fspath, err)
+	}
+
+	if fowner != owner {
+		return os.ErrPermission
+	}
+
+	return nil
+}
diff --git a/internal/fsext/owner_windows.go b/internal/fsext/owner_windows.go
index 107cda00..41f9091c 100644
--- a/internal/fsext/owner_windows.go
+++ b/internal/fsext/owner_windows.go
@@ -2,8 +2,14 @@
 
 package fsext
 
+import "os"
+
 // Owner retrieves the user ID of the owner of the file or directory at the
 // specified path.
 func Owner(path string) (int, error) {
+	_, err := os.Stat(path)
+	if err != nil {
+		return 0, err
+	}
 	return -1, nil
 }
diff --git a/internal/fsext/parent.go b/internal/fsext/parent.go
deleted file mode 100644
index bd319361..00000000
--- a/internal/fsext/parent.go
+++ /dev/null
@@ -1,60 +0,0 @@
-package fsext
-
-import (
-	"errors"
-	"os"
-	"path/filepath"
-
-	"github.com/charmbracelet/crush/internal/home"
-)
-
-// SearchParent searches for a target file or directory starting from dir
-// and walking up the directory tree until found or root or home is reached.
-// It also checks the ownership of directories to ensure that the search does
-// not cross ownership boundaries.
-// Returns the full path to the target if found, empty string and false otherwise.
-// The search includes the starting directory itself.
-func SearchParent(dir, target string) (string, bool) {
-	absDir, err := filepath.Abs(dir)
-	if err != nil {
-		return "", false
-	}
-
-	path := filepath.Join(absDir, target)
-	if _, err := os.Stat(path); err == nil {
-		return path, true
-	} else if !errors.Is(err, os.ErrNotExist) {
-		return "", false
-	}
-
-	previousParent := absDir
-	previousOwner, err := Owner(previousParent)
-	if err != nil {
-		return "", false
-	}
-
-	for {
-		parent := filepath.Dir(previousParent)
-		if parent == previousParent || parent == home.Dir() {
-			return "", false
-		}
-
-		parentOwner, err := Owner(parent)
-		if err != nil {
-			return "", false
-		}
-		if parentOwner != previousOwner {
-			return "", false
-		}
-
-		path := filepath.Join(parent, target)
-		if _, err := os.Stat(path); err == nil {
-			return path, true
-		} else if !errors.Is(err, os.ErrNotExist) {
-			return "", false
-		}
-
-		previousParent = parent
-		previousOwner = parentOwner
-	}
-}
diff --git a/internal/llm/agent/mcp-tools.go b/internal/llm/agent/mcp-tools.go
index 90011c43..67d46b54 100644
--- a/internal/llm/agent/mcp-tools.go
+++ b/internal/llm/agent/mcp-tools.go
@@ -15,6 +15,7 @@ import (
 
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/csync"
+	"github.com/charmbracelet/crush/internal/home"
 	"github.com/charmbracelet/crush/internal/llm/tools"
 	"github.com/charmbracelet/crush/internal/permission"
 	"github.com/charmbracelet/crush/internal/pubsub"
@@ -360,7 +361,7 @@ func createMcpClient(name string, m config.MCPConfig) (*client.Client, error) {
 			return nil, fmt.Errorf("mcp stdio config requires a non-empty 'command' field")
 		}
 		return client.NewStdioMCPClientWithOptions(
-			m.Command,
+			home.Long(m.Command),
 			m.ResolvedEnv(),
 			m.Args,
 			transport.WithCommandLogger(mcpLogger{name: name}),
diff --git a/internal/lsp/client.go b/internal/lsp/client.go
index 70146d3a..aedf2476 100644
--- a/internal/lsp/client.go
+++ b/internal/lsp/client.go
@@ -15,6 +15,7 @@ import (
 	"github.com/charmbracelet/crush/internal/config"
 	"github.com/charmbracelet/crush/internal/csync"
 	"github.com/charmbracelet/crush/internal/fsext"
+	"github.com/charmbracelet/crush/internal/home"
 	powernap "github.com/charmbracelet/x/powernap/pkg/lsp"
 	"github.com/charmbracelet/x/powernap/pkg/lsp/protocol"
 	"github.com/charmbracelet/x/powernap/pkg/transport"
@@ -55,7 +56,7 @@ func New(ctx context.Context, name string, config config.LSPConfig) (*Client, er
 
 	// Create powernap client config
 	clientConfig := powernap.ClientConfig{
-		Command: config.Command,
+		Command: home.Long(config.Command),
 		Args:    config.Args,
 		RootURI: rootURI,
 		Environment: func() map[string]string {



Test patch:
diff --git a/internal/fsext/lookup_test.go b/internal/fsext/lookup_test.go
new file mode 100644
index 00000000..b7604331
--- /dev/null
+++ b/internal/fsext/lookup_test.go
@@ -0,0 +1,483 @@
+package fsext
+
+import (
+	"errors"
+	"os"
+	"path/filepath"
+	"testing"
+
+	"github.com/charmbracelet/crush/internal/home"
+	"github.com/stretchr/testify/require"
+)
+
+func TestLookupClosest(t *testing.T) {
+	tempDir := t.TempDir()
+
+	// Change to temp directory
+	oldWd, _ := os.Getwd()
+	err := os.Chdir(tempDir)
+	require.NoError(t, err)
+
+	t.Cleanup(func() {
+		os.Chdir(oldWd)
+	})
+
+	t.Run("target found in starting directory", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create target file in current directory
+		targetFile := filepath.Join(testDir, "target.txt")
+		err := os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		foundPath, found := LookupClosest(testDir, "target.txt")
+		require.True(t, found)
+		require.Equal(t, targetFile, foundPath)
+	})
+
+	t.Run("target found in parent directory", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create subdirectory
+		subDir := filepath.Join(testDir, "subdir")
+		err := os.Mkdir(subDir, 0o755)
+		require.NoError(t, err)
+
+		// Create target file in parent directory
+		targetFile := filepath.Join(testDir, "target.txt")
+		err = os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		foundPath, found := LookupClosest(subDir, "target.txt")
+		require.True(t, found)
+		require.Equal(t, targetFile, foundPath)
+	})
+
+	t.Run("target found in grandparent directory", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create nested subdirectories
+		subDir := filepath.Join(testDir, "subdir")
+		err := os.Mkdir(subDir, 0o755)
+		require.NoError(t, err)
+
+		subSubDir := filepath.Join(subDir, "subsubdir")
+		err = os.Mkdir(subSubDir, 0o755)
+		require.NoError(t, err)
+
+		// Create target file in grandparent directory
+		targetFile := filepath.Join(testDir, "target.txt")
+		err = os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		foundPath, found := LookupClosest(subSubDir, "target.txt")
+		require.True(t, found)
+		require.Equal(t, targetFile, foundPath)
+	})
+
+	t.Run("target not found", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		foundPath, found := LookupClosest(testDir, "nonexistent.txt")
+		require.False(t, found)
+		require.Empty(t, foundPath)
+	})
+
+	t.Run("target directory found", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create target directory in current directory
+		targetDir := filepath.Join(testDir, "targetdir")
+		err := os.Mkdir(targetDir, 0o755)
+		require.NoError(t, err)
+
+		foundPath, found := LookupClosest(testDir, "targetdir")
+		require.True(t, found)
+		require.Equal(t, targetDir, foundPath)
+	})
+
+	t.Run("stops at home directory", func(t *testing.T) {
+		// This test is limited as we can't easily create files above home directory
+		// but we can test the behavior by searching from home directory itself
+		homeDir := home.Dir()
+
+		// Search for a file that doesn't exist from home directory
+		foundPath, found := LookupClosest(homeDir, "nonexistent_file_12345.txt")
+		require.False(t, found)
+		require.Empty(t, foundPath)
+	})
+
+	t.Run("invalid starting directory", func(t *testing.T) {
+		foundPath, found := LookupClosest("/invalid/path/that/does/not/exist", "target.txt")
+		require.False(t, found)
+		require.Empty(t, foundPath)
+	})
+
+	t.Run("relative path handling", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Change to test directory
+		oldWd, _ := os.Getwd()
+		err := os.Chdir(testDir)
+		require.NoError(t, err)
+		defer os.Chdir(oldWd)
+
+		// Create target file in current directory
+		err = os.WriteFile("target.txt", []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		// Search using relative path
+		foundPath, found := LookupClosest(".", "target.txt")
+		require.True(t, found)
+
+		// Resolve symlinks to handle macOS /private/var vs /var discrepancy
+		expectedPath, err := filepath.EvalSymlinks(filepath.Join(testDir, "target.txt"))
+		require.NoError(t, err)
+		actualPath, err := filepath.EvalSymlinks(foundPath)
+		require.NoError(t, err)
+		require.Equal(t, expectedPath, actualPath)
+	})
+}
+
+func TestLookupClosestWithOwnership(t *testing.T) {
+	// Note: Testing ownership boundaries is difficult in a cross-platform way
+	// without creating complex directory structures with different owners.
+	// This test focuses on the basic functionality when ownership checks pass.
+
+	tempDir := t.TempDir()
+
+	// Change to temp directory
+	oldWd, _ := os.Getwd()
+	err := os.Chdir(tempDir)
+	require.NoError(t, err)
+
+	t.Cleanup(func() {
+		os.Chdir(oldWd)
+	})
+
+	t.Run("search respects same ownership", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create subdirectory structure
+		subDir := filepath.Join(testDir, "subdir")
+		err := os.Mkdir(subDir, 0o755)
+		require.NoError(t, err)
+
+		// Create target file in parent directory
+		targetFile := filepath.Join(testDir, "target.txt")
+		err = os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		// Search should find the target assuming same ownership
+		foundPath, found := LookupClosest(subDir, "target.txt")
+		require.True(t, found)
+		require.Equal(t, targetFile, foundPath)
+	})
+}
+
+func TestLookup(t *testing.T) {
+	tempDir := t.TempDir()
+
+	// Change to temp directory
+	oldWd, _ := os.Getwd()
+	err := os.Chdir(tempDir)
+	require.NoError(t, err)
+
+	t.Cleanup(func() {
+		os.Chdir(oldWd)
+	})
+
+	t.Run("no targets returns empty slice", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		found, err := Lookup(testDir)
+		require.NoError(t, err)
+		require.Empty(t, found)
+	})
+
+	t.Run("single target found in starting directory", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create target file in current directory
+		targetFile := filepath.Join(testDir, "target.txt")
+		err := os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		found, err := Lookup(testDir, "target.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 1)
+		require.Equal(t, targetFile, found[0])
+	})
+
+	t.Run("multiple targets found in starting directory", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create multiple target files in current directory
+		targetFile1 := filepath.Join(testDir, "target1.txt")
+		targetFile2 := filepath.Join(testDir, "target2.txt")
+		targetFile3 := filepath.Join(testDir, "target3.txt")
+
+		err := os.WriteFile(targetFile1, []byte("test1"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile2, []byte("test2"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile3, []byte("test3"), 0o644)
+		require.NoError(t, err)
+
+		found, err := Lookup(testDir, "target1.txt", "target2.txt", "target3.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 3)
+		require.Contains(t, found, targetFile1)
+		require.Contains(t, found, targetFile2)
+		require.Contains(t, found, targetFile3)
+	})
+
+	t.Run("targets found in parent directories", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create subdirectory
+		subDir := filepath.Join(testDir, "subdir")
+		err := os.Mkdir(subDir, 0o755)
+		require.NoError(t, err)
+
+		// Create target files in parent directory
+		targetFile1 := filepath.Join(testDir, "target1.txt")
+		targetFile2 := filepath.Join(testDir, "target2.txt")
+		err = os.WriteFile(targetFile1, []byte("test1"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile2, []byte("test2"), 0o644)
+		require.NoError(t, err)
+
+		found, err := Lookup(subDir, "target1.txt", "target2.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 2)
+		require.Contains(t, found, targetFile1)
+		require.Contains(t, found, targetFile2)
+	})
+
+	t.Run("targets found across multiple directory levels", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create nested subdirectories
+		subDir := filepath.Join(testDir, "subdir")
+		err := os.Mkdir(subDir, 0o755)
+		require.NoError(t, err)
+
+		subSubDir := filepath.Join(subDir, "subsubdir")
+		err = os.Mkdir(subSubDir, 0o755)
+		require.NoError(t, err)
+
+		// Create target files at different levels
+		targetFile1 := filepath.Join(testDir, "target1.txt")
+		targetFile2 := filepath.Join(subDir, "target2.txt")
+		targetFile3 := filepath.Join(subSubDir, "target3.txt")
+
+		err = os.WriteFile(targetFile1, []byte("test1"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile2, []byte("test2"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile3, []byte("test3"), 0o644)
+		require.NoError(t, err)
+
+		found, err := Lookup(subSubDir, "target1.txt", "target2.txt", "target3.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 3)
+		require.Contains(t, found, targetFile1)
+		require.Contains(t, found, targetFile2)
+		require.Contains(t, found, targetFile3)
+	})
+
+	t.Run("some targets not found", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create only some target files
+		targetFile1 := filepath.Join(testDir, "target1.txt")
+		targetFile2 := filepath.Join(testDir, "target2.txt")
+
+		err := os.WriteFile(targetFile1, []byte("test1"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile(targetFile2, []byte("test2"), 0o644)
+		require.NoError(t, err)
+
+		// Search for existing and non-existing targets
+		found, err := Lookup(testDir, "target1.txt", "nonexistent.txt", "target2.txt", "another_nonexistent.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 2)
+		require.Contains(t, found, targetFile1)
+		require.Contains(t, found, targetFile2)
+	})
+
+	t.Run("no targets found", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		found, err := Lookup(testDir, "nonexistent1.txt", "nonexistent2.txt", "nonexistent3.txt")
+		require.NoError(t, err)
+		require.Empty(t, found)
+	})
+
+	t.Run("target directories found", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create target directories
+		targetDir1 := filepath.Join(testDir, "targetdir1")
+		targetDir2 := filepath.Join(testDir, "targetdir2")
+		err := os.Mkdir(targetDir1, 0o755)
+		require.NoError(t, err)
+		err = os.Mkdir(targetDir2, 0o755)
+		require.NoError(t, err)
+
+		found, err := Lookup(testDir, "targetdir1", "targetdir2")
+		require.NoError(t, err)
+		require.Len(t, found, 2)
+		require.Contains(t, found, targetDir1)
+		require.Contains(t, found, targetDir2)
+	})
+
+	t.Run("mixed files and directories", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Create target files and directories
+		targetFile := filepath.Join(testDir, "target.txt")
+		targetDir := filepath.Join(testDir, "targetdir")
+		err := os.WriteFile(targetFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+		err = os.Mkdir(targetDir, 0o755)
+		require.NoError(t, err)
+
+		found, err := Lookup(testDir, "target.txt", "targetdir")
+		require.NoError(t, err)
+		require.Len(t, found, 2)
+		require.Contains(t, found, targetFile)
+		require.Contains(t, found, targetDir)
+	})
+
+	t.Run("invalid starting directory", func(t *testing.T) {
+		found, err := Lookup("/invalid/path/that/does/not/exist", "target.txt")
+		require.Error(t, err)
+		require.Empty(t, found)
+	})
+
+	t.Run("relative path handling", func(t *testing.T) {
+		testDir := t.TempDir()
+
+		// Change to test directory
+		oldWd, _ := os.Getwd()
+		err := os.Chdir(testDir)
+		require.NoError(t, err)
+
+		t.Cleanup(func() {
+			os.Chdir(oldWd)
+		})
+
+		// Create target files in current directory
+		err = os.WriteFile("target1.txt", []byte("test1"), 0o644)
+		require.NoError(t, err)
+		err = os.WriteFile("target2.txt", []byte("test2"), 0o644)
+		require.NoError(t, err)
+
+		// Search using relative path
+		found, err := Lookup(".", "target1.txt", "target2.txt")
+		require.NoError(t, err)
+		require.Len(t, found, 2)
+
+		// Resolve symlinks to handle macOS /private/var vs /var discrepancy
+		expectedPath1, err := filepath.EvalSymlinks(filepath.Join(testDir, "target1.txt"))
+		require.NoError(t, err)
+		expectedPath2, err := filepath.EvalSymlinks(filepath.Join(testDir, "target2.txt"))
+		require.NoError(t, err)
+
+		// Check that found paths match expected paths (order may vary)
+		foundEvalSymlinks := make([]string, len(found))
+		for i, path := range found {
+			evalPath, err := filepath.EvalSymlinks(path)
+			require.NoError(t, err)
+			foundEvalSymlinks[i] = evalPath
+		}
+
+		require.Contains(t, foundEvalSymlinks, expectedPath1)
+		require.Contains(t, foundEvalSymlinks, expectedPath2)
+	})
+}
+
+func TestProbeEnt(t *testing.T) {
+	t.Run("existing file with correct owner", func(t *testing.T) {
+		tempDir := t.TempDir()
+
+		// Create test file
+		testFile := filepath.Join(tempDir, "test.txt")
+		err := os.WriteFile(testFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		// Get owner of temp directory
+		owner, err := Owner(tempDir)
+		require.NoError(t, err)
+
+		// Test probeEnt with correct owner
+		err = probeEnt(testFile, owner)
+		require.NoError(t, err)
+	})
+
+	t.Run("existing directory with correct owner", func(t *testing.T) {
+		tempDir := t.TempDir()
+
+		// Create test directory
+		testDir := filepath.Join(tempDir, "testdir")
+		err := os.Mkdir(testDir, 0o755)
+		require.NoError(t, err)
+
+		// Get owner of temp directory
+		owner, err := Owner(tempDir)
+		require.NoError(t, err)
+
+		// Test probeEnt with correct owner
+		err = probeEnt(testDir, owner)
+		require.NoError(t, err)
+	})
+
+	t.Run("nonexistent file", func(t *testing.T) {
+		tempDir := t.TempDir()
+
+		nonexistentFile := filepath.Join(tempDir, "nonexistent.txt")
+		owner, err := Owner(tempDir)
+		require.NoError(t, err)
+
+		err = probeEnt(nonexistentFile, owner)
+		require.Error(t, err)
+		require.True(t, errors.Is(err, os.ErrNotExist))
+	})
+
+	t.Run("nonexistent file in nonexistent directory", func(t *testing.T) {
+		nonexistentFile := "/this/directory/does/not/exists/nonexistent.txt"
+
+		err := probeEnt(nonexistentFile, -1)
+		require.Error(t, err)
+		require.True(t, errors.Is(err, os.ErrNotExist))
+	})
+
+	t.Run("ownership bypass with -1", func(t *testing.T) {
+		tempDir := t.TempDir()
+
+		// Create test file
+		testFile := filepath.Join(tempDir, "test.txt")
+		err := os.WriteFile(testFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		// Test probeEnt with -1 (bypass ownership check)
+		err = probeEnt(testFile, -1)
+		require.NoError(t, err)
+	})
+
+	t.Run("ownership mismatch returns permission error", func(t *testing.T) {
+		tempDir := t.TempDir()
+
+		// Create test file
+		testFile := filepath.Join(tempDir, "test.txt")
+		err := os.WriteFile(testFile, []byte("test"), 0o644)
+		require.NoError(t, err)
+
+		// Test probeEnt with different owner (use 9999 which is unlikely to be the actual owner)
+		err = probeEnt(testFile, 9999)
+		require.Error(t, err)
+		require.True(t, errors.Is(err, os.ErrPermission))
+	})
+}