Use command-line flags for edit instructions and scaffold descriptions instead of global variables to improve modularity and avoid globals.
92 lines
2.4 KiB
Go
92 lines
2.4 KiB
Go
package cmd
|
|
|
|
import (
|
|
"bufio"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/spf13/cobra"
|
|
"gmgauthier.com/grokkit/config"
|
|
"gmgauthier.com/grokkit/internal/grok"
|
|
)
|
|
|
|
var editCmd = &cobra.Command{
|
|
Use: "edit [file]",
|
|
Short: "Edit a file in-place with Grok (safe preview)",
|
|
Long: `Ask Grok to edit a file. Shows a preview diff and requires explicit confirmation before writing.`,
|
|
Run: runEdit,
|
|
}
|
|
|
|
func init() {
|
|
editCmd.Flags().String("instruction", "", "Edit instruction (used internally by agent mode)")
|
|
rootCmd.AddCommand(editCmd)
|
|
}
|
|
|
|
func runEdit(cmd *cobra.Command, args []string) {
|
|
if len(args) == 0 {
|
|
color.Red("Usage: grokkit edit <file>")
|
|
return
|
|
}
|
|
file := args[0]
|
|
|
|
// If agent mode passed an instruction, use it directly (no prompt)
|
|
var instruction string
|
|
if editInstruction != "" {
|
|
instruction = editInstruction
|
|
color.Cyan("Agent instruction: %s", instruction)
|
|
} else {
|
|
// Normal interactive mode
|
|
color.Yellow("Enter edit instruction for %s: ", file)
|
|
scanner := bufio.NewScanner(os.Stdin)
|
|
if scanner.Scan() {
|
|
instruction = strings.TrimSpace(scanner.Text())
|
|
}
|
|
if instruction == "" {
|
|
color.Yellow("No instruction provided.")
|
|
return
|
|
}
|
|
}
|
|
|
|
client := grok.NewClient()
|
|
messages := buildEditMessages(file, instruction)
|
|
|
|
color.Yellow("Asking Grok to edit %s...", file)
|
|
edited := client.Stream(messages, config.GetModel("edit", ""))
|
|
|
|
// Show preview
|
|
color.Cyan("\n--- Proposed changes to %s ---\n%s\n--------------------------------", file, edited)
|
|
|
|
var confirm string
|
|
color.Yellow("Apply these changes to %s? (y/n): ", file)
|
|
fmt.Scanln(&confirm)
|
|
|
|
if confirm != "y" && confirm != "Y" {
|
|
color.Yellow("Aborted.")
|
|
return
|
|
}
|
|
|
|
if err := os.WriteFile(file, []byte(edited), 0644); err != nil {
|
|
color.Red("Failed to write file: %v", err)
|
|
return
|
|
}
|
|
|
|
color.Green("✅ Successfully edited %s", file)
|
|
}
|
|
|
|
// buildEditMessages is kept unchanged from original
|
|
func buildEditMessages(file, instruction string) []map[string]string {
|
|
content, _ := os.ReadFile(file)
|
|
return []map[string]string{
|
|
{
|
|
"role": "system",
|
|
"content": "You are an expert programmer. Edit the following file according to the user's instruction. Return ONLY the full new file content. Do not include any explanations.",
|
|
},
|
|
{
|
|
"role": "user",
|
|
"content": fmt.Sprintf("File: %s\n\nCurrent content:\n%s\n\nInstruction: %s", file, string(content), instruction),
|
|
},
|
|
}
|
|
}
|