mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-12 04:54:27 +00:00
perf(lsp): emit workspace-relative paths in definition/references
lsp_query printed absolute paths from URIToFile (e.g. the full /Users/.../internal/... prefix repeated per result) while file_search and the AST summary already relativize. On a find_references across many files that ~60-char root prefix repeats per file group — wasted tokens for the LLM consumer. Extract a Server.relPath helper (dedups the AST summary's inline block) and apply it to definition and references display paths; the absolute path is kept where the file is actually re-read for previews. Adds a relPath unit test (in-workspace relativized, out-of-workspace unchanged).
This commit is contained in:
@@ -213,6 +213,20 @@ func TestASTQuerySkipsDependencyDirs(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestRelPath verifies workspace-relative display paths (token saving) with a
|
||||
// safe fallback to the original path for anything outside the root.
|
||||
func TestRelPath(t *testing.T) {
|
||||
srv, tmpDir := newFeaturesServer(t)
|
||||
if got := srv.relPath(filepath.Join(tmpDir, "pkg", "a.go")); got != filepath.Join("pkg", "a.go") {
|
||||
t.Errorf("in-workspace path should be relativized, got %q", got)
|
||||
}
|
||||
// Outside the workspace root → returned unchanged (never a ../ escape string).
|
||||
outside := "/definitely/outside/x.go"
|
||||
if got := srv.relPath(outside); got != outside {
|
||||
t.Errorf("out-of-workspace path should be returned as-is, got %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- Feature 3 (ast_query): pagination cursor ----
|
||||
|
||||
// TestASTQueryFirstPageCursor is a strict regression guard: page 1 must emit a
|
||||
|
||||
@@ -263,15 +263,7 @@ func (s *Server) generateASTSummary(ctx context.Context, path string, content []
|
||||
|
||||
var sb strings.Builder
|
||||
|
||||
// Get relative path
|
||||
relPath := path
|
||||
if absPath, err := filepath.Abs(path); err == nil {
|
||||
if rel, err := filepath.Rel(s.cfg.WorkspaceRoot, absPath); err == nil && !strings.HasPrefix(rel, "..") {
|
||||
relPath = rel
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(&sb, "**%s** (%d lines, %s)\n\n", relPath, countLines(content), lang)
|
||||
fmt.Fprintf(&sb, "**%s** (%d lines, %s)\n\n", s.relPath(path), countLines(content), lang)
|
||||
sb.WriteString("Symbols:\n")
|
||||
|
||||
for _, sym := range symbols {
|
||||
@@ -282,6 +274,18 @@ func (s *Server) generateASTSummary(ctx context.Context, path string, content []
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
// relPath renders path relative to the workspace root for display, saving the
|
||||
// tokens an absolute path would cost. Falls back to the original path when it
|
||||
// can't be relativized (outside the root, or on error).
|
||||
func (s *Server) relPath(path string) string {
|
||||
if absPath, err := filepath.Abs(path); err == nil {
|
||||
if rel, err := filepath.Rel(s.cfg.WorkspaceRoot, absPath); err == nil && !strings.HasPrefix(rel, "..") {
|
||||
return rel
|
||||
}
|
||||
}
|
||||
return path
|
||||
}
|
||||
|
||||
// symbolKindIcon returns an icon/prefix for a symbol kind.
|
||||
func symbolKindIcon(kind protocol.SymbolKind) string {
|
||||
switch kind {
|
||||
|
||||
@@ -181,7 +181,7 @@ func (s *Server) lspDefinition(ctx context.Context, file string, line, col int,
|
||||
|
||||
for _, loc := range locations {
|
||||
filePath := lsp.URIToFile(loc.URI)
|
||||
fmt.Fprintf(&output, "**%s:%d:%d**\n", filePath, loc.Range.Start.Line+1, loc.Range.Start.Character+1)
|
||||
fmt.Fprintf(&output, "**%s:%d:%d**\n", s.relPath(filePath), loc.Range.Start.Line+1, loc.Range.Start.Character+1)
|
||||
|
||||
preview := s.readFilePreview(filePath, loc.Range.Start.Line+1, 3)
|
||||
if preview != "" {
|
||||
@@ -210,7 +210,9 @@ func (s *Server) lspReferences(ctx context.Context, file string, line, col int,
|
||||
fileGroups := make(map[string][]lsp.Location)
|
||||
fileOrder := make([]string, 0)
|
||||
for _, loc := range locations {
|
||||
filePath := lsp.URIToFile(loc.URI)
|
||||
// Relativize for display; references are not re-read so the absolute
|
||||
// path isn't needed downstream.
|
||||
filePath := s.relPath(lsp.URIToFile(loc.URI))
|
||||
if _, seen := fileGroups[filePath]; !seen {
|
||||
fileOrder = append(fileOrder, filePath)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user