From c773e61f4e5e87f8bb9c43caf964d9b6af1672e1 Mon Sep 17 00:00:00 2001 From: Robin Olsen Date: Tue, 10 Feb 2026 00:04:13 +0100 Subject: [PATCH] implement suggestions from copilot --- pkg/cli/commands/close.go | 21 ++++++++++++--------- pkg/cli/commands/create.go | 18 ++++++++---------- pkg/cli/commands/delete.go | 10 +++++----- pkg/cli/commands/update.go | 6 +++++- pkg/cli/repl/suggestions.go | 10 ++++++++++ 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/pkg/cli/commands/close.go b/pkg/cli/commands/close.go index 4bfecaa..b4ff882 100644 --- a/pkg/cli/commands/close.go +++ b/pkg/cli/commands/close.go @@ -2,7 +2,6 @@ package commands import ( "fmt" - "strings" "github.com/charmbracelet/huh" "github.com/spf13/cobra" @@ -11,19 +10,21 @@ import ( // closeCmd represents the close command, // which allows users to close an existing issue by its ID. var closeCmd = &cobra.Command{ - Use: "close [id]", - Short: "Close an existing issue", - Long: `Close an existing issue by its ID.`, - Example: `pm close pm-abc`, - ValidArgsFunction: completeIssues, + Use: "close [id]", + Short: "Close an existing issue", + Long: `Close an existing issue by its ID.`, + Example: `pm close pm-abc`, + Args: cobra.ExactArgs(1), RunE: runCloseCmd, + + ValidArgsFunction: completeIssues, } // runCloseCmd executes the close command logic, // which closes an issue by its ID after confirming with the user. func runCloseCmd(cmd *cobra.Command, args []string) error { - closeID := strings.Join(args, " ") + closeID := args[0] if closeID == "" { return fmt.Errorf("issue ID cannot be empty") @@ -40,8 +41,10 @@ func runCloseCmd(cmd *cobra.Command, args []string) error { } // Ask for closing reason - huh.NewInput().Value(&issue.CloseReason). - Title("Reason for closing the issue?").WithTheme(huh.ThemeBase()).Run() + if err = huh.NewInput().Value(&issue.CloseReason). + Title("Reason for closing the issue?").WithTheme(huh.ThemeBase()).Run(); err != nil { + return fmt.Errorf("error getting close reason: %w", err) + } // Close the issue. err = svc.Beads.CloseIssue(cmd.Context(), closeID, issue.CloseReason, "", "") diff --git a/pkg/cli/commands/create.go b/pkg/cli/commands/create.go index 84504db..538ed27 100644 --- a/pkg/cli/commands/create.go +++ b/pkg/cli/commands/create.go @@ -72,34 +72,32 @@ func runCreateInteractive() error { huh.NewGroup( huh.NewInput().Value(&createFlags.title).Title("Title"), - huh.NewText().Value(&createFlags.description).Title("Description"), - ).Title("Issue Details"), + huh.NewText().Value(&createFlags.description).Title("Description")), huh.NewGroup( - huh.NewSelect[string](). + huh.NewSelect[string]().Title("Status"). Options( huh.NewOption("Open", "open"), huh.NewOption("Closed", "closed"), huh.NewOption("In Progress", "in_progress"), - ).Value(&createFlags.status).Title("Status"), + ).Value(&createFlags.status), - huh.NewSelect[string](). + huh.NewSelect[string]().Title("Type"). Options( huh.NewOption("Bug", "bug"), huh.NewOption("Feature", "feature"), huh.NewOption("Task", "task"), - ).Value(&createFlags.issueType).Title("Type"), + ).Value(&createFlags.issueType), - huh.NewSelect[int](). + huh.NewSelect[int]().Title("Priority"). Options( huh.NewOption("0", 0), huh.NewOption("1", 1), huh.NewOption("2", 2), huh.NewOption("3", 3), huh.NewOption("4", 4), - ).Value(&createFlags.priority).Title("Priority"), - ).Title("Create New Issue").WithTheme(huh.ThemeBase()), - ) + ).Value(&createFlags.priority), + )).WithTheme(huh.ThemeBase16()) return form.Run() } diff --git a/pkg/cli/commands/delete.go b/pkg/cli/commands/delete.go index a684e53..b96e659 100644 --- a/pkg/cli/commands/delete.go +++ b/pkg/cli/commands/delete.go @@ -36,7 +36,7 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { deleteID := strings.Join(args, " ") if deleteInteractive { - if err := runDeleteInteractive(); err != nil { + if err := runDeleteInteractive(cmd.Context()); err != nil { return err } return nil @@ -82,10 +82,10 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error { // runDeleteInteractive runs the interactive mode for deleting issues, // allowing users to select multiple issues for deletion. -func runDeleteInteractive() error { +func runDeleteInteractive(ctx context.Context) error { options := []huh.Option[string]{} - issues, err := svc.Beads.SearchIssues(context.Background(), "", models.IssueFilter{}) + issues, err := svc.Beads.SearchIssues(ctx, "", models.IssueFilter{}) if err != nil { return fmt.Errorf("error fetching issues: %w", err) } @@ -97,7 +97,7 @@ func runDeleteInteractive() error { form := huh.NewForm( huh.NewGroup( - huh.NewMultiSelect[string]().Value(&deleteIDs). + huh.NewMultiSelect[string](). Options(options...).Value(&deleteIDs). Title("Select issues to delete"))).WithTheme(huh.ThemeBase()) @@ -110,7 +110,7 @@ func runDeleteInteractive() error { } for _, id := range deleteIDs { - err := svc.Beads.DeleteIssue(context.Background(), id) + err := svc.Beads.DeleteIssue(ctx, id) if err != nil { return fmt.Errorf("error deleting issue with ID %s: %w", id, err) } diff --git a/pkg/cli/commands/update.go b/pkg/cli/commands/update.go index a93bc36..099a08c 100644 --- a/pkg/cli/commands/update.go +++ b/pkg/cli/commands/update.go @@ -24,10 +24,14 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error { issueID := args[0] issue, err := svc.Beads.GetIssue(cmd.Context(), issueID) - if err != nil || issue == nil { + if err != nil { return fmt.Errorf("error getting issue: %w", err) } + if issue == nil { + return fmt.Errorf("issue with ID %s not found", issueID) + } + updates, err := getUpdateValues(cmd) if err != nil { return fmt.Errorf("error getting update values: %w", err) diff --git a/pkg/cli/repl/suggestions.go b/pkg/cli/repl/suggestions.go index ba79385..e99c681 100644 --- a/pkg/cli/repl/suggestions.go +++ b/pkg/cli/repl/suggestions.go @@ -31,6 +31,7 @@ var baseSuggestions = []prompt.Suggest{ // createFlags is a list of prompt suggestions for the create command flags. var createFlags = []prompt.Suggest{ + {Text: "--interactive", Description: "Create issue interactively"}, {Text: "--desc", Description: "Issue description"}, {Text: "--status", Description: "Issue status (open, closed, in_progress)"}, {Text: "--type", Description: "Issue type (bug, feature, task)"}, @@ -56,6 +57,11 @@ var listFlags = []prompt.Suggest{ {Text: "--limit", Description: "Limit number of results"}, } +var deleteFlags = []prompt.Suggest{ + {Text: "--yes", Description: "Confirm deletion without prompt"}, + {Text: "--interactive", Description: "Select issues to delete interactively"}, +} + // statusValues is a list of prompt suggestions for status types var statusValues = []prompt.Suggest{ {Text: "open", Description: "Open status"}, @@ -101,6 +107,10 @@ var commandFlags = map[string][]prompt.Suggest{ "list": listFlags, "ls": listFlags, "search": listFlags, + "delete": deleteFlags, + "del": deleteFlags, + "rm": deleteFlags, + "remove": deleteFlags, } // commandSuggestions returns a list of prompt suggestions based on the current input words.