mirror of
https://github.com/lukaszraczylo/filepuff-mcp.git
synced 2026-10-12 04:54:27 +00:00
fixup! fixup! Add Docker usage instructions to README
This commit is contained in:
@@ -11,6 +11,17 @@ import (
|
|||||||
"github.com/mark3labs/mcp-go/mcp"
|
"github.com/mark3labs/mcp-go/mcp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// unescapeNewlines converts literal \n, \t, \" sequences to actual characters.
|
||||||
|
// This handles cases where MCP clients send double-escaped JSON strings.
|
||||||
|
func unescapeNewlines(s string) string {
|
||||||
|
// Replace common escape sequences
|
||||||
|
s = strings.ReplaceAll(s, "\\n", "\n")
|
||||||
|
s = strings.ReplaceAll(s, "\\t", "\t")
|
||||||
|
s = strings.ReplaceAll(s, "\\\"", "\"")
|
||||||
|
s = strings.ReplaceAll(s, "\\\\", "\\")
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
// handleEditPreview handles the edit_preview tool.
|
// handleEditPreview handles the edit_preview tool.
|
||||||
func (s *Server) handleEditPreview(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
func (s *Server) handleEditPreview(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
|
||||||
return s.handleEdit(ctx, request, false)
|
return s.handleEdit(ctx, request, false)
|
||||||
@@ -52,10 +63,15 @@ func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest, ap
|
|||||||
// The edit engine automatically detects whether to use AST or text mode.
|
// The edit engine automatically detects whether to use AST or text mode.
|
||||||
|
|
||||||
// Build edit request with both AST and text-mode selectors
|
// Build edit request with both AST and text-mode selectors
|
||||||
|
newContent := request.GetString("new_content", "")
|
||||||
|
|
||||||
|
// Unescape common escape sequences that may be double-encoded by MCP clients
|
||||||
|
newContent = unescapeNewlines(newContent)
|
||||||
|
|
||||||
astEdit := &edit.ASTEdit{
|
astEdit := &edit.ASTEdit{
|
||||||
File: file,
|
File: file,
|
||||||
Operation: edit.EditOperation(operation),
|
Operation: edit.EditOperation(operation),
|
||||||
NewContent: request.GetString("new_content", ""),
|
NewContent: newContent,
|
||||||
Selector: edit.ASTSelector{
|
Selector: edit.ASTSelector{
|
||||||
// AST-mode selectors
|
// AST-mode selectors
|
||||||
Kind: request.GetString("selector_kind", ""),
|
Kind: request.GetString("selector_kind", ""),
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package server
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestUnescapeNewlines(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input string
|
||||||
|
expected string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "no escapes",
|
||||||
|
input: "func test() {\n\treturn true;\n}",
|
||||||
|
expected: "func test() {\n\treturn true;\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "literal backslash n",
|
||||||
|
input: "func test() {\\n\\treturn true;\\n}",
|
||||||
|
expected: "func test() {\n\treturn true;\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "literal backslash t",
|
||||||
|
input: "func test() {\\n\\treturn true;\\n}",
|
||||||
|
expected: "func test() {\n\treturn true;\n}",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "literal quotes",
|
||||||
|
input: `func test() {\n\treturn \"true\";\n}`,
|
||||||
|
expected: "func test() {\n\treturn \"true\";\n}",
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
name: "mixed content",
|
||||||
|
input: "line1\\nline2\\tindented\\nline3",
|
||||||
|
expected: "line1\nline2\tindented\nline3",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := unescapeNewlines(tt.input)
|
||||||
|
if result != tt.expected {
|
||||||
|
t.Errorf("unescapeNewlines(%q) = %q, expected %q", tt.input, result, tt.expected)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user