diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index afd66dad..d84bd472 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -38,6 +38,7 @@ {"id":"bd-e92","content_hash":"12073b3293b06f99051bc9c00188aeb520cd2e4792cf4694f1fa4b784e625e54","title":"Add test coverage for internal/autoimport package","description":"","design":"The autoimport package has only 1 test file. Need comprehensive tests. Target: 70% coverage","acceptance_criteria":"- At least 3 test files\n- Package coverage \u003e= 70%\n- Tests cover main functionality, error paths, edge cases","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T21:21:22.338577-05:00","updated_at":"2025-11-20T21:21:22.338577-05:00","source_repo":".","dependencies":[{"issue_id":"bd-e92","depends_on_id":"bd-ge7","type":"blocks","created_at":"2025-11-20T21:21:31.128625-05:00","created_by":"daemon"}]} {"id":"bd-g9eu","content_hash":"4c5542fdd6422092607cca0f8d5f82a41bd366c348a97a604299d6dc75970b3a","title":"Investigate TestRoutingIntegration failure","description":"TestRoutingIntegration/maintainer_with_SSH_remote failed during pre-commit check with \"expected role maintainer, got contributor\".\nThis occurred while running `go test -short ./...` on darwin/arm64.\nThe failure appears unrelated to storage/sqlite changes.\nNeed to investigate if this is a flaky test or environmental issue.","status":"closed","priority":2,"issue_type":"task","created_at":"2025-11-20T15:55:19.337094-08:00","updated_at":"2025-11-23T23:52:29.996817-08:00","closed_at":"2025-11-23T23:38:55.477369-08:00","source_repo":"."} {"id":"bd-ge7","content_hash":"84248781654b9924e1f4284058f141b73d761dead05ef9a3d1cc9b9f8cd4b60d","title":"Improve Beads test coverage from 46% to 80%","description":"","design":"Currently at 46% test coverage. Need to systematically improve coverage across all subsystems, focusing first on packages with minimal or no tests.\n\nTarget: 80% overall coverage\n\nApproach:\n- Break down by subsystem (internal/* packages)\n- Prioritize packages with 0-1 test files\n- Each child issue targets specific coverage goals\n- Focus on unit tests for core logic, error paths, and edge cases\n\nThis epic will be executed by the VC executor to test its ability to handle sustained multi-issue work.","acceptance_criteria":"- Overall test coverage reaches 80% or higher\n- All internal/* packages have at least 60% coverage\n- All packages with only 1 test file now have at least 3 test files\n- Quality gates (go test, golangci-lint) pass\n- Tests are maintainable and test actual behavior, not implementation details","status":"open","priority":1,"issue_type":"epic","created_at":"2025-11-20T21:21:03.700271-05:00","updated_at":"2025-11-20T21:21:03.700271-05:00","source_repo":"."} +{"id":"bd-gfu","content_hash":"e85415557f3b861b559c924864187bf05a16e64225529232e377d60526616926","title":"Add --start flag to bd daemon, show help with no args","description":"Currently `bd daemon` with no args immediately starts the daemon. This is inconsistent with other daemon management commands like `--stop`, `--status`, etc.\n\n## Proposed Changes\n\n1. Add `--start` flag to explicitly start daemon\n2. With no args or flags, print help text showing available options\n3. Maintain backward compatibility where feasible\n\n## Current Consumers\n\n- **Auto-start logic** (`daemon_autostart.go:106, 270`): Calls `bd daemon` programmatically - needs update\n- **MCP docs** (SETUP_DAEMON.md:111): Already incorrectly shows `bd daemon start` - will be fixed by this change\n- **Python daemon client**: Suggests `bd daemon` in error messages - needs doc update\n\n## Implementation Notes\n\n- Default behavior (no args/flags) should show help\n- `--start` should start daemon (current no-args behavior)\n- Auto-start code needs to pass `--start` flag explicitly\n- Update all documentation to use `bd daemon --start`\n- Ensure backward compat doesn't break existing workflows","status":"in_progress","priority":2,"issue_type":"feature","created_at":"2025-11-23T23:54:49.906553-08:00","updated_at":"2025-11-23T23:55:05.324538-08:00","source_repo":"."} {"id":"bd-gqo","content_hash":"21642505de8036d9501f8593b78de7b761f05869f9d8d11758278e9c0b33c9c3","title":"Implement health checks in daemon event loop","description":"Add health checks to checkDaemonHealth() function in daemon_event_loop.go:170:\n- Database integrity check\n- Disk space check\n- Memory usage check\n\nCurrently it's just a no-op placeholder.","status":"open","priority":3,"issue_type":"feature","created_at":"2025-11-21T18:55:07.534304-05:00","updated_at":"2025-11-21T18:55:07.534304-05:00","source_repo":"."} {"id":"bd-hdt","content_hash":"8e6cf1653ef2ea583b39a421b3d708763ab7c042d6cd494e77202a92af0a7398","title":"Implement auto-merge functionality in duplicates command","description":"The duplicates.go file has a TODO at line 95 to implement the performMerge function for automatic duplicate merging. Currently it just prints a warning message. This would automate the merge process instead of just suggesting commands.","status":"open","priority":2,"issue_type":"feature","created_at":"2025-11-21T18:55:02.828619-05:00","updated_at":"2025-11-21T18:55:02.828619-05:00","source_repo":"."} {"id":"bd-j3zt","content_hash":"531ad51101f41375a93d66b8d22105ce7c4913261db78b662bb759e802bc01e2","title":"Fix mypy errors in beads-mcp","description":"Running `mypy .` in `integrations/beads-mcp` reports 287 errors. These should be addressed to improve type safety and code quality.","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-20T18:53:28.557708-05:00","updated_at":"2025-11-20T18:53:28.557708-05:00","source_repo":"."} diff --git a/.beads/metadata.json b/.beads/metadata.json index 9907e98d..5db8bf36 100644 --- a/.beads/metadata.json +++ b/.beads/metadata.json @@ -1,5 +1,5 @@ { "database": "beads.db", "jsonl_export": "beads.jsonl", - "last_bd_version": "0.24.2" + "last_bd_version": "0.24.3" } \ No newline at end of file diff --git a/cmd/bd/daemon.go b/cmd/bd/daemon.go index 255354e8..ebbb40ab 100644 --- a/cmd/bd/daemon.go +++ b/cmd/bd/daemon.go @@ -21,8 +21,8 @@ import ( var daemonCmd = &cobra.Command{ Use: "daemon", - Short: "Run background sync daemon", - Long: `Run a background daemon that automatically syncs issues with git remote. + Short: "Manage background sync daemon", + Long: `Manage the background daemon that automatically syncs issues with git remote. The daemon will: - Poll for changes at configurable intervals (default: 5 seconds) @@ -32,10 +32,15 @@ The daemon will: - Pull remote changes periodically - Auto-import when remote changes detected -Use --stop to stop a running daemon. -Use --status to check if daemon is running. -Use --health to check daemon health and metrics.`, +Common operations: + bd daemon --start Start the daemon + bd daemon --stop Stop a running daemon + bd daemon --status Check if daemon is running + bd daemon --health Check daemon health and metrics + +Run 'bd daemon' with no flags to see available options.`, Run: func(cmd *cobra.Command, args []string) { + start, _ := cmd.Flags().GetBool("start") stop, _ := cmd.Flags().GetBool("stop") status, _ := cmd.Flags().GetBool("status") health, _ := cmd.Flags().GetBool("health") @@ -47,9 +52,15 @@ Use --health to check daemon health and metrics.`, logFile, _ := cmd.Flags().GetString("log") global, _ := cmd.Flags().GetBool("global") + // If no operation flags provided, show help + if !start && !stop && !status && !health && !metrics && !migrateToGlobal { + _ = cmd.Help() + return + } + // If auto-commit/auto-push flags weren't explicitly provided, read from config // (skip if --stop, --status, --health, --metrics, or --migrate-to-global) - if !stop && !status && !health && !metrics && !migrateToGlobal && !global { + if start && !stop && !status && !health && !metrics && !migrateToGlobal && !global { if !cmd.Flags().Changed("auto-commit") { if dbPath := beads.FindDatabasePath(); dbPath != "" { ctx := context.Background() @@ -112,6 +123,14 @@ Use --health to check daemon health and metrics.`, return } + // If we get here and --start wasn't provided, something is wrong + // (should have been caught by help check above) + if !start { + fmt.Fprintf(os.Stderr, "Error: --start flag is required to start the daemon\n") + fmt.Fprintf(os.Stderr, "Run 'bd daemon --help' to see available options\n") + os.Exit(1) + } + // Skip daemon-running check if we're the forked child (BD_DAEMON_FOREGROUND=1) // because the check happens in the parent process before forking if os.Getenv("BD_DAEMON_FOREGROUND") != "1" { @@ -197,6 +216,7 @@ Use --health to check daemon health and metrics.`, } func init() { + daemonCmd.Flags().Bool("start", false, "Start the daemon") daemonCmd.Flags().Duration("interval", 5*time.Second, "Sync check interval") daemonCmd.Flags().Bool("auto-commit", false, "Automatically commit changes") daemonCmd.Flags().Bool("auto-push", false, "Automatically push commits") diff --git a/cmd/bd/daemon_autostart.go b/cmd/bd/daemon_autostart.go index 42dfa9d4..4a29b45d 100644 --- a/cmd/bd/daemon_autostart.go +++ b/cmd/bd/daemon_autostart.go @@ -103,7 +103,7 @@ func restartDaemonForVersionMismatch() bool { return false } - args := []string{"daemon"} + args := []string{"daemon", "--start"} cmd := exec.Command(exe, args...) cmd.Env = append(os.Environ(), "BD_DAEMON_FOREGROUND=1") @@ -267,7 +267,7 @@ func startDaemonProcess(socketPath string, isGlobal bool) bool { binPath = os.Args[0] } - args := []string{"daemon"} + args := []string{"daemon", "--start"} if isGlobal { args = append(args, "--global") } diff --git a/cmd/bd/daemon_lifecycle.go b/cmd/bd/daemon_lifecycle.go index 8bb1f902..b9dc16f8 100644 --- a/cmd/bd/daemon_lifecycle.go +++ b/cmd/bd/daemon_lifecycle.go @@ -387,7 +387,7 @@ func startDaemon(interval time.Duration, autoCommit, autoPush bool, logFile, pid os.Exit(1) } - args := []string{"daemon", + args := []string{"daemon", "--start", "--interval", interval.String(), } if autoCommit { diff --git a/commands/daemon.md b/commands/daemon.md index e2f2c59d..69c8bb2b 100644 --- a/commands/daemon.md +++ b/commands/daemon.md @@ -1,9 +1,9 @@ --- -description: Run background sync daemon -argument-hint: [--stop] [--status] [--health] +description: Manage background sync daemon +argument-hint: [--start] [--stop] [--status] [--health] --- -Run a per-project background daemon that manages database connections and syncs with git. +Manage the per-project background daemon that handles database connections and syncs with git. ## Per-Project Daemon (LSP Model) @@ -39,7 +39,7 @@ Each project runs its own daemon at `.beads/bd.sock` for complete database isola ## Common Operations -- **Start**: `bd daemon` (auto-starts on first `bd` command) +- **Start**: `bd daemon --start` (or auto-starts on first `bd` command) - **Stop**: `bd daemon --stop` - **Status**: `bd daemon --status` - **Health**: `bd daemon --health` - shows uptime, cache stats, performance metrics diff --git a/docs/DAEMON.md b/docs/DAEMON.md index 57a2f4e9..fc0a64fe 100644 --- a/docs/DAEMON.md +++ b/docs/DAEMON.md @@ -173,7 +173,7 @@ FileWatcher (platform-native) ```bash # Enable for single daemon -BEADS_DAEMON_MODE=events bd daemon start +BEADS_DAEMON_MODE=events bd daemon --start # Set globally in shell profile export BEADS_DAEMON_MODE=events @@ -200,14 +200,14 @@ bd daemons killall ```bash # Fail if watcher unavailable (e.g., testing) -BEADS_WATCHER_FALLBACK=false BEADS_DAEMON_MODE=events bd daemon start +BEADS_WATCHER_FALLBACK=false BEADS_DAEMON_MODE=events bd daemon --start ``` **Switch back to polling:** ```bash # Explicitly use polling mode -BEADS_DAEMON_MODE=poll bd daemon start +BEADS_DAEMON_MODE=poll bd daemon --start # Or unset to use default unset BEADS_DAEMON_MODE @@ -280,7 +280,7 @@ bd info --json | grep daemon_running export BEADS_AUTO_START_DAEMON=false # Start manually -bd daemon start +bd daemon --start ``` **Auto-start with exponential backoff:** diff --git a/integrations/beads-mcp/SETUP_DAEMON.md b/integrations/beads-mcp/SETUP_DAEMON.md index 934575b8..ca717449 100644 --- a/integrations/beads-mcp/SETUP_DAEMON.md +++ b/integrations/beads-mcp/SETUP_DAEMON.md @@ -28,7 +28,7 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json`: In your beads project directory: ```bash -bd daemon start +bd daemon --start ``` The daemon will: @@ -108,19 +108,19 @@ If you want to temporarily use CLI mode: ```bash # Start daemon -bd daemon start +bd daemon --start # Check status -bd daemon status +bd daemon --status # View logs -bd daemon logs +bd daemons logs . # Stop daemon -bd daemon stop +bd daemon --stop # Restart daemon -bd daemon stop && bd daemon start +bd daemon --stop && bd daemon --start ``` ## Troubleshooting @@ -130,7 +130,7 @@ bd daemon stop && bd daemon start Start the daemon in your beads project: ```bash cd ~/src/vc/adar/beads -bd daemon start +bd daemon --start ``` ### Wrong database being used diff --git a/integrations/beads-mcp/src/beads_mcp/bd_daemon_client.py b/integrations/beads-mcp/src/beads_mcp/bd_daemon_client.py index e7d663e3..5ec671d5 100644 --- a/integrations/beads-mcp/src/beads_mcp/bd_daemon_client.py +++ b/integrations/beads-mcp/src/beads_mcp/bd_daemon_client.py @@ -110,7 +110,7 @@ class BdDaemonClient(BdClientBase): # No socket found anywhere raise DaemonNotRunningError( - "Daemon socket not found. Is the daemon running? Try: bd daemon (local) or bd daemon --global" + "Daemon socket not found. Is the daemon running? Try: bd daemon --start" ) async def _send_request(self, operation: str, args: Dict[str, Any]) -> Any: