From c3bbcfd83232fd4b550089d299c1e16cabffcbab Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 15:14:45 +0100 Subject: [PATCH 01/12] update coding task to alignt with latest iteration --- cmd/pm/tasks/codingTask.go | 181 ++++++++++++++++++++++++++++--------- 1 file changed, 137 insertions(+), 44 deletions(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 5b7d3e0..c06cb22 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -2,37 +2,80 @@ package tasks import ( "context" + "fmt" "os" + "strings" + "github.com/LazyBachelor/LazyPM/internal/models" "github.com/LazyBachelor/LazyPM/internal/utils/check" - "github.com/charmbracelet/huh" ) -const codingDescription = `You are tasked with writing a simple function. +const codingDescription = `You are tasked with doing a chore in the codebase. -This task will test your ability to write clean, working code. +This task will test your ablity to read and understand instructions, change text, and save it to a file. + +The MongoDB Driver dependency in the file is outdated and needs to be updated to the latest version. +This is a common task for developers, and it requires attention to detail and the ability to follow instructions carefully. Your task: -1. Review the requirements below -2. Write a function that takes two integers and returns their sum -3. The function should be named "Add" -4. The function should be part of the "coding" package -5. Save your code to the code.txt file +1. Assing this Issue to yourself as "Me" and mark it as "In Progress" +2. Create a New Issue and give it these details: + - Title: "Upgrade MongoDB Driver Dependency" + - Description: "We need to upgrade the MongoDB Driver dependency to the latest version." + - Status: "In Progress" + - Issue Type: "Chore" +3. A file will appear on your desktop named "code.txt". + Open it and follow the instructions inside. And save the file after you are done. +4. When you are done, mark this and the issue you made as "Closed".` -Requirements: -- Function name: Add -- Parameters: two integers -- Return value: integer (sum of the two inputs) -- Package: coding` +var textFileDescription = ` +Please upgrade the MongoDB Driver dependency in the go.mod file to the latest version. +It should be v1.17.9. After you are done, save the file and mark the task as completed. +############################################################` -var textFileContent = codingDescription + ` -Please write your code below this line! -############################################################ +var code = ` +require ( + charm.land/lipgloss/v2 v2.0.0-beta.3.0.20251106193318-19329a3e8410 + github.com/go-git/go-git/v6 v6.0.0-20260222090600-424e9964d3a3 + github.com/muesli/reflow v0.3.0 + github.com/steveyegge/beads v0.49.6 + go.mongodb.org/mongo-driver v1.17.8 + go.mongodb.org/mongo-driver/v2 v2.5.0 +) + +require ( + github.com/c-bata/go-prompt v0.2.6 + github.com/charmbracelet/bubbles v0.21.1 + github.com/charmbracelet/bubbletea v1.3.10 + github.com/charmbracelet/fang v0.4.4 + github.com/charmbracelet/huh v0.8.0 + github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834 + github.com/spf13/cobra v1.10.2 + golang.org/x/term v0.40.0 +) + +require ( + github.com/NYTimes/gziphandler v1.1.1 + github.com/a-h/templ v0.3.977 + github.com/donseba/go-htmx v1.12.1 + github.com/go-chi/chi/v5 v5.2.5 + github.com/go-playground/form/v4 v4.3.0 + github.com/go-playground/validator/v10 v10.30.1 + github.com/rs/cors v1.11.1 +) + +tool ( + github.com/a-h/templ/cmd/templ + github.com/haatos/goshipit/cmd/gsi +) ` +var textFileContent = codingDescription + textFileDescription + "\n" + code + type CodingTask struct { - done bool - app *App + done bool + setupIssue *Issue + app *App } func NewCodingTask(app *App) *CodingTask { @@ -48,35 +91,11 @@ func (t *CodingTask) Details() TaskDetails { } func (t *CodingTask) Questions(interfaceType InterfaceType) (questions Questions) { - return BaseQuestions(interfaceType). - With( - ReplQuestion(interfaceType, - huh.NewConfirm().Key("repl_experience").Title("Question only for REPL interface")), - ). - With( - WebQuestion(interfaceType, - huh.NewInput().Key("web_feedback").Title("Question only for Web interface")), - ). - With( - TUIQuestion(interfaceType, - huh.NewConfirm().Key("tui_experience").Title("Question only for TUI interface")), - ). - With( - Question( - huh.NewConfirm().Key("final_confirmation").Title("One last question for all interfaces!")), - ) + return BaseQuestions(interfaceType) } func (t *CodingTask) QuestionnaireKeys(interfaceType InterfaceType) []string { keys := []string{"task_completed", "task_difficulty", "final_confirmation"} - switch interfaceType { - case InterfaceTypeREPL: - keys = append(keys, "repl_experience") - case InterfaceTypeWeb: - keys = append(keys, "web_feedback") - case InterfaceTypeTUI: - keys = append(keys, "tui_experience") - } return keys } @@ -85,6 +104,17 @@ func (t *CodingTask) Setup(ctx context.Context) error { return err } + t.setupIssue = NewIssueBuilder(). + WithTitle("Coding Task - Upgrade MongoDB Driver"). + WithDescription(codingDescription). + WithStatus(models.StatusOpen). + WithIssueType(models.TypeTask). + Build() + + if err := t.app.Issues.CreateIssue(ctx, t.setupIssue, "LazyPM"); err != nil { + return err + } + if err := os.WriteFile("./code.txt", []byte(textFileContent), 0644); err != nil { return err } @@ -94,6 +124,69 @@ func (t *CodingTask) Setup(ctx context.Context) error { func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { expect := check.NewExpector() - expect.Assert(true, "This task is always valid") + + issues, err := FetchIssues(ctx, t.app, t.setupIssue) + if err != nil { + return expect.ValidationFeedback + } + + expect.Assert(t.setupIssue.Assignee == "Me", "The original issue should be assigned to 'Me'. Please assign the issue to yourself.") + expect.Assert(len(issues) > 0, "No new issues created. Please create an issue with the specified details.") + + if len(issues) == 0 { + expect.Fail("No new issues created") + return expect.ValidationFeedback + } + + issue := issues[0] + + 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 == "Upgrade MongoDB Driver Dependency", + fmt.Sprintf("Issue title does not match the expected value 'Upgrade MongoDB Driver Dependency', but was '%s'", issue.Title)) + + expect.NotEmptyString(issue.Description, "Issue description should not be empty") + expect.Assert(issue.Description == "We need to upgrade the MongoDB Driver dependency to the latest version.", + fmt.Sprintf("Issue description does not match the expected value 'We need to upgrade the MongoDB Driver dependency to the latest version.', but was '%s'", issue.Description)) + + expect.Assert(issue.IssueType == models.TypeChore, + fmt.Sprintf("Issue type should be 'Chore', but was '%s'", issue.IssueType)) + + 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 _, err := os.Stat("./code.txt"); os.IsNotExist(err) { + expect.Fail("The code.txt file should exist on the desktop. Please create the file with the specified content.") + return expect.ValidationFeedback + } + + fileContent, err := os.ReadFile("./code.txt") + if err != nil { + expect.Fail("Error reading code.txt file: " + err.Error()) + return expect.ValidationFeedback + } + + code, ok := strings.CutPrefix(string(fileContent), codingDescription+textFileDescription+"\n") + if !ok { + expect.Fail("The content of code.txt does not match the expected format. Please ensure the file contains the correct instructions and code.") + return expect.ValidationFeedback + } + + expect.Assert(strings.Contains(code, "go.mongodb.org/mongo-driver v1.17.9"), + "The go.mod file should still contain the old version of the MongoDB Driver (v1.17.8). Please make sure to update it to the latest version (v1.17.9).") + + 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() } From 817dbc57b7265bcadc482bb9ea48dd93b2b1988c Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:32:13 +0100 Subject: [PATCH 02/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index c06cb22..f73083c 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -180,7 +180,7 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { } expect.Assert(strings.Contains(code, "go.mongodb.org/mongo-driver v1.17.9"), - "The go.mod file should still contain the old version of the MongoDB Driver (v1.17.8). Please make sure to update it to the latest version (v1.17.9).") + "The go.mod snippet in code.txt should contain the updated MongoDB Driver version (v1.17.9). Please make sure you have updated the dependency in the snippet accordingly.") if !isInProgress { return expect.ValidationFeedback From 077cbc96e8bf1f9d3295a774a4331c1a90f79e43 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:32:37 +0100 Subject: [PATCH 03/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index f73083c..009a013 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -186,6 +186,9 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { return expect.ValidationFeedback } else if issue.Status != models.StatusClosed { expect.Fail("Issue should be set to Closed once the work is completed") + } else { + expect.Assert(t.setupIssue.Status == models.StatusClosed, + "The original setup issue should be set to Closed once the work is completed") } return expect.Complete() From f0025f8929a96cd35ff626d33d07b1080725ece2 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:32:55 +0100 Subject: [PATCH 04/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 009a013..4866145 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -131,6 +131,7 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { } expect.Assert(t.setupIssue.Assignee == "Me", "The original issue should be assigned to 'Me'. Please assign the issue to yourself.") + expect.Assert(t.setupIssue.Status == models.StatusInProgress, "The original issue should be marked as In Progress before starting work. Please update the issue status to In Progress.") expect.Assert(len(issues) > 0, "No new issues created. Please create an issue with the specified details.") if len(issues) == 0 { From 003fae4193e3bbb2865d4f0dfa313d2095c9a9bb Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:33:08 +0100 Subject: [PATCH 05/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 4866145..fc51621 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -12,7 +12,7 @@ import ( const codingDescription = `You are tasked with doing a chore in the codebase. -This task will test your ablity to read and understand instructions, change text, and save it to a file. +This task will test your ability to read and understand instructions, change text, and save it to a file. The MongoDB Driver dependency in the file is outdated and needs to be updated to the latest version. This is a common task for developers, and it requires attention to detail and the ability to follow instructions carefully. From 1f51336288867b10cea7878ec56c33c9c94acd61 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:33:18 +0100 Subject: [PATCH 06/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index fc51621..93b8710 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -18,7 +18,7 @@ The MongoDB Driver dependency in the file is outdated and needs to be updated to This is a common task for developers, and it requires attention to detail and the ability to follow instructions carefully. Your task: -1. Assing this Issue to yourself as "Me" and mark it as "In Progress" +1. Assign this Issue to yourself as "Me" and mark it as "In Progress" 2. Create a New Issue and give it these details: - Title: "Upgrade MongoDB Driver Dependency" - Description: "We need to upgrade the MongoDB Driver dependency to the latest version." From 4f70142316c69e26740005d093f8c8de7912f1bf Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:33:30 +0100 Subject: [PATCH 07/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 93b8710..123f0e4 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -24,7 +24,7 @@ Your task: - Description: "We need to upgrade the MongoDB Driver dependency to the latest version." - Status: "In Progress" - Issue Type: "Chore" -3. A file will appear on your desktop named "code.txt". +3. A file will appear in the current directory named "code.txt". Open it and follow the instructions inside. And save the file after you are done. 4. When you are done, mark this and the issue you made as "Closed".` From a907de5b940f8088d0aa51b5d1e524b35a3b6ca0 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Wed, 4 Mar 2026 17:33:48 +0100 Subject: [PATCH 08/12] Update cmd/pm/tasks/codingTask.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- cmd/pm/tasks/codingTask.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 123f0e4..388d6b0 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -95,7 +95,7 @@ func (t *CodingTask) Questions(interfaceType InterfaceType) (questions Questions } func (t *CodingTask) QuestionnaireKeys(interfaceType InterfaceType) []string { - keys := []string{"task_completed", "task_difficulty", "final_confirmation"} + keys := []string{"task_completed", "task_difficulty"} return keys } From 6e1c46948a0067c53b816c9c7e8a7413ae12c10e Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 17:49:32 +0100 Subject: [PATCH 09/12] expand width of task text box --- pkg/task/taskui.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/task/taskui.go b/pkg/task/taskui.go index cfdbea0..2f7086b 100644 --- a/pkg/task/taskui.go +++ b/pkg/task/taskui.go @@ -69,7 +69,7 @@ func (m TaskModel) View() string { style.TextStyle.Render("Terminal too small.")) } - boxWidth := min(m.width-10, 80) + boxWidth := min(m.width-10, 120) detailsText := fmt.Sprintf("Time to complete: %s | Difficulty: %s", m.TimeToComplete, m.Difficulty) From 44d4b0e543fb4343649d1abfd1f2232e470296d6 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 17:49:49 +0100 Subject: [PATCH 10/12] make sure we get the checks --- pkg/repl/repl.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/repl/repl.go b/pkg/repl/repl.go index 091d0f0..607100d 100644 --- a/pkg/repl/repl.go +++ b/pkg/repl/repl.go @@ -129,6 +129,7 @@ func (r *REPL) watchValidation() { r.app.CurrentFeedback = &ValidationFeedback{ Success: feedback.Success, Message: feedback.Message, + Checks: feedback.Checks, } } if feedback.Success { From 5a8b9fc9fbeef1ef5d5510073a33398320d9544c Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 17:50:00 +0100 Subject: [PATCH 11/12] print the checks --- internal/commands/survey/status.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/commands/survey/status.go b/internal/commands/survey/status.go index 2168d18..0e5a954 100644 --- a/internal/commands/survey/status.go +++ b/internal/commands/survey/status.go @@ -25,6 +25,13 @@ func runStatusCmd(cmd *cobra.Command, args []string) error { return nil } - cmd.Print(app.CurrentFeedback.Message) + cmd.Println(app.CurrentFeedback.Message) + for _, check := range app.CurrentFeedback.Checks { + if check.Valid { + cmd.Printf("✅ %s\n", check.Message) + } else { + cmd.Printf("❌ %s\n", check.Message) + } + } return nil } From 7d2c00c582f2f384e2a36274fa5aded57cafc2ed Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Mar 2026 17:50:24 +0100 Subject: [PATCH 12/12] update coding task for better readability --- cmd/pm/tasks/codingTask.go | 40 +++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/cmd/pm/tasks/codingTask.go b/cmd/pm/tasks/codingTask.go index 388d6b0..5df0ec3 100644 --- a/cmd/pm/tasks/codingTask.go +++ b/cmd/pm/tasks/codingTask.go @@ -122,6 +122,8 @@ func (t *CodingTask) Setup(ctx context.Context) error { return nil } +var codeTaskInProgress = false + func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { expect := check.NewExpector() @@ -130,9 +132,14 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { return expect.ValidationFeedback } - expect.Assert(t.setupIssue.Assignee == "Me", "The original issue should be assigned to 'Me'. Please assign the issue to yourself.") - expect.Assert(t.setupIssue.Status == models.StatusInProgress, "The original issue should be marked as In Progress before starting work. Please update the issue status to In Progress.") - expect.Assert(len(issues) > 0, "No new issues created. Please create an issue with the specified details.") + expect.Assert(t.setupIssue.Assignee == "Me", + "The original issue should be assigned to 'Me'.") + + expect.Assert(t.setupIssue.Status == models.StatusInProgress, + "The original issue should be marked as In Progress before starting work.") + + expect.Assert(len(issues) > 0, + "No new issues created. Please create an issue with the specified details.") if len(issues) == 0 { expect.Fail("No new issues created") @@ -141,15 +148,20 @@ func (t *CodingTask) 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.NotEmptyString(issue.Title, "Issue title should not be empty") expect.Assert(issue.Title == "Upgrade MongoDB Driver Dependency", fmt.Sprintf("Issue title does not match the expected value 'Upgrade MongoDB Driver Dependency', but was '%s'", issue.Title)) - expect.NotEmptyString(issue.Description, "Issue description should not be empty") + expect.NotEmptyString(issue.Description, + "Issue description should not be empty") + expect.Assert(issue.Description == "We need to upgrade the MongoDB Driver dependency to the latest version.", - fmt.Sprintf("Issue description does not match the expected value 'We need to upgrade the MongoDB Driver dependency to the latest version.', but was '%s'", issue.Description)) + fmt.Sprintf("Issue description does not match 'We need to upgrade the MongoDB Driver dependency to the latest version.', but was '%s'", issue.Description)) expect.Assert(issue.IssueType == models.TypeChore, fmt.Sprintf("Issue type should be 'Chore', but was '%s'", issue.IssueType)) @@ -157,14 +169,14 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { 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 + if issue.Status == models.StatusInProgress || codeTaskInProgress { + codeTaskInProgress = true } else { - expect.Fail("Issue should be marked as in-progress when work starts") + expect.Fail("Issue should be marked as In Progress when work starts") } if _, err := os.Stat("./code.txt"); os.IsNotExist(err) { - expect.Fail("The code.txt file should exist on the desktop. Please create the file with the specified content.") + expect.Fail("The code.txt file should exist on the desktop.") return expect.ValidationFeedback } @@ -176,14 +188,14 @@ func (t *CodingTask) Validate(ctx context.Context) ValidationFeedback { code, ok := strings.CutPrefix(string(fileContent), codingDescription+textFileDescription+"\n") if !ok { - expect.Fail("The content of code.txt does not match the expected format. Please ensure the file contains the correct instructions and code.") + expect.Fail("The content of code.txt does not match the expected format.") return expect.ValidationFeedback } expect.Assert(strings.Contains(code, "go.mongodb.org/mongo-driver v1.17.9"), - "The go.mod snippet in code.txt should contain the updated MongoDB Driver version (v1.17.9). Please make sure you have updated the dependency in the snippet accordingly.") + "The MongoDB Driver dependency should be updated to version v1.17.9 in the file.") - if !isInProgress { + if !codeTaskInProgress { return expect.ValidationFeedback } else if issue.Status != models.StatusClosed { expect.Fail("Issue should be set to Closed once the work is completed")