Eliminate .bak file backups from edit, docs, lint, testgen, and agent commands to simplify safety features, relying on previews and confirmations instead. Update README, architecture docs, troubleshooting, and TODOs to reflect changes. Adjust tests to remove backup assertions.
102 lines
3.0 KiB
Go
102 lines
3.0 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/spf13/cobra"
|
|
"gmgauthier.com/grokkit/config"
|
|
"gmgauthier.com/grokkit/internal/grok"
|
|
"gmgauthier.com/grokkit/internal/logger"
|
|
)
|
|
|
|
var editCmd = &cobra.Command{
|
|
Use: "edit FILE INSTRUCTION",
|
|
Short: "Edit a file in-place with Grok (safe preview)",
|
|
Args: cobra.ExactArgs(2),
|
|
Run: func(cmd *cobra.Command, args []string) {
|
|
filePath := args[0]
|
|
instruction := args[1]
|
|
|
|
modelFlag, _ := cmd.Flags().GetString("model")
|
|
model := config.GetModel("edit", modelFlag)
|
|
|
|
logger.Info("edit command started",
|
|
"file", filePath,
|
|
"instruction", instruction,
|
|
"model", model)
|
|
|
|
if _, err := os.Stat(filePath); os.IsNotExist(err) {
|
|
logger.Error("file not found", "file", filePath, "error", err)
|
|
color.Red("File not found: %s", filePath)
|
|
os.Exit(1)
|
|
}
|
|
|
|
original, err := os.ReadFile(filePath)
|
|
if err != nil {
|
|
logger.Error("failed to read file", "file", filePath, "error", err)
|
|
color.Red("Failed to read file: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
logger.Debug("file read successfully", "file", filePath, "size_bytes", len(original))
|
|
cleanedOriginal := removeLastModifiedComments(string(original))
|
|
|
|
client := grok.NewClient()
|
|
messages := []map[string]string{
|
|
{"role": "system", "content": "You are an expert programmer. Remove all unnecessary comments including last modified timestamps and ownership comments. Return only the cleaned code with no explanations, no markdown, no extra text."},
|
|
{"role": "user", "content": fmt.Sprintf("File: %s\n\nOriginal content:\n%s\n\nTask: %s", filepath.Base(filePath), cleanedOriginal, instruction)},
|
|
}
|
|
|
|
color.Yellow("Asking Grok to %s...\n", instruction)
|
|
raw := client.StreamSilent(messages, model)
|
|
newContent := grok.CleanCodeResponse(raw)
|
|
color.Green("✓ Response received")
|
|
|
|
color.Cyan("\nProposed changes:")
|
|
fmt.Println("--- a/" + filepath.Base(filePath))
|
|
fmt.Println("+++ b/" + filepath.Base(filePath))
|
|
fmt.Print(newContent)
|
|
|
|
fmt.Print("\n\nApply these changes? (y/n): ")
|
|
var confirm string
|
|
if _, err := fmt.Scanln(&confirm); err != nil {
|
|
color.Red("Failed to read input: %v", err)
|
|
color.Yellow("Changes discarded.")
|
|
return
|
|
}
|
|
if confirm != "y" && confirm != "Y" {
|
|
color.Yellow("Changes discarded.")
|
|
return
|
|
}
|
|
|
|
logger.Debug("applying changes", "file", filePath, "new_size_bytes", len(newContent))
|
|
if err := os.WriteFile(filePath, []byte(newContent), 0644); err != nil {
|
|
logger.Error("failed to write file", "file", filePath, "error", err)
|
|
color.Red("Failed to write file: %v", err)
|
|
os.Exit(1)
|
|
}
|
|
logger.Info("changes applied successfully",
|
|
"file", filePath,
|
|
"original_size", len(original),
|
|
"new_size", len(newContent))
|
|
color.Green("✅ Applied successfully!")
|
|
},
|
|
}
|
|
|
|
func removeLastModifiedComments(content string) string {
|
|
lines := strings.Split(content, "\n")
|
|
var cleanedLines []string
|
|
|
|
for _, line := range lines {
|
|
if strings.Contains(line, "Last modified") {
|
|
continue
|
|
}
|
|
cleanedLines = append(cleanedLines, line)
|
|
}
|
|
|
|
return strings.Join(cleanedLines, "\n")
|
|
}
|