feat(completion): optimize ID prefix filtering and add completions to more commands
Improvements to shell completions from PR #935: 1. Add IDPrefix field to IssueFilter for efficient database-level filtering - Queries are now filtered at SQL level instead of fetching all issues - Updated sqlite, transaction, and memory stores to support IDPrefix 2. Add ValidArgsFunction to additional commands: - dep (add, remove, list, tree) - comments, comment (add) - delete - graph - label (add, remove, list) - duplicate, supersede - audit - move - relate, unrelate - refile - gate (show, resolve, add-waiter) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Executed-By: beads/crew/dave Rig: beads Role: crew
This commit is contained in:
committed by
Steve Yegge
parent
025cdac962
commit
5dfb838d60
@@ -160,6 +160,9 @@ func init() {
|
||||
auditLabelCmd.Flags().StringVar(&auditLabelValue, "label", "", `Label value (e.g. "good" or "bad")`)
|
||||
auditLabelCmd.Flags().StringVar(&auditLabelReason, "reason", "", "Reason for label")
|
||||
|
||||
// Issue ID completions
|
||||
auditCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
auditCmd.AddCommand(auditRecordCmd)
|
||||
auditCmd.AddCommand(auditLabelCmd)
|
||||
rootCmd.AddCommand(auditCmd)
|
||||
|
||||
@@ -218,11 +218,16 @@ func init() {
|
||||
commentsCmd.AddCommand(commentsAddCmd)
|
||||
commentsAddCmd.Flags().StringP("file", "f", "", "Read comment text from file")
|
||||
commentsAddCmd.Flags().StringP("author", "a", "", "Add author to comment")
|
||||
|
||||
|
||||
// Add the same flags to the alias
|
||||
commentCmd.Flags().StringP("file", "f", "", "Read comment text from file")
|
||||
commentCmd.Flags().StringP("author", "a", "", "Add author to comment")
|
||||
|
||||
|
||||
// Issue ID completions
|
||||
commentsCmd.ValidArgsFunction = issueIDCompletion
|
||||
commentsAddCmd.ValidArgsFunction = issueIDCompletion
|
||||
commentCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
rootCmd.AddCommand(commentsCmd)
|
||||
rootCmd.AddCommand(commentCmd)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
@@ -51,8 +50,10 @@ func issueIDCompletion(cmd *cobra.Command, args []string, toComplete string) ([]
|
||||
defer currentStore.Close()
|
||||
}
|
||||
|
||||
// Use SearchIssues with empty query and default filter to get all issues
|
||||
filter := types.IssueFilter{}
|
||||
// Use SearchIssues with IDPrefix filter to efficiently query matching issues
|
||||
filter := types.IssueFilter{
|
||||
IDPrefix: toComplete, // Filter at database level for better performance
|
||||
}
|
||||
issues, err := currentStore.SearchIssues(ctx, "", filter)
|
||||
if err != nil {
|
||||
// If we can't list issues, return empty completion
|
||||
@@ -62,11 +63,6 @@ func issueIDCompletion(cmd *cobra.Command, args []string, toComplete string) ([]
|
||||
// Build completion list
|
||||
completions := make([]string, 0, len(issues))
|
||||
for _, issue := range issues {
|
||||
// Filter based on what's already typed
|
||||
if toComplete != "" && !strings.HasPrefix(issue.ID, toComplete) {
|
||||
continue
|
||||
}
|
||||
|
||||
// Format: ID\tTitle (shown during completion)
|
||||
completions = append(completions, fmt.Sprintf("%s\t%s", issue.ID, issue.Title))
|
||||
}
|
||||
|
||||
@@ -833,5 +833,6 @@ func init() {
|
||||
deleteCmd.Flags().Bool("cascade", false, "Recursively delete all dependent issues")
|
||||
deleteCmd.Flags().Bool("hard", false, "Permanently delete (skip tombstone, cannot be recovered via sync)")
|
||||
deleteCmd.Flags().String("reason", "", "Reason for deletion (stored in tombstone for audit trail)")
|
||||
deleteCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(deleteCmd)
|
||||
}
|
||||
|
||||
@@ -1167,6 +1167,12 @@ func init() {
|
||||
depListCmd.Flags().String("direction", "down", "Direction: 'down' (dependencies), 'up' (dependents)")
|
||||
depListCmd.Flags().StringP("type", "t", "", "Filter by dependency type (e.g., tracks, blocks, parent-child)")
|
||||
|
||||
// Issue ID completions for dep subcommands
|
||||
depAddCmd.ValidArgsFunction = issueIDCompletion
|
||||
depRemoveCmd.ValidArgsFunction = issueIDCompletion
|
||||
depListCmd.ValidArgsFunction = issueIDCompletion
|
||||
depTreeCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
depCmd.AddCommand(depAddCmd)
|
||||
depCmd.AddCommand(depRemoveCmd)
|
||||
depCmd.AddCommand(depListCmd)
|
||||
|
||||
@@ -50,10 +50,12 @@ var (
|
||||
func init() {
|
||||
duplicateCmd.Flags().StringVar(&duplicateOf, "of", "", "Canonical issue ID (required)")
|
||||
_ = duplicateCmd.MarkFlagRequired("of") // Only fails if flag missing (caught in tests)
|
||||
duplicateCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(duplicateCmd)
|
||||
|
||||
supersedeCmd.Flags().StringVar(&supersededWith, "with", "", "Replacement issue ID (required)")
|
||||
_ = supersedeCmd.MarkFlagRequired("with") // Only fails if flag missing (caught in tests)
|
||||
supersedeCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(supersedeCmd)
|
||||
}
|
||||
|
||||
|
||||
@@ -871,6 +871,11 @@ func init() {
|
||||
gateCheckCmd.Flags().BoolP("escalate", "e", false, "Escalate failed/expired gates")
|
||||
gateCheckCmd.Flags().IntP("limit", "l", 100, "Limit results (default 100)")
|
||||
|
||||
// Issue ID completions
|
||||
gateShowCmd.ValidArgsFunction = issueIDCompletion
|
||||
gateResolveCmd.ValidArgsFunction = issueIDCompletion
|
||||
gateAddWaiterCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
// Add subcommands
|
||||
gateCmd.AddCommand(gateListCmd)
|
||||
gateCmd.AddCommand(gateShowCmd)
|
||||
|
||||
@@ -117,6 +117,7 @@ Colors indicate status:
|
||||
}
|
||||
|
||||
func init() {
|
||||
graphCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(graphCmd)
|
||||
}
|
||||
|
||||
|
||||
@@ -314,6 +314,11 @@ var labelListAllCmd = &cobra.Command{
|
||||
},
|
||||
}
|
||||
func init() {
|
||||
// Issue ID completions
|
||||
labelAddCmd.ValidArgsFunction = issueIDCompletion
|
||||
labelRemoveCmd.ValidArgsFunction = issueIDCompletion
|
||||
labelListCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
labelCmd.AddCommand(labelAddCmd)
|
||||
labelCmd.AddCommand(labelRemoveCmd)
|
||||
labelCmd.AddCommand(labelListCmd)
|
||||
|
||||
@@ -276,5 +276,6 @@ func init() {
|
||||
moveCmd.Flags().String("to", "", "Target rig or prefix (required)")
|
||||
moveCmd.Flags().Bool("keep-open", false, "Keep the source issue open (don't close it)")
|
||||
moveCmd.Flags().Bool("skip-deps", false, "Skip dependency remapping")
|
||||
moveCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(moveCmd)
|
||||
}
|
||||
|
||||
@@ -160,5 +160,6 @@ Examples:
|
||||
|
||||
func init() {
|
||||
refileCmd.Flags().Bool("keep-open", false, "Keep the source issue open (don't close it)")
|
||||
refileCmd.ValidArgsFunction = issueIDCompletion
|
||||
rootCmd.AddCommand(refileCmd)
|
||||
}
|
||||
|
||||
@@ -41,6 +41,10 @@ Example:
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Issue ID completions
|
||||
relateCmd.ValidArgsFunction = issueIDCompletion
|
||||
unrelateCmd.ValidArgsFunction = issueIDCompletion
|
||||
|
||||
// Add as subcommands of dep
|
||||
depCmd.AddCommand(relateCmd)
|
||||
depCmd.AddCommand(unrelateCmd)
|
||||
|
||||
Reference in New Issue
Block a user