implement suggestions from copilot

This commit is contained in:
Robin Olsen
2026-02-10 00:04:13 +01:00
parent bb096ff19d
commit c773e61f4e
5 changed files with 40 additions and 25 deletions

View File

@@ -2,7 +2,6 @@ package commands
import ( import (
"fmt" "fmt"
"strings"
"github.com/charmbracelet/huh" "github.com/charmbracelet/huh"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -15,15 +14,17 @@ var closeCmd = &cobra.Command{
Short: "Close an existing issue", Short: "Close an existing issue",
Long: `Close an existing issue by its ID.`, Long: `Close an existing issue by its ID.`,
Example: `pm close pm-abc`, Example: `pm close pm-abc`,
ValidArgsFunction: completeIssues,
Args: cobra.ExactArgs(1),
RunE: runCloseCmd, RunE: runCloseCmd,
ValidArgsFunction: completeIssues,
} }
// runCloseCmd executes the close command logic, // runCloseCmd executes the close command logic,
// which closes an issue by its ID after confirming with the user. // which closes an issue by its ID after confirming with the user.
func runCloseCmd(cmd *cobra.Command, args []string) error { func runCloseCmd(cmd *cobra.Command, args []string) error {
closeID := strings.Join(args, " ") closeID := args[0]
if closeID == "" { if closeID == "" {
return fmt.Errorf("issue ID cannot be empty") return fmt.Errorf("issue ID cannot be empty")
@@ -40,8 +41,10 @@ func runCloseCmd(cmd *cobra.Command, args []string) error {
} }
// Ask for closing reason // Ask for closing reason
huh.NewInput().Value(&issue.CloseReason). if err = huh.NewInput().Value(&issue.CloseReason).
Title("Reason for closing the issue?").WithTheme(huh.ThemeBase()).Run() Title("Reason for closing the issue?").WithTheme(huh.ThemeBase()).Run(); err != nil {
return fmt.Errorf("error getting close reason: %w", err)
}
// Close the issue. // Close the issue.
err = svc.Beads.CloseIssue(cmd.Context(), closeID, issue.CloseReason, "", "") err = svc.Beads.CloseIssue(cmd.Context(), closeID, issue.CloseReason, "", "")

View File

@@ -72,34 +72,32 @@ func runCreateInteractive() error {
huh.NewGroup( huh.NewGroup(
huh.NewInput().Value(&createFlags.title).Title("Title"), huh.NewInput().Value(&createFlags.title).Title("Title"),
huh.NewText().Value(&createFlags.description).Title("Description"), huh.NewText().Value(&createFlags.description).Title("Description")),
).Title("Issue Details"),
huh.NewGroup( huh.NewGroup(
huh.NewSelect[string](). huh.NewSelect[string]().Title("Status").
Options( Options(
huh.NewOption("Open", "open"), huh.NewOption("Open", "open"),
huh.NewOption("Closed", "closed"), huh.NewOption("Closed", "closed"),
huh.NewOption("In Progress", "in_progress"), huh.NewOption("In Progress", "in_progress"),
).Value(&createFlags.status).Title("Status"), ).Value(&createFlags.status),
huh.NewSelect[string](). huh.NewSelect[string]().Title("Type").
Options( Options(
huh.NewOption("Bug", "bug"), huh.NewOption("Bug", "bug"),
huh.NewOption("Feature", "feature"), huh.NewOption("Feature", "feature"),
huh.NewOption("Task", "task"), huh.NewOption("Task", "task"),
).Value(&createFlags.issueType).Title("Type"), ).Value(&createFlags.issueType),
huh.NewSelect[int](). huh.NewSelect[int]().Title("Priority").
Options( Options(
huh.NewOption("0", 0), huh.NewOption("0", 0),
huh.NewOption("1", 1), huh.NewOption("1", 1),
huh.NewOption("2", 2), huh.NewOption("2", 2),
huh.NewOption("3", 3), huh.NewOption("3", 3),
huh.NewOption("4", 4), huh.NewOption("4", 4),
).Value(&createFlags.priority).Title("Priority"), ).Value(&createFlags.priority),
).Title("Create New Issue").WithTheme(huh.ThemeBase()), )).WithTheme(huh.ThemeBase16())
)
return form.Run() return form.Run()
} }

View File

@@ -36,7 +36,7 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error {
deleteID := strings.Join(args, " ") deleteID := strings.Join(args, " ")
if deleteInteractive { if deleteInteractive {
if err := runDeleteInteractive(); err != nil { if err := runDeleteInteractive(cmd.Context()); err != nil {
return err return err
} }
return nil return nil
@@ -82,10 +82,10 @@ func runDeleteCmd(cmd *cobra.Command, args []string) error {
// runDeleteInteractive runs the interactive mode for deleting issues, // runDeleteInteractive runs the interactive mode for deleting issues,
// allowing users to select multiple issues for deletion. // allowing users to select multiple issues for deletion.
func runDeleteInteractive() error { func runDeleteInteractive(ctx context.Context) error {
options := []huh.Option[string]{} options := []huh.Option[string]{}
issues, err := svc.Beads.SearchIssues(context.Background(), "", models.IssueFilter{}) issues, err := svc.Beads.SearchIssues(ctx, "", models.IssueFilter{})
if err != nil { if err != nil {
return fmt.Errorf("error fetching issues: %w", err) return fmt.Errorf("error fetching issues: %w", err)
} }
@@ -97,7 +97,7 @@ func runDeleteInteractive() error {
form := huh.NewForm( form := huh.NewForm(
huh.NewGroup( huh.NewGroup(
huh.NewMultiSelect[string]().Value(&deleteIDs). huh.NewMultiSelect[string]().
Options(options...).Value(&deleteIDs). Options(options...).Value(&deleteIDs).
Title("Select issues to delete"))).WithTheme(huh.ThemeBase()) Title("Select issues to delete"))).WithTheme(huh.ThemeBase())
@@ -110,7 +110,7 @@ func runDeleteInteractive() error {
} }
for _, id := range deleteIDs { for _, id := range deleteIDs {
err := svc.Beads.DeleteIssue(context.Background(), id) err := svc.Beads.DeleteIssue(ctx, id)
if err != nil { if err != nil {
return fmt.Errorf("error deleting issue with ID %s: %w", id, err) return fmt.Errorf("error deleting issue with ID %s: %w", id, err)
} }

View File

@@ -24,10 +24,14 @@ func runUpdateCmd(cmd *cobra.Command, args []string) error {
issueID := args[0] issueID := args[0]
issue, err := svc.Beads.GetIssue(cmd.Context(), issueID) issue, err := svc.Beads.GetIssue(cmd.Context(), issueID)
if err != nil || issue == nil { if err != nil {
return fmt.Errorf("error getting issue: %w", err) 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) updates, err := getUpdateValues(cmd)
if err != nil { if err != nil {
return fmt.Errorf("error getting update values: %w", err) return fmt.Errorf("error getting update values: %w", err)

View File

@@ -31,6 +31,7 @@ var baseSuggestions = []prompt.Suggest{
// createFlags is a list of prompt suggestions for the create command flags. // createFlags is a list of prompt suggestions for the create command flags.
var createFlags = []prompt.Suggest{ var createFlags = []prompt.Suggest{
{Text: "--interactive", Description: "Create issue interactively"},
{Text: "--desc", Description: "Issue description"}, {Text: "--desc", Description: "Issue description"},
{Text: "--status", Description: "Issue status (open, closed, in_progress)"}, {Text: "--status", Description: "Issue status (open, closed, in_progress)"},
{Text: "--type", Description: "Issue type (bug, feature, task)"}, {Text: "--type", Description: "Issue type (bug, feature, task)"},
@@ -56,6 +57,11 @@ var listFlags = []prompt.Suggest{
{Text: "--limit", Description: "Limit number of results"}, {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 // statusValues is a list of prompt suggestions for status types
var statusValues = []prompt.Suggest{ var statusValues = []prompt.Suggest{
{Text: "open", Description: "Open status"}, {Text: "open", Description: "Open status"},
@@ -101,6 +107,10 @@ var commandFlags = map[string][]prompt.Suggest{
"list": listFlags, "list": listFlags,
"ls": listFlags, "ls": listFlags,
"search": listFlags, "search": listFlags,
"delete": deleteFlags,
"del": deleteFlags,
"rm": deleteFlags,
"remove": deleteFlags,
} }
// commandSuggestions returns a list of prompt suggestions based on the current input words. // commandSuggestions returns a list of prompt suggestions based on the current input words.