feature/recipe_implementation #5
@ -37,11 +37,16 @@ func (r *Runner) Run() error {
|
||||
previousResults = append(previousResults, "Discovered files:\n"+result)
|
||||
fmt.Println(result)
|
||||
|
||||
case strings.Contains(titleLower, "refactor"):
|
||||
r.refactorFiles(previousResults) // <-- new one-file-at-a-time handler
|
||||
continue
|
||||
|
||||
case strings.Contains(titleLower, "apply") || strings.Contains(titleLower, "patch"):
|
||||
r.handleApplyStep(previousResults)
|
||||
continue
|
||||
|
||||
default:
|
||||
// fallback for any other step
|
||||
prompt := fmt.Sprintf(`Recipe Overview:
|
||||
%s
|
||||
|
||||
@ -76,7 +81,7 @@ Execute this step now. Respond ONLY with the expected output format — no expla
|
||||
return nil
|
||||
}
|
||||
|
||||
// discoverFiles — temporary .go hard-code (we'll generalize with extensions next)
|
||||
// discoverFiles — real filesystem scan (we'll generalize with extensions next)
|
||||
func (r *Runner) discoverFiles() []string {
|
||||
var files []string
|
||||
root := "internal"
|
||||
@ -98,6 +103,50 @@ func (r *Runner) discoverFiles() []string {
|
||||
return files
|
||||
}
|
||||
|
||||
// refactorFiles — one file at a time (small JSON, no truncation)
|
||||
func (r *Runner) refactorFiles(previousResults []string) {
|
||||
discoveredLine := previousResults[len(previousResults)-1]
|
||||
lines := strings.Split(discoveredLine, "\n")
|
||||
|
||||
for _, line := range lines {
|
||||
filePath := strings.TrimSpace(line)
|
||||
if filePath == "" || strings.HasPrefix(filePath, "Discovered") || filePath == "No files found matching the criteria." {
|
||||
continue
|
||||
}
|
||||
|
||||
fmt.Printf(" Refactoring %s...\n", filePath)
|
||||
|
||||
content, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
fmt.Printf(" ❌ Could not read %s\n", filePath)
|
||||
continue
|
||||
}
|
||||
|
||||
prompt := fmt.Sprintf(`Refactor the following file to use Result[T] instead of naked errors.
|
||||
Follow existing style and preserve all comments.
|
||||
Return ONLY this exact JSON (no extra text, no markdown):
|
||||
|
||||
{
|
||||
"file": "%s",
|
||||
"content": "the complete refactored file here"
|
||||
}
|
||||
|
||||
Original file:
|
||||
%s`, filePath, string(content))
|
||||
|
||||
messages := []map[string]string{
|
||||
{"role": "system", "content": "You are Grok, built by xAI. Precise expert programmer and refactoring assistant."},
|
||||
{"role": "user", "content": prompt},
|
||||
}
|
||||
|
||||
response := r.Client.Stream(messages, r.Model)
|
||||
fmt.Println()
|
||||
|
||||
// store the JSON response for the apply step
|
||||
previousResults = append(previousResults, response)
|
||||
}
|
||||
}
|
||||
|
||||
type FileChange struct {
|
||||
File string `json:"file"`
|
||||
Content string `json:"content"`
|
||||
@ -109,32 +158,30 @@ func (r *Runner) handleApplyStep(previousResults []string) {
|
||||
return
|
||||
}
|
||||
|
||||
lastResult := previousResults[len(previousResults)-1]
|
||||
// collect all JSON objects from the refactor step(s)
|
||||
var allChanges []FileChange
|
||||
for _, res := range previousResults {
|
||||
start := strings.Index(res, "{")
|
||||
end := strings.LastIndex(res, "}") + 1
|
||||
if start == -1 {
|
||||
continue
|
||||
}
|
||||
jsonStr := res[start:end]
|
||||
|
||||
// Find the JSON array in the response
|
||||
start := strings.Index(lastResult, "[")
|
||||
end := strings.LastIndex(lastResult, "]") + 1
|
||||
if start == -1 || end == 0 {
|
||||
fmt.Println(" ⚠️ No JSON found in previous step — skipping.")
|
||||
return
|
||||
var ch FileChange
|
||||
if err := json.Unmarshal([]byte(jsonStr), &ch); err == nil {
|
||||
allChanges = append(allChanges, ch)
|
||||
}
|
||||
}
|
||||
|
||||
jsonStr := lastResult[start:end]
|
||||
|
||||
var changes []FileChange
|
||||
if err := json.Unmarshal([]byte(jsonStr), &changes); err != nil {
|
||||
fmt.Printf(" ⚠️ Could not parse JSON: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(changes) == 0 {
|
||||
fmt.Println(" ⚠️ No files to apply — skipping.")
|
||||
if len(allChanges) == 0 {
|
||||
fmt.Println(" ⚠️ No valid file changes found — skipping.")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(" 📄 Dry-run mode: creating patch file...")
|
||||
patchPath := filepath.Join(".", "recipe-refactor.patch")
|
||||
if err := createUnifiedPatch(changes, patchPath); err != nil {
|
||||
if err := createUnifiedPatch(allChanges, patchPath); err != nil {
|
||||
fmt.Printf(" ❌ Failed to create patch: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user