package tui import ( "fmt" "strings" "gopkg.in/yaml.v3" "git.unkin.net/unkin/forgebot/pkg/models" ) type editableTask struct { Status string `yaml:"status"` Message string `yaml:"message"` ErrorMessage string `yaml:"error_message"` } type newTask struct { Command string `yaml:"command"` Repository string `yaml:"repository"` Ref string `yaml:"ref"` Body string `yaml:"body"` Author string `yaml:"author"` Skill string `yaml:"skill"` PoolRef string `yaml:"pool_ref"` } func marshalTaskForEdit(task *models.Task) []byte { var b strings.Builder fmt.Fprintf(&b, "# forgebot task %s\n", task.ID) b.WriteString("# Editable: status, message, error_message\n\n") et := editableTask{ Status: string(task.Status), Message: task.Result, ErrorMessage: task.ErrorMessage, } data, _ := yaml.Marshal(et) b.Write(data) b.WriteString("\n# -- Context (read-only) --\n") fmt.Fprintf(&b, "# command: %s\n", task.Command) fmt.Fprintf(&b, "# repository: %s\n", task.Repository) fmt.Fprintf(&b, "# ref: %s\n", task.Ref) fmt.Fprintf(&b, "# author: %s\n", task.Author) if task.IssueNumber > 0 { fmt.Fprintf(&b, "# issue: %d\n", task.IssueNumber) } if task.PRNumber > 0 { fmt.Fprintf(&b, "# pr: %d\n", task.PRNumber) } fmt.Fprintf(&b, "# created: %s\n", task.CreatedAt.Format("2006-01-02T15:04:05Z")) if task.Body != "" { b.WriteString("#\n# body:\n") for _, line := range strings.Split(task.Body, "\n") { fmt.Fprintf(&b, "# %s\n", line) } } if task.Result != "" { b.WriteString("#\n# result:\n") for _, line := range strings.Split(task.Result, "\n") { fmt.Fprintf(&b, "# %s\n", line) } } return []byte(b.String()) } func unmarshalEditedTask(data []byte) (*editableTask, error) { var et editableTask if err := yaml.Unmarshal(data, &et); err != nil { return nil, fmt.Errorf("parse edited task: %w", err) } return &et, nil } func diffEditableTask(original *models.Task, edited *editableTask) *models.UpdateTaskRequest { req := &models.UpdateTaskRequest{} changed := false if edited.Status != string(original.Status) { req.Status = models.TaskStatus(edited.Status) changed = true } if edited.Message != original.Result { req.Message = edited.Message changed = true } if edited.ErrorMessage != original.ErrorMessage { req.ErrorMessage = edited.ErrorMessage changed = true } if !changed { return nil } return req } func marshalNewTask() []byte { var b strings.Builder b.WriteString("# New forgebot task\n\n") nt := newTask{ Command: "implement", Repository: "", Ref: "main", Body: "", Author: "", Skill: "", PoolRef: "", } data, _ := yaml.Marshal(nt) b.Write(data) return []byte(b.String()) } func unmarshalNewTask(data []byte) (*models.CreateTaskRequest, error) { var nt newTask if err := yaml.Unmarshal(data, &nt); err != nil { return nil, fmt.Errorf("parse new task: %w", err) } if nt.Command == "" || nt.Repository == "" { return nil, fmt.Errorf("command and repository are required") } return &models.CreateTaskRequest{ Command: nt.Command, Repository: nt.Repository, Ref: nt.Ref, Body: nt.Body, Author: nt.Author, Skill: nt.Skill, PoolRef: nt.PoolRef, }, nil }