grokkit/cmd/edit.go
Greg Gauthier 98eb5505a5 chore(headers): add last modified timestamps to source files
Implemented automatic addition of "// Last modified: [timestamp]" headers across command and internal files for better tracking. Updated prompts in agent and edit commands to enforce header format. Added logic to prepend header if missing in generated content. Fixed minor issues like missing newlines at end of files.
2026-02-28 22:47:30 +00:00

64 lines
2.0 KiB
Go

// Last modified: 2026-02-28 22:43:40 GMT
package cmd
import (
"fmt"
"os"
"path/filepath"
"time"
"github.com/fatih/color"
"github.com/spf13/cobra"
"gmgauthier.com/grokkit/config"
"gmgauthier.com/grokkit/internal/grok"
)
var editCmd = &cobra.Command{
Use: "edit FILE INSTRUCTION",
Short: "Edit a file in-place with Grok (safe preview + backup)",
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(modelFlag)
if _, err := os.Stat(filePath); os.IsNotExist(err) {
color.Red("File not found: %s", filePath)
os.Exit(1)
}
original, _ := os.ReadFile(filePath)
backupPath := filePath + ".bak"
_ = os.WriteFile(backupPath, original, 0644)
client := grok.NewClient()
messages := []map[string]string{
{"role": "system", "content": fmt.Sprintf("You are an expert programmer. The VERY FIRST LINE of the returned file MUST be a header comment in this exact format: '// Last modified: %s'. Then return the complete updated file content. No explanations, no markdown, no diffs, no extra text.", time.Now().Format("2006-01-02 15:04:05 MST"))},
{"role": "user", "content": fmt.Sprintf("File: %s\n\nOriginal content:\n%s\n\nTask: %s", filepath.Base(filePath), original, instruction)},
}
color.Yellow("Asking Grok to %s...", instruction)
raw := client.Stream(messages, model)
newContent := grok.CleanCodeResponse(raw)
// Nice unified diff preview
color.Cyan("\nProposed changes:")
fmt.Println("--- a/" + filepath.Base(filePath))
fmt.Println("+++ b/" + filepath.Base(filePath))
// simple diff output (you can make it fancier later)
fmt.Print(newContent)
fmt.Print("\n\nApply these changes? (y/n): ")
var confirm string
fmt.Scanln(&confirm)
if confirm != "y" && confirm != "Y" {
color.Yellow("Changes discarded. Backup saved as %s", backupPath)
return
}
_ = os.WriteFile(filePath, []byte(newContent), 0644)
color.Green("✅ Applied successfully! Backup: %s", backupPath)
},
}