Add command documentation and improve daemon UX

- Added human-readable uptime formatting (51m 59s vs 3119.4 seconds)
- Fixed daemon stop race condition with SIGKILL
- Added markdown docs for 19 commands: blocked, comments, compact, daemon,
  delete, dep, epic, export, import, label, list, quickstart, rename-prefix,
  renumber, reopen, repos, restore, stale, sync
- Closed: bd-159, bd-152, bd-168
- Deleted test issues: bd-144, bd-145

Amp-Thread-ID: https://ampcode.com/threads/T-9f7c3fed-62de-4bcd-a059-8c1b77cdb841
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
Steve Yegge
2025-10-19 22:24:14 -07:00
parent 581ea11a7c
commit 7658c4a8e8
21 changed files with 560 additions and 6 deletions

View File

@@ -48,8 +48,6 @@
{"id":"bd-141","title":"Add daemon RPC support for comments and label subcommands","description":"The 'bd comments' and 'bd label' subcommands don't work in direct mode because they don't inherit PersistentPreRun from root command. Need to add daemon RPC handlers similar to how show/update/create work.\n\nAffected commands:\n- bd comments \u003cid\u003e\n- bd comments add \u003cid\u003e \"text\"\n- bd label list \u003cid\u003e\n- bd label add \u003cid\u003e \u003clabel\u003e\n- bd label remove \u003cid\u003e \u003clabel\u003e\n\nSolution: Add RPC handlers in daemon.go for these operations and update the CLI commands to use daemon RPC when available (check daemonClient != nil pattern used in other commands).","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-19T16:08:42.16553-07:00","updated_at":"2025-10-19T21:14:12.233179-07:00","closed_at":"2025-10-19T21:14:12.233179-07:00"} {"id":"bd-141","title":"Add daemon RPC support for comments and label subcommands","description":"The 'bd comments' and 'bd label' subcommands don't work in direct mode because they don't inherit PersistentPreRun from root command. Need to add daemon RPC handlers similar to how show/update/create work.\n\nAffected commands:\n- bd comments \u003cid\u003e\n- bd comments add \u003cid\u003e \"text\"\n- bd label list \u003cid\u003e\n- bd label add \u003cid\u003e \u003clabel\u003e\n- bd label remove \u003cid\u003e \u003clabel\u003e\n\nSolution: Add RPC handlers in daemon.go for these operations and update the CLI commands to use daemon RPC when available (check daemonClient != nil pattern used in other commands).","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-19T16:08:42.16553-07:00","updated_at":"2025-10-19T21:14:12.233179-07:00","closed_at":"2025-10-19T21:14:12.233179-07:00"}
{"id":"bd-142","title":"MCP server workspace routing broken - using wrong server for workspace","description":"When working in ~/src/beads, AI agent is calling mcp__beads-wyvern__* functions which are configured for ~/wyvern workspace. This causes MCP commands to fail or operate on wrong database.\n\nExpected: Should use correct MCP server based on current workspace\nActual: Using beads-wyvern MCP server when in beads repo\n\nNeed to investigate:\n- How MCP server routing/selection works\n- Why wrong server is being selected\n- How to fix workspace detection","notes":"Root cause: Using multiple MCP servers (beads-adar, beads-wyvern, beads-vc, beads) instead of single MCP server with global daemon. AI randomly selects wrong server for workspace.\n\nFixed:\n1. Started global daemon: bd daemon --global\n2. Simplified config to single MCP server in ~/.config/amp/settings.json\n3. Updated AGENTS.md to emphasize single MCP server as RECOMMENDED approach\n4. Marked legacy multiple-server approach with warning about workspace routing issues\n\nUser needs to restart Amp for config changes to take effect.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T18:32:04.513755-07:00","updated_at":"2025-10-19T20:52:23.598206-07:00","closed_at":"2025-10-19T18:35:00.167234-07:00"} {"id":"bd-142","title":"MCP server workspace routing broken - using wrong server for workspace","description":"When working in ~/src/beads, AI agent is calling mcp__beads-wyvern__* functions which are configured for ~/wyvern workspace. This causes MCP commands to fail or operate on wrong database.\n\nExpected: Should use correct MCP server based on current workspace\nActual: Using beads-wyvern MCP server when in beads repo\n\nNeed to investigate:\n- How MCP server routing/selection works\n- Why wrong server is being selected\n- How to fix workspace detection","notes":"Root cause: Using multiple MCP servers (beads-adar, beads-wyvern, beads-vc, beads) instead of single MCP server with global daemon. AI randomly selects wrong server for workspace.\n\nFixed:\n1. Started global daemon: bd daemon --global\n2. Simplified config to single MCP server in ~/.config/amp/settings.json\n3. Updated AGENTS.md to emphasize single MCP server as RECOMMENDED approach\n4. Marked legacy multiple-server approach with warning about workspace routing issues\n\nUser needs to restart Amp for config changes to take effect.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T18:32:04.513755-07:00","updated_at":"2025-10-19T20:52:23.598206-07:00","closed_at":"2025-10-19T18:35:00.167234-07:00"}
{"id":"bd-143","title":"Renumber command fails with foreign key constraint error","description":"When running 'bd renumber --force' after deleting issues, the command fails with: 'failed to rename bd-73 to temp ID: failed to update issue ID: constraint failed: FOREIGN KEY constraint failed (787)'. This suggests the renumber implementation doesn't properly handle foreign key constraints during the ID swap process. May need to disable foreign keys temporarily or use a different renumbering strategy.","notes":"Deeper investigation: All child tables (dependencies, labels, events, dirty_issues, issue_snapshots, compaction_snapshots, comments) have FK constraints to issues(id) ON DELETE CASCADE. When renumbering tries to UPDATE issues SET id = temp-uuid WHERE id = bd-32, the FK checks fire immediately despite PRAGMA foreign_keys = OFF being called. Issue might be that Go sql.DB connection pooling means the PRAGMA isn't applied to the actual connection doing the UPDATE. Testing with explicit connection (s.db.Conn()) to ensure PRAGMA sticks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T19:33:20.324768-07:00","updated_at":"2025-10-19T20:52:23.598384-07:00","closed_at":"2025-10-19T19:35:57.175627-07:00"} {"id":"bd-143","title":"Renumber command fails with foreign key constraint error","description":"When running 'bd renumber --force' after deleting issues, the command fails with: 'failed to rename bd-73 to temp ID: failed to update issue ID: constraint failed: FOREIGN KEY constraint failed (787)'. This suggests the renumber implementation doesn't properly handle foreign key constraints during the ID swap process. May need to disable foreign keys temporarily or use a different renumbering strategy.","notes":"Deeper investigation: All child tables (dependencies, labels, events, dirty_issues, issue_snapshots, compaction_snapshots, comments) have FK constraints to issues(id) ON DELETE CASCADE. When renumbering tries to UPDATE issues SET id = temp-uuid WHERE id = bd-32, the FK checks fire immediately despite PRAGMA foreign_keys = OFF being called. Issue might be that Go sql.DB connection pooling means the PRAGMA isn't applied to the actual connection doing the UPDATE. Testing with explicit connection (s.db.Conn()) to ensure PRAGMA sticks.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T19:33:20.324768-07:00","updated_at":"2025-10-19T20:52:23.598384-07:00","closed_at":"2025-10-19T19:35:57.175627-07:00"}
{"id":"bd-144","title":"Concurrent test issue 2","description":"","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-19T19:51:16.598972-07:00","updated_at":"2025-10-19T20:52:23.598558-07:00"}
{"id":"bd-145","title":"Concurrent test issue 1","description":"","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-19T19:51:16.670081-07:00","updated_at":"2025-10-19T20:52:23.598726-07:00"}
{"id":"bd-146","title":"Single-user issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:51:36.918878-07:00","updated_at":"2025-10-19T20:52:23.598889-07:00"} {"id":"bd-146","title":"Single-user issue","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:51:36.918878-07:00","updated_at":"2025-10-19T20:52:23.598889-07:00"}
{"id":"bd-147","title":"Direct mode test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:19.768858-07:00","updated_at":"2025-10-19T20:52:23.599056-07:00"} {"id":"bd-147","title":"Direct mode test","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:19.768858-07:00","updated_at":"2025-10-19T20:52:23.599056-07:00"}
{"id":"bd-148","title":"Direct mode test2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:25.87028-07:00","updated_at":"2025-10-19T20:52:23.599218-07:00"} {"id":"bd-148","title":"Direct mode test2","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:25.87028-07:00","updated_at":"2025-10-19T20:52:23.599218-07:00"}
@@ -57,14 +55,14 @@
{"id":"bd-15","title":"Implement full cross-type cycle prevention in AddDependency","description":"Expand cycle prevention in AddDependency to check for cycles across ALL dependency types, not just 'blocks'. Currently only 'blocks' type dependencies are checked for cycles, allowing cross-type circular dependencies to form (e.g., A blocks B, B parent-child A). This can cause semantic confusion and is a maintenance hazard for future operations that traverse dependencies.","design":"Implementation approach:\n1. Modify the cycle check in AddDependency (postgres.go:559-599)\n2. Remove the 'type = blocks' filter from the recursive CTE\n3. Check for cycles regardless of dependency type being added\n4. Return a clear error message indicating which types form the cycle\n\nTrade-offs to consider:\n- This is more mathematically correct (no cycles in dependency DAG)\n- May break legitimate use cases where cross-type cycles are intentional\n- Need to evaluate whether ANY cross-type cycles are valid in practice\n- Alternative: make this configurable with a --allow-cycle flag\n\nBefore implementing, should investigate:\n- Are there legitimate reasons for cross-type cycles?\n- What's the performance impact on large graphs (1000+ issues)?\n- Should certain type combinations be allowed to cycle?","acceptance_criteria":"- AddDependency prevents cycles across all dependency types, not just 'blocks'\n- Clear error message when cycle would be created, including dependency types\n- All existing tests pass\n- Performance benchmarked on large dependency graphs (100+ issues)\n- Decision documented on whether to add --allow-cycle flag or exception rules","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.599577-07:00","closed_at":"2025-10-16T20:31:19.174534-07:00"} {"id":"bd-15","title":"Implement full cross-type cycle prevention in AddDependency","description":"Expand cycle prevention in AddDependency to check for cycles across ALL dependency types, not just 'blocks'. Currently only 'blocks' type dependencies are checked for cycles, allowing cross-type circular dependencies to form (e.g., A blocks B, B parent-child A). This can cause semantic confusion and is a maintenance hazard for future operations that traverse dependencies.","design":"Implementation approach:\n1. Modify the cycle check in AddDependency (postgres.go:559-599)\n2. Remove the 'type = blocks' filter from the recursive CTE\n3. Check for cycles regardless of dependency type being added\n4. Return a clear error message indicating which types form the cycle\n\nTrade-offs to consider:\n- This is more mathematically correct (no cycles in dependency DAG)\n- May break legitimate use cases where cross-type cycles are intentional\n- Need to evaluate whether ANY cross-type cycles are valid in practice\n- Alternative: make this configurable with a --allow-cycle flag\n\nBefore implementing, should investigate:\n- Are there legitimate reasons for cross-type cycles?\n- What's the performance impact on large graphs (1000+ issues)?\n- Should certain type combinations be allowed to cycle?","acceptance_criteria":"- AddDependency prevents cycles across all dependency types, not just 'blocks'\n- Clear error message when cycle would be created, including dependency types\n- All existing tests pass\n- Performance benchmarked on large dependency graphs (100+ issues)\n- Decision documented on whether to add --allow-cycle flag or exception rules","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.599577-07:00","closed_at":"2025-10-16T20:31:19.174534-07:00"}
{"id":"bd-150","title":"Direct mode test clean","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:56.4305-07:00","updated_at":"2025-10-19T20:52:23.600206-07:00"} {"id":"bd-150","title":"Direct mode test clean","description":"","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T19:52:56.4305-07:00","updated_at":"2025-10-19T20:52:23.600206-07:00"}
{"id":"bd-151","title":"Multi-repo daemon routing fails in testing","description":"Test 4 from DAEMON_ARCHITECTURE.md showed daemon starts but doesn't route requests correctly to multi-repo databases. When running bd list in repo A after creating an issue, it shows 0 issues. Debug output shows 'daemon socket not ready after 5 seconds' despite daemon process running.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T20:01:18.977976-07:00","updated_at":"2025-10-19T20:52:23.600406-07:00","closed_at":"2025-10-19T20:07:40.203797-07:00"} {"id":"bd-151","title":"Multi-repo daemon routing fails in testing","description":"Test 4 from DAEMON_ARCHITECTURE.md showed daemon starts but doesn't route requests correctly to multi-repo databases. When running bd list in repo A after creating an issue, it shows 0 issues. Debug output shows 'daemon socket not ready after 5 seconds' despite daemon process running.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-19T20:01:18.977976-07:00","updated_at":"2025-10-19T20:52:23.600406-07:00","closed_at":"2025-10-19T20:07:40.203797-07:00"}
{"id":"bd-152","title":"Daemon stop has race condition with SIGKILL","description":"When stopping daemon, sometimes see 'Warning: daemon did not stop after 5 seconds, sending SIGKILL' followed by 'Error killing process: os: process already finished'. Indicates timing issue where process exits between check and kill.","status":"open","priority":2,"issue_type":"bug","created_at":"2025-10-19T20:01:18.979589-07:00","updated_at":"2025-10-19T20:52:23.600571-07:00"} {"id":"bd-152","title":"Daemon stop has race condition with SIGKILL","description":"When stopping daemon, sometimes see 'Warning: daemon did not stop after 5 seconds, sending SIGKILL' followed by 'Error killing process: os: process already finished'. Indicates timing issue where process exits between check and kill.","status":"closed","priority":2,"issue_type":"bug","created_at":"2025-10-19T20:01:18.979589-07:00","updated_at":"2025-10-19T21:49:35.916052-07:00","closed_at":"2025-10-19T21:49:35.916052-07:00"}
{"id":"bd-153","title":"Implement storage cache eviction and memory limits","description":"Implement LRU cache eviction and memory pressure detection for daemon storage cache to prevent unbounded memory growth.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.761129-07:00","updated_at":"2025-10-19T20:52:23.600736-07:00","closed_at":"2025-10-19T20:14:24.888631-07:00"} {"id":"bd-153","title":"Implement storage cache eviction and memory limits","description":"Implement LRU cache eviction and memory pressure detection for daemon storage cache to prevent unbounded memory growth.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.761129-07:00","updated_at":"2025-10-19T20:52:23.600736-07:00","closed_at":"2025-10-19T20:14:24.888631-07:00"}
{"id":"bd-154","title":"Clean up MCP integration for daemon reliability","description":"Ensure MCP server properly handles daemon lifecycle, connection failures, and recovery scenarios.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.764086-07:00","updated_at":"2025-10-19T20:52:23.600903-07:00","closed_at":"2025-10-19T20:15:11.006871-07:00"} {"id":"bd-154","title":"Clean up MCP integration for daemon reliability","description":"Ensure MCP server properly handles daemon lifecycle, connection failures, and recovery scenarios.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.764086-07:00","updated_at":"2025-10-19T20:52:23.600903-07:00","closed_at":"2025-10-19T20:15:11.006871-07:00"}
{"id":"bd-155","title":"Add daemon health checks and monitoring","description":"Add health check endpoint that validates daemon state, storage connections, and resource usage.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.764154-07:00","updated_at":"2025-10-19T20:52:23.601114-07:00","closed_at":"2025-10-19T20:14:38.291678-07:00"} {"id":"bd-155","title":"Add daemon health checks and monitoring","description":"Add health check endpoint that validates daemon state, storage connections, and resource usage.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.764154-07:00","updated_at":"2025-10-19T20:52:23.601114-07:00","closed_at":"2025-10-19T20:14:38.291678-07:00"}
{"id":"bd-156","title":"Implement daemon crash recovery and restart","description":"Detect stale daemon processes, clean up orphaned resources, and auto-restart daemon after crashes.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.766856-07:00","updated_at":"2025-10-19T20:52:23.601346-07:00","closed_at":"2025-10-19T20:15:02.211576-07:00"} {"id":"bd-156","title":"Implement daemon crash recovery and restart","description":"Detect stale daemon processes, clean up orphaned resources, and auto-restart daemon after crashes.","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-19T20:13:59.766856-07:00","updated_at":"2025-10-19T20:52:23.601346-07:00","closed_at":"2025-10-19T20:15:02.211576-07:00"}
{"id":"bd-157","title":"Implement resource limits and connection pooling","description":"Add configurable limits for connections, file descriptors, and memory usage.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T20:13:59.768745-07:00","updated_at":"2025-10-19T20:52:23.601547-07:00"} {"id":"bd-157","title":"Implement resource limits and connection pooling","description":"Add configurable limits for connections, file descriptors, and memory usage.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T20:13:59.768745-07:00","updated_at":"2025-10-19T20:52:23.601547-07:00"}
{"id":"bd-158","title":"Add daemon telemetry and metrics","description":"Track and report daemon metrics: request count, latency, cache hits/misses, error rates.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T20:13:59.77094-07:00","updated_at":"2025-10-19T20:52:23.601784-07:00"} {"id":"bd-158","title":"Add daemon telemetry and metrics","description":"Track and report daemon metrics: request count, latency, cache hits/misses, error rates.","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-19T20:13:59.77094-07:00","updated_at":"2025-10-19T20:52:23.601784-07:00"}
{"id":"bd-159","title":"Improve daemon visibility and status reporting","description":"Add clear daemon status output, uptime reporting, and user-friendly error messages.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-19T20:13:59.772435-07:00","updated_at":"2025-10-19T20:52:23.602042-07:00"} {"id":"bd-159","title":"Improve daemon visibility and status reporting","description":"Add clear daemon status output, uptime reporting, and user-friendly error messages.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-19T20:13:59.772435-07:00","updated_at":"2025-10-19T21:44:50.340047-07:00","closed_at":"2025-10-19T21:44:50.340047-07:00"}
{"id":"bd-16","title":"Refactor duplicate flush logic in PersistentPostRun","description":"PersistentPostRun contains a complete copy of the flush logic instead of calling flushToJSONL(). This violates DRY principle and makes maintenance harder. Refactor to use flushToJSONL() with a force parameter to bypass isDirty check, or extract shared logic into a helper function. Located in cmd/bd/main.go:104-138.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.602241-07:00","closed_at":"2025-10-18T09:44:24.167574-07:00"} {"id":"bd-16","title":"Refactor duplicate flush logic in PersistentPostRun","description":"PersistentPostRun contains a complete copy of the flush logic instead of calling flushToJSONL(). This violates DRY principle and makes maintenance harder. Refactor to use flushToJSONL() with a force parameter to bypass isDirty check, or extract shared logic into a helper function. Located in cmd/bd/main.go:104-138.","status":"closed","priority":3,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.602241-07:00","closed_at":"2025-10-18T09:44:24.167574-07:00"}
{"id":"bd-160","title":"Add daemon/client version compatibility checks","description":"Verify daemon and client versions are compatible before allowing connections.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-19T20:13:59.774304-07:00","updated_at":"2025-10-19T20:52:23.602618-07:00"} {"id":"bd-160","title":"Add daemon/client version compatibility checks","description":"Verify daemon and client versions are compatible before allowing connections.","status":"open","priority":1,"issue_type":"task","created_at":"2025-10-19T20:13:59.774304-07:00","updated_at":"2025-10-19T20:52:23.602618-07:00"}
{"id":"bd-161","title":"Enhance label functionality and documentation","description":"Improve beads label system to support cross-cutting concerns and contextual metadata beyond structured fields (status, priority, type).\n\nCurrent state: Basic label storage exists (labels table, Add/GetLabels methods)\nTarget state: Full label lifecycle management with CLI, filtering, automation, and documentation\n\nCore principles:\n- Labels for cross-cutting concerns (technical metadata, scope, effort, quality gates)\n- Structured fields for workflow state (status, priority, type remain primary)\n- Multi-dimensional tagging without schema changes\n\nSee removed LABELS.md for detailed use cases and design rationale.","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-19T20:45:24.163728-07:00","updated_at":"2025-10-19T20:52:23.602796-07:00"} {"id":"bd-161","title":"Enhance label functionality and documentation","description":"Improve beads label system to support cross-cutting concerns and contextual metadata beyond structured fields (status, priority, type).\n\nCurrent state: Basic label storage exists (labels table, Add/GetLabels methods)\nTarget state: Full label lifecycle management with CLI, filtering, automation, and documentation\n\nCore principles:\n- Labels for cross-cutting concerns (technical metadata, scope, effort, quality gates)\n- Structured fields for workflow state (status, priority, type remain primary)\n- Multi-dimensional tagging without schema changes\n\nSee removed LABELS.md for detailed use cases and design rationale.","status":"open","priority":2,"issue_type":"epic","created_at":"2025-10-19T20:45:24.163728-07:00","updated_at":"2025-10-19T20:52:23.602796-07:00"}
@@ -74,6 +72,7 @@
{"id":"bd-165","title":"Document label best practices and use cases","description":"Create documentation covering:\n- When to use labels vs structured fields\n- Common label sets (coding agents, open source, product dev, SRE)\n- Naming conventions (kebab-case, specificity, present tense)\n- Anti-patterns (too many labels, overlapping, personal labels)\n- Label lifecycle management\n\nContent from LABELS.md analysis document.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-19T20:45:36.867864-07:00","updated_at":"2025-10-19T20:52:23.603503-07:00"} {"id":"bd-165","title":"Document label best practices and use cases","description":"Create documentation covering:\n- When to use labels vs structured fields\n- Common label sets (coding agents, open source, product dev, SRE)\n- Naming conventions (kebab-case, specificity, present tense)\n- Anti-patterns (too many labels, overlapping, personal labels)\n- Label lifecycle management\n\nContent from LABELS.md analysis document.","status":"open","priority":3,"issue_type":"task","created_at":"2025-10-19T20:45:36.867864-07:00","updated_at":"2025-10-19T20:52:23.603503-07:00"}
{"id":"bd-166","title":"Implement label CLI commands (add, remove, list)","description":"Add CLI commands for label management:\n- bd label add \u003cissue\u003e \u003clabel...\u003e\n- bd label remove \u003cissue\u003e \u003clabel...\u003e\n- bd label list \u003cissue\u003e\n- bd labels (list all labels in use)\n\nBackend already has AddLabel/GetLabels/RemoveLabel methods in storage layer.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T20:49:44.344807-07:00","updated_at":"2025-10-19T21:14:12.231668-07:00","closed_at":"2025-10-19T21:14:12.231668-07:00"} {"id":"bd-166","title":"Implement label CLI commands (add, remove, list)","description":"Add CLI commands for label management:\n- bd label add \u003cissue\u003e \u003clabel...\u003e\n- bd label remove \u003cissue\u003e \u003clabel...\u003e\n- bd label list \u003cissue\u003e\n- bd labels (list all labels in use)\n\nBackend already has AddLabel/GetLabels/RemoveLabel methods in storage layer.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T20:49:44.344807-07:00","updated_at":"2025-10-19T21:14:12.231668-07:00","closed_at":"2025-10-19T21:14:12.231668-07:00"}
{"id":"bd-167","title":"MCP server tools should accept workspace_root parameter","description":"","design":"After set_context is called, Amp appears to inject workspace_root as a parameter to subsequent tool calls. The beads-mcp server should accept this parameter (likely ignore it or map it to working_dir) to avoid errors.","notes":"Oracle review found two additional issues: 1) Missing workspace_root on where_am_i tool, 2) set_context should always set env vars even when DB not found (so init works right after). Both fixed.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T21:17:06.93365-07:00","updated_at":"2025-10-19T21:36:07.030443-07:00","closed_at":"2025-10-19T21:29:38.326609-07:00"} {"id":"bd-167","title":"MCP server tools should accept workspace_root parameter","description":"","design":"After set_context is called, Amp appears to inject workspace_root as a parameter to subsequent tool calls. The beads-mcp server should accept this parameter (likely ignore it or map it to working_dir) to avoid errors.","notes":"Oracle review found two additional issues: 1) Missing workspace_root on where_am_i tool, 2) set_context should always set env vars even when DB not found (so init works right after). Both fixed.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-19T21:17:06.93365-07:00","updated_at":"2025-10-19T21:36:07.030443-07:00","closed_at":"2025-10-19T21:29:38.326609-07:00"}
{"id":"bd-168","title":"Update commands/ directory with new commands (comments, labels, etc)","description":"The commands/ directory contains documentation for bd commands, but several new commands have been added that aren't documented there yet: 'comments', 'labels', and possibly others. Need to audit what's missing and add documentation.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-10-19T21:54:04.65288-07:00","updated_at":"2025-10-19T21:57:28.943347-07:00","closed_at":"2025-10-19T21:57:28.943347-07:00"}
{"id":"bd-17","title":"Test issue with explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.603831-07:00","closed_at":"2025-10-16T10:07:34.124331-07:00"} {"id":"bd-17","title":"Test issue with explicit ID","description":"","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.603831-07:00","closed_at":"2025-10-16T10:07:34.124331-07:00"}
{"id":"bd-18","title":"Critical bug","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.604005-07:00","closed_at":"2025-10-14T14:16:08.107546-07:00"} {"id":"bd-18","title":"Critical bug","description":"","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.604005-07:00","closed_at":"2025-10-14T14:16:08.107546-07:00"}
{"id":"bd-19","title":"Verify auto-export works","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.604167-07:00","closed_at":"2025-10-14T14:16:09.268591-07:00"} {"id":"bd-19","title":"Verify auto-export works","description":"","status":"closed","priority":0,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-19T20:52:23.604167-07:00","closed_at":"2025-10-14T14:16:09.268591-07:00"}

View File

@@ -268,6 +268,25 @@ func isDaemonRunning(pidFile string) (bool, int) {
return true, pid return true, pid
} }
func formatUptime(seconds float64) string {
if seconds < 60 {
return fmt.Sprintf("%.1f seconds", seconds)
}
if seconds < 3600 {
minutes := int(seconds / 60)
secs := int(seconds) % 60
return fmt.Sprintf("%dm %ds", minutes, secs)
}
if seconds < 86400 {
hours := int(seconds / 3600)
minutes := int(seconds/60) % 60
return fmt.Sprintf("%dh %dm", hours, minutes)
}
days := int(seconds / 86400)
hours := int(seconds/3600) % 24
return fmt.Sprintf("%dd %dh", days, hours)
}
func showDaemonStatus(pidFile string, global bool) { func showDaemonStatus(pidFile string, global bool) {
if isRunning, pid := isDaemonRunning(pidFile); isRunning { if isRunning, pid := isDaemonRunning(pidFile); isRunning {
scope := "local" scope := "local"
@@ -342,7 +361,7 @@ func showDaemonHealth(global bool) {
fmt.Printf("%s Daemon Health: %s\n", statusIcon, health.Status) fmt.Printf("%s Daemon Health: %s\n", statusIcon, health.Status)
fmt.Printf(" Version: %s\n", health.Version) fmt.Printf(" Version: %s\n", health.Version)
fmt.Printf(" Uptime: %.1f seconds\n", health.Uptime) fmt.Printf(" Uptime: %s\n", formatUptime(health.Uptime))
fmt.Printf(" Cache Size: %d databases\n", health.CacheSize) fmt.Printf(" Cache Size: %d databases\n", health.CacheSize)
fmt.Printf(" Cache Hits: %d\n", health.CacheHits) fmt.Printf(" Cache Hits: %d\n", health.CacheHits)
fmt.Printf(" Cache Misses: %d\n", health.CacheMisses) fmt.Printf(" Cache Misses: %d\n", health.CacheMisses)
@@ -551,8 +570,18 @@ func stopDaemon(pidFile string) {
} }
fmt.Fprintf(os.Stderr, "Warning: daemon did not stop after 5 seconds, sending SIGKILL\n") fmt.Fprintf(os.Stderr, "Warning: daemon did not stop after 5 seconds, sending SIGKILL\n")
// Check one more time before SIGKILL to avoid race condition
if isRunning, _ := isDaemonRunning(pidFile); !isRunning {
fmt.Println("✓ Daemon stopped")
return
}
if err := process.Kill(); err != nil { if err := process.Kill(); err != nil {
fmt.Fprintf(os.Stderr, "Error killing process: %v\n", err) // Ignore "process already finished" errors
if !strings.Contains(err.Error(), "process already finished") {
fmt.Fprintf(os.Stderr, "Error killing process: %v\n", err)
}
} }
os.Remove(pidFile) os.Remove(pidFile)
fmt.Println("✓ Daemon killed") fmt.Println("✓ Daemon killed")

15
commands/blocked.md Normal file
View File

@@ -0,0 +1,15 @@
---
description: Show blocked issues
argument-hint: []
---
Show all issues that are blocked by dependencies.
Use `bd blocked` to see which issues have blockers preventing them from being worked on. This is the inverse of `bd ready` - it shows what's NOT ready.
Blocked issues have one or more dependencies with type "blocks" that are still open. Once all blocking dependencies are closed, the issue becomes ready and will appear in `bd ready`.
Useful for:
- Understanding why work is stuck
- Identifying critical path items
- Planning dependency resolution

28
commands/comments.md Normal file
View File

@@ -0,0 +1,28 @@
---
description: View or manage comments on an issue
argument-hint: [issue-id]
---
View or add comments to a beads issue.
## View Comments
To view all comments on an issue:
- $1: Issue ID (e.g., bd-123)
Use the beads CLI `bd comments <issue-id>` to list all comments. Show them to the user with timestamps and authors.
## Add Comment
To add a comment:
- $1: "add"
- $2: Issue ID
- $3: Comment text (or use -f flag for file input)
Use `bd comments add <issue-id> "comment text"` to add a comment. Confirm the comment was added successfully.
Comments are useful for:
- Progress updates during work
- Design notes or technical decisions
- Links to related resources
- Questions or blockers

31
commands/compact.md Normal file
View File

@@ -0,0 +1,31 @@
---
description: Compact old closed issues using semantic summarization
argument-hint: [--all] [--id issue-id] [--dry-run]
---
Reduce database size by summarizing closed issues no longer actively referenced.
## Compaction Tiers
- **Tier 1**: Semantic compression (30+ days closed, ~70% size reduction)
- **Tier 2**: Ultra compression (90+ days closed, ~95% size reduction)
## Usage
- **Preview candidates**: `bd compact --dry-run`
- **Compact all eligible**: `bd compact --all`
- **Compact specific issue**: `bd compact --id bd-42`
- **Force compact**: `bd compact --id bd-42 --force` (bypass age checks)
- **View statistics**: `bd compact --stats`
## Options
- **--tier**: Choose compaction tier (1 or 2, default: 1)
- **--workers**: Parallel workers (default: 5)
- **--batch-size**: Issues per batch (default: 10)
## Important
This is **permanent graceful decay** - original content is discarded. Use `bd restore <id>` to view full history from git if needed.
Useful for long-running projects to keep database size manageable.

35
commands/daemon.md Normal file
View File

@@ -0,0 +1,35 @@
---
description: Run background sync daemon
argument-hint: [--global] [--stop] [--status] [--health]
---
Run a background daemon that manages database connections and optionally syncs with git.
## Daemon Modes
- **Local daemon**: Socket at `.beads/bd.sock` (per-repository)
- **Global daemon**: Socket at `~/.beads/bd.sock` (all repositories)
## Common Operations
- **Start**: `bd daemon` or `bd daemon --global`
- **Stop**: `bd daemon --stop` or `bd daemon --global --stop`
- **Status**: `bd daemon --status` or `bd daemon --global --status`
- **Health**: `bd daemon --health` - shows uptime, cache stats, performance metrics
- **Metrics**: `bd daemon --metrics` - detailed operational telemetry
## Sync Options
- **--auto-commit**: Automatically commit JSONL changes
- **--auto-push**: Automatically push commits to remote
- **--interval**: Sync check interval (default: 5m)
## Migration
- **--migrate-to-global**: Migrate from local to global daemon
The daemon provides:
- Connection pooling and caching
- Better performance for frequent operations
- Automatic JSONL sync
- Optional git sync

32
commands/delete.md Normal file
View File

@@ -0,0 +1,32 @@
---
description: Delete issues and clean up references
argument-hint: [issue-ids...] [--force]
---
Delete one or more issues and clean up all references.
## Safety Features
- **Preview mode**: Default shows what would be deleted
- **--force**: Required to actually delete
- **--dry-run**: Preview collision detection
- **Dependency checks**: Fails if issue has dependents (unless --cascade or --force)
## Batch Deletion
- Delete multiple: `bd delete bd-1 bd-2 bd-3 --force`
- Delete from file: `bd delete --from-file deletions.txt --force`
## Dependency Handling
- **Default**: Fails if issue has dependents not in deletion set
- **--cascade**: Recursively delete all dependent issues
- **--force**: Delete and orphan dependents
## What Gets Deleted
1. All dependency links (any type, both directions)
2. Text references updated to "[deleted:ID]" in connected issues
3. Issue removed from database
This operation cannot be undone. Use with caution!

38
commands/dep.md Normal file
View File

@@ -0,0 +1,38 @@
---
description: Manage dependencies between issues
argument-hint: [command] [from-id] [to-id]
---
Manage dependencies between beads issues.
## Available Commands
- **add**: Add a dependency between issues
- $1: "add"
- $2: From issue ID
- $3: To issue ID
- $4: Dependency type (blocks, related, parent-child, discovered-from)
- **remove**: Remove a dependency
- $1: "remove"
- $2: From issue ID
- $3: To issue ID
- **tree**: Show dependency tree for an issue
- $1: "tree"
- $2: Issue ID
- **cycles**: Detect dependency cycles
## Dependency Types
- **blocks**: Hard blocker (from blocks to) - affects ready queue
- **related**: Soft relationship - for context only
- **parent-child**: Epic/subtask relationship
- **discovered-from**: Track issues found during work
## Examples
- `bd dep add bd-10 bd-20 --type blocks`: bd-10 blocks bd-20
- `bd dep tree bd-20`: Show what blocks bd-20 and what bd-20 blocks
- `bd dep cycles`: Check for circular dependencies

26
commands/epic.md Normal file
View File

@@ -0,0 +1,26 @@
---
description: Epic management commands
argument-hint: [command]
---
Manage epics (large features composed of multiple issues).
## Available Commands
- **status**: Show epic completion status
- Shows progress for each epic
- Lists child issues and their states
- Calculates completion percentage
- **close-eligible**: Close epics where all children are complete
- Automatically closes epics when all child issues are done
- Useful for bulk epic cleanup
## Epic Workflow
1. Create epic: `bd create "Large Feature" -t epic -p 1`
2. Link subtasks: `bd dep add bd-10 bd-20 --type parent-child` (epic bd-10 is parent of task bd-20)
3. Track progress: `bd epic status`
4. Auto-close when done: `bd epic close-eligible`
Epics use parent-child dependencies to track subtasks.

24
commands/export.md Normal file
View File

@@ -0,0 +1,24 @@
---
description: Export issues to JSONL format
argument-hint: [-o output-file]
---
Export all issues to JSON Lines format (one JSON object per line).
## Usage
- **To stdout**: `bd export`
- **To file**: `bd export -o issues.jsonl`
- **Filter by status**: `bd export --status open`
Issues are sorted by ID for consistent diffs, making git diffs readable.
## Automatic Export
The daemon automatically exports to `.beads/issues.jsonl` after any CRUD operation (5-second debounce). Manual export is rarely needed unless you need a custom output location or filtered export.
Export is used for:
- Git version control
- Backup
- Sharing issues between repositories
- Data migration

36
commands/import.md Normal file
View File

@@ -0,0 +1,36 @@
---
description: Import issues from JSONL format
argument-hint: [-i input-file]
---
Import issues from JSON Lines format (one JSON object per line).
## Usage
- **From stdin**: `bd import` (reads from stdin)
- **From file**: `bd import -i issues.jsonl`
- **Preview**: `bd import -i issues.jsonl --dry-run`
- **Resolve collisions**: `bd import -i issues.jsonl --resolve-collisions`
## Behavior
- **Existing issues** (same ID): Updated with new data
- **New issues**: Created
- **Collisions** (same ID, different content): Detected and reported
## Collision Handling
When merging branches or pulling changes, ID collisions can occur:
- **--dry-run**: Preview collisions without making changes
- **--resolve-collisions**: Automatically remap colliding issues to new IDs
- All text references and dependencies are automatically updated
## Automatic Import
The daemon automatically imports from `.beads/issues.jsonl` when it's newer than the database (e.g., after `git pull`). Manual import is rarely needed.
## Options
- **--skip-existing**: Skip updates to existing issues
- **--strict**: Fail on dependency errors instead of warnings

33
commands/label.md Normal file
View File

@@ -0,0 +1,33 @@
---
description: Manage issue labels
argument-hint: [command] [issue-id] [label]
---
Manage labels on beads issues. Labels provide flexible cross-cutting metadata beyond structured fields (status, priority, type).
## Available Commands
- **add**: Add a label to an issue
- $1: "add"
- $2: Issue ID
- $3: Label name
- **remove**: Remove a label from an issue
- $1: "remove"
- $2: Issue ID
- $3: Label name
- **list**: List labels on a specific issue
- $1: "list"
- $2: Issue ID
- **list-all**: Show all labels used across all issues
## Common Label Use Cases
- Technical scope: `backend`, `frontend`, `api`, `database`
- Quality gates: `needs-review`, `needs-tests`, `security-review`
- Effort sizing: `quick-win`, `complex`, `spike`
- Context: `technical-debt`, `documentation`, `performance`
Use `bd label add <issue-id> <label>` to tag issues with contextual metadata.

30
commands/list.md Normal file
View File

@@ -0,0 +1,30 @@
---
description: List issues with optional filters
argument-hint: [--status] [--priority] [--type] [--assignee] [--label]
---
List beads issues with optional filtering.
## Filters
- **--status, -s**: Filter by status (open, in_progress, blocked, closed)
- **--priority, -p**: Filter by priority (0-4: 0=critical, 1=high, 2=medium, 3=low, 4=backlog)
- **--type, -t**: Filter by type (bug, feature, task, epic, chore)
- **--assignee, -a**: Filter by assignee
- **--label, -l**: Filter by labels (comma-separated, must have ALL labels)
- **--title**: Filter by title text (case-insensitive substring match)
- **--limit, -n**: Limit number of results
## Examples
- `bd list --status open --priority 1`: High priority open issues
- `bd list --type bug --assignee alice`: Alice's assigned bugs
- `bd list --label backend,needs-review`: Backend issues needing review
- `bd list --title "auth"`: Issues with "auth" in the title
## Output Formats
- Default: Human-readable table
- `--json`: JSON format for scripting
- `--format digraph`: Graph format for golang.org/x/tools/cmd/digraph
- `--format dot`: Graphviz DOT format

17
commands/quickstart.md Normal file
View File

@@ -0,0 +1,17 @@
---
description: Quick start guide for bd workflows
argument-hint: []
---
Display a quick start guide showing common bd workflows and patterns.
Use `bd quickstart` to see:
- Getting started with bd
- Common workflow patterns
- Basic commands
- Dependency management
- Git integration
This is an interactive tutorial that walks through the essential bd commands and concepts for new users.
No arguments needed - just run `bd quickstart` to see the full guide.

24
commands/rename-prefix.md Normal file
View File

@@ -0,0 +1,24 @@
---
description: Rename the issue prefix for all issues
argument-hint: <new-prefix> [--dry-run]
---
Rename the issue prefix for all issues in the database.
Updates all issue IDs and all text references across all fields.
## Prefix Rules
- Max length: 8 characters
- Allowed: lowercase letters, numbers, hyphens
- Must start with a letter
- Must end with a hyphen (e.g., 'kw-', 'work-')
## Usage
- **Preview**: `bd rename-prefix kw- --dry-run`
- **Apply**: `bd rename-prefix kw-`
Example: Rename from 'knowledge-work-' to 'kw-'
All dependencies and text references are automatically updated.

29
commands/renumber.md Normal file
View File

@@ -0,0 +1,29 @@
---
description: Renumber all issues sequentially
argument-hint: [--dry-run] [--force]
---
Renumber all issues sequentially to eliminate gaps in the ID space.
## What It Does
- Renumber all issues starting from 1 (keeps chronological order)
- Update all dependency links (all types)
- Update all text references in descriptions, notes, acceptance criteria
- Show mapping report: old ID -> new ID
- Export updated database to JSONL
## Usage
- **Preview**: `bd renumber --dry-run`
- **Apply**: `bd renumber --force`
## Risks
⚠️ **Warning**: This operation cannot be undone!
- May break external references in GitHub issues, docs, commits
- Git history may become confusing
- Backup recommended before running
Use sparingly - only when ID gaps are problematic.

22
commands/reopen.md Normal file
View File

@@ -0,0 +1,22 @@
---
description: Reopen closed issues
argument-hint: [issue-ids...] [--reason]
---
Reopen one or more closed issues.
Sets status to 'open' and clears the closed_at timestamp. Emits a Reopened event.
## Usage
- **Reopen single**: `bd reopen bd-42`
- **Reopen multiple**: `bd reopen bd-42 bd-43 bd-44`
- **With reason**: `bd reopen bd-42 --reason "Found regression"`
More explicit than `bd update --status open` - specifically designed for reopening workflow.
Common reasons for reopening:
- Regression found
- Requirements changed
- Incomplete implementation
- New information discovered

25
commands/repos.md Normal file
View File

@@ -0,0 +1,25 @@
---
description: Manage work across multiple repositories
argument-hint: [command]
---
Manage work across multiple repositories when using a global daemon.
**Requires**: Running global daemon (`bd daemon --global`)
## Available Commands
- **list**: List all cached repositories
- **ready**: Show ready work across all repositories
- `--group`: Group results by repository
- **stats**: Show combined statistics across all repositories
- **clear-cache**: Clear all cached repository connections
## Usage
- `bd repos list` - See all repositories connected to global daemon
- `bd repos ready` - View all ready work across projects
- `bd repos ready --group` - Group ready work by repository
- `bd repos stats` - Combined statistics from all repos
Useful for managing multiple beads projects from a single global daemon.

28
commands/restore.md Normal file
View File

@@ -0,0 +1,28 @@
---
description: Restore full history of compacted issue from git
argument-hint: <issue-id>
---
Restore full history of a compacted issue from git version control.
When an issue is compacted, the git commit hash is saved. This command:
1. Reads the compacted_at_commit from the database
2. Checks out that commit temporarily
3. Reads the full issue from JSONL at that point in history
4. Displays the full issue history (description, events, etc.)
5. Returns to the current git state
## Usage
`bd restore bd-42`
This is **read-only** - it does not modify the database or git state.
Useful for:
- Reviewing old issues after compaction
- Recovering forgotten context
- Audit trails
- Historical research
Requires git repository with issue history.

25
commands/stale.md Normal file
View File

@@ -0,0 +1,25 @@
---
description: Show orphaned claims and dead executors
argument-hint: [--release] [--threshold]
---
Show issues stuck in_progress with execution_state where the executor is dead or stopped.
Helps identify orphaned work that needs manual recovery.
## Stale Detection
An issue is stale if:
- It has an execution_state (claimed by an executor)
- AND the executor status is 'stopped'
- OR the executor's last_heartbeat is older than threshold
Default threshold: 300 seconds (5 minutes)
## Usage
- **List stale issues**: `bd stale`
- **Custom threshold**: `bd stale --threshold 600` (10 minutes)
- **Auto-release**: `bd stale --release` (automatically release all stale issues)
Useful for parallel execution systems where workers may crash or get stopped.

28
commands/sync.md Normal file
View File

@@ -0,0 +1,28 @@
---
description: Synchronize issues with git remote
argument-hint: [--dry-run] [--message]
---
Synchronize issues with git remote in a single operation.
## Sync Steps
1. Export pending changes to JSONL
2. Commit changes to git
3. Pull from remote (with conflict resolution)
4. Import updated JSONL
5. Push local commits to remote
Wraps the entire git-based sync workflow for multi-device use.
## Usage
- **Basic sync**: `bd sync`
- **Preview**: `bd sync --dry-run`
- **Custom message**: `bd sync --message "Closed sprint issues"`
- **Pull only**: `bd sync --no-push`
- **Push only**: `bd sync --no-pull`
## Note
Most users should rely on the daemon's automatic sync (`bd daemon --auto-commit --auto-push`) instead of running manual sync. This command is useful for one-off syncs or when not using the daemon.