feat: bd list defaults to non-closed issues with 50 limit (GH#788)

Changes:
- Default to excluding closed issues (use --all to include)
- Default limit of 50 issues (use --limit 0 for unlimited)
- --all flag now overrides the closed filter

This addresses agent context blowout from seeing hundreds of closed issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-29 17:53:57 -08:00
parent a7f34d8f89
commit 34e2548c86
6 changed files with 48 additions and 2 deletions

View File

@@ -315,6 +315,7 @@ var listCmd = &cobra.Command{
assignee, _ := cmd.Flags().GetString("assignee")
issueType, _ := cmd.Flags().GetString("type")
limit, _ := cmd.Flags().GetInt("limit")
allFlag, _ := cmd.Flags().GetBool("all")
formatStr, _ := cmd.Flags().GetString("format")
labels, _ := cmd.Flags().GetStringSlice("label")
labelsAny, _ := cmd.Flags().GetStringSlice("label-any")
@@ -404,6 +405,11 @@ var listCmd = &cobra.Command{
s := types.Status(status)
filter.Status = &s
}
// Default to non-closed issues unless --all or explicit --status (GH#788)
if status == "" && !allFlag {
filter.ExcludeStatus = []types.Status{types.StatusClosed}
}
// Use Changed() to properly handle P0 (priority=0)
if cmd.Flags().Changed("priority") {
priorityStr, _ := cmd.Flags().GetString("priority")
@@ -573,7 +579,7 @@ var listCmd = &cobra.Command{
Status: status,
IssueType: issueType,
Assignee: assignee,
Limit: limit,
Limit: effectiveLimit,
}
if cmd.Flags().Changed("priority") {
priorityStr, _ := cmd.Flags().GetString("priority")
@@ -641,6 +647,13 @@ var listCmd = &cobra.Command{
// Parent filtering
listArgs.ParentID = parentID
// Status exclusion (GH#788)
if len(filter.ExcludeStatus) > 0 {
for _, s := range filter.ExcludeStatus {
listArgs.ExcludeStatus = append(listArgs.ExcludeStatus, string(s))
}
}
resp, err := daemonClient.List(listArgs)
if err != nil {
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
@@ -906,7 +919,7 @@ func init() {
listCmd.Flags().String("id", "", "Filter by specific issue IDs (comma-separated, e.g., bd-1,bd-5,bd-10)")
listCmd.Flags().IntP("limit", "n", 50, "Limit results (default 50, use 0 for unlimited)")
listCmd.Flags().String("format", "", "Output format: 'digraph' (for golang.org/x/tools/cmd/digraph), 'dot' (Graphviz), or Go template")
listCmd.Flags().Bool("all", false, "Show all issues (default behavior; flag provided for CLI familiarity)")
listCmd.Flags().Bool("all", false, "Show all issues including closed (overrides default filter)")
listCmd.Flags().Bool("long", false, "Show detailed multi-line output for each issue")
listCmd.Flags().String("sort", "", "Sort by field: priority, created, updated, closed, status, id, title, type, assignee")
listCmd.Flags().BoolP("reverse", "r", false, "Reverse sort order")

View File

@@ -208,6 +208,9 @@ type ListArgs struct {
// Molecule type filtering
MolType string `json:"mol_type,omitempty"`
// Status exclusion (for default non-closed behavior, GH#788)
ExcludeStatus []string `json:"exclude_status,omitempty"`
}
// CountArgs represents arguments for the count operation

View File

@@ -980,6 +980,13 @@ func (s *Server) handleList(req *Request) Response {
filter.MolType = &molType
}
// Status exclusion (for default non-closed behavior, GH#788)
if len(listArgs.ExcludeStatus) > 0 {
for _, s := range listArgs.ExcludeStatus {
filter.ExcludeStatus = append(filter.ExcludeStatus, types.Status(s))
}
}
// Guard against excessive ID lists to avoid SQLite parameter limits
const maxIDs = 1000
if len(filter.IDs) > maxIDs {

View File

@@ -1604,6 +1604,16 @@ func (s *SQLiteStorage) SearchIssues(ctx context.Context, query string, filter t
args = append(args, types.StatusTombstone)
}
// Status exclusion (for default non-closed behavior, GH#788)
if len(filter.ExcludeStatus) > 0 {
placeholders := make([]string, len(filter.ExcludeStatus))
for i, s := range filter.ExcludeStatus {
placeholders[i] = "?"
args = append(args, string(s))
}
whereClauses = append(whereClauses, fmt.Sprintf("status NOT IN (%s)", strings.Join(placeholders, ",")))
}
if filter.Priority != nil {
whereClauses = append(whereClauses, "priority = ?")
args = append(args, *filter.Priority)

View File

@@ -998,6 +998,16 @@ func (t *sqliteTxStorage) SearchIssues(ctx context.Context, query string, filter
args = append(args, types.StatusTombstone)
}
// Status exclusion (for default non-closed behavior, GH#788)
if len(filter.ExcludeStatus) > 0 {
placeholders := make([]string, len(filter.ExcludeStatus))
for i, s := range filter.ExcludeStatus {
placeholders[i] = "?"
args = append(args, string(s))
}
whereClauses = append(whereClauses, fmt.Sprintf("status NOT IN (%s)", strings.Join(placeholders, ",")))
}
if filter.Priority != nil {
whereClauses = append(whereClauses, "priority = ?")
args = append(args, *filter.Priority)

View File

@@ -720,6 +720,9 @@ type IssueFilter struct {
// Molecule type filtering
MolType *MolType // Filter by molecule type (nil = any, swarm/patrol/work)
// Status exclusion (for default non-closed behavior)
ExcludeStatus []Status // Exclude issues with these statuses
}
// SortPolicy determines how ready work is ordered