- Changed file permissions from 0644 → 0600 for JSONL exports and config files
- Changed directory permissions from 0755 → 0750 in all test code
- Updated .golangci.yml with proper exclusions for false positives
- Reduced gosec warnings from 102 to 22 (all remaining are acceptable)
Closes bd-57
Amp-Thread-ID: https://ampcode.com/threads/T-f754d957-9e42-4e74-861e-57235c7e6436
Co-authored-by: Amp <amp@ampcode.com>
- Added testUserAlice constant for 'alice' in test files
- Added windowsOS constant for 'windows' in test files
- Added testIssueBD1/testIssueBD2 constants for 'bd-1'/'bd-2' in test files
- Added testVersion100 constant for '1.0.0' in version tests
- Added testIssueCustom1 constant for 'custom-1' in lazy init tests
Closes bd-54
Amp-Thread-ID: https://ampcode.com/threads/T-0a4e5d44-2d95-4948-8f4a-d8facf8657c7
Co-authored-by: Amp <amp@ampcode.com>
- Add daemon RPC support to reopen command
- Check daemonClient != nil first, use RPC if available
- Fall back to direct store access with nil check
- Reopened bd-55 for remaining cyclomatic complexity work
Amp-Thread-ID: https://ampcode.com/threads/T-2ea7e226-4672-4a49-96b4-81ab5cf953cd
Co-authored-by: Amp <amp@ampcode.com>
- Prompts user to install hooks on first init if in git repo
- Auto-installs with Y/n prompt (defaults to yes)
- Skips prompt if hooks already installed
- Detects bd hooks by signature comment in files
- Added --flush-only flag to bd sync command
- Created pre-commit hook to flush pending changes before commit
- Created post-merge hook to import changes after pull/merge
- Added install script for easy setup
- Updated AGENTS.md with git hooks workflow
- Resolves race condition where daemon auto-flush fires after commit
Amp-Thread-ID: https://ampcode.com/threads/T-00b80d3a-4194-4c75-a60e-25a318cf9f91
Co-authored-by: Amp <amp@ampcode.com>
- Run initial sync in background so daemon becomes responsive immediately
- Skip daemon-running check for forked child process (BD_DAEMON_FOREGROUND=1)
- Fix PID file conflict between acquireDaemonLock and runDaemonLoop
- Daemon now starts reliably even with slow/failing git pulls
Fixes issue where daemon would timeout during auto-start because it was
blocked on git pull in the initial sync cycle. Now the RPC server starts
immediately and sync runs asynchronously.
Amp-Thread-ID: https://ampcode.com/threads/T-57f3c00a-02b4-4878-adba-c7d1649759b4
Co-authored-by: Amp <amp@ampcode.com>
- Add comprehensive tests for cmd/bd/compact.go
- Test dry run, validation, stats, progress bar, uptime formatting
- Test compaction eligibility checks
- Add comprehensive tests for cmd/bd/ready.go
- Test ready work filtering by priority, assignee, limit
- Test blocking dependencies exclusion
- Test in-progress issues inclusion
- Add comprehensive tests for cmd/bd/dep.go
- Test dependency add/remove operations
- Test all dependency types (blocks, related, parent-child, discovered-from)
- Test cycle detection and prevention
Coverage improved from 45.6% to 46.0% overall
cmd/bd coverage improved from 20.0% to 20.4%
Amp-Thread-ID: https://ampcode.com/threads/T-0707eb82-f56e-4b2d-b64a-f18cc5bc7421
Co-authored-by: Amp <amp@ampcode.com>
- Implement FindAllDatabases() to scan hierarchy for all .beads directories
- Add DatabaseInfo struct with path, beads dir, and issue count
- Add warnMultipleDatabases() with formatted warning display
- Show active database with ▶ marker and issue counts
- Add comprehensive tests for multi-database detection
- Document warning and solutions in TROUBLESHOOTING.md
- Prevent confusion and database pollution from accidental duplicates
Amp-Thread-ID: https://ampcode.com/threads/T-4941975f-2686-40d0-bc12-aabf38a05890
Co-authored-by: Amp <amp@ampcode.com>
Fixes silent data loss when .beads/ directory removed and daemon auto-starts.
Root cause: checkGitForIssues() hardcoded 'issues.jsonl' but git tracks 'beads.jsonl'
Changes:
- Fix A (bd-131): checkGitForIssues() tries beads.jsonl first, then issues.jsonl
- Fix B (bd-132): Immediate export after import in bd init to prevent daemon race
- Fix C (bd-133): Safety check that fails loudly if import fails
- Fix D (bd-134): Daemon startup auto-import when DB empty but git has issues
- Tests (bd-135): Comprehensive integration test suite
Oracle-recommended improvements:
- Export to exact git-relative path (prevents path drift)
- filepath.ToSlash for Windows git compatibility
- 64MB scanner buffer for large JSONL lines
- Improved safety check messages (only suggest local file if exists)
All tests passing. No regressions.
Amp-Thread-ID: https://ampcode.com/threads/T-0e31dc6a-a0d9-46c6-87b2-cfdebe829a52
Co-authored-by: Amp <amp@ampcode.com>
- New 'bd duplicates' command finds content duplicates across database
- Groups by content hash (title, description, design, acceptance criteria)
- Chooses merge target by reference count or smallest ID
- Supports --auto-merge and --dry-run flags
- Added --dedupe-after flag to 'bd import' for post-import detection
- Comprehensive test coverage for duplicate detection
- Updated AGENTS.md and ADVANCED.md with usage examples
Amp-Thread-ID: https://ampcode.com/threads/T-6f99566f-c979-43ed-bd8f-5aa38b0f6191
Co-authored-by: Amp <amp@ampcode.com>
- Stub out 'bd repos' command with deprecation message
- Remove 140+ lines of global daemon/multi-repo docs from ADVANCED.md
- Add architecture section explaining daemon/MCP/beads roles (LSP model)
- Update AGENTS.md, MCP README, FAQ.md to emphasize per-project daemons
- Update commands/daemon.md and commands/repos.md
Closes#140
Global daemon was removed in v0.16.0 due to cross-project pollution
risks. bd now uses per-project local daemons (one per workspace) for
complete database isolation, following LSP architecture patterns.
Amp-Thread-ID: https://ampcode.com/threads/T-c45147dc-8939-43bf-8fbd-303ed4a8d845
Co-authored-by: Amp <amp@ampcode.com>
Fixed all unchecked error returns in production code:
- os.Remove() calls in cleanup paths
- cmd.Wait() in goroutines
- fmt.Fprintf() writes
- Type assertions with proper ok checks
Reduces linter issues from 99 to 88. CI should now pass linting.
- Write PID to daemon.pid when acquiring lock for Windows compatibility
- Increase socket cleanup timeout to 5s for Windows
- Windows can't read locked files, so PID file is required fallback
- Fix PID detection: Open lock file with O_RDWR for Windows LockFileEx
- Fix script tests: Increase timeout to 2-5s for Windows process startup
- Fix uptime test: Use math.Ceil with minimum 1 second to prevent flakiness
- Fix socket cleanup: Add done channel to wait for Start() cleanup completion
All 5 failing Windows tests should now pass.
Implements automatic daemon version detection and restart when client
and daemon versions are incompatible. Eliminates need for manual
'bd daemon --stop' after upgrades.
Changes:
- Check daemon version during health check in PersistentPreRun
- Auto-restart mismatched daemon or fall back to direct mode
- Check version when starting daemon, auto-stop old daemon if incompatible
- Robust restart logic: sets working dir, cleans stale sockets, reaps processes
- Uses waitForSocketReadiness helper for reliable startup detection
- Updated AGENTS.md with version management documentation
Closes bd-89
Amp-Thread-ID: https://ampcode.com/threads/T-231a3701-c9c8-49e4-a1b0-e67c94e5c365
Co-authored-by: Amp <amp@ampcode.com>
When importing JSONL that matches the database exactly, import was
reporting '0 created, 0 updated' which was confusing. Now it properly
tracks and reports unchanged issues.
Changes:
- Added Unchanged field to ImportResult
- Track unchanged issues separately from skipped/updated
- Display unchanged count in import summary
- Updated dry-run output to show unchanged count
- Added test to verify correct reporting behavior
Example output: 'Import complete: 0 created, 0 updated, 88 unchanged'
Amp-Thread-ID: https://ampcode.com/threads/T-5dd4843e-9ce3-4fe0-9658-d2227b0a2e4e
Co-authored-by: Amp <amp@ampcode.com>
- Added OpEpicStatus operation to protocol
- Implemented handleEpicStatus() in RPC server
- Added EpicStatus() method to RPC client
- Updated epic.go to use daemon RPC when available
- Server-side filtering for close-eligible reduces RPC payload
- Both 'bd epic status' and 'bd epic close-eligible' now work in daemon mode
Fixes#62
Closes bd-87
Amp-Thread-ID: https://ampcode.com/threads/T-44c6044e-de04-40a0-bac3-b26238c32a17
Co-authored-by: Amp <amp@ampcode.com>
- Change version.go constants to variables for ldflags to work
- Fix changelog regex to properly match feat(scope): and fix(scope):
- Enable windows/arm64 builds (pure Go, no CGO issues)
- Add concurrency guard to release workflow
Oracle review feedback implemented.
Based on code review feedback:
- Remove unsafe type assertions that could panic
- Add robust type conversion helpers (strFrom, intFrom, equalStatus, equalIssueType)
- Support multiple numeric types for priority (int, int32, int64, float64)
- Treat empty string and nil as equal for optional fields
- Add default case to detect unknown fields (conservative)
- Add comprehensive unit tests for all edge cases
- Test coverage: enums as strings, numeric conversions, nil/empty handling
Amp-Thread-ID: https://ampcode.com/threads/T-225f8c56-0710-46e9-9db2-dbf90cf91911
Co-authored-by: Amp <amp@ampcode.com>
- Add issueDataChanged() to detect when issue content actually changes
- Only call UpdateIssue when data differs from existing issue
- Unchanged issues are skipped to avoid updating timestamps
- Add tests for idempotent import behavior
- Fixes perpetually dirty JSONL after every bd command
Amp-Thread-ID: https://ampcode.com/threads/T-225f8c56-0710-46e9-9db2-dbf90cf91911
Co-authored-by: Amp <amp@ampcode.com>
Fixes#114 and #122 by adding --description/-d flag to bd update CLI
and description parameter to MCP update_issue tool.
Changes:
- CLI: Added --description flag to updateCmd
- RPC: Added Description field to UpdateArgs
- Daemon: Updated updatesFromArgs to handle description
- MCP: Added description to update_issue, UpdateIssueParams, and clients
- Storage: description already supported in allowedUpdateFields
Tested in both daemon and direct modes.
Fixes#118 - Users can now initialize databases outside project directory
Changes:
- Check BEADS_DB env var in init command (PersistentPreRun skipped for init)
- Use global dbPath from --db flag or BEADS_DB, else default to .beads/{prefix}.db
- Use canonical path comparison (filepath.Abs + Clean) instead of strings.Contains
- Only create .beads/ directory when database is actually local
- Ensure parent directory exists for custom database paths
- Add comprehensive tests for --db flag, BEADS_DB env var, and edge cases
- Fix test isolation by resetting global dbPath in test setup
Tests:
- Custom path with --db flag
- Custom path with BEADS_DB env var
- Custom path containing ".beads" substring (prevents false positive)
- Flag precedence over env var
- All existing tests still pass
Amp-Thread-ID: https://ampcode.com/threads/T-04e2c94f-894a-4b49-8132-980450b2300d
Co-authored-by: Amp <amp@ampcode.com>
Bug: updateDependencyReferences() was incorrectly updating ALL dependencies
in the database during collision resolution with --resolve-collisions,
including dependencies belonging to existing issues.
Root cause: The function checked if dep.IssueID was in idMapping keys
(old imported IDs like 'bd-1'), but those are also the IDs of existing
database issues. This caused existing dependencies to be incorrectly
modified or deleted.
Fix: Changed logic to only update dependencies where IssueID is in
idMapping VALUES (new remapped IDs like 'bd-295'). This ensures only
dependencies from remapped issues are updated, not existing ones.
During normal import flow, this is effectively a no-op since imported
dependencies haven't been added to the database yet when RemapCollisions
runs (they're added later in Phase 5 of import_shared.go).
Changes:
- Updated updateDependencyReferences() in collision.go to build a set
of new remapped IDs and only update dependencies with those IDs
- Added comprehensive documentation explaining the correct semantics
- Added regression tests: TestRemapCollisionsRemapsImportedNotExisting
and TestRemapCollisionsDoesNotUpdateNonexistentDependencies
- Skipped 3 tests that expected the old buggy behavior with clear
notes about why they need to be rewritten
Real-world impact: In one case, 125 dependencies were incorrectly
deleted from 157 existing issues during collision resolution.
Fixes https://github.com/steveyegge/beads/issues/120
Fixes bd-56
- Implement robust worktree detection using git-dir vs git-common-dir comparison
- Add prominent warning when daemon mode is active in a worktree
- Warn in 3 places: initial connection, auto-start, and daemon start command
- Show shared database path and clarify BEADS_AUTO_START_DAEMON behavior
- Document limitations and solutions in README.md and AGENTS.md
- Add comprehensive tests for detection and path truncation
Fixes#55
Amp-Thread-ID: https://ampcode.com/threads/T-254eb9e3-1a42-42d7-afdf-b7ca2d2dcb8b
Co-authored-by: Amp <amp@ampcode.com>