Add todo mode and replace the plan with TODO.md
This commit is contained in:
@@ -13,9 +13,58 @@ import (
|
||||
"g.fc.run/misc/byre/internal/git"
|
||||
"g.fc.run/misc/byre/internal/mcp"
|
||||
"g.fc.run/misc/byre/internal/store"
|
||||
"g.fc.run/misc/byre/internal/todo"
|
||||
)
|
||||
|
||||
func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, createdBy, base string) (api.Task, error) {
|
||||
return m.createTask(ctx, project, title, createdBy, base, nil)
|
||||
}
|
||||
|
||||
func (m *Manager) StartTodo(ctx context.Context, project api.Project, creator api.User, title, model string) (api.Task, error) {
|
||||
if creator.GitName == "" || creator.GitEmail == "" {
|
||||
return api.Task{}, ErrNoGitIdentity
|
||||
}
|
||||
|
||||
src, found, err := git.ReadFile(project.RepoPath, project.DefaultBranch, todo.File)
|
||||
if err != nil {
|
||||
return api.Task{}, err
|
||||
}
|
||||
if !found {
|
||||
return api.Task{}, fmt.Errorf("%w: %s has no %s", store.ErrNotFound, project.DefaultBranch, todo.File)
|
||||
}
|
||||
item, found := todo.Find(todo.Parse(src), title)
|
||||
if !found {
|
||||
return api.Task{}, fmt.Errorf("%w: %s on %s has no item %q", store.ErrNotFound, todo.File, project.DefaultBranch, title)
|
||||
}
|
||||
|
||||
tasks, err := m.store.ListTasks(ctx, project.Id)
|
||||
if err != nil {
|
||||
return api.Task{}, err
|
||||
}
|
||||
for _, t := range tasks {
|
||||
if t.Status == api.TaskStatusActive && t.TodoItem != nil && *t.TodoItem == title {
|
||||
return api.Task{}, fmt.Errorf("%w: task %s is already working on %q", ErrConflict, t.Id, title)
|
||||
}
|
||||
}
|
||||
|
||||
task, err := m.createTask(ctx, project, item.Title, creator.Login, project.DefaultBranch, &item.Title)
|
||||
if err != nil {
|
||||
return api.Task{}, err
|
||||
}
|
||||
|
||||
_, err = m.create(ctx, task, creator, todoPrompt(item), model, creator.Login, nil)
|
||||
if err != nil {
|
||||
return api.Task{}, fmt.Errorf("task %s created, but its agent did not start: %w", task.Id, err)
|
||||
}
|
||||
return task, nil
|
||||
}
|
||||
|
||||
func todoPrompt(item api.TodoItem) string {
|
||||
return fmt.Sprintf("Work on this item from %[1]s at the repo root:\n\n%[2]s\n\nWhen the work is done, remove this item from %[1]s in this worktree, so the removal lands in the same merge as the work.",
|
||||
todo.File, todo.Markdown(item))
|
||||
}
|
||||
|
||||
func (m *Manager) createTask(ctx context.Context, project api.Project, title, createdBy, base string, todoItem *string) (api.Task, error) {
|
||||
id := store.NewID()
|
||||
t := api.Task{
|
||||
Id: id,
|
||||
@@ -27,6 +76,7 @@ func (m *Manager) CreateTask(ctx context.Context, project api.Project, title, cr
|
||||
Status: api.TaskStatusActive,
|
||||
CreatedBy: createdBy,
|
||||
CreatedAt: time.Now().UTC(),
|
||||
TodoItem: todoItem,
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
Reference in New Issue
Block a user