Commit Graph

24 Commits

Author SHA1 Message Date
Steve Yegge
2e2b8d7c2c feat: Accept both integer and P-format for priority flags in bd list
Implements bd-au0.4: Standardize priority flag parsing across all commands.

Changes:
- Use registerPriorityFlag() for main priority flag (was IntP)
- Change priority-min/max from Int to String flags
- Add validation import and use ValidatePriority() for all priority parsing
- Update both direct mode and daemon RPC code paths

Now supports both formats consistently:
- Numeric: --priority 0, --priority-min 1, --priority-max 2
- P-format: --priority P0, --priority-min P1, --priority-max P2

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-21 21:57:23 -05:00
Steve Yegge
57253f93a3 Context propagation with graceful cancellation (bd-rtp, bd-yb8, bd-2o2)
Complete implementation of signal-aware context propagation for graceful
cancellation across all commands and storage operations.

Key changes:

1. Signal-aware contexts (bd-rtp):
   - Added rootCtx/rootCancel in main.go using signal.NotifyContext()
   - Set up in PersistentPreRun, cancelled in PersistentPostRun
   - Daemon uses same pattern in runDaemonLoop()
   - Handles SIGINT/SIGTERM for graceful shutdown

2. Context propagation (bd-yb8):
   - All commands now use rootCtx instead of context.Background()
   - sqlite.New() receives context for cancellable operations
   - Database operations respect context cancellation
   - Storage layer propagates context through all queries

3. Cancellation tests (bd-2o2):
   - Added import_cancellation_test.go with comprehensive tests
   - Added export cancellation test in export_test.go
   - Tests verify database integrity after cancellation
   - All cancellation tests passing

Fixes applied during review:
   - Fixed rootCtx lifecycle (removed premature defer from PersistentPreRun)
   - Fixed test context contamination (reset rootCtx in test cleanup)
   - Fixed export tests missing context setup

Impact:
   - Pressing Ctrl+C during import/export now cancels gracefully
   - No database corruption or hanging transactions
   - Clean shutdown of all operations

Tested:
   - go build ./cmd/bd ✓
   - go test ./cmd/bd -run TestImportCancellation ✓
   - go test ./cmd/bd -run TestExportCommand ✓
   - Manual Ctrl+C testing verified

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 21:57:23 -05:00
Steve Yegge
9088988edd Improve staleness check error handling and optimization (bd-n4td, bd-o4qy, bd-c4rq)
This commit implements three related improvements to database staleness checking:

**bd-n4td (P2): Add warning when staleness check errors**
- Added stderr warnings when CheckStaleness fails in ensureDatabaseFresh
- Users now see "Warning: could not check database staleness: <error>"
- Provides visibility into staleness check failures while allowing operations to proceed

**bd-o4qy (P2): Improve CheckStaleness error handling**
- Updated CheckStaleness to distinguish between expected and abnormal conditions:
  * Returns (false, nil) for expected "no data yet" scenarios (missing metadata, missing JSONL)
  * Returns (false, err) for abnormal errors (glob failures, permission errors)
- Updated RPC server (2 locations) to log staleness errors but allow requests to proceed
- Prevents blocking operations due to transient staleness check issues
- Added comprehensive function documentation

**bd-c4rq (P3): Refactor staleness check to avoid function call overhead**
- Moved daemon check from inside ensureDatabaseFresh to all 8 call sites
- Avoids unnecessary function call when running in daemon mode
- Updated: list.go, info.go, status.go, show.go, stale.go, duplicates.go, ready.go, validate.go
- Extracted staleness functions to new staleness.go for better organization

**Code review fixes:**
- Removed dead code in CheckStaleness (unreachable jsonlPath == "" check)
- Removed unused ensureDatabaseFreshQuiet function

**Files changed:**
- New: cmd/bd/staleness.go (extracted staleness checking functions)
- Modified: 8 command files (added daemon check before staleness calls)
- Modified: internal/autoimport/autoimport.go (improved error handling)
- Modified: internal/rpc/server_export_import_auto.go (handle errors gracefully)
2025-11-20 20:45:39 -05:00
Steve Yegge
968d9e2ea1 Optimize bd list: replace N+1 label queries with bulk fetch
Problem:
In direct mode, bd list was making a separate GetLabels() call for
each issue when displaying labels. With 538 issues, this resulted in
538 separate database queries.

While investigating the reported 5+ second slowness, discovered this
N+1 query issue that would impact performance with many issues.

Solution:
1. Added GetLabelsForIssues(issueIDs []string) to Storage interface
2. Implemented bulk fetch in SQLite (already existed, now exposed)
3. Implemented bulk fetch in MemoryStorage
4. Updated list.go to fetch all labels in single query

Changes:
- internal/storage/storage.go: Add GetLabelsForIssues to interface
- internal/storage/memory/memory.go: Implement GetLabelsForIssues
- cmd/bd/list.go: Use bulk fetching in all output modes

Impact:
Eliminates N queries for labels, replacing with 1 bulk query.
This optimization applies to direct mode only (daemon mode already
uses bulk operations via RPC).

Note: The reported 5s slowness was actually caused by daemon auto-start
timeout. Use --no-daemon flag or run 'bd migrate --update-repo-id' to
resolve the legacy database issue causing daemon startup failures.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-20 20:27:09 -05:00
Steve Yegge
e6d580e14b Change bd list to one line per issue, add --long flag
Make bd list print exactly one line per issue by default to fix agent
miscounting. Agents were getting confused by the multi-line format and
incorrectly counting open issues.

The new compact format shows:
  bd-zo7o [P0] [task] open @assignee [labels] - Title

The original detailed multi-line format is preserved behind --long flag.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-08 01:32:13 -08:00
Steve Yegge
9520e7a2e2 Extract normalizeLabels to internal/util/strings.go
- Created internal/util/strings.go with NormalizeLabels function
- Added comprehensive tests in internal/util/strings_test.go
- Updated internal/rpc/server_issues_epics.go to use util.NormalizeLabels
- Updated cmd/bd/list.go and cmd/bd/ready.go to use util.NormalizeLabels
- Updated cmd/bd/list_test.go to use util.NormalizeLabels
- Removed duplicate implementations
- All tests pass

Fixes bd-fb95094c.6

Amp-Thread-ID: https://ampcode.com/threads/T-edb3c286-cd60-4231-94cd-edaf75d84a3d
Co-authored-by: Amp <amp@ampcode.com>
2025-11-06 20:00:08 -08:00
Steve Yegge
fbe790aa40 feat: Add ancestor_id field and implement epic/child filtering
Amp-Thread-ID: https://ampcode.com/threads/T-22f7d7c5-6f7b-4783-beda-8494360d887a
Co-authored-by: Amp <amp@ampcode.com>
2025-11-05 00:44:41 -08:00
Steve Yegge
e5f1e4b971 Fix --json flag shadowing issue causing test failures
Fixed TestHashIDs_IdenticalContentDedup test failure by removing duplicate
--json flag definitions that were shadowing the global persistent flag.

Root cause: Commands had both a persistent --json flag (main.go) and local
--json flags (in individual command files). The local flags shadowed the
persistent flag, preventing jsonOutput variable from being set correctly.

Changes:
- Removed 31 duplicate --json flag definitions from 15 command files
- All commands now use the single persistent --json flag from main.go
- Commands now correctly output JSON when --json flag is specified

Test results:
- TestHashIDs_IdenticalContentDedup: Now passes (was failing)
- TestHashIDs_MultiCloneConverge: Passes without JSON parsing warnings
- All other tests: Pass with no regressions

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-02 18:52:44 -08:00
Steve Yegge
0215e73780 Fix config system: rename config.json → metadata.json, fix config.yaml loading
- Renamed config.json to metadata.json to clarify purpose (database metadata)
- Fixed config.yaml/config.json conflict by making Viper explicitly load only config.yaml
- Added automatic migration from config.json to metadata.json on first read
- Fixed jsonOutput variable shadowing across 22 command files
- Updated bd init to create both metadata.json and config.yaml template
- Fixed 5 failing JSON output tests
- All tests passing

Resolves config file confusion and makes config.yaml work correctly.
Closes #178 (global flags), addresses config issues from #193

Amp-Thread-ID: https://ampcode.com/threads/T-e6ac8192-e18f-4ed7-83bc-4a5986718bb7
Co-authored-by: Amp <amp@ampcode.com>
2025-11-02 14:31:22 -08:00
Nikolai Prokoschenko
c65cfa1ebd Add dependency and dependent counts to bd list JSON output (#198)
When using `bd list --json`, each issue now includes:
- `dependency_count`: Number of issues this issue depends on
- `dependent_count`: Number of issues that depend on this issue

This provides quick access to dependency relationship counts without
needing to fetch full dependency lists or run multiple bd show commands.

Performance:
- Uses single bulk query (GetDependencyCounts) instead of N individual queries
- Overhead: ~26% for 500 issues (24ms vs 19ms baseline)
- Avoids N+1 query problem that would have caused 2.2x slowdown

Implementation:
- Added GetDependencyCounts() to Storage interface for bulk counting
- Efficient SQLite query using UNION ALL + GROUP BY
- Memory storage implementation for testing
- Moved IssueWithCounts to types package to avoid duplication
- Both RPC and direct modes use optimized bulk query

Tests:
- Added comprehensive tests for GetDependencyCounts
- Tests cover: normal operation, empty list, nonexistent IDs
- All existing tests continue to pass

Backwards compatible: JSON structure is additive, all original fields preserved.

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

Co-authored-by: Claude <noreply@anthropic.com>
2025-11-01 19:59:15 -07:00
Steve Yegge
a4eb4fe451 Add two-clone collision test proving beads multi-agent workflow failure
- Creates TestTwoCloneCollision integration test
- Sets up 2 independent clones with git hooks and daemons
- Both file issues with same ID (test-1)
- Demonstrates databases don't converge after collision resolution
- Clone A: test-1='Issue from clone A', test-2='Issue from clone B'
- Clone B: test-1='Issue from clone B', test-2='Issue from clone A'
- Git status shows dirty state in both clones
- Test proves beads fails at basic multi-agent workflow

Also adds --json flag to create, ready, and list commands for
better test integration.

Amp-Thread-ID: https://ampcode.com/threads/T-8fa0ab6c-2226-4f9b-8e11-14e1156537fc
Co-authored-by: Amp <amp@ampcode.com>
2025-10-28 11:34:27 -07:00
Steve Yegge
b5a2734f78 feat: Add --all flag to bd list for CLI familiarity
Common CLI pattern (git branch -a, docker ps -a, ls -a).
No-op since bd list already shows all issues by default,
but prevents error/retry cycles when agents reflexively use it.
2025-10-26 14:45:09 -07:00
Steve Yegge
7ae148cf2b Add --id flag to bd list for filtering by specific issue IDs
- Add --id flag accepting comma-separated IDs
- Implements ID filtering at CLI, RPC, and storage layers
- Normalizes IDs (trim, dedupe, remove empty) like labels
- Guards against excessive ID lists (max 1000)
- Works with other filters (status, priority, etc.)

Closes bd-200

Amp-Thread-ID: https://ampcode.com/threads/T-377464f2-1e7f-46f9-b23e-1e3cfd611061
Co-authored-by: Amp <amp@ampcode.com>
2025-10-21 19:53:27 -07:00
Steve Yegge
3f4878eb09 Auto-import from git on empty DB (bd-189)
- Add checkAndAutoImport() that detects empty DB with issues in git
- Automatically imports from git HEAD:.beads/issues.jsonl
- Integrated into list, ready, and stats commands
- Zero cognitive load for agents in fresh clones
- Makes JSONL truly the source of truth
- DB becomes ephemeral cache that auto-rebuilds

Also:
- Update AGENTS.md onboarding section with import instructions
- Merge PR #98 (enhanced .gitignore)

Amp-Thread-ID: https://ampcode.com/threads/T-ffcb5e95-e5a0-486b-a0ae-ce8bd861ab9d
Co-authored-by: Amp <amp@ampcode.com>
2025-10-21 14:10:26 -07:00
Steve Yegge
a86f3e139e Add native Windows support (#91)
- Native Windows daemon using TCP loopback endpoints
- Direct-mode fallback for CLI/daemon compatibility
- Comment operations over RPC
- PowerShell installer script
- Go 1.24 requirement
- Cross-OS testing documented

Co-authored-by: danshapiro <danshapiro@users.noreply.github.com>
Amp-Thread-ID: https://ampcode.com/threads/T-c6230265-055f-4af1-9712-4481061886db
Co-authored-by: Amp <amp@ampcode.com>
2025-10-20 21:08:49 -07:00
Steve Yegge
422c102f46 Add label filtering to bd list with AND/OR semantics
- Add --label flag for AND filtering (must have ALL labels)
- Add --label-any flag for OR filtering (must have AT LEAST ONE label)
- Add normalizeLabels() helper to trim, dedupe, and clean inputs
- Fix RPC title filtering parity bug (forward via Query field)
- Add comprehensive tests for label filtering including combined AND+OR
- Update documentation in README and CHANGELOG
- Improve flag help text to clarify combined semantics

Closes bd-161
2025-10-19 23:03:02 -07:00
Steve Yegge
f1ec927a7c feat: Add label display to bd show and bd list
- Populate labels in bd list human-readable output (direct mode)
- Populate labels in bd list JSON output (direct and daemon modes)
- Populate labels in daemon RPC handlers (handleList, handleShow)
- handleShow now returns full IssueDetails with labels/deps/dependents
- Labels displayed with 'Labels: [label1, label2]' format

Closes bd-164

Amp-Thread-ID: https://ampcode.com/threads/T-30cd607d-c509-4a8c-9cac-c2aea2ad75c6
Co-authored-by: Amp <amp@ampcode.com>
2025-10-19 22:44:39 -07:00
Steve Yegge
c17174b80a fix: bd list --status all showing 0 issues (bd-148)
The status filter was treating 'all' as a literal status value instead of
a special case meaning 'show all statuses'. This caused the SQL query to
filter for 'WHERE status = all' which matched no issues.

Fixed by checking if status is 'all' and skipping the filter in that case.

- Fix list.go to skip status filter when status == 'all'
- Update CHANGELOG with fix details
- All tests pass
2025-10-17 21:56:03 -07:00
Steve Yegge
39b586a7be Phase 2: Add client auto-detection in bd commands (bd-112)
- Add daemon client infrastructure to main.go with TryConnect logic
- Update PersistentPreRun to detect daemon socket and route through RPC
- Add --no-daemon flag to force direct storage mode
- Update all commands (create, update, close, show, list, ready) to use daemon when available
- Maintain backward compatibility with graceful fallback to direct mode
- All commands work identically in both daemon and direct modes

Part of bd-110 daemon architecture implementation.

Amp-Thread-ID: https://ampcode.com/threads/T-bfe2c083-be7c-4064-8673-fa69c22a730e
Co-authored-by: Amp <amp@ampcode.com>
2025-10-16 23:13:22 -07:00
Steve Yegge
e2c42c35c4 Add label and title filtering to bd list (closes #45, bd-269)
- Add --label/-l flag to filter issues by labels (AND logic)
- Add --title flag to filter issues by title substring
- Add TitleSearch field to IssueFilter type
- Implement label and title filtering in SearchIssues
- Perfect for worktree-specific issue management

Examples:
  bd list --label worktree,feature-x
  bd list --title "authentication"
  bd list --label worktree --title "bug"
2025-10-15 23:51:57 -07:00
Travis Cline
4131e6bf38 list: add status-based color coding to dot format
Enhance Graphviz dot output with status-based fill colors:
- open: white background (default)
- in_progress: light yellow background
- blocked: light coral background
- closed: light gray background with dimmed text

Node labels show: ID, type, priority, title, and status.
Priority is visible in the label (e.g., [bug P0]) but not color-coded
to keep the visualization clean and focused on status.
2025-10-15 15:27:49 -07:00
Travis Cline
6f357ea536 list: add --format flag with template support
Add flexible --format flag to 'bd list' command supporting:
- Built-in presets: 'digraph' (basic 'from to' format) and 'dot' (Graphviz)
- Custom Go templates for dependency output
- Template variables: IssueID, DependsOnID, Type, Issue, Dependency

This enables graph analysis with tools like golang.org/x/tools/cmd/digraph while allowing users to customize output format for their specific needs.

Examples:
  bd list --format=digraph | digraph nodes
  bd list --format=dot | dot -Tsvg -o deps.svg
  bd list --format='{{.IssueID}} -> {{.DependsOnID}} [{{.Type}}]'
2025-10-15 15:27:24 -07:00
Travis Cline
0c3c613890 list: add filter value enums to help 2025-10-15 15:27:24 -07:00
Travis Cline
cf8ff4227d list: extract command to separate file 2025-10-15 15:27:24 -07:00