Implements bd-jx90: simple cleanup command without API key requirement.
Features:
- Delete all closed issues with --force
- Filter by age with --older-than N (days)
- Preview with --dry-run
- Cascade deletion with --cascade
- JSON output support
Usage:
bd cleanup --force # Delete all closed
bd cleanup --older-than 30 --force # Delete >30 days old
bd cleanup --dry-run # Preview
Closes bd-jx90
Amp-Thread-ID: https://ampcode.com/threads/T-8d905db0-4ec7-411e-95de-1f044219dc9c
Co-authored-by: Amp <amp@ampcode.com>
- Add failIfProductionDatabase() check in Go test helpers
- Add temp directory verification in RPC test setup
- Create conftest.py with pytest safety checks for Python tests
- Add BEADS_TEST_MODE env var to mark test execution
- Tests now fail fast if they detect production .beads/ usage
This prevents test issues from polluting the production database
like the incident on Nov 7, 2025 where 29+ test issues were created
in .beads/beads.db instead of isolated test databases.
Resolves: bd-2c5a
Amp-Thread-ID: https://ampcode.com/threads/T-635a8807-1120-4122-a0cb-4c21970362ce
Co-authored-by: Amp <amp@ampcode.com>
- Add BD_RPC_DEBUG=1 for lightweight timing logs to stderr
- Log socket path, socket exists check, dial timing, health check timing
- Improve daemon status message when lock not held
- Helps field triage of connection issues without verbose daemon logs
- Fixes bd-j7e2
Improvements:
1. Added top-level panic recovery in runDaemonLoop
- Captures stack trace and logs to daemon.log
- Writes daemon-error file with crash details for user visibility
- Cleans up PID file on panic
2. Replaced os.Exit calls with return statements where possible
- Allows deferred cleanup to run (lock release, socket removal, etc)
- Improves graceful shutdown on errors
3. Enhanced stopDaemon forced-kill path
- Removes stale socket file after process.Kill()
- Prevents socket artifacts from accumulating
4. Added integration tests for crash recovery
Closes bd-vcg5
- Changed TryConnect default from 2s to 200ms
- Updated fallback timeout in TryConnectWithTimeout
- Complements bd-wgu4 lock probe to eliminate 5s delays
- Fixes GH#243 (5s delay when daemon socket missing)
- Health checks still use longer timeouts via explicit TryConnectWithTimeout calls
Prevents data loss when exporting stale database by comparing issue IDs,
not just counts. Detects both scenarios:
- Database has fewer issues than JSONL
- Database has different issues than JSONL (same count)
Shows specific missing issue IDs in error. Allows override with --force.
Includes comprehensive tests for all scenarios.
- Add repair_deps(fix=False) for orphaned dependencies
- Add detect_pollution(clean=False) for test issue detection
- Add validate(checks=None, fix_all=False) for health checks
- Implemented in BdCliClient, stubs in BdDaemonClient
- Registered as MCP tools in server.py
Amp-Thread-ID: https://ampcode.com/threads/T-9ce04c75-201b-4019-b9f1-0cf10663557c
Co-authored-by: Amp <amp@ampcode.com>
bd export currently silently overwrites issues.jsonl even when the
database is stale (older than the JSONL file). This causes data loss
in multi-agent workflows.
Real incident from vc project:
- Agent A created 4 discovery epics and exported
- Agent B had stale database and exported, removing those epics
- Required manual recovery
Proposed fix: Check database freshness before export, similar to
VC's ValidateDatabaseFreshness(). Require --force to override.
Priority P1: Silent data loss in common multi-agent scenario.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix BdCliClient._run_command() to pass BEADS_DIR/BEADS_DB env vars to subprocess
- Update temp_db fixture to create .beads in workspace and return .beads dir path
- Update mcp_client fixture to use beads_dir and enable BEADS_NO_DAEMON mode
- Simplify test_init_tool to work with connection pool architecture
Result: All 19 integration tests now pass (was 19 failing)
Amp-Thread-ID: https://ampcode.com/threads/T-c1da2a55-f086-4284-9c85-0dfa4c479cf9
Co-authored-by: Amp <amp@ampcode.com>
- Update tests to use issue_id/depends_on_id instead of from_id/to_id
- Fix test_client_lazy_initialization to mock create_bd_client instead of BdClient
- Add workspace setup for lazy initialization test
- Fixes 2 test failures (now 123 passing, down from 121)
Amp-Thread-ID: https://ampcode.com/threads/T-71b3ce65-87cb-451a-a30d-162d76d92f9c
Co-authored-by: Amp <amp@ampcode.com>
- Add shell=True for subprocess.run() on Windows platform
- Improves git command PATH resolution on Windows
- Add debug logging for git detection failures
- Fixes GH#245 timeout issue where git rev-parse times out in MCP server
Amp-Thread-ID: https://ampcode.com/threads/T-71b3ce65-87cb-451a-a30d-162d76d92f9c
Co-authored-by: Amp <amp@ampcode.com>
- Add ParentPID field to DaemonLockInfo struct
- Daemon monitors parent process every 10 seconds
- Gracefully exits when parent process dies
- Prevents accumulation of orphaned daemons from dead sessions
- Fixes race conditions from multiple daemons on same database
Closes bd-zpnq
The daemon RPC server was crashing with a nil pointer dereference when the
global daemon received list, ready, stats, or other storage-dependent RPC
requests. The global daemon is created with nil storage, causing these
operations to panic when they attempted to access storage methods.
This fix adds defensive nil checks at the beginning of all RPC handlers
that require storage access. When storage is unavailable, they now return
a proper JSON error response instead of crashing the daemon.
The error message also informs users that the global daemon is deprecated
and they should use local daemons instead.
Handlers fixed:
- handleCreate, handleUpdate, handleClose
- handleList, handleShow, handleReady, handleStale
- handleResolveID, handleStats, handleEpicStatus
- handleCompact, handleCompactStats
- handleDepAdd (and via handleSimpleStoreOp for all label/dep/comment ops)
Co-authored-by: Test User <test@example.com>
* fix: Use correct SQLite driver name 'sqlite3' instead of 'sqlite'
The ncruces/go-sqlite3 driver registers as 'sqlite3', but doctor.go
and example code were using 'sqlite', causing 'unknown driver' errors.
This fix corrects all sql.Open() calls to use the proper driver name:
- cmd/bd/doctor.go: 6 instances fixed
- docs/EXTENDING.md: 2 documentation examples updated
- examples/bd-example-extension-go/: Fixed example code and README
Fixes#230
Amp-Thread-ID: https://ampcode.com/threads/T-1e8c5473-cb79-4457-be07-4517bfdb73f4
Co-authored-by: Amp <amp@ampcode.com>
* Revert CGO_ENABLED back to 0 for pure-Go SQLite driver
The ncruces/go-sqlite3 driver is pure-Go and doesn't require CGO.
The previous change to CGO_ENABLED=1 in commit f9771cd was an
attempted fix for #230, but the real issue was the driver name
mismatch ('sqlite' vs 'sqlite3'), which is now fixed.
Benefits of CGO_ENABLED=0:
- Simpler cross-compilation (no C toolchain required)
- Smaller binaries
- Faster builds
- Matches the intended design of the pure-Go driver
---------
Co-authored-by: Amp <amp@ampcode.com>