feat: Add bd repos multi-repo commands and fix bd ready for in_progress issues
- Add 'bd repos' command for multi-repository management (bd-123)
- bd repos list: show all cached repositories
- bd repos ready: aggregate ready work across repos
- bd repos stats: combined statistics across repos
- bd repos clear-cache: clear repository cache
- Requires global daemon (bd daemon --global)
- Fix bd ready to show in_progress issues (bd-165)
- bd ready now shows both 'open' and 'in_progress' issues with no blockers
- Allows epics/tasks ready to close to appear in ready work
- Critical P0 bug fix for workflow
- Apply code review improvements to repos implementation
- Use strongly typed RPC responses (remove interface{})
- Fix clear-cache lock handling (close connections outside lock)
- Add error collection for per-repo failures
- Add context timeouts (1-2s) to prevent hangs
- Add lock strategy comments
- Update documentation (README.md, AGENTS.md)
- Add comprehensive tests for both features
Amp-Thread-ID: https://ampcode.com/threads/T-1de989a1-1890-492c-9847-a34144259e0f
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -25,7 +25,7 @@
|
||||
{"id":"bd-120","title":"Fix nil pointer crash in bd export command","description":"When running `bd export -o .beads/issues.jsonl`, the command crashes with a nil pointer dereference.\n\n## Error\n```\npanic: runtime error: invalid memory address or nil pointer dereference\n[signal SIGSEGV: segmentation violation code=0x2 addr=0x108 pc=0x1034456fc]\n\ngoroutine 1 [running]:\nmain.init.func14(0x103c24380, {0x1034a9695?, 0x4?, 0x1034a95c9?})\n /Users/stevey/src/vc/adar/beads/cmd/bd/export.go:74 +0x15c\n```\n\n## Context\n- This happened after closing bd-105, bd-114, bd-115\n- Auto-export from daemon still works fine\n- Only the manual `bd export` command crashes\n- Data was already synced via auto-export, so no data loss\n\n## Location\nFile: `cmd/bd/export.go` line 74","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-17T17:34:05.014619-07:00","updated_at":"2025-10-17T17:35:41.414218-07:00","closed_at":"2025-10-17T17:35:41.414218-07:00"}
|
||||
{"id":"bd-121","title":"Add --global flag to daemon for multi-repo support","description":"Currently daemon creates socket at .beads/bd.sock in each repo. For multi-repo support, add --global flag to create socket in ~/.beads/bd.sock that can serve requests from any repository.\n\nImplementation:\n- Add --global flag to daemon command\n- When --global is set, use ~/.beads/bd.sock instead of ./.beads/bd.sock \n- Don't require being in a git repo when --global is used\n- Update daemon discovery logic to check ~/.beads/bd.sock as fallback\n- Document that global daemon can serve multiple repos simultaneously\n\nBenefits:\n- Single daemon serves all repos on the system\n- No need to start daemon per-repo\n- Better resource usage\n- Enables system-wide task tracking\n\nContext: Per-request context routing (bd-115) already implemented - daemon can handle multiple repos. This issue is about making the UX better.\n\nRelated: bd-73 (parent issue for multi-repo support)","status":"closed","priority":1,"issue_type":"feature","created_at":"2025-10-17T20:43:47.080685-07:00","updated_at":"2025-10-17T22:45:42.411986-07:00","closed_at":"2025-10-17T22:45:42.411986-07:00","dependencies":[{"issue_id":"bd-121","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:02.2335-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-122","title":"Document multi-repo workflow with daemon","description":"The daemon already supports multi-repo via per-request context routing (bd-115), but this isn't documented. Users need to know how to use beads across multiple projects.\n\nAdd documentation for:\n1. How daemon serves multiple repos simultaneously\n2. Starting daemon in one repo, using from others\n3. MCP server multi-repo configuration\n4. Example: tracking work across a dozen projects\n5. Comparison to workspace/global instance approaches\n\nDocumentation locations:\n- README.md (Multi-repo section)\n- AGENTS.md (MCP multi-repo config)\n- integrations/beads-mcp/README.md (working_dir parameter)\n\nInclude:\n- Architecture diagram showing one daemon, many repos\n- Example MCP config with BEADS_WORKING_DIR\n- CLI workflow example\n- Reference to test_multi_repo.py as proof of concept\n\nContext: Feature already works (proven by test_multi_repo.py), just needs user-facing docs.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-17T20:43:48.91315-07:00","updated_at":"2025-10-17T22:49:32.514372-07:00","closed_at":"2025-10-17T22:49:32.514372-07:00","dependencies":[{"issue_id":"bd-122","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:03.261924-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-123","title":"Add 'bd repos' command for multi-repo aggregation","description":"When using daemon in multi-repo mode, users need commands to view/manage work across all active repositories.\n\nAdd 'bd repos' subcommand with:\n\n1. bd repos list\n - Show all repositories daemon has cached\n - Display: path, prefix, issue count, last activity\n - Example output:\n ~/src/project1 [p1-] 45 issues (active)\n ~/src/project2 [p2-] 12 issues (2m ago)\n\n2. bd repos ready --all \n - Aggregate ready work across all repos\n - Group by repo or show combined list\n - Support priority/assignee filters\n\n3. bd repos stats\n - Combined statistics across all repos\n - Total issues, breakdown by status/priority\n - Per-repo breakdown\n\n4. bd repos clear-cache\n - Close all cached storage connections\n - Useful for freeing resources\n\nImplementation notes:\n- Requires daemon to track active storage instances\n- May need RPC protocol additions for multi-repo queries\n- Should gracefully handle repos that no longer exist\n\nDepends on: Global daemon flag (makes this more useful)\n\nContext: This provides the UX layer on top of existing multi-repo support. The daemon can already serve multiple repos - this makes it easy to work with them.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-10-17T20:43:49.816998-07:00","updated_at":"2025-10-17T20:43:49.816998-07:00","dependencies":[{"issue_id":"bd-123","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:04.407138-07:00","created_by":"daemon"},{"issue_id":"bd-123","depends_on_id":"bd-121","type":"blocks","created_at":"2025-10-17T20:44:13.681626-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-123","title":"Add 'bd repos' command for multi-repo aggregation","description":"When using daemon in multi-repo mode, users need commands to view/manage work across all active repositories.\n\nAdd 'bd repos' subcommand with:\n\n1. bd repos list\n - Show all repositories daemon has cached\n - Display: path, prefix, issue count, last activity\n - Example output:\n ~/src/project1 [p1-] 45 issues (active)\n ~/src/project2 [p2-] 12 issues (2m ago)\n\n2. bd repos ready --all \n - Aggregate ready work across all repos\n - Group by repo or show combined list\n - Support priority/assignee filters\n\n3. bd repos stats\n - Combined statistics across all repos\n - Total issues, breakdown by status/priority\n - Per-repo breakdown\n\n4. bd repos clear-cache\n - Close all cached storage connections\n - Useful for freeing resources\n\nImplementation notes:\n- Requires daemon to track active storage instances\n- May need RPC protocol additions for multi-repo queries\n- Should gracefully handle repos that no longer exist\n\nDepends on: Global daemon flag (makes this more useful)\n\nContext: This provides the UX layer on top of existing multi-repo support. The daemon can already serve multiple repos - this makes it easy to work with them.","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-17T20:43:49.816998-07:00","updated_at":"2025-10-18T00:04:42.197247-07:00","closed_at":"2025-10-18T00:04:42.197247-07:00","dependencies":[{"issue_id":"bd-123","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:04.407138-07:00","created_by":"daemon"},{"issue_id":"bd-123","depends_on_id":"bd-121","type":"blocks","created_at":"2025-10-17T20:44:13.681626-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-124","title":"Add daemon auto-start on first use","description":"Currently users must manually start daemon with 'bd daemon'. For better UX, auto-start daemon when first bd command is run.\n\nImplementation:\n\n1. In PersistentPreRun, check if daemon is running\n2. If not, check if auto-start is enabled (default: true)\n3. Start daemon with appropriate flags (--global if configured)\n4. Wait for socket to be ready (with timeout)\n5. Retry connection to newly-started daemon\n6. Silently fail back to direct mode if daemon won't start\n\nConfiguration:\n- BEADS_AUTO_START_DAEMON env var (default: true)\n- --no-auto-daemon flag to disable\n- Config file option: auto_start_daemon = true\n\nSafety considerations:\n- Don't auto-start if daemon failed recently (exponential backoff)\n- Log auto-start to daemon.log\n- Clear error messages if auto-start fails\n- Never auto-start if --no-daemon flag is set\n\nBenefits:\n- Zero-configuration experience\n- Daemon benefits (speed, multi-repo) automatic\n- Still supports direct mode as fallback\n\nDepends on: Global daemon flag would make this more useful","status":"closed","priority":2,"issue_type":"feature","created_at":"2025-10-17T20:43:50.961453-07:00","updated_at":"2025-10-17T23:33:57.173903-07:00","closed_at":"2025-10-17T23:33:57.173903-07:00","dependencies":[{"issue_id":"bd-124","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:05.502634-07:00","created_by":"daemon"},{"issue_id":"bd-124","depends_on_id":"bd-121","type":"blocks","created_at":"2025-10-17T20:44:14.987308-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-125","title":"Add workspace config file for multi-repo management (optional enhancement)","description":"For users who want explicit control over multi-repo setup without daemon, add optional workspace config file.\n\nConfig file: ~/.beads/workspaces.toml\n\nExample:\n[workspaces]\ncurrent = \"global\"\n\n[workspace.global]\ndb = \"~/.beads/global.db\"\ndescription = \"System-wide tasks\"\n\n[workspace.project1] \ndb = \"~/src/project1/.beads/db.sqlite\"\ndescription = \"Main product\"\n\n[workspace.project2]\ndb = \"~/src/project2/.beads/db.sqlite\"\ndescription = \"Internal tools\"\n\nCommands:\nbd workspace list # Show all workspaces\nbd workspace add NAME PATH # Add workspace\nbd workspace remove NAME # Remove workspace \nbd workspace use NAME # Switch active workspace\nbd workspace current # Show current workspace\nbd --workspace NAME \u003ccommand\u003e # Override for single command\n\nImplementation:\n- Load config in PersistentPreRun\n- Override dbPath based on current workspace\n- Store workspace state in config file\n- Support both workspace config AND auto-discovery\n- Workspace config takes precedence over auto-discovery\n\nPriority rationale:\n- Priority 3 (low) because daemon approach already solves this\n- Only implement if users request explicit workspace management\n- Adds complexity vs daemon's automatic discovery\n\nAlternative: Users can use BEADS_DB env var for manual workspace switching today.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-10-17T20:43:52.348572-07:00","updated_at":"2025-10-17T20:43:52.348572-07:00","dependencies":[{"issue_id":"bd-125","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:06.411344-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-126","title":"Add cross-repo issue references (future enhancement)","description":"Support referencing issues across different beads repositories. Useful for tracking dependencies between separate projects.\n\nProposed syntax:\n- Local reference: bd-123 (current behavior)\n- Cross-repo by path: ~/src/other-project#bd-456\n- Cross-repo by workspace name: @project2:bd-789\n\nUse cases:\n1. Frontend project depends on backend API issue\n2. Shared library changes blocking multiple projects\n3. System administrator tracking work across machines\n4. Monorepo with separate beads databases per component\n\nImplementation challenges:\n- Storage layer needs to query external databases\n- Dependency resolution across repos\n- What if external repo not available?\n- How to handle in JSONL export/import?\n- Security: should repos be able to read others?\n\nDesign questions to resolve first:\n1. Read-only references vs full cross-repo dependencies?\n2. How to handle repo renames/moves?\n3. Absolute paths vs workspace names vs git remotes?\n4. Should bd-73 auto-discover related repos?\n\nRecommendation: \n- Gather user feedback first\n- Start with read-only references\n- Implement as plugin/extension?\n\nContext: This is mentioned in bd-73 as approach #2. Much more complex than daemon multi-repo approach. Only implement if there's strong user demand.\n\nPriority: Backlog (4) - wait for user feedback before designing","status":"open","priority":4,"issue_type":"feature","created_at":"2025-10-17T20:43:54.04594-07:00","updated_at":"2025-10-17T20:43:54.04594-07:00","dependencies":[{"issue_id":"bd-126","depends_on_id":"bd-73","type":"parent-child","created_at":"2025-10-17T20:44:07.576103-07:00","created_by":"daemon"}]}
|
||||
@@ -51,6 +51,10 @@
|
||||
{"id":"bd-160","title":"Global daemon should warn/reject --auto-commit and --auto-push","description":"When user runs 'bd daemon --global --auto-commit', it's unclear which repo the daemon will commit to (especially after fixing bd-122 where global daemon won't open a DB).\n\nOptions:\n1. Warn and ignore the flags in global mode\n2. Error out with clear message\n\nLine 87-91 already checks autoPush, but should skip check entirely for global mode. Add user-friendly messaging about flag incompatibility.","status":"closed","priority":3,"issue_type":"feature","created_at":"2025-10-17T22:58:02.137987-07:00","updated_at":"2025-10-17T23:04:30.223432-07:00","closed_at":"2025-10-17T23:04:30.223432-07:00"}
|
||||
{"id":"bd-163","title":"Test A","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-17T23:06:59.59343-07:00","updated_at":"2025-10-17T23:06:59.740704-07:00","closed_at":"2025-10-17T23:06:59.740704-07:00","dependencies":[{"issue_id":"bd-163","depends_on_id":"bd-164","type":"blocks","created_at":"2025-10-17T23:06:59.668292-07:00","created_by":"daemon"}]}
|
||||
{"id":"bd-164","title":"Test B","description":"","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-17T23:06:59.626612-07:00","updated_at":"2025-10-17T23:06:59.744519-07:00","closed_at":"2025-10-17T23:06:59.744519-07:00"}
|
||||
{"id":"bd-165","title":"bd ready doesn't show epics/tasks ready to close when all children complete","description":"The 'bd ready' command doesn't show epics that have all children complete as ready work. Example: vc-30 (epic) blocks 4 children - 3 are closed, 1 is in_progress. The epic itself should be reviewable/closable but doesn't show in ready work. Similarly, vc-61 (epic, in_progress) depends on vc-48 (closed) but doesn't show as ready. Expected: epics with all dependencies satisfied should show as ready to review/close. Actual: 'bd ready' returns 'no ready work' even though multiple epics are completable.","acceptance_criteria":"bd ready shows epics/tasks that have all dependencies satisfied (even if status is in_progress), allowing user to review and close them","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-18T00:04:41.811991-07:00","updated_at":"2025-10-18T00:20:36.188211-07:00","closed_at":"2025-10-18T00:20:36.188211-07:00"}
|
||||
{"id":"bd-167","title":"CleanupStaleInstances() never called in production - orphaned claims accumulate","description":"The CleanupStaleInstances() method exists in storage layer but is never called in production code. This means dead executors leave orphaned claims that block work forever. Example: vc-106 claimed by executor that died 2 hours ago, still shows in_progress with execution_state record. Need to: 1) Add periodic cleanup to executor main loop (every 5 min?), 2) Make cleanup also release claimed issues (delete execution_state AND reset status to open), 3) Add comment explaining why released.","design":"Add background goroutine in executor that calls CleanupStaleInstances() every 5 minutes. When marking instance stopped, also query for all issues claimed by that instance and release them (delete execution_state, set status=open, add event comment).","acceptance_criteria":"Dead executors automatically release their claims within 5-10 minutes of going stale, issues return to open status and become available for re-execution","status":"open","priority":0,"issue_type":"bug","created_at":"2025-10-18T00:24:57.920072-07:00","updated_at":"2025-10-18T00:24:57.920072-07:00"}
|
||||
{"id":"bd-168","title":"releaseIssueWithError() deletes execution_state but leaves status as in_progress","description":"When an executor hits an error and releases an issue via releaseIssueWithError(), it deletes the execution_state but leaves the issue status as in_progress. This means the issue drops out of ready work but has no active executor. Expected: releasing should reset status to open so the issue becomes available again. Current code in conversation.go just calls ReleaseIssue() which only deletes execution_state.","design":"Update releaseIssueWithError() to also update issue status back to open. Or create a new ReleaseAndReopen() method that does both atomically in a transaction.","acceptance_criteria":"Issues released due to errors automatically return to open status and show in bd ready","status":"open","priority":1,"issue_type":"bug","created_at":"2025-10-18T00:25:06.798843-07:00","updated_at":"2025-10-18T00:25:06.798843-07:00"}
|
||||
{"id":"bd-169","title":"Add 'bd stale' command to show orphaned claims and dead executors","description":"Need visibility into orphaned claims - issues stuck in_progress with execution_state but executor is dead/stopped. Add command to show: 1) All issues with execution_state where executor status=stopped or last_heartbeat \u003e threshold, 2) Executor instance details (when died, how long claimed), 3) Option to auto-release them. Makes manual recovery easier until auto-cleanup (bd-167) is implemented.","design":"Query: SELECT i.*, ei.status, ei.last_heartbeat FROM issues i JOIN issue_execution_state ies ON i.id = ies.issue_id JOIN executor_instances ei ON ies.executor_instance_id = ei.instance_id WHERE ei.status='stopped' OR ei.last_heartbeat \u003c NOW() - threshold. Add --release flag to auto-release all found issues.","acceptance_criteria":"bd stale shows orphaned claims, bd stale --release cleans them up","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-18T00:25:16.530937-07:00","updated_at":"2025-10-18T00:25:16.530937-07:00"}
|
||||
{"id":"bd-17","title":"bd should auto-detect .beads/*.db in current directory","description":"When bd is run without --db flag, it defaults to beads' own database instead of looking for a .beads/*.db file in the current working directory. This causes confusion when working on other projects that use beads for issue tracking (like vc).\n\nExpected behavior: bd should search for .beads/*.db in cwd and use that if found, before falling back to default beads database.\n\nExample: Running 'bd ready' in /Users/stevey/src/vc/vc/ should automatically find and use .beads/vc.db without requiring --db flag every time.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.650584-07:00","closed_at":"2025-10-16T10:07:34.046944-07:00"}
|
||||
{"id":"bd-18","title":"Document or automate JSONL sync workflow for git collaboration","description":"When using beads across multiple machines/environments via git, there's a workflow gap:\n\n1. Machine A: Create issues → stored in .beads/project.db\n2. Machine A: bd export -o .beads/issues.jsonl\n3. Machine A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n4. Machine B: git pull\n5. Machine B: ??? issues.jsonl exists but project.db is empty/stale\n\nThe missing step is: bd import --db .beads/project.db -i .beads/issues.jsonl\n\nThis needs to be either:\na) Documented clearly in workflow docs\nb) Automated (e.g., git hook, or bd auto-imports if jsonl is newer than db)\nc) Both\n\nReal-world impact: User had Claude Code on GCP VM create vc issues from BOOTSTRAP.md. They were exported to issues.jsonl and committed. But on local machine, vc.db was empty until manual import was run.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.651438-07:00","closed_at":"2025-10-14T02:51:52.199766-07:00"}
|
||||
{"id":"bd-19","title":"Root issue for dep tree test","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.652067-07:00","closed_at":"2025-10-16T10:07:34.1266-07:00"}
|
||||
|
||||
Reference in New Issue
Block a user