From 7eadda8e33e6dd4c2afa21fff415f7a78148223d Mon Sep 17 00:00:00 2001 From: Moira Daniella A Sebastian Date: Wed, 4 Feb 2026 18:21:06 +0100 Subject: [PATCH 01/20] Added title and description for CREATE ISSUE CLI --- pkg/cli/commands/create.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/pkg/cli/commands/create.go b/pkg/cli/commands/create.go index 7b8704d..bf5c700 100644 --- a/pkg/cli/commands/create.go +++ b/pkg/cli/commands/create.go @@ -1,13 +1,19 @@ package commands import ( - "github.com/LazyBachelor/LazyPM/internal/models" "fmt" "os" + "github.com/LazyBachelor/LazyPM/internal/models" + "github.com/spf13/cobra" ) +var ( + createTitle string + createDescription string +) + var createCmd = &cobra.Command{ Use: "create", Short: "Create a new issue", @@ -15,10 +21,16 @@ var createCmd = &cobra.Command{ RunE: runCreateCmd, } +func init() { + createCmd.Flags().StringVar(&createTitle, "title", "", "Issue title") + _ = createCmd.MarkFlagRequired("title") + createCmd.Flags().StringVar(&createDescription, "desc", "", "Issue description") +} + func runCreateCmd(cmd *cobra.Command, args []string) error { issue := &models.Issue{ - Title: "test", - Description: "This is a test issue created by the CLI.", + Title: createTitle, + Description: createDescription, Status: models.StatusOpen, IssueType: models.TypeBug, Priority: 0, From 16898301e61bbafd5b9eb1989d864093748a068a Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Feb 2026 19:46:39 +0100 Subject: [PATCH 02/20] gitignore .idea --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 62a01e9..4f41aae 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .pm *.db *.ext -bin \ No newline at end of file +bin +.idea \ No newline at end of file From 640bc45f2ca58be5fa7afad7ef707b430181101b Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Feb 2026 20:19:11 +0100 Subject: [PATCH 03/20] just return to avoid printing error twice --- cmd/cli/main.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/cmd/cli/main.go b/cmd/cli/main.go index 54e7634..d4f103d 100644 --- a/cmd/cli/main.go +++ b/cmd/cli/main.go @@ -1,11 +1,10 @@ package main import ( + "context" + "github.com/LazyBachelor/LazyPM/internal/service" "github.com/LazyBachelor/LazyPM/pkg/cli" - "context" - "fmt" - "os" ) func main() { @@ -16,7 +15,6 @@ func main() { } if err := cli.Run(context.Background(), config); err != nil { - fmt.Fprintf(os.Stderr, "Error: %v\n", err) - os.Exit(1) + return } } From a92cb71081dbea8ba528c3c973da0161025cfe61 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Feb 2026 20:19:31 +0100 Subject: [PATCH 04/20] disable completon command --- pkg/cli/commands/root.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/cli/commands/root.go b/pkg/cli/commands/root.go index 9cfa819..7f3488f 100644 --- a/pkg/cli/commands/root.go +++ b/pkg/cli/commands/root.go @@ -21,4 +21,5 @@ func Execute(services *service.Services) error { func init() { rootCmd.AddCommand(createCmd) + rootCmd.CompletionOptions.DisableDefaultCmd = true } From 3a7f48fc4333a547a664bee410195f0fac859f4d Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Feb 2026 20:19:53 +0100 Subject: [PATCH 05/20] add other flags and validation --- pkg/cli/commands/create.go | 56 ++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/pkg/cli/commands/create.go b/pkg/cli/commands/create.go index bf5c700..5cbfba1 100644 --- a/pkg/cli/commands/create.go +++ b/pkg/cli/commands/create.go @@ -2,7 +2,6 @@ package commands import ( "fmt" - "os" "github.com/LazyBachelor/LazyPM/internal/models" @@ -10,37 +9,70 @@ import ( ) var ( - createTitle string createDescription string + createStatus string + createType string + createPriority int ) var createCmd = &cobra.Command{ - Use: "create", + Use: "issue [title]", Short: "Create a new issue", Long: `Create a new issue with the specified details.`, RunE: runCreateCmd, + Args: cobra.ExactArgs(1), } func init() { - createCmd.Flags().StringVar(&createTitle, "title", "", "Issue title") - _ = createCmd.MarkFlagRequired("title") - createCmd.Flags().StringVar(&createDescription, "desc", "", "Issue description") + createCmd.Flags().StringVarP(&createDescription, "desc", "d", "", "Issue description") + createCmd.Flags().StringVarP(&createStatus, "status", "s", "open", "Issue status(open, closed, in_progress)") + createCmd.Flags().StringVarP(&createType, "type", "t", "task", "Issue type(bug, feature, task)") + createCmd.Flags().IntVarP(&createPriority, "priority", "p", 0, "Issue priority(0-5)") } func runCreateCmd(cmd *cobra.Command, args []string) error { + createTitle := args[0] + + if createTitle == "" { + return fmt.Errorf("issue title cannot be empty") + } + issue := &models.Issue{ Title: createTitle, Description: createDescription, - Status: models.StatusOpen, - IssueType: models.TypeBug, - Priority: 0, + Status: models.Status(createStatus), + IssueType: models.IssueType(createType), + Priority: createPriority, } err := svc.Beads.CreateIssue(cmd.Context(), issue, "test_actor") if err != nil { - fmt.Fprintf(os.Stderr, "Error creating issue: %v\n", err) - os.Exit(1) + return fmt.Errorf("error creating issue: %w", err) } - fmt.Printf("Created issue: %s\n", issue.ID) + + str := fmt.Sprintf("Created issue with ID: %s\n", issue.ID) + + if issue.Title != "" { + str += fmt.Sprintf("Title: %s\n", issue.Title) + } + + if issue.Description != "" { + str += fmt.Sprintf("Description: %s\n", issue.Description) + } + + if issue.Status != "" { + str += fmt.Sprintf("Status: %s\n", issue.Status) + } + + if issue.IssueType != "" { + str += fmt.Sprintf("Type: %s\n", issue.IssueType) + } + + if issue.Priority != 0 { + str += fmt.Sprintf("Priority: %d\n", issue.Priority) + } + + fmt.Print(str) + return nil } From ee6ed50143787a335448d94057516a81b89a0028 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Wed, 4 Feb 2026 20:23:32 +0100 Subject: [PATCH 06/20] cange back use to create --- pkg/cli/commands/create.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/cli/commands/create.go b/pkg/cli/commands/create.go index 5cbfba1..1403271 100644 --- a/pkg/cli/commands/create.go +++ b/pkg/cli/commands/create.go @@ -16,7 +16,7 @@ var ( ) var createCmd = &cobra.Command{ - Use: "issue [title]", + Use: "create [title]", Short: "Create a new issue", Long: `Create a new issue with the specified details.`, RunE: runCreateCmd, From 4a8ad82558a3957e5a3cfdac295f5da3579577a5 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 11:05:36 +0100 Subject: [PATCH 07/20] move help and completion command to group --- pkg/cli/commands/root.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/cli/commands/root.go b/pkg/cli/commands/root.go index 7f3488f..ebe772f 100644 --- a/pkg/cli/commands/root.go +++ b/pkg/cli/commands/root.go @@ -21,5 +21,8 @@ func Execute(services *service.Services) error { func init() { rootCmd.AddCommand(createCmd) - rootCmd.CompletionOptions.DisableDefaultCmd = true + rootCmd.CompletionOptions.DisableDefaultCmd = false + rootCmd.AddGroup(&cobra.Group{ID: "other", Title: "Helping Commands"}) + rootCmd.SetCompletionCommandGroupID("other") + rootCmd.SetHelpCommandGroupID("other") } From 5f5826d13a8acef29f0bdee707d4a6154e54304e Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 11:07:09 +0100 Subject: [PATCH 08/20] make title be read from multible args instead of one. add completions to crate command --- pkg/cli/commands/create.go | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/pkg/cli/commands/create.go b/pkg/cli/commands/create.go index 1403271..ea2e529 100644 --- a/pkg/cli/commands/create.go +++ b/pkg/cli/commands/create.go @@ -2,6 +2,7 @@ package commands import ( "fmt" + "strings" "github.com/LazyBachelor/LazyPM/internal/models" @@ -19,8 +20,11 @@ var createCmd = &cobra.Command{ Use: "create [title]", Short: "Create a new issue", Long: `Create a new issue with the specified details.`, - RunE: runCreateCmd, - Args: cobra.ExactArgs(1), + Example: `pm create New issue -d "Description" -s open -t task -p 3 +pm create Fix bug --desc "Bug description" --status in_progress --type bug --priority 5`, + RunE: runCreateCmd, + Aliases: []string{"add"}, + Args: cobra.MinimumNArgs(1), } func init() { @@ -28,10 +32,22 @@ func init() { createCmd.Flags().StringVarP(&createStatus, "status", "s", "open", "Issue status(open, closed, in_progress)") createCmd.Flags().StringVarP(&createType, "type", "t", "task", "Issue type(bug, feature, task)") createCmd.Flags().IntVarP(&createPriority, "priority", "p", 0, "Issue priority(0-5)") + + createCmd.RegisterFlagCompletionFunc("type", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"bug", "feature", "task"}, cobra.ShellCompDirectiveDefault + }) + + createCmd.RegisterFlagCompletionFunc("status", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"open", "closed", "in_progress"}, cobra.ShellCompDirectiveDefault + }) + + createCmd.RegisterFlagCompletionFunc("priority", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"0", "1", "2", "3", "4", "5"}, cobra.ShellCompDirectiveDefault + }) } func runCreateCmd(cmd *cobra.Command, args []string) error { - createTitle := args[0] + createTitle := strings.Join(args, " ") if createTitle == "" { return fmt.Errorf("issue title cannot be empty") From d3911ec1f9b3c5f58801a97e2c07703791f063fe Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 12:48:09 +0100 Subject: [PATCH 09/20] add ls command for listing all issues with query and filter tags --- pkg/cli/commands/ls.go | 91 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 pkg/cli/commands/ls.go diff --git a/pkg/cli/commands/ls.go b/pkg/cli/commands/ls.go new file mode 100644 index 0000000..76e68aa --- /dev/null +++ b/pkg/cli/commands/ls.go @@ -0,0 +1,91 @@ +package commands + +import ( + "strings" + + "github.com/LazyBachelor/LazyPM/internal/models" + "github.com/spf13/cobra" +) + +var ( + titleFlag string + descriptionFlag string + statusFlag string + typeFlag string + priorityFlag int + limit int = 25 +) + +const ( + lsExamples = `pm ls [id|title|description] +pm ls --status open --type bug +pm ls --title "New feature" --desc "feature description" +pm ls -p 1 -l 10` +) + +var getIssuesCmd = &cobra.Command{ + Use: "ls [search query]", + Short: "List all issues", + Long: `List all issues in the project management system.`, + Aliases: []string{"list", "search"}, + Example: lsExamples, + Args: cobra.MinimumNArgs(0), + RunE: runGetIssuesCmd, +} + +func runGetIssuesCmd(cmd *cobra.Command, args []string) error { + + queryArg := strings.Join(args, " ") + + filter := models.IssueFilter{ + TitleSearch: titleFlag, + DescriptionContains: descriptionFlag, + Limit: limit, + } + + if cmd.Flags().Changed("status") { + s := models.Status(statusFlag) + filter.Status = &s + } + if cmd.Flags().Changed("type") { + t := models.IssueType(typeFlag) + filter.IssueType = &t + } + if cmd.Flags().Changed("priority") { + filter.Priority = &priorityFlag + } + + issuesPtr, err := svc.Beads.SearchIssues(cmd.Context(), queryArg, filter) + if err != nil { + return err + } + + issues := models.IssuesPtrToIssues(issuesPtr) + + models.PrintIssues(issues) + + return nil +} + +func init() { + getIssuesCmd.Flags().StringVar(&titleFlag, "title", "", "Filter issues by title") + getIssuesCmd.Flags().StringVarP(&descriptionFlag, "desc", "d", "", "Filter issues by description") + getIssuesCmd.Flags().StringVarP(&statusFlag, "status", "s", "", "Filter issues by status (open, closed, in_progress)") + getIssuesCmd.Flags().StringVarP(&typeFlag, "type", "t", "", "Filter issues by type (bug, feature, task)") + getIssuesCmd.Flags().IntVarP(&priorityFlag, "priority", "p", 0, "Filter issues by priority (0-5)") + getIssuesCmd.Flags().IntVarP(&limit, "limit", "l", 25, "Limit the number of issues returned") + + getIssuesCmd.RegisterFlagCompletionFunc("status", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"open", "closed", "in_progress"}, cobra.ShellCompDirectiveDefault + }) + + getIssuesCmd.RegisterFlagCompletionFunc("type", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"bug", "feature", "task"}, cobra.ShellCompDirectiveDefault + }) + + getIssuesCmd.RegisterFlagCompletionFunc("priority", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + return []string{"0", "1", "2", "3", "4", "5"}, cobra.ShellCompDirectiveDefault + }) + + rootCmd.AddCommand(getIssuesCmd) +} From 7e0c45e9a2629c71f8b532132730a6045318c404 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 12:49:23 +0100 Subject: [PATCH 10/20] add helper for printing issue list. add helper for converting issue pointer to issue --- internal/models/beads.go | 41 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/internal/models/beads.go b/internal/models/beads.go index d009e86..83ec37b 100644 --- a/internal/models/beads.go +++ b/internal/models/beads.go @@ -1,6 +1,13 @@ package models -import "github.com/steveyegge/beads" +import ( + "fmt" + "os" + "text/tabwriter" + + "github.com/muesli/reflow/truncate" + "github.com/steveyegge/beads" +) type ( Issue = beads.Issue @@ -71,3 +78,35 @@ const ( EventLabelRemoved = beads.EventLabelRemoved EventCompacted = beads.EventCompacted ) + +func IssuesPtrToIssues(issuePtr []*Issue) []Issue { + issues := make([]Issue, 0, len(issuePtr)) + for _, issue := range issuePtr { + issues = append(issues, *issue) + } + return issues +} + +func FormatIssueRow(issue Issue) string { + return fmt.Sprintf( + "%s\t%s\t%s\t%s\t%s\t%d", + truncate.String(issue.ID, 5), + truncate.StringWithTail(issue.Title, 25, "..."), + truncate.StringWithTail(issue.Description, 40, "..."), + issue.Status, + issue.IssueType, + issue.Priority, + ) +} + +func PrintIssues(issues []Issue) { + w := tabwriter.NewWriter(os.Stdout, 8, 10, 5, ' ', 0) + + fmt.Fprintln(w, "ID\tTITLE\tDESCRIPTION\tSTATUS\tTYPE\tPRIORITY") + + for _, issue := range issues { + fmt.Fprintln(w, FormatIssueRow(issue)) + } + + w.Flush() +} From 98df41ff54a158e53f81f5df2c8b9d14736663f4 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 12:50:01 +0100 Subject: [PATCH 11/20] add read/describe command for viewing issue details --- pkg/cli/commands/read.go | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pkg/cli/commands/read.go diff --git a/pkg/cli/commands/read.go b/pkg/cli/commands/read.go new file mode 100644 index 0000000..0116b96 --- /dev/null +++ b/pkg/cli/commands/read.go @@ -0,0 +1,63 @@ +package commands + +import ( + "strings" + + "github.com/spf13/cobra" +) + +var getIssueCmd = &cobra.Command{ + Use: "describe [issue ID]", + Aliases: []string{"get", "read"}, + Short: "Gets issue details", + Long: `Gets issue details by ID`, + RunE: runGetCmd, + Args: cobra.ExactArgs(1), + ValidArgsFunction: completeIssues, +} + +func runGetCmd(cmd *cobra.Command, args []string) error { + issueID := args[0] + + issue, err := svc.Beads.GetIssue(cmd.Context(), issueID) + if err != nil { + return err + } + + cmd.Printf("Title: %s\n", issue.Title) + cmd.Printf("Description: %s\n", issue.Description) + cmd.Printf("Status: %s\n", issue.Status) + cmd.Printf("Type: %s\n", issue.IssueType) + cmd.Printf("Priority: %d\n", issue.Priority) + + return nil +} + +func init() { + rootCmd.AddCommand(getIssueCmd) +} + +func completeIssues(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if svc == nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + issues, err := svc.Beads.AllIssues(cmd.Context()) + if err != nil { + return nil, cobra.ShellCompDirectiveNoFileComp + } + + var completions []string + for _, issue := range issues { + + if strings.HasPrefix(issue.Title, toComplete) { + completions = append(completions, issue.ID) + } + + if strings.HasPrefix(issue.ID, toComplete) { + completions = append(completions, issue.ID) + } + } + + return completions, cobra.ShellCompDirectiveNoFileComp +} From 6caf654af9d471a2314799803eb4408b66803dcc Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 13:24:24 +0100 Subject: [PATCH 12/20] add variable to service config to store rootcmd name --- internal/service/service.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/internal/service/service.go b/internal/service/service.go index 344ac92..c6afc25 100644 --- a/internal/service/service.go +++ b/internal/service/service.go @@ -1,16 +1,18 @@ package service import ( - "github.com/LazyBachelor/LazyPM/internal/models" - "github.com/LazyBachelor/LazyPM/internal/storage" "context" "time" + "github.com/LazyBachelor/LazyPM/internal/models" + "github.com/LazyBachelor/LazyPM/internal/storage" + "github.com/google/uuid" "github.com/steveyegge/beads" ) type Config struct { + RootCmd string WebAddress string BeadsDBPath string IssuePrefix string From 12748ede0050b0cf99e2295c8b3bf7ce8f88f6ff Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 13:25:34 +0100 Subject: [PATCH 13/20] use new rootCmd name var --- cmd/{cli => pm}/main.go | 4 ++-- pkg/cli/commands/root.go | 9 +++++---- 2 files changed, 7 insertions(+), 6 deletions(-) rename cmd/{cli => pm}/main.go (78%) diff --git a/cmd/cli/main.go b/cmd/pm/main.go similarity index 78% rename from cmd/cli/main.go rename to cmd/pm/main.go index d4f103d..5ad70e1 100644 --- a/cmd/cli/main.go +++ b/cmd/pm/main.go @@ -3,12 +3,12 @@ package main import ( "context" - "github.com/LazyBachelor/LazyPM/internal/service" "github.com/LazyBachelor/LazyPM/pkg/cli" ) func main() { - config := service.Config{ + config := cli.CLIConfig{ + RootCmd: "pm", IssuePrefix: "pm", BeadsDBPath: "./.pm/db.db", StatisticsStoragePath: "./.pm/stats.json", diff --git a/pkg/cli/commands/root.go b/pkg/cli/commands/root.go index ebe772f..edee54c 100644 --- a/pkg/cli/commands/root.go +++ b/pkg/cli/commands/root.go @@ -9,20 +9,21 @@ import ( var svc *service.Services var rootCmd = &cobra.Command{ - Use: "pm", Short: "Project Management CLI", Long: `Project Management CLI for managing issues and tasks.`, } func Execute(services *service.Services) error { svc = services + rootCmd.Use = svc.Config.RootCmd return rootCmd.Execute() } func init() { rootCmd.AddCommand(createCmd) + rootCmd.CompletionOptions.DisableDefaultCmd = false - rootCmd.AddGroup(&cobra.Group{ID: "other", Title: "Helping Commands"}) - rootCmd.SetCompletionCommandGroupID("other") - rootCmd.SetHelpCommandGroupID("other") + rootCmd.AddGroup(&cobra.Group{ID: "help", Title: "Helping Commands"}) + rootCmd.SetCompletionCommandGroupID("help") + rootCmd.SetHelpCommandGroupID("help") } From d3207c26fb31ba0667c8e2a33edf4d5d55004bf0 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 13:26:02 +0100 Subject: [PATCH 14/20] add completion scripts for command line autocomplete --- Makefile | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ee8af5e..2e82291 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,5 @@ +SHELL := /bin/bash + tidy: go mod tidy @@ -27,4 +29,34 @@ tw: watch: @make -j2 dev tw -.PHONY: tidy clean build cli tui web dev tw \ No newline at end of file +completions: + @go build -o ./bin/pm ./cmd/pm + @mkdir -p ./bin + @./bin/pm completion bash > ./bin/pm_bash.sh + @./bin/pm completion zsh > ./bin/pm_zsh.sh + @./bin/pm completion fish > ./bin/pm_fish.sh + @./bin/pm completion powershell > ./bin/pm_powershell.ps1 + +install-bash-temp: completions + @go install ./cmd/pm + @source ./bin/pm_bash.sh + +install-zsh-temp: completions + @go install ./cmd/pm + @source ./bin/pm_zsh.sh + +install-fish-temp: completions + @go install ./cmd/pm + @source ./bin/pm_fish.sh + +install-powershell-temp: completions + @go install ./cmd/pm + @source ./bin/pm_powershell.ps1 + + +install-cli: completions + @go install ./cmd/pm + @sudo cp ./bin/pm_bash.sh /etc/bash_completion.d/pm + + +.PHONY: tidy clean build cli tui web dev tw completions install-bash-temp install-zsh-temp install-fish-temp install-powershell-temp install-cli \ No newline at end of file From 03ff8b41b7dd6ea1c7e0e1c31859f590175cbc6a Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 13:26:52 +0100 Subject: [PATCH 15/20] use tui config for consistency --- cmd/tui/main.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cmd/tui/main.go b/cmd/tui/main.go index 9d2e455..45b0974 100644 --- a/cmd/tui/main.go +++ b/cmd/tui/main.go @@ -3,12 +3,11 @@ package main import ( "context" - "github.com/LazyBachelor/LazyPM/internal/service" "github.com/LazyBachelor/LazyPM/pkg/tui" ) func main() { - config := service.Config{ + config := tui.TUIConfig{ StatisticsStoragePath: "./.pm/stats.json", BeadsDBPath: "./.pm/db.db", IssuePrefix: "pm", From 07af46c46b9ac55ffad9fdd7f55809d61e875fc3 Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:48:41 +0100 Subject: [PATCH 16/20] Update pkg/cli/commands/read.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/cli/commands/read.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/cli/commands/read.go b/pkg/cli/commands/read.go index 0116b96..53e1ba7 100644 --- a/pkg/cli/commands/read.go +++ b/pkg/cli/commands/read.go @@ -50,12 +50,10 @@ func completeIssues(cmd *cobra.Command, args []string, toComplete string) ([]str var completions []string for _, issue := range issues { - if strings.HasPrefix(issue.Title, toComplete) { - completions = append(completions, issue.ID) - } - if strings.HasPrefix(issue.ID, toComplete) { completions = append(completions, issue.ID) + } else if strings.HasPrefix(issue.Title, toComplete) { + completions = append(completions, issue.ID) } } From a731e375d3b09d8e5d59606e63651887ba884e0e Mon Sep 17 00:00:00 2001 From: Robin Olsen <129996395+Telikz@users.noreply.github.com> Date: Thu, 5 Feb 2026 13:51:19 +0100 Subject: [PATCH 17/20] Update pkg/cli/commands/read.go Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- pkg/cli/commands/read.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cli/commands/read.go b/pkg/cli/commands/read.go index 53e1ba7..42e292b 100644 --- a/pkg/cli/commands/read.go +++ b/pkg/cli/commands/read.go @@ -9,8 +9,8 @@ import ( var getIssueCmd = &cobra.Command{ Use: "describe [issue ID]", Aliases: []string{"get", "read"}, - Short: "Gets issue details", - Long: `Gets issue details by ID`, + Short: "Get issue details", + Long: `Get issue details by ID`, RunE: runGetCmd, Args: cobra.ExactArgs(1), ValidArgsFunction: completeIssues, From 893c9e3bd69639a5dcc9663aa87842b4cc119038 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 13:55:20 +0100 Subject: [PATCH 18/20] chack for nil pointer in helper use helper for converting to issue --- internal/models/beads.go | 6 ++++-- internal/service/beads.go | 7 +------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/internal/models/beads.go b/internal/models/beads.go index 83ec37b..0e9c663 100644 --- a/internal/models/beads.go +++ b/internal/models/beads.go @@ -81,8 +81,10 @@ const ( func IssuesPtrToIssues(issuePtr []*Issue) []Issue { issues := make([]Issue, 0, len(issuePtr)) - for _, issue := range issuePtr { - issues = append(issues, *issue) + for _, issuePtr := range issuePtr { + if issuePtr != nil { + issues = append(issues, *issuePtr) + } } return issues } diff --git a/internal/service/beads.go b/internal/service/beads.go index e9a191d..06c8373 100644 --- a/internal/service/beads.go +++ b/internal/service/beads.go @@ -37,12 +37,7 @@ func (s *BeadsService) AllIssues(ctx context.Context) ([]models.Issue, error) { return []models.Issue{}, nil } - issues := make([]models.Issue, 0, len(issuesPtr)) - for _, issuePtr := range issuesPtr { - if issuePtr != nil { - issues = append(issues, *issuePtr) - } - } + issues := models.IssuesPtrToIssues(issuesPtr) return issues, nil } From 1c248b2c8d1eddfa874d5b94c007c199d5ba96f7 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 14:27:44 +0100 Subject: [PATCH 19/20] decrease truncate leangth for issueID --- internal/models/beads.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/models/beads.go b/internal/models/beads.go index 0e9c663..bae490a 100644 --- a/internal/models/beads.go +++ b/internal/models/beads.go @@ -92,7 +92,7 @@ func IssuesPtrToIssues(issuePtr []*Issue) []Issue { func FormatIssueRow(issue Issue) string { return fmt.Sprintf( "%s\t%s\t%s\t%s\t%s\t%d", - truncate.String(issue.ID, 5), + truncate.String(issue.ID, 10), truncate.StringWithTail(issue.Title, 25, "..."), truncate.StringWithTail(issue.Description, 40, "..."), issue.Status, From d6884b6ac5ce89f728ab9c725fef864f9b039edb Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Thu, 5 Feb 2026 14:28:15 +0100 Subject: [PATCH 20/20] nil check issue so it does not crash when issue not found --- pkg/cli/commands/read.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pkg/cli/commands/read.go b/pkg/cli/commands/read.go index 42e292b..eb054c0 100644 --- a/pkg/cli/commands/read.go +++ b/pkg/cli/commands/read.go @@ -24,6 +24,11 @@ func runGetCmd(cmd *cobra.Command, args []string) error { return err } + if issue == nil { + cmd.Printf("Issue with ID '%s' not found\n", issueID) + return nil + } + cmd.Printf("Title: %s\n", issue.Title) cmd.Printf("Description: %s\n", issue.Description) cmd.Printf("Status: %s\n", issue.Status)