@@ -34,6 +34,9 @@ type Client struct {
3434 client *powernap.Client
3535 name string
3636
37+ // Working directory this LSP is scoped to.
38+ workDir string
39+
3740 // File types this LSP server handles (e.g., .go, .rs, .py)
3841 fileTypes []string
3942
@@ -133,6 +136,7 @@ func (c *Client) createPowernapClient() error {
133136 }
134137
135138 rootURI := string(protocol.URIFromPath(workDir))
139+ c.workDir = workDir
136140
137141 command, err := c.resolver.ResolveValue(c.config.Command)
138142 if err != nil {
@@ -305,9 +309,22 @@ type OpenFileInfo struct {
305309 URI protocol.DocumentURI
306310}
307311
308−// HandlesFile checks if this LSP client handles the given file based on its extension.
312+// HandlesFile checks if this LSP client handles the given file based on its
313+// extension and whether it's within the working directory.
309314func (c *Client) HandlesFile(path string) bool {
310− // If no file types are specified, handle all files (backward compatibility)
315+ // Check if file is within working directory.
316+ absPath, err := filepath.Abs(path)
317+ if err != nil {
318+ slog.Debug("cannot resolve path", "name", c.name, "file", path, "error", err)
319+ return false
320+ }
321+ relPath, err := filepath.Rel(c.workDir, absPath)
322+ if err != nil || strings.HasPrefix(relPath, "..") {
323+ slog.Debug("file outside workspace", "name", c.name, "file", path, "workDir", c.workDir)
324+ return false
325+ }
326+
327+ // If no file types are specified, handle all files (backward compatibility).
311328 if len(c.fileTypes) == 0 {
312329 return true
313330 }