(ctx context.Context, args map[string]interface{})
| 394 | } |
| 395 | |
| 396 | func executeSandboxRuntimeEditFile(ctx context.Context, args map[string]interface{}) (*ToolResult, error) { |
| 397 | path, ok := args["path"].(string) |
| 398 | if !ok || strings.TrimSpace(path) == "" { |
| 399 | return nil, fmt.Errorf("missing path argument") |
| 400 | } |
| 401 | path, err := normalizeSandboxWorkspacePath(path) |
| 402 | if err != nil { |
| 403 | return nil, err |
| 404 | } |
| 405 | oldString, ok := args["old_string"].(string) |
| 406 | if !ok || oldString == "" { |
| 407 | return nil, fmt.Errorf("missing old_string argument") |
| 408 | } |
| 409 | newString, ok := args["new_string"].(string) |
| 410 | if !ok { |
| 411 | return nil, fmt.Errorf("missing new_string argument") |
| 412 | } |
| 413 | replaceAll := parseBoolValue(args["replace_all"]) |
| 414 | session, err := runtimeSessionForContext(ctx) |
| 415 | if err != nil { |
| 416 | return nil, err |
| 417 | } |
| 418 | rt, err := getSandboxRuntime() |
| 419 | if err != nil { |
| 420 | return nil, err |
| 421 | } |
| 422 | data, err := rt.ReadFile(ctx, session, path, 0) |
| 423 | if err != nil { |
| 424 | return nil, err |
| 425 | } |
| 426 | content := string(data) |
| 427 | matchCount := strings.Count(content, oldString) |
| 428 | if matchCount == 0 { |
| 429 | return nil, fmt.Errorf("old_string not found in file") |
| 430 | } |
| 431 | if !replaceAll && matchCount > 1 { |
| 432 | return nil, fmt.Errorf("old_string found %d times, set replace_all=true or provide a more specific match", matchCount) |
| 433 | } |
| 434 | newContent := content |
| 435 | replacements := 1 |
| 436 | if replaceAll { |
| 437 | newContent = strings.ReplaceAll(content, oldString, newString) |
| 438 | replacements = matchCount |
| 439 | } else { |
| 440 | newContent = strings.Replace(content, oldString, newString, 1) |
| 441 | } |
| 442 | newContent = normalizeSandboxTextContentForPath(path, newContent) |
| 443 | if err := rt.WriteFiles(ctx, session, []sandboxruntime.FileObject{{Path: path, Data: []byte(newContent)}}); err != nil { |
| 444 | return nil, err |
| 445 | } |
| 446 | if err := formatSandboxRuntimeWrittenFiles(ctx, rt, session, []sandboxruntime.FileObject{{Path: path, Data: []byte(newContent)}}); err != nil { |
| 447 | return nil, err |
| 448 | } |
| 449 | if err := validateSandboxRuntimeWrittenFiles(ctx, rt, session, []sandboxruntime.FileObject{{Path: path, Data: []byte(newContent)}}); err != nil { |
| 450 | return nil, err |
| 451 | } |
| 452 | prevSnapshot := loadSandboxOutputSnapshot(ctx) |
| 453 | outputFiles, currentSnapshot, collectErr := collectRuntimeOutputFiles(ctx, session, prevSnapshot) |
no test coverage detected