- Use path normalization (EvalSymlinks) to reliably match daemons across symlinks
- Check for stale sockets directly (catches cases where RPC failed)
- Detect multiple daemons for same workspace
- Enhanced error details for stale daemon detection
- Use global daemon registry instead of path-scoped discovery
Test proves the bug exists:
- Agent A closes issue and pushes
- Agent B does git pull (JSONL shows 'closed')
- Daemon query returns 'open' (stale SQLite)
Test currently fails, confirming daemon doesn't auto-import
after git pull updates JSONL. Will pass once fix is complete.
Fixes#197: bd doctor was hardcoded to look for beads.db and didn't
check config.json for custom database names like beady.db.
Now both checkDatabaseVersion() and checkIDFormat() check config.json
first before falling back to the canonical database name.
When daemon detects multiple .db files (after filtering .backup and vc.db),
it now writes detailed error to .beads/daemon-error file before exiting.
The error file is checked and displayed when:
- Daemon discovery fails to connect
- Auto-start fails to yield a running daemon
- User runs 'bd daemons list'
This makes the error immediately visible without requiring users to check
daemon logs.
Changes:
- cmd/bd/daemon.go: Write daemon-error file on multiple .db detection
- internal/daemon/discovery.go: Read and surface daemon-error in DaemonInfo.Error
- cmd/bd/main.go: Display daemon-error when auto-start fails
Amp-Thread-ID: https://ampcode.com/threads/T-1005a8d1-7a5a-4844-ad2d-2b8a6145825f
Co-authored-by: Amp <amp@ampcode.com>
- Changed backup file filtering from checking file extension (.backup) to checking if filename contains '.backup'
- This now properly filters files like 'beads.backup-pre-hash-20251030-171258.db'
- Also exclude vc.db from database detection
- Add strings import to beads.go
- Improve error message to suggest manual removal
Fixes bd-373c
- Add test for runCompactStats function (both JSON and regular output)
- Add tests for outputDotFormat and outputFormattedList functions
- Test dot format, digraph preset, custom templates, and error cases
- Coverage increased from 21.0% to 26.2% (5.2 percentage points)
Part of bd-27ea (multi-session effort to reach 40% coverage)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Event-driven daemon is now production-ready after hardening fixes in
commit 349b892. Making it the default for v0.21.0.
Users can still opt back to polling mode with BEADS_DAEMON_MODE=poll
if needed.
Benefits:
- <500ms sync latency (vs 5000ms with polling)
- ~60% less CPU usage
- Instant reactivity to mutations and file changes
- Fallback polling when file watcher unavailable
Amp-Thread-ID: https://ampcode.com/threads/T-a9a67394-37ca-4b79-aa23-c5c011f9c0cd
Co-authored-by: Amp <amp@ampcode.com>
Three critical fixes to make event-driven mode production-ready:
1. Skip redundant imports: Check JSONL mtime vs DB mtime to avoid
self-triggered import loops after export writes JSONL
2. Add server.Stop() in serverErrChan case: Ensures clean RPC
server shutdown on errors
3. Fallback ticker (60s): When file watcher unavailable (e.g., network
filesystems), fall back to periodic polling to detect remote changes
These minimal fixes address Oracle's concerns without over-engineering.
Event-driven mode is now safe for default.
Amp-Thread-ID: https://ampcode.com/threads/T-a9a67394-37ca-4b79-aa23-c5c011f9c0cd
Co-authored-by: Amp <amp@ampcode.com>
Based on oracle feedback:
- Add parseChecks() helper for check normalization and validation
- Supports synonyms: dupes→duplicates, git-conflicts→conflicts
- Case-insensitive, whitespace-tolerant parsing
- Deduplicates repeated checks while preserving order
- Returns error for unknown checks (exit code 2)
- Fix JSON output robustness
- Serialize errors as strings, not objects
- Add 'failed' boolean per check
- Fix 'healthy' to include error state
- Improve error handling
- hasFailures() now includes check errors
- Exit code 1 for any failures (issues or errors)
- Exit code 2 for usage errors (invalid checks)
- Optimize database access
- Single SearchIssues() call shared across checks
- Only fetch if needed (orphans/duplicates/pollution)
- Stabilize output ordering
- Print checks in deterministic order (not map iteration)
- Use result.name for display labels
- Better UX
- Unknown checks fail fast with helpful message
- Deterministic output for CI/scripting
- More robust JSON for machine consumption
- Added --json flag registration for blockedCmd
- Fixed blockedCmd to read json flag from cmd.Flags()
- All commands now consistently support --json for agent use
- Completes the fix started in earlier commits for show/update/close/stats
- Test checkAndAutoImport with various conditions
- Test findBeadsDir and findBeadsDir in parent
- Test checkGitForIssues edge cases
- Test boolToFlag utility function
- cmd/bd coverage: 20.4% -> 20.5%
- Added tests for extractIssuePrefix, loadIssuesFromJSONL, detectPrefix, writeIssuesToJSONL
- Added tests for walkWithDepth depth limiting and hidden directory skipping
- Added tests for DiscoverDaemons registry and legacy discovery paths
- Improved test coverage for cmd/bd and internal/daemon
- Removed 5 unreachable functions (~200 LOC)
- computeIssueContentHash, shouldSkipExport from autoflush.go
- addDependencyUnchecked, removeDependencyIfExists from dependencies.go
- isUniqueConstraintError alias from util.go
- All tests still pass
- Closes bd-7c5915ae
Adds `bd dep tree --format mermaid` to export dependency trees as Mermaid.js flowcharts.
Features:
- Status indicators: ☐ open, ◧ in_progress, ⚠ blocked, ☑ closed
- Theme-agnostic design
- Works with --reverse flag
- Comprehensive unit tests following TDD
Co-authored-by: David Laing <david@davidlaing.com>
* Add bd doctor command for installation health checks
Implements a comprehensive health check command similar to claude doctor
that validates beads installation and provides actionable recommendations.
Features:
- Installation check (.beads/ directory exists)
- Database version verification (compares with CLI version)
- ID format detection (hash-based vs sequential)
- CLI version check (fetches latest from GitHub)
- Storage type detection (SQLite vs JSONL-only mode)
- Tree-style output with color-coded warnings
- JSON output for scripting (--json flag)
- Actionable fix recommendations for each issue
Implementation improvements:
- Status constants instead of magic strings
- Semantic version comparison (fixes 0.10.0 vs 0.9.9 edge case)
- Documented defer pattern for intentional error ignore
- Comprehensive test coverage including version comparison edge cases
- Clean integration using slices.Contains for command list
Usage:
bd doctor # Check current directory
bd doctor /path/to/repo # Check specific repository
bd doctor --json # Machine-readable output
* Simplify bd doctor documentation in README
Reduce verbose health check section to 2 lines as requested.
* Fix bd doctor to handle JSONL-only mode for ID format check
When no SQLite database exists (JSONL-only mode), skip the ID format
check instead of showing an error. This prevents the confusing
'Unable to query issues' error when the installation is actually fine.
- Bump version across all components (CLI, plugin, MCP server)
- Update CHANGELOG.md with comprehensive hash ID migration notes
- Replace critical multi-clone warning with hash ID announcement
- Add Hash-Based Issue IDs section to README with:
- ID format explanation (4/5/6 char progressive scaling)
- Why hash IDs solve collision issues
- Birthday paradox collision probability math
- Migration instructions
- Update all examples to use hash IDs (bd-a1b2) instead of sequential (bd-1)
Breaking changes:
- Sequential ID generation removed (bd-c7af, bd-8e05, bd-4c74)
- issue_counters table removed from schema
- --resolve-collisions flag removed (no longer needed)
Migration: Run 'bd migrate' to upgrade database schema
Amp-Thread-ID: https://ampcode.com/threads/T-0b000145-350a-4dfe-a3f1-67d4d52a6717
Co-authored-by: Amp <amp@ampcode.com>
Remove obsolete test file and update remaining tests to not use the
removed --resolve-collisions flag. Hash-based IDs make collision
resolution unnecessary.
Changes:
- Delete internal/rpc/server_autoimport_test.go (obsolete)
- Remove --resolve-collisions from beads_nway_test.go
- Remove --resolve-collisions from beads_twoclone_test.go
- Remove --resolve-collisions from cmd/bd/sync.go
All tests now pass.
Hash-based IDs make collision resolution unnecessary. The flag was
already non-functional (handleCollisions returns error on collision
regardless of flag value).
Removed:
- --resolve-collisions flag from bd import
- ResolveCollisions field from ImportOptions and importer.Options
- All references in daemon, auto-import, and tests
- Updated error messages to reflect hash IDs don't collide
All import tests pass.
Amp-Thread-ID: https://ampcode.com/threads/T-47dfa0cc-bb71-4467-ac86-f0966a7c5d58
Co-authored-by: Amp <amp@ampcode.com>
- Removed SyncAllCounters() and all call sites (already no-op with hash IDs)
- Removed AllocateNextID() and getNextIDForPrefix() - sequential ID generation
- Removed collision remapping logic in internal/storage/sqlite/collision.go
- Removed rename collision handling in internal/importer/importer.go
- Removed branch-merge example (collision resolution no longer needed)
- Updated EXTENDING.md to remove counter sync examples
These were all deprecated code paths for sequential IDs that are obsolete
with hash-based IDs. Hash ID collisions are handled by extending the hash,
not by remapping to new sequential IDs.
- Removed nextSequentialID() and getIDMode() functions
- Removed issue_counters table from schema
- Made SyncAllCounters() a no-op for backward compatibility
- Simplified ID generation to hash-only (adaptive length)
- Removed id_mode config setting
- Removed sequential ID tests and migration code
- Updated CONFIG.md and AGENTS.md to remove sequential ID references
Follow-up bd-2a70 will remove obsolete test files and renumber command.
- Created global daemon registry at ~/.beads/registry.json
- Daemons auto-register on start, unregister on graceful shutdown
- DiscoverDaemons() now uses registry instead of filesystem scan
- Instant daemon discovery (35ms vs indefinite hang)
- Auto-cleanup of stale registry entries
- Full test coverage
Closes bd-07b8c8, bd-acb971c7
- Changed generateHashID to start with 6 chars (3 bytes), expand to 7/8 on collision
- Updated both CreateIssue and CreateIssues (batch) to use progressive length fallback
- Updated tests to accept 9-11 char IDs (bd- + 6-8 hex chars)
- All new issues now generate with shorter, more readable IDs
- Existing 8-char IDs preserved (no migration needed)
Amp-Thread-ID: https://ampcode.com/threads/T-8a6058af-9f42-4bff-be02-8c8bce41eeb5
Co-authored-by: Amp <amp@ampcode.com>