From 63631fc42f64038ca346dad144ac2743a16c2be0 Mon Sep 17 00:00:00 2001 From: Moira Daniella A Sebastian Date: Mon, 2 Mar 2026 20:17:08 +0100 Subject: [PATCH 1/4] Implemented add comments for tui --- pkg/tui/views/dashboard/help_bar.go | 3 +- pkg/tui/views/dashboard/issue_detail.go | 42 +++++++++++--- pkg/tui/views/dashboard/keys.go | 24 +++++--- pkg/tui/views/dashboard/model.go | 35 ++++++++++-- pkg/tui/views/dashboard/operations.go | 74 ++++++++++++++++++++++--- pkg/tui/views/dashboard/view.go | 15 +++++ 6 files changed, 165 insertions(+), 28 deletions(-) diff --git a/pkg/tui/views/dashboard/help_bar.go b/pkg/tui/views/dashboard/help_bar.go index 3ad63cc..d5b7891 100644 --- a/pkg/tui/views/dashboard/help_bar.go +++ b/pkg/tui/views/dashboard/help_bar.go @@ -36,7 +36,7 @@ func (h HelpBar) shortHelp() string { styles.HighlightKey("↓/j") + " down", styles.HighlightKey("pgup/pgdn") + " page", styles.HighlightKey("a") + " add", - styles.HighlightKey("e/d/s/p/t") + " edit", + styles.HighlightKey("e/d/s/p/t/c") + " edit", styles.HighlightKey("x") + " delete", styles.HighlightKey("q") + " quit", styles.HighlightKey("?") + " help", @@ -75,6 +75,7 @@ func (h HelpBar) fullHelp() string { renderRow("pgup", "page up", "pgdn", "page down"), renderRow("b", "back to list", "a", "add issue"), renderRow("e", "edit title", "d", "edit desc"), + renderRow("c", "add comment", "", ""), renderRow("s", "change status", "p", "change priority"), renderRow("t", "change type", "x", "delete issue"), renderRow("?", "help", "q", "quit"), diff --git a/pkg/tui/views/dashboard/issue_detail.go b/pkg/tui/views/dashboard/issue_detail.go index 8681800..2899bca 100644 --- a/pkg/tui/views/dashboard/issue_detail.go +++ b/pkg/tui/views/dashboard/issue_detail.go @@ -1,6 +1,8 @@ package dashboard import ( + "time" + "github.com/LazyBachelor/LazyPM/internal/models" "github.com/LazyBachelor/LazyPM/pkg/tui/styles" "github.com/charmbracelet/bubbles/viewport" @@ -10,6 +12,7 @@ import ( type IssueDetail struct { viewport viewport.Model issue models.Issue + comments []*models.Comment focused bool } @@ -25,6 +28,12 @@ func (i *IssueDetail) SetIssue(issue models.Issue) { i.refreshContent() } +// SetComments updates the list of comments displayed for the current issue. +func (i *IssueDetail) SetComments(comments []*models.Comment) { + i.comments = comments + i.refreshContent() +} + func (i *IssueDetail) SetSize(width, height int) { i.viewport.Height = height i.viewport.Width = width @@ -60,19 +69,34 @@ func (i *IssueDetail) refreshContent() { descLabel := styles.LabelStyle.Render("Description:") descContent := styles.ValueStyle.Render(i.issue.Description) - content := lipgloss.JoinVertical(lipgloss.Left, - titleRow, - idRow, - typeRow, - statusRow, - priorityRow, - descLabel, - descContent, - ) + var parts []string + parts = append(parts, titleRow, idRow, typeRow, statusRow, priorityRow, descLabel, descContent) + // Comments section + commentsLabel := styles.LabelStyle.Render("Comments:") + parts = append(parts, commentsLabel) + if len(i.comments) == 0 { + parts = append(parts, lipgloss.NewStyle().Foreground(styles.FaintText).Render(" No comments yet.")) + } else { + for _, c := range i.comments { + authorDate := lipgloss.NewStyle().Foreground(styles.Primary).Render(c.Author) + " " + + lipgloss.NewStyle().Foreground(styles.FaintText).Render(formatCommentTime(c.CreatedAt)) + commentRow := lipgloss.JoinVertical(lipgloss.Left, + authorDate, + styles.ValueStyle.Render(c.Text), + ) + parts = append(parts, commentRow) + } + } + + content := lipgloss.JoinVertical(lipgloss.Left, parts...) i.viewport.SetContent(content) } +func formatCommentTime(t time.Time) string { + return t.Format("Jan 2, 15:04") +} + func (i IssueDetail) View() string { content := i.viewport.View() diff --git a/pkg/tui/views/dashboard/keys.go b/pkg/tui/views/dashboard/keys.go index 34760f5..8f44517 100644 --- a/pkg/tui/views/dashboard/keys.go +++ b/pkg/tui/views/dashboard/keys.go @@ -18,6 +18,7 @@ type DashboardKeyMap struct { ChangeStatus key.Binding ChangePriority key.Binding ChangeType key.Binding + AddComment key.Binding AddIssue key.Binding DeleteIssue key.Binding } @@ -71,6 +72,10 @@ var defaultDashboardKeyMap = DashboardKeyMap{ key.WithKeys("t"), key.WithHelp("t", "change type"), ), + AddComment: key.NewBinding( + key.WithKeys("c"), + key.WithHelp("c", "add comment"), + ), AddIssue: key.NewBinding( key.WithKeys("a"), key.WithHelp("a", "add issue"), @@ -99,32 +104,37 @@ func (d *Model) handleKeyMsg(msg tea.KeyMsg) tea.Cmd { d.issueDetail.ScrollUp(1) case d.IsFocusedOnDetail() && key.Matches(msg, d.keyMap.ScrollDown): d.issueDetail.ScrollDown(1) - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.EditTitle): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.EditTitle): if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { d.startEditTitle(selected) cmd = d.titleInput.Focus() } - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.EditDescription): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.EditDescription): if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { d.startEditDescription(selected) cmd = d.descriptionInput.Focus() } - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.ChangeStatus): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.ChangeStatus): if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { d.startChooseStatus(selected) } - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.ChangePriority): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.ChangePriority): if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { d.startChoosePriority(selected) } - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.ChangeType): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.ChangeType): if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { d.startChooseType(selected) } - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.AddIssue): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.AddComment): + if selected := d.FocusedIssueList().SelectedItem(); selected.ID != "" { + d.startAddComment(selected) + cmd = d.commentInput.Focus() + } + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.AddIssue): d.startCreateIssue() cmd = d.createTitleInput.Focus() - case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && key.Matches(msg, d.keyMap.DeleteIssue): + case !d.editingTitle && !d.creatingIssue && !d.editingDescription && !d.choosingStatus && !d.choosingPriority && !d.confirmingDelete && !d.choosingType && !d.addingComment && key.Matches(msg, d.keyMap.DeleteIssue): fl := d.FocusedIssueList() if selected := fl.SelectedItem(); selected.ID != "" { d.startConfirmDelete(selected.ID, fl.Index()) diff --git a/pkg/tui/views/dashboard/model.go b/pkg/tui/views/dashboard/model.go index dde0979..11283fc 100644 --- a/pkg/tui/views/dashboard/model.go +++ b/pkg/tui/views/dashboard/model.go @@ -47,6 +47,9 @@ type Model struct { priorityIssueID string choosingType bool // true while choosing a type typeIssueID string + addingComment bool // true while adding a comment + commentInput textarea.Model + commentIssueID string feedbackChan chan models.ValidationFeedback quitChan chan bool currentFeedback models.ValidationFeedback @@ -89,15 +92,39 @@ func NewDashboard(app *app.App, feedbackChan chan models.ValidationFeedback, qui descTa.SetHeight(8) m.descriptionInput = descTa + commentTa := textarea.New() + commentTa.Placeholder = "Write your comment..." + commentTa.SetWidth(56) + commentTa.SetHeight(6) + m.commentInput = commentTa + if selected := m.issueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } else if selected := m.closedIssueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } return m } +// setDetailIssueWithComments sets the issue in the detail pane and loads its comments. +func (m *Model) setDetailIssueWithComments(issue models.Issue) { + m.issueDetail.SetIssue(issue) + if issue.ID == "" { + m.issueDetail.SetComments(nil) + return + } + comments, _ := m.app.Issues.GetIssueComments(context.Background(), issue.ID) + m.issueDetail.SetComments(comments) +} + +func (m *Model) startAddComment(selected ListIssue) { + m.addingComment = true + m.commentIssueID = selected.ID + m.commentInput.SetValue("") + m.commentInput.Reset() +} + func (m *Model) startEditTitle(selected ListIssue) { m.editingTitle = true m.editingIssueID = selected.ID @@ -203,11 +230,11 @@ func (m *Model) ToggleFocusedWindow() { m.focusedWindow = 1 - m.focusedWindow if m.focusedWindow == 0 { if selected := m.issueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } } else { if selected := m.closedIssueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } } m.issueDetail.SetFocused(m.IsFocusedOnDetail()) diff --git a/pkg/tui/views/dashboard/operations.go b/pkg/tui/views/dashboard/operations.go index 8d53ee9..07cfc37 100644 --- a/pkg/tui/views/dashboard/operations.go +++ b/pkg/tui/views/dashboard/operations.go @@ -2,6 +2,8 @@ package dashboard import ( "context" + "os" + "os/user" "github.com/LazyBachelor/LazyPM/internal/app" "github.com/LazyBachelor/LazyPM/internal/models" @@ -9,6 +11,19 @@ import ( tea "github.com/charmbracelet/bubbletea" ) +func defaultCommentAuthor() string { + if u, err := user.Current(); err == nil && u.Username != "" { + return u.Username + } + if s := os.Getenv("USER"); s != "" { + return s + } + if s := os.Getenv("USERNAME"); s != "" { + return s + } + return "user" +} + type issueTitleUpdatedMsg struct { IssueID string Err error @@ -49,6 +64,18 @@ type issueDeletedMsg struct { PreviousIndex int } +type issueCommentAddedMsg struct { + IssueID string + Err error +} + +func addIssueCommentCmd(app *app.App, issueID, author, text string) tea.Cmd { + return func() tea.Msg { + _, err := app.Issues.AddIssueComment(context.Background(), issueID, author, text) + return issueCommentAddedMsg{IssueID: issueID, Err: err} + } +} + func updateIssueTitleCmd(app *app.App, issueID, newTitle string) tea.Cmd { return func() tea.Msg { updates := map[string]interface{}{"title": newTitle} @@ -121,7 +148,7 @@ func (m *Model) refreshIssueListsAndSelectIssue(issueID string) tea.Cmd { closedSetCmd := m.closedIssueList.SetIssues(ClosedOnly(issues)) for _, issue := range issues { if issue.ID == issueID { - m.issueDetail.SetIssue(*issue) + m.setDetailIssueWithComments(*issue) break } } @@ -203,8 +230,17 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { } } - m.issueDetail.SetIssue(*selectedIssue) + m.setDetailIssueWithComments(*selectedIssue) return m, tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: selectedIssue.ID} }) + case issueCommentAddedMsg: + m.addingComment = false + m.commentIssueID = "" + m.commentInput.Blur() + m.commentInput.Reset() + if msg.Err != nil { + return m, nil + } + return m, m.refreshIssueListsAndSelectIssue(msg.IssueID) case issueDeletedMsg: m.confirmingDelete = false m.deleteConfirmID = "" @@ -221,7 +257,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { closedSetCmd := m.closedIssueList.SetIssues(closedIssues) // If there are no issues at all, clear the detail view and return. if len(openIssues) == 0 && len(closedIssues) == 0 { - m.issueDetail.SetIssue(models.Issue{}) + m.setDetailIssueWithComments(models.Issue{}) return m, tea.Sequence(setItemsCmd, closedSetCmd) } @@ -245,7 +281,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // Safety: if targetIssues is still empty here, just clear detail and return. if len(targetIssues) == 0 { - m.issueDetail.SetIssue(models.Issue{}) + m.setDetailIssueWithComments(models.Issue{}) return m, tea.Sequence(setItemsCmd, closedSetCmd) } @@ -254,7 +290,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { newIndex = len(targetIssues) - 1 } selectedIssue := targetIssues[newIndex] - m.issueDetail.SetIssue(*selectedIssue) + m.setDetailIssueWithComments(*selectedIssue) return m, tea.Sequence(setItemsCmd, closedSetCmd, func() tea.Msg { return selectIssueMsg{IssueID: selectedIssue.ID} }) @@ -388,6 +424,30 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return m, cmd } + if m.addingComment { + if msg.String() == "ctrl+s" || msg.String() == "enter" { + text := m.commentInput.Value() + if text != "" { + issueID := m.commentIssueID + m.addingComment = false + m.commentIssueID = "" + m.commentInput.Blur() + m.commentInput.Reset() + return m, addIssueCommentCmd(m.app, issueID, defaultCommentAuthor(), text) + } + } + if msg.String() == "esc" { + m.addingComment = false + m.commentIssueID = "" + m.commentInput.Blur() + m.commentInput.Reset() + return m, nil + } + var cmd tea.Cmd + m.commentInput, cmd = m.commentInput.Update(msg) + return m, cmd + } + if m.editingDescription { if msg.String() == "ctrl+s" { issueID := m.editingDescIssueID @@ -441,7 +501,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cmd, changed := m.issueList.Update(msg) if changed { if selected := m.issueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } } return m, cmd @@ -449,7 +509,7 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { cmd, changed := m.closedIssueList.Update(msg) if changed { if selected := m.closedIssueList.SelectedItem(); selected.ID != "" { - m.issueDetail.SetIssue(selected.Issue) + m.setDetailIssueWithComments(selected.Issue) } } return m, cmd diff --git a/pkg/tui/views/dashboard/view.go b/pkg/tui/views/dashboard/view.go index 2df8781..74aca51 100644 --- a/pkg/tui/views/dashboard/view.go +++ b/pkg/tui/views/dashboard/view.go @@ -70,6 +70,21 @@ func (m *Model) View() string { return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, editBox) } + if m.addingComment { + editBoxWidth := min(60, m.width-4) + m.commentInput.SetWidth(editBoxWidth - 2) + m.commentInput.SetHeight(8) + editContent := lipgloss.JoinVertical(lipgloss.Left, + styles.LabelStyle.Render("Add comment for "+m.commentIssueID+" (Ctrl+S or Enter to save, Esc to cancel):"), + m.commentInput.View(), + ) + editBox := styles.ContainerStyle. + Width(editBoxWidth). + BorderForeground(styles.PrimaryBorder). + Render(editContent) + return lipgloss.Place(m.width, m.height, lipgloss.Center, lipgloss.Center, editBox) + } + if m.editingDescription { editBoxWidth := min(60, m.width-4) m.descriptionInput.SetWidth(editBoxWidth - 2) From 77b38692c695d289d66117eeb7ea488c686135e8 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 14:00:35 +0100 Subject: [PATCH 2/4] align task with description add a complete with message in case we need that --- cmd/pm/tasks/createIssue.go | 38 +++++++++++++++++++++++++++------- internal/utils/check/expect.go | 8 +++++++ pkg/task/runner.go | 4 +++- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/cmd/pm/tasks/createIssue.go b/cmd/pm/tasks/createIssue.go index b10c32c..952b322 100644 --- a/cmd/pm/tasks/createIssue.go +++ b/cmd/pm/tasks/createIssue.go @@ -4,6 +4,7 @@ import ( "context" "fmt" + "github.com/LazyBachelor/LazyPM/internal/models" "github.com/LazyBachelor/LazyPM/internal/utils/check" ) @@ -12,10 +13,10 @@ const description = `You are tasked with creating a new issue in the project man This task will test your ability to use the issue creation workflow effectively. Your task: -1. Create a new issue with a clear title -2. Add a detailed description explaining what needs to be done -3. Assign the issue to yourself -4. Mark the issue as in-progress when you start working on it +1. Create a new issue with a the title "My first Issue" +2. Add this detailed description "I need to do some coding" +3. Assign the issue to yourself as "Me" +4. Mark the issue as In Progress when you start working on it 5. Close the issue once you've completed the work Make sure to fill out all the necessary details to help others understand the work item.` @@ -55,6 +56,8 @@ func (t *CreateIssueTask) Setup(ctx context.Context) error { return t.app.Issues.CreateIssue(ctx, t.setupIssue, "") } +var isInProgress = false + func (t *CreateIssueTask) Validate(ctx context.Context) ValidationFeedback { expect := check.NewExpector() @@ -63,9 +66,6 @@ func (t *CreateIssueTask) Validate(ctx context.Context) ValidationFeedback { return expect.ValidationFeedback } - expect.NotEmptyString(t.setupIssue.Assignee, - fmt.Sprintf("%s is not assigned to anyone", t.setupIssue.ID)) - if len(issues) == 0 { expect.Fail("No new issues created") return expect.ValidationFeedback @@ -73,8 +73,30 @@ func (t *CreateIssueTask) Validate(ctx context.Context) ValidationFeedback { issue := issues[0] - expect.Assert(len(issues) < 2, "Multiple issues were created instead of one") + expect.Assert(len(issues) < 2, "Multiple issues were created instead of one delete the extra issues and try again") + + expect.NotEmptyString(issue.Title, "Issue title should not be empty") + expect.Assert(issue.Title == "My first Issue", + fmt.Sprintf("Issue title does not match the expected value 'My first Issue', but was '%s'", issue.Title)) + expect.NotEmptyString(issue.Description, "Issue description should not be empty") + expect.Assert(issue.Description == "I need to do some coding", + fmt.Sprintf("Issue description does not match the expected value 'I need to do some coding', but was '%s'", issue.Description)) + + expect.Assert(issue.Assignee == "Me", + fmt.Sprintf("Issue should be assigned to 'Me', but was assigned to '%s'", issue.Assignee)) + + if issue.Status == models.StatusInProgress || isInProgress { + isInProgress = true + } else { + expect.Fail("Issue should be marked as in-progress when work starts") + } + + if !isInProgress { + return expect.ValidationFeedback + } else if issue.Status != models.StatusClosed { + expect.Fail("Issue should be set to Closed once the work is completed") + } return expect.Complete() } diff --git a/internal/utils/check/expect.go b/internal/utils/check/expect.go index cfa40a2..670fcdb 100644 --- a/internal/utils/check/expect.go +++ b/internal/utils/check/expect.go @@ -35,6 +35,14 @@ func (e *Expector) Complete() ValidationFeedback { return e.ValidationFeedback } +func (e *Expector) CompleteWithMessage(message string) ValidationFeedback { + e.Success = len(e.Errors()) == 0 + if !e.Success { + e.Message = message + } + return e.ValidationFeedback +} + func (e *Expector) Fail(message string) ValidationFeedback { e.Checks = append(e.Checks, NewCheck(message, false)) return e.ValidationFeedback diff --git a/pkg/task/runner.go b/pkg/task/runner.go index a9c4389..ea15b2b 100644 --- a/pkg/task/runner.go +++ b/pkg/task/runner.go @@ -100,7 +100,9 @@ func startValidationLoop(ctx context.Context, t Tasker, feedbackChan chan Valida case <-ticker.C: feedback := t.Validate(ctx) if feedback.Success { - feedback.Message = "Task completed successfully!" + if feedback.Message == "" { + feedback.Message = "Task completed successfully! Going back to the survey menu..." + } feedbackChan <- feedback time.Sleep(4 * time.Second) doneChan <- true From 81a046e9358c3a8da937c01ab9a602fe9d50dca4 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:20:47 +0100 Subject: [PATCH 3/4] Update cmd/pm/tasks/createIssue.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/createIssue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/createIssue.go b/cmd/pm/tasks/createIssue.go index 952b322..21cef28 100644 --- a/cmd/pm/tasks/createIssue.go +++ b/cmd/pm/tasks/createIssue.go @@ -13,7 +13,7 @@ const description = `You are tasked with creating a new issue in the project man This task will test your ability to use the issue creation workflow effectively. Your task: -1. Create a new issue with a the title "My first Issue" +1. Create a new issue with the title "My first Issue" 2. Add this detailed description "I need to do some coding" 3. Assign the issue to yourself as "Me" 4. Mark the issue as In Progress when you start working on it From a47ff2a39b71d5a01af9286b7681010b76d6915d Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 14:21:13 +0100 Subject: [PATCH 4/4] Update cmd/pm/tasks/createIssue.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/createIssue.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/createIssue.go b/cmd/pm/tasks/createIssue.go index 21cef28..c6757d4 100644 --- a/cmd/pm/tasks/createIssue.go +++ b/cmd/pm/tasks/createIssue.go @@ -73,7 +73,7 @@ func (t *CreateIssueTask) Validate(ctx context.Context) ValidationFeedback { issue := issues[0] - expect.Assert(len(issues) < 2, "Multiple issues were created instead of one delete the extra issues and try again") + expect.Assert(len(issues) < 2, "Multiple issues were created instead of one. Delete the extra issues and try again.") expect.NotEmptyString(issue.Title, "Issue title should not be empty") expect.Assert(issue.Title == "My first Issue",