diff --git a/README.md b/README.md index 9077757..32afdca 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ A Go-based MCP (Model Context Protocol) server for Claude Code providing intelli - **AST-Aware File Reading**: Read files with symbol extraction using Tree-sitter - **Code Pattern Matching**: Query code using patterns with capture placeholders - **LSP Integration**: Go-to-definition, find references, and symbol info via language servers -- **Safe Editing**: AST-aware file editing with syntax validation and preview +- **Safe Editing**: AST-aware file editing with syntax validation (edit_apply) - **Multi-Language Support**: Go, TypeScript, JavaScript, Python, C, C++, HTML, Vue, React - **Token Efficient**: Optimized for minimal token usage with symbols-only mode and output limiting @@ -140,13 +140,13 @@ For optimal performance, keep the most frequently used tools loaded at startup a "filepuff": { "command": "mcp-filepuff", "args": ["-workspace", "."], - "alwaysAllow": ["file_read", "file_search", "edit_apply", "edit_preview"] + "alwaysAllow": ["file_read", "file_search", "edit_apply"] } } } ``` -This keeps `file_read`, `file_search`, `edit_apply`, and `edit_preview` immediately available while deferring less frequently used tools (`ping`, `ast_query`, `symbol_at`, `find_definition`, `find_references`). +This keeps `file_read`, `file_search`, and `edit_apply` immediately available while deferring less frequently used tools (`ping`, `ast_query`, `symbol_at`, `find_definition`, `find_references`). #### System Prompt Guidance @@ -158,7 +158,7 @@ You have access to filepuff MCP tools providing: - Fast regex search powered by ripgrep (file_search) - Structural code pattern matching across 9+ languages (ast_query) - LSP-powered go-to-definition, find-references, and symbol info (find_definition, find_references, symbol_at) -- AST-aware file editing with syntax validation and preview (edit_preview, edit_apply) +- AST-aware file editing with syntax validation (edit_apply) ``` ## Usage @@ -241,7 +241,7 @@ When performing file operations, prefer filepuff MCP tools over built-in equival | Read files | `mcp__filepuff__file_read` | Read | | Search content | `mcp__filepuff__file_search` | Grep | | AST pattern search | `mcp__filepuff__ast_query` | Grep/Glob | -| Edit files | `mcp__filepuff__edit_preview` + `mcp__filepuff__edit_apply` | Edit | +| Edit files | `mcp__filepuff__edit_apply` | Edit | | Find definitions | `mcp__filepuff__find_definition` | Grep | | Find references | `mcp__filepuff__find_references` | Grep | | Symbol info | `mcp__filepuff__symbol_at` | - | @@ -399,8 +399,8 @@ Find all references to the symbol at a specific position. --- -### `edit_preview` -Preview an edit without applying it. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++), and text-based editing for other files (Markdown, JSON, YAML, config files, etc.). +### `edit_apply` +Apply an edit to a file. Uses AST-aware editing for code files with syntax validation, and text-based editing for other files. **Parameters**: - `file` (required): Path to the file to edit @@ -420,13 +420,6 @@ Preview an edit without applying it. Uses AST-aware editing for code files (Go, - `selector_text`: Exact text to match (must be unique or use selector_index) - `selector_pattern`: Regex pattern to match ---- - -### `edit_apply` -Apply an edit to a file. Uses AST-aware editing for code files with syntax validation, and text-based editing for other files. - -**Parameters**: Same as `edit_preview` - **Example (AST mode - Go file)**: ```json { @@ -544,8 +537,7 @@ make clean │ MCP Server │ ├─────────────────────────────────────────────────────────┤ │ Tools: file_search, file_read, ast_query, symbol_at, │ -│ find_definition, find_references, │ -│ edit_preview, edit_apply, ping │ +│ find_definition, find_references, edit_apply, ping │ ├─────────────────────────────────────────────────────────┤ │ Core Engines │ ├───────────┬─────────────┬────────────┬─────────────────┤ @@ -746,7 +738,7 @@ flowchart TB C -->|Read| E[file_read] C -->|Query| F[ast_query] C -->|LSP| G[symbol_at
find_definition
find_references] - C -->|Edit| H[edit_preview
edit_apply] + C -->|Edit| H[edit_apply] end subgraph "Core Engines" @@ -819,7 +811,6 @@ The edit engine validates syntax before and after edits. **Solution**: - Ensure `new_content` is syntactically valid for the target language -- Use `edit_preview` first to see the proposed changes - Check that the selector matches exactly one node #### Timeout Errors diff --git a/cmd/docgen/main.go b/cmd/docgen/main.go index c2aa9fe..da5e71e 100644 --- a/cmd/docgen/main.go +++ b/cmd/docgen/main.go @@ -175,34 +175,6 @@ func AllTools() []Tool { "Results grouped by file", }, }, - { - Name: "edit_preview", - Description: "Preview an edit without applying it. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++), and text-based editing for other files (Markdown, JSON, YAML, config files, etc.).", - Category: "Edit Operations", - ReadOnly: true, - Parameters: []ToolParameter{ - {Name: "file", Type: "string", Required: true, Description: "Path to the file to edit"}, - {Name: "operation", Type: "string", Required: true, Description: "Edit operation: replace, insert_before, insert_after, delete"}, - {Name: "new_content", Type: "string", Required: false, Description: "New content (required for replace/insert operations)"}, - {Name: "selector_kind", Type: "string", Required: false, Description: "AST node type to match (e.g., function_declaration, class_declaration). For code files only."}, - {Name: "selector_name", Type: "string", Required: false, Description: "Name of the symbol to match. For code files only."}, - {Name: "selector_line", Type: "number", Required: false, Description: "Line number (1-indexed). For AST mode: narrows search. For text mode: start of line range."}, - {Name: "selector_index", Type: "number", Required: false, Description: "Index of the match to use if multiple matches found (default: 0)"}, - {Name: "selector_line_end", Type: "number", Required: false, Description: "End line number for range selection (text mode). Used with selector_line."}, - {Name: "selector_text", Type: "string", Required: false, Description: "Exact text to match (text mode). Must be unique or use selector_index."}, - {Name: "selector_pattern", Type: "string", Required: false, Description: "Regex pattern to match (text mode). Must be unique or use selector_index."}, - }, - Examples: []string{ - `{"file": "server.go", "operation": "replace", "selector_kind": "function_declaration", "selector_name": "Hello", "new_content": "func Hello() {\\n\\tprintln(\\"New Hello\\")\\n}"}`, - `{"file": "README.md", "operation": "replace", "selector_text": "## Installation", "new_content": "## Getting Started"}`, - `{"file": "package.json", "operation": "replace", "selector_pattern": "\\"version\\":\\\\s*\\"[^\\"]+\\"", "new_content": "\\"version\\": \\"2.0.0\\""}`, - }, - Notes: []string{ - "Returns a diff showing proposed changes", - "Does not modify the file", - "Use to validate changes before applying", - }, - }, { Name: "edit_apply", Description: "Apply an edit to a file. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++) with syntax validation, and text-based editing for other files (Markdown, JSON, YAML, config files, etc.).", diff --git a/docs/API.md b/docs/API.md index 0348bad..38561fb 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,6 +1,6 @@ # MCP Filepuff API Reference -> Auto-generated on 2026-01-28 +> Auto-generated on 2026-03-12 This document provides detailed API documentation for all MCP tools available in filepuff. @@ -24,7 +24,6 @@ This document provides detailed API documentation for all MCP tools available in - [`find_references`](#find_references) ### Edit Operations -- [`edit_preview`](#edit_preview) - [`edit_apply`](#edit_apply) --- @@ -47,10 +46,9 @@ Health check - returns pong to verify the server is running {"tool": "ping"} ``` -**Returns:** `"pong"` text string. - **Notes:** +- Returns: "pong" - Use to verify server connectivity --- @@ -85,8 +83,6 @@ Search for text patterns in files using ripgrep. Supports regex patterns, file t {"pattern": "TODO", "ignore_case": true, "context_lines": 3} ``` -**Returns:** Results grouped by file with match context. Format: `"Found N matches in M files:"` followed by file sections, each with matching lines prefixed by `"L{line}│"` and context lines prefixed by `" │"`. - **Notes:** - Requires ripgrep (rg) to be installed @@ -131,8 +127,6 @@ Read a file's contents with optional line range and AST symbol summary {"path": "large_file.go", "max_lines": 100} ``` -**Returns:** File content with numbered lines (format: `" 12│ line text"`). When `include_ast=true`: prepends symbol summary (`"**file.go** (N lines, go)\nSymbols:\n func Name L12\n struct Config L45"`). When `symbols_only=true`: returns only the symbol summary (~95% fewer tokens). When `max_lines` is set: truncates output with `"[... N more lines omitted]"` notice. - **Notes:** - symbols_only mode reduces token usage by ~90-98% @@ -175,8 +169,6 @@ Search for AST patterns in code files. Use code patterns with $VAR placeholders {"pattern": "function $NAME($PROPS) { $$$BODY }", "language": "javascript", "name_matches": "^[A-Z]"} ``` -**Returns:** `"Found N match(es):"` followed by entries in format `"**file:line** (node_type)"` with code blocks and captured variables (`$NAME=value`). Returns `"No matches found."` when no results. - **Notes:** - $NAME captures identifiers @@ -208,8 +200,6 @@ Get information about the symbol at a specific position in a file. Returns type, {"file": "server.go", "line": 25, "column": 10} ``` -**Returns:** `"**Symbol Information**"` followed by hover/type information from LSP, or `"**Symbol Information** (AST fallback)"` with node type and text when LSP unavailable. Returns `"No symbol information available at this position."` when nothing is found. - **Notes:** - Requires LSP server for full type information @@ -237,11 +227,10 @@ Find the definition of the symbol at a specific position. Uses LSP to locate whe {"file": "server.go", "line": 42, "column": 15} ``` -**Returns:** `"Found N definition(s):"` with entries showing `"**file:line:column**"` and a 3-line code preview with the target line marked by `">"`. Returns `"No definition found."` when the symbol has no definition. - **Notes:** - Requires language server for the file type +- Returns file path, line, and column of definition - Shows code preview at definition location --- @@ -271,8 +260,6 @@ Find all references to the symbol at a specific position. Uses LSP to locate all {"file": "server.go", "line": 42, "column": 15, "include_declaration": false} ``` -**Returns:** `"Found N reference(s):"` grouped by file, each showing `"**file** (count)"` with locations as `"L{line}:{column}"`. Returns `"No references found."` when no usages exist. - **Notes:** - Requires language server for the file type @@ -282,49 +269,6 @@ Find all references to the symbol at a specific position. Uses LSP to locate all ### Edit Operations -#### `edit_preview` - -Preview an edit without applying it. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++), and text-based editing for other files (Markdown, JSON, YAML, config files, etc.). - -🔒 **Read-only**: This tool does not modify files. - -**Parameters:** - -| Name | Type | Required | Description | -|------|------|----------|-------------| -| `file` | `string` | **Yes** | Path to the file to edit | -| `operation` | `string` | **Yes** | Edit operation: replace, insert_before, insert_after, delete | -| `new_content` | `string` | No | New content (required for replace/insert operations) | -| `selector_kind` | `string` | No | AST node type to match (e.g., function_declaration, class_declaration). For code files only. | -| `selector_name` | `string` | No | Name of the symbol to match. For code files only. | -| `selector_line` | `number` | No | Line number (1-indexed). For AST mode: narrows search. For text mode: start of line range. | -| `selector_index` | `number` | No | Index of the match to use if multiple matches found (default: 0) | -| `selector_line_end` | `number` | No | End line number for range selection (text mode). Used with selector_line. | -| `selector_text` | `string` | No | Exact text to match (text mode). Must be unique or use selector_index. | -| `selector_pattern` | `string` | No | Regex pattern to match (text mode). Must be unique or use selector_index. | - -**Examples:** - -```json -{"file": "server.go", "operation": "replace", "selector_kind": "function_declaration", "selector_name": "Hello", "new_content": "func Hello() {\\n\\tprintln(\\"New Hello\\")\\n}"} -``` - -```json -{"file": "README.md", "operation": "replace", "selector_text": "## Installation", "new_content": "## Getting Started"} -``` - -```json -{"file": "package.json", "operation": "replace", "selector_pattern": "\\"version\\":\\\\s*\\"[^\\"]+\\"", "new_content": "\\"version\\": \\"2.0.0\\""} -``` - -**Returns:** `"**Edit Preview**"` followed by a unified diff showing proposed changes. Does not modify the file. For code files: uses AST-aware mode with syntax validation. For other files: uses text-based mode. - -**Notes:** - -- Use to validate changes before applying - ---- - #### `edit_apply` Apply an edit to a file. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++) with syntax validation, and text-based editing for other files (Markdown, JSON, YAML, config files, etc.). @@ -356,10 +300,9 @@ Apply an edit to a file. Uses AST-aware editing for code files (Go, TypeScript, {"file": "config.yaml", "operation": "replace", "selector_line": 5, "selector_line_end": 10, "new_content": "database:\\n host: production.db.example.com\\n port: 5432"} ``` -**Returns:** `"**Edit Applied Successfully**"` followed by a unified diff of the changes made. For code files, validates syntax before writing — returns an error if the edit would produce invalid syntax. - **Notes:** +- For code files: validates syntax before and after edit - Preserves file permissions - Uses atomic writes for safety - File locking prevents concurrent edits diff --git a/docs/ERROR_CODES.md b/docs/ERROR_CODES.md index 4b54383..0a3d493 100644 --- a/docs/ERROR_CODES.md +++ b/docs/ERROR_CODES.md @@ -451,8 +451,7 @@ Review the edit request and ensure all required fields are provided. **Remediation**: 1. Validate `new_content` syntax independently -2. Use `edit_preview` to see the proposed changes -3. Ensure the edit maintains valid syntax +2. Ensure the edit maintains valid syntax --- @@ -622,9 +621,8 @@ mcp-filepuff -workspace /path/to/workspace **Symptoms**: Edit operation rejected with syntax error **Solution**: -1. Use `edit_preview` first to see proposed changes -2. Validate `new_content` is syntactically correct -3. Check that surrounding code structure is maintained +1. Validate `new_content` is syntactically correct +2. Check that surrounding code structure is maintained ### Scenario 3: Search Returns Too Many Results diff --git a/internal/server/handlers_edit.go b/internal/server/handlers_edit.go index 3e1fe19..c14e241 100644 --- a/internal/server/handlers_edit.go +++ b/internal/server/handlers_edit.go @@ -22,18 +22,13 @@ func unescapeNewlines(s string) string { return s } -// handleEditPreview handles the edit_preview tool. -func (s *Server) handleEditPreview(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - return s.handleEdit(ctx, request, false) -} - // handleEditApply handles the edit_apply tool. func (s *Server) handleEditApply(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { - return s.handleEdit(ctx, request, true) + return s.handleEdit(ctx, request) } -// handleEdit is the shared implementation for edit_preview and edit_apply. -func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest, apply bool) (*mcp.CallToolResult, error) { +// handleEdit performs an edit operation (always applies changes). +func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) { file, err := request.RequireString("file") if err != nil { return mcp.NewToolResultError("file is required"), nil @@ -85,13 +80,8 @@ func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest, ap }, } - // Perform edit - var result *edit.EditResult - if apply { - result, err = s.editor.Apply(ctx, astEdit) - } else { - result, err = s.editor.Preview(ctx, astEdit) - } + // Perform edit (always apply) + result, err := s.editor.Apply(ctx, astEdit) if err != nil { return mcp.NewToolResultError(fmt.Sprintf("edit failed: %s", errors.SanitizeError(err))), nil @@ -103,11 +93,7 @@ func (s *Server) handleEdit(ctx context.Context, request mcp.CallToolRequest, ap // Format output var output strings.Builder - if apply { - output.WriteString("**Edit Applied Successfully**\n\n") - } else { - output.WriteString("**Edit Preview**\n\n") - } + output.WriteString("**Edit Applied Successfully**\n\n") output.WriteString("Diff:\n```diff\n") output.WriteString(result.Diff) diff --git a/internal/server/integration_test.go b/internal/server/integration_test.go index 87be036..9ca7156 100644 --- a/internal/server/integration_test.go +++ b/internal/server/integration_test.go @@ -96,35 +96,17 @@ func Hello() string { } }) - // Test 4: Edit preview and apply + // Test 4: Edit workflow t.Run("edit_workflow", func(t *testing.T) { - // Preview edit - previewReq := mcp.CallToolRequest{} - previewReq.Params.Arguments = map[string]interface{}{ + // Apply edit directly (preview removed to avoid confusing LLMs) + applyReq := mcp.CallToolRequest{} + applyReq.Params.Arguments = map[string]interface{}{ "file": testFile, "operation": "replace", "selector_kind": "function_declaration", "selector_name": "Hello", "new_content": "func Hello() string {\n\treturn \"goodbye\"\n}", } - previewResult, err := srv.handleEditPreview(ctx, previewReq) - if err != nil { - t.Errorf("handleEditPreview() error = %v", err) - } - if previewResult == nil { - t.Fatal("handleEditPreview() returned nil") - return - } - - // Verify file unchanged after preview - originalContent, _ := os.ReadFile(testFile) - if string(originalContent) != content { - t.Error("preview should not modify file") - } - - // Apply edit - applyReq := mcp.CallToolRequest{} - applyReq.Params.Arguments = previewReq.Params.Arguments applyResult, err := srv.handleEditApply(ctx, applyReq) if err != nil { t.Errorf("handleEditApply() error = %v", err) @@ -267,10 +249,8 @@ func TestMCPErrorResponses(t *testing.T) { expectError: true, }, { - name: "edit_missing_file", - handler: func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { - return srv.handleEdit(ctx, req, false) - }, + name: "edit_missing_file", + handler: srv.handleEditApply, setupReq: func() mcp.CallToolRequest { req := mcp.CallToolRequest{} req.Params.Arguments = map[string]interface{}{ @@ -281,10 +261,8 @@ func TestMCPErrorResponses(t *testing.T) { expectError: true, }, { - name: "edit_missing_operation", - handler: func(ctx context.Context, req mcp.CallToolRequest) (*mcp.CallToolResult, error) { - return srv.handleEdit(ctx, req, false) - }, + name: "edit_missing_operation", + handler: srv.handleEditApply, setupReq: func() mcp.CallToolRequest { req := mcp.CallToolRequest{} req.Params.Arguments = map[string]interface{}{ @@ -376,7 +354,7 @@ func Add(a, b int) int { return } - // 3. Preview edit + // 3. Edit (no preview) editReq := mcp.CallToolRequest{} editReq.Params.Arguments = map[string]interface{}{ "file": testFile, @@ -385,12 +363,12 @@ func Add(a, b int) int { "selector_name": "Add", "new_content": "func Add(a, b int) int {\n\treturn a + b + 1\n}", } - editResult, err := srv.handleEditPreview(ctx, editReq) + editResult, err := srv.handleEditApply(ctx, editReq) if err != nil { - t.Fatalf("handleEditPreview() error = %v", err) + t.Fatalf("handleEditApply() error = %v", err) } if editResult == nil { - t.Fatal("handleEditPreview() returned nil") + t.Fatal("handleEditApply() returned nil") return } }) diff --git a/internal/server/server.go b/internal/server/server.go index 82ff009..80c038c 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -290,54 +290,6 @@ func (s *Server) registerTools() { } // Register edit tools - s.mcp.AddTool( - mcp.NewTool("edit_preview", - mcp.WithDescription("Preview an edit without applying it. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++, Rust), and text-based editing for other files (Markdown, JSON, YAML, config files, etc.).\n\n"+ - "Returns: \"**Edit Preview**\" followed by a unified diff showing proposed changes. Does not modify the file. "+ - "For code files: uses AST-aware mode with syntax validation. For other files: uses text-based mode.\n\n"+ - "Examples:\n"+ - " AST mode: {\"file\": \"main.go\", \"operation\": \"replace\", \"selector_kind\": \"function_declaration\", \"selector_name\": \"Hello\", \"new_content\": \"func Hello() {\\n\\treturn\\n}\"}\n"+ - " Text mode: {\"file\": \"README.md\", \"operation\": \"replace\", \"selector_text\": \"## Old Header\", \"new_content\": \"## New Header\"}\n"+ - " Line range: {\"file\": \"config.yaml\", \"operation\": \"replace\", \"selector_line\": 5, \"selector_line_end\": 10, \"new_content\": \"key: value\"}"), - mcp.WithString("file", - mcp.Required(), - mcp.Description("Path to the file to edit"), - ), - mcp.WithString("operation", - mcp.Required(), - mcp.Description("Edit operation: replace, insert_before, insert_after, delete"), - ), - mcp.WithString("new_content", - mcp.Description("New content (required for replace/insert operations)"), - ), - // AST-mode selectors (for code files) - mcp.WithString("selector_kind", - mcp.Description("AST node type to match (e.g., function_declaration, class_declaration). For code files only."), - ), - mcp.WithString("selector_name", - mcp.Description("Name of the symbol to match. For code files only."), - ), - // Shared selectors - mcp.WithNumber("selector_line", - mcp.Description("Line number (1-indexed). For AST mode: narrows search. For text mode: start of line range."), - ), - mcp.WithNumber("selector_index", - mcp.Description("Index of the match to use if multiple matches found (default: 0)"), - ), - // Text-mode selectors (for non-code files or explicit text matching) - mcp.WithNumber("selector_line_end", - mcp.Description("End line number for range selection (text mode). Used with selector_line."), - ), - mcp.WithString("selector_text", - mcp.Description("Exact text to match (text mode). Must be unique or use selector_index."), - ), - mcp.WithString("selector_pattern", - mcp.Description("Regex pattern to match (text mode). Must be unique or use selector_index."), - ), - ), - s.handleEditPreview, - ) - s.mcp.AddTool( mcp.NewTool("edit_apply", mcp.WithDescription("Apply an edit to a file. Uses AST-aware editing for code files (Go, TypeScript, JavaScript, Python, C, C++, Rust) with syntax validation, and text-based editing for other files (Markdown, JSON, YAML, config files, etc.).\n\n"+ diff --git a/internal/server/server_test.go b/internal/server/server_test.go index 2df72af..caea7f4 100644 --- a/internal/server/server_test.go +++ b/internal/server/server_test.go @@ -283,56 +283,6 @@ func Goodbye() error { } } -func TestHandleEditPreview(t *testing.T) { - tmpDir := t.TempDir() - - // Create a test file - testFile := filepath.Join(tmpDir, "test.go") - content := `package main - -func Hello() { - println("Hello") -} -` - if err := os.WriteFile(testFile, []byte(content), 0600); err != nil { - t.Fatalf("failed to write test file: %v", err) - } - - cfg := &config.Config{WorkspaceRoot: tmpDir, EnableLSP: false} - logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelError})) - - srv, err := New(cfg, logger) - if err != nil { - t.Fatalf("New() error = %v", err) - } - - ctx := context.Background() - req := mcp.CallToolRequest{} - req.Params.Arguments = map[string]interface{}{ - "file": testFile, - "operation": "replace", - "selector_kind": "function_declaration", - "selector_name": "Hello", - "new_content": "func Hello() {\n\tprintln(\"Goodbye\")\n}", - } - - result, err := srv.handleEdit(ctx, req, false) - if err != nil { - t.Errorf("handleEdit(preview) error = %v", err) - } - - if result == nil { - t.Fatal("handleEdit(preview) returned nil result") - return - } - - // Verify file was NOT modified (it's just a preview) - fileContent, _ := os.ReadFile(testFile) - if string(fileContent) != content { - t.Error("handleEdit(preview) should not modify the file") - } -} - func TestHandleEditApply(t *testing.T) { tmpDir := t.TempDir() @@ -366,20 +316,20 @@ func Hello() { "new_content": "func Hello() {\n\tprintln(\"Goodbye\")\n}", } - result, err := srv.handleEdit(ctx, req, true) + result, err := srv.handleEditApply(ctx, req) if err != nil { - t.Errorf("handleEdit(apply) error = %v", err) + t.Errorf("handleEditApply error = %v", err) } if result == nil { - t.Fatal("handleEdit(apply) returned nil result") + t.Fatal("handleEditApply returned nil result") return } // Verify file WAS modified fileContent, _ := os.ReadFile(testFile) if string(fileContent) == content { - t.Error("handleEdit(apply) should modify the file") + t.Error("handleEditApply should modify the file") } }