- Auto-starts daemon on first bd command (unless --no-daemon or BEADS_AUTO_START_DAEMON=false)
- Exponential backoff on failures: 5s, 10s, 20s, 40s, 80s, 120s (max)
- Lockfile prevents race conditions when multiple commands start daemon simultaneously
- Stdio redirected to /dev/null to prevent daemon output in foreground
- Uses os.Executable() for security (prevents PATH hijacking)
- Socket readiness verified with actual connection test
- Accepts multiple falsy values: false, 0, no, off (case-insensitive)
- Working directory set to database directory for local daemon context
- Comprehensive test coverage including backoff math and concurrent starts
Fixes:
- Closes bd-1 (won't fix - compaction keeps DBs small)
- Closes bd-124 (daemon auto-start implemented)
Documentation updated in README.md and AGENTS.md
Amp-Thread-ID: https://ampcode.com/threads/T-b10fe866-ab85-417f-9c4c-5d1f044c5796
Co-authored-by: Amp <amp@ampcode.com>
- bd-159: Global daemon now runs in routing mode without opening DB
- bd-158: Set socket permissions to 0600 for security
- bd-160: Reject --auto-commit/--auto-push with --global
- bd-157: Verified stale socket cleanup (already working)
- bd-56: Closed as won't-do (cycle prevention is better)
- bd-73: Multi-repo support complete
Implements bd-122: Document how to use beads across multiple projects
Added comprehensive multi-repo documentation:
- README.md: Global daemon section with architecture diagram
- AGENTS.md: MCP multi-repo configuration (global daemon + per-project)
- integrations/beads-mcp/README.md: BEADS_WORKING_DIR usage
- Mermaid diagram showing one daemon serving multiple repos
Documentation covers:
- Global daemon (bd daemon --global) for system-wide usage
- Per-project MCP instances with BEADS_WORKING_DIR
- Comparison table (local vs global)
- When to use each approach
- Example workflows for multi-project setups
Benefits of global daemon:
- One daemon process for all repos
- Automatic socket discovery (local -> global fallback)
- Better resource usage
- Per-request context routing to correct database
Amp-Thread-ID: https://ampcode.com/threads/T-ea606216-b886-4af0-bba8-56d000362d01
Co-authored-by: Amp <amp@ampcode.com>
The status filter was treating 'all' as a literal status value instead of
a special case meaning 'show all statuses'. This caused the SQL query to
filter for 'WHERE status = all' which matched no issues.
Fixed by checking if status is 'all' and skipping the filter in that case.
- Fix list.go to skip status filter when status == 'all'
- Update CHANGELOG with fix details
- All tests pass
- Add DeleteIssues() method in sqlite.go for atomic batch deletion
- Support multiple issue IDs as arguments or from file
- Add --from-file flag to read IDs from file (supports comments)
- Add --dry-run mode for safe preview without deleting
- Add --cascade flag for recursive deletion of dependents
- Add --force flag to orphan dependents instead of failing
- Pre-collect connected issues before deletion for text reference updates
- Add orphan deduplication to prevent duplicate IDs
- Add rows.Err() checks in all row iteration loops
- Full transaction safety - all deletions succeed or none do
- Comprehensive statistics tracking (deleted, dependencies, labels, events)
- Update README and CHANGELOG with batch deletion docs
Fixed critical code review issues:
- Dry-run mode now properly uses dryRun parameter instead of deleting data
- Text references are pre-collected before deletion so they update correctly
- Added orphan deduplication and error checks
- Updated defer rollback pattern per Go best practices
- MCP server now uses daemon client by default with CLI fallback
- Added BEADS_USE_DAEMON environment variable (default: enabled)
- Created multi-repo integration test (all tests pass)
- Updated .gitignore for daemon runtime files
- Added SETUP_DAEMON.md with migration instructions
- Closed bd-105 (investigation complete) and bd-114 (multi-server confusion)
This enables single MCP server to handle multiple repos via daemon
with per-request context routing. No more multiple MCP server configs!
Amp-Thread-ID: https://ampcode.com/threads/T-c222692e-f6ef-4649-9726-db59470b82ef
Co-authored-by: Amp <amp@ampcode.com>
- Add 'bd epic status' to show epic completion with child progress
- Add 'bd epic close-eligible' to bulk-close completed epics
- Add GetEpicsEligibleForClosure() storage method
- Update 'bd stats' to show count of epics ready to close
- Add EpicStatus type for tracking epic/child relationships
- Support --eligible-only, --dry-run, and --json flags
- Fix golangci-lint config version requirement
Addresses GitHub issue #62 - epics now have visibility and
management tools for closure when all children are complete.
Amp-Thread-ID: https://ampcode.com/threads/T-e8ac3f48-f0cf-4858-8e8f-aace2481c30d
Co-authored-by: Amp <amp@ampcode.com>
- Add TestInitCommand with subtests for default prefix, custom prefix, quiet flag, and prefix normalization
- Add TestInitAlreadyInitialized to verify re-initialization works correctly
- Tests verify database creation, config storage, and metadata
- Tests verify -q/--quiet flag suppresses output correctly
- All tests pass
The -q flag was already working correctly; this just adds test coverage.
- Add daemon client infrastructure to main.go with TryConnect logic
- Update PersistentPreRun to detect daemon socket and route through RPC
- Add --no-daemon flag to force direct storage mode
- Update all commands (create, update, close, show, list, ready) to use daemon when available
- Maintain backward compatibility with graceful fallback to direct mode
- All commands work identically in both daemon and direct modes
Part of bd-110 daemon architecture implementation.
Amp-Thread-ID: https://ampcode.com/threads/T-bfe2c083-be7c-4064-8673-fa69c22a730e
Co-authored-by: Amp <amp@ampcode.com>
The counter wasn't being properly reset after renumbering because
SyncAllCounters uses MAX(old, new) which kept higher values from
deleted issues.
Solution: Add ResetCounter() method to delete the counter entry,
then SyncAllCounters recreates it from the actual max ID in database.
Now after renumbering 108 issues to bd-1..bd-108, the counter is
correctly set to 108 and next issue will be bd-109.
After renumbering issues to bd-1 through bd-108, the counter was still
at the old value (346), causing next issue to be bd-347 instead of bd-109.
Fix: Call SyncAllCounters after renumbering to recalculate counter from
actual max ID in database.
Problem: Incremental flush merged dirty issues with existing JSONL, leaving
old IDs when issues were renamed (e.g., test-3 remained after renumbering to test-2).
Solution:
- Add needsFullExport flag to force complete JSONL rebuild from DB
- Skip loading existing JSONL when fullExport=true (start with empty map)
- Use markDirtyAndScheduleFullExport() in renumber and rename-prefix commands
- PersistentPostRun flushes immediately before process exits (respects fullExport)
Test: Verified renumber with gaps correctly exports only current IDs to JSONL
- Replace predictable temp IDs (temp-renumber-N) with UUIDs (temp-<uuid>)
- Fetch dependencies before ID updates to preserve them correctly
- Add comprehensive tests for renumbering with ID gaps, dependencies, and text refs
- All tests pass
Removed 237 issues that were accidentally added from wyvern project:
- 225 test issues (Test incremental 2, Test merged features)
- 12 wyvern deployment issues (SSL certs, Docker, OAuth, GCR, etc.)
Now down to 107 legitimate beads issues (IDs 1-344 with gaps).
Next step: renumber to compact ID space.
- GetMetadata() failures now set lastHash='' instead of returning early
- Allows auto-import to recover from corrupt/missing metadata
- Prevents auto-import from being permanently disabled
- All tests pass
Amp-Thread-ID: https://ampcode.com/threads/T-4e4a57c4-9ac0-43dc-a78e-b7e88123cc65
Co-authored-by: Amp <amp@ampcode.com>
- Batch fetch all existing issues with SearchIssues() upfront
- Use O(1) map lookup instead of O(n) GetIssue() calls
- Improves performance dramatically with 1000+ issues
- All tests pass
- Added deduplicateIncomingIssues() to consolidate content-identical issues
- DetectCollisions now deduplicates within incoming batch before processing
- Keeps issue with smallest ID when duplicates found
- Added comprehensive test suite in collision_dedup_test.go
- Export clean JSONL with bd-421 fix applied
Amp-Thread-ID: https://ampcode.com/threads/T-c17dd8bf-c298-4a80-baa5-55fa7c7bb9a3
Co-authored-by: Amp <amp@ampcode.com>
- Created autoimport_collision_test.go with 10 new test scenarios
- Added helper functions: createTestDBWithIssues, writeJSONLFile, captureStderr
- Tests cover: multiple collisions, all collisions, exact matches, hash fast path,
parse errors, empty JSONL, new issues only, field conflicts, JSONL not found
- Achieved 75.3% coverage of autoImportIfNewer function
- All 17 auto-import tests passing in ~1 second
- Tests verify collision auto-remapping behavior
Closes bd-401
Amp-Thread-ID: https://ampcode.com/threads/T-d3cbaebd-54e8-425e-8e4a-d41cf5ccd247
Co-authored-by: Amp <amp@ampcode.com>
- Add compacted_at_commit field to Issue type (bd-405)
- Add database schema and migration for new field
- Create GetCurrentCommitHash() helper function
- Update ApplyCompaction to store git commit hash (bd-395)
- Update compaction calls to capture current commit
- Update tests to verify commit hash storage
- All tests passing
Amp-Thread-ID: https://ampcode.com/threads/T-5518cccb-7fc9-4dcd-ba5a-e22cd10e45d7
Co-authored-by: Amp <amp@ampcode.com>
- Implement bd rename-prefix command with --dry-run and --json flags
- Add prefix validation (max 8 chars, lowercase, starts with letter)
- Update all issue IDs and text references atomically per issue
- Update dependencies, labels, events, and counters
- Fix counter merge to use MAX() to prevent ID collisions
- Update snapshot tables for FK integrity
- Add comprehensive tests for validation and rename workflow
- Document in README.md and AGENTS.md
Known limitation: Each issue updates in its own transaction.
A failure mid-way could leave mixed state. Acceptable for
intended use case (infrequent operation on small DBs).
Amp-Thread-ID: https://ampcode.com/threads/T-7e77b779-bd88-44f2-9f0b-a9f2ccd54d38
Co-authored-by: Amp <amp@ampcode.com>
- bd-169: Add -q/--quiet flag to bd init command
- bd-28: Improve error handling in RemoveDependency
- Now checks RowsAffected and returns error if dependency doesn't exist
- New removeDependencyIfExists() helper for collision remapping
- bd-393: CRITICAL - Fix auto-import skipping collisions
- Auto-import was LOSING work from other workers
- Now automatically remaps collisions to new IDs
- Calls RemapCollisions() instead of skipping
All tests pass.
Amp-Thread-ID: https://ampcode.com/threads/T-cba86837-28db-47ce-94eb-67fade82376a
Co-authored-by: Amp <amp@ampcode.com>
- Created comprehensive benchmark suite for cycle detection
- Tested linear chains, tree structures, and dense graphs
- Results: 3-4ms overhead per AddDependency is acceptable
- Documented findings in test file and DESIGN.md
- Closed bd-311 and epic bd-307