mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-19 05:57:38 +00:00
V2/token optimization (#11)
* v2.0: token-optimization overhaul Additive (backward-compatible flags): - file_read: skeleton mode, strip (imports/license/block_comments), compact_line_numbers, 8-char etag with prefix-match compat - ast_query: format=verbose|compact|location, pagination cursor - file_search: cluster mode, pagination cursor - lsp_query (references): compact output Breaking (v2): - Preambles removed; opt-in verbose=true restores - edit_apply: response=count|diff|none, default count - ping tool removed - symbol_at/find_definition/find_references merged into lsp_query - Tool descriptions trimmed -83%, help moved to filepuff://help/<tool> - Batch file_read dedups by etag Protocol: - ResourceLink returned for file_read >64 KiB (force_inline override) - OnAfterInitialize hook reads capabilities.experimental.filepuff for session defaults (default_format, default_max_results, default_cluster, compact_refs, line_numbers, resource_link_threshold) * fix: drop --max-total-count from ripgrep args The flag does not exist in stable ripgrep (confirmed up to 15.1.0 -- "unrecognized flag --max-total-count, similar flags that are available: --max-count"). Every file_search call failed on hosts with stock rg. --max-count is per-file, not a drop-in replacement, so rely on the in-process truncation in parseOutput that was already the documented safety net.
This commit is contained in:
@@ -4,12 +4,10 @@ package server
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/lukaszraczylo/mcp-filepuff/internal/edit"
|
||||
"github.com/lukaszraczylo/mcp-filepuff/pkg/errors"
|
||||
"github.com/lukaszraczylo/mcp-filepuff/pkg/protocol"
|
||||
"github.com/mark3labs/mcp-go/mcp"
|
||||
)
|
||||
|
||||
@@ -82,27 +80,56 @@ func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest) (*
|
||||
return mcp.NewToolResultError(result.Error), nil
|
||||
}
|
||||
|
||||
// compact_response: return just the modified symbol instead of the full diff
|
||||
if request.GetBool("compact_response", false) && selectorName != "" {
|
||||
if content, readErr := os.ReadFile(file); readErr == nil {
|
||||
if start, end, found := s.resolveSymbolLines(ctx, file, content, selectorName, protocol.SymbolKind("")); found {
|
||||
lines := splitLines(string(content))
|
||||
var sb strings.Builder
|
||||
sb.WriteString(fmt.Sprintf("**Edit Applied** — %s (L%d-L%d):\n\n", selectorName, start, end))
|
||||
for i := start - 1; i < end && i < len(lines); i++ {
|
||||
sb.WriteString(fmt.Sprintf("%4d| %s\n", i+1, lines[i]))
|
||||
}
|
||||
return mcp.NewToolResultText(sb.String()), nil
|
||||
}
|
||||
}
|
||||
// fall through to diff if symbol lookup fails
|
||||
// Determine response mode.
|
||||
// compact_response is a deprecated alias for response="count".
|
||||
respMode := request.GetString("response", "count")
|
||||
if request.GetBool("compact_response", false) {
|
||||
// Deprecated: use response=count
|
||||
respMode = "count"
|
||||
}
|
||||
|
||||
var output strings.Builder
|
||||
output.WriteString("**Edit Applied Successfully**\n\n")
|
||||
output.WriteString("Diff:\n```diff\n")
|
||||
output.WriteString(result.Diff)
|
||||
output.WriteString("```\n")
|
||||
switch respMode {
|
||||
case "none":
|
||||
return mcp.NewToolResultText(""), nil
|
||||
|
||||
return mcp.NewToolResultText(output.String()), nil
|
||||
case "count":
|
||||
// Compute +added/-removed line counts from the unified diff.
|
||||
added, removed := countDiffLines(result.Diff)
|
||||
return mcp.NewToolResultText(fmt.Sprintf("+%d -%d", added, removed)), nil
|
||||
|
||||
case "diff":
|
||||
var output strings.Builder
|
||||
output.WriteString("Diff:\n```diff\n")
|
||||
output.WriteString(result.Diff)
|
||||
output.WriteString("```\n")
|
||||
return mcp.NewToolResultText(output.String()), nil
|
||||
|
||||
default:
|
||||
// Fallback: treat unknown values as "diff" for safety.
|
||||
var output strings.Builder
|
||||
output.WriteString("Diff:\n```diff\n")
|
||||
output.WriteString(result.Diff)
|
||||
output.WriteString("```\n")
|
||||
return mcp.NewToolResultText(output.String()), nil
|
||||
}
|
||||
}
|
||||
|
||||
// countDiffLines counts added (+) and removed (-) lines in a unified diff string.
|
||||
func countDiffLines(diff string) (added, removed int) {
|
||||
for _, line := range strings.Split(diff, "\n") {
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
switch line[0] {
|
||||
case '+':
|
||||
if !strings.HasPrefix(line, "+++") {
|
||||
added++
|
||||
}
|
||||
case '-':
|
||||
if !strings.HasPrefix(line, "---") {
|
||||
removed++
|
||||
}
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user