- Add JSONL-only mode detection in ensureStoreActive() with context-aware
error messages that suggest correct actions based on project state
- Improve error messages in main.go to detect JSONL presence and suggest
appropriate solutions (bd init, --no-db flag, or config.yaml setting)
- Update documentation to use issues.jsonl as canonical filename:
- AGENT_INSTRUCTIONS.md, README.md, resolve-beads-conflict.md
- docs/GIT_INTEGRATION.md
- Update hook template comments to clarify issues.jsonl is canonical
while maintaining backward compatibility for beads.jsonl
Fixes#534🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Stealth mode was adding generic `.beads/` pattern to global gitignore,
which ignored ALL .beads/ folders across all repositories. Users who
want stealth mode in one project but open beads usage in others were
blocked.
Now uses absolute project paths instead:
- `/path/to/project/.beads/`
- `/path/to/project/.claude/settings.local.json`
This allows multiple stealth projects while other repos can use beads
openly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix daemon auto-sync delete mutation not reflected in sync branch
When deleting an issue with `bd delete <id> --force`, the daemon auto-sync now properly removes the deleted issue from the sync branch.
**Problem:** The merge logic saw fewer local issues (due to deletion) and would re-add the deleted issue.
**Solution:** Add `ForceOverwrite` option to bypass merge logic when mutations occur. Mutation-triggered exports are authoritative and should overwrite, not merge.
Reviewed-by: stevey
Add two new doctor checks for tombstone health:
1. Updated Deletions Manifest check:
- Warns when legacy deletions.jsonl has entries (suggests migration)
- Shows "Migrated to tombstones" when .migrated file exists
- Shows "Using inline tombstones" for new repos
2. New Tombstones check:
- Reports total tombstone count
- Warns about expired tombstones (older than 30 days)
- Shows tombstones expiring within 7 days
- Suggests 'bd compact' to prune expired tombstones
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reorganize the claude-code-skill into a publishable plugin that can be
installed through the beads-marketplace. Users can now reference the
'beads' skill right after installing the marketplace.
Co-authored-by: Steve Yegge <steve.yegge@gmail.com>
* fix(daemon): check for stale startlock before waiting 5 seconds
When a previous daemon startup left behind a bd.sock.startlock file
(e.g., from a crashed process), the code was waiting 5 seconds before
checking if the lock was stale. This caused unnecessary delays on
every bd command when the daemon wasn't running.
Now checks if the PID in the startlock file is alive BEFORE waiting.
If the PID is dead or unreadable, the stale lock is cleaned up
immediately and lock acquisition is retried.
Fixes ~5s delay when startlock file exists from crashed process.
* perf: add benchmarks for large descriptions, bulk operations, and sync merge
Added three new performance benchmarks to identify bottlenecks in common operations:
1. BenchmarkLargeDescription - Tests handling of 100KB+ issue descriptions
- Measures string allocation/parsing overhead
- Result: 3.3ms/op, 874KB/op allocation
2. BenchmarkBulkCloseIssues - Tests closing 100 issues sequentially
- Measures batch write performance
- Result: 1.9s total, shows write amplification
3. BenchmarkSyncMerge - Tests JSONL merge cycle with creates/updates
- Simulates real sync operations (10 creates + 10 updates per iteration)
- Result: 29ms/op, identifies sync bottlenecks
Added BENCHMARKS.md documentation describing:
- How to run benchmarks with various options
- All available benchmark categories
- Performance targets on M2 Pro hardware
- Dataset caching strategy
- CPU profiling integration
- Optimization workflow
This completes performance testing coverage for previously unmeasured scenarios.
* docs: clarify daemon lock acquisition logic in comments
Improve comments to clarify that acquireStartLock does both:
1. Immediately check for stale locks from crashed processes (avoids 5s delay)
2. If PID is alive, properly wait for legitimate daemon startup (5s timeout)
No code changes - only clarified comment documentation for maintainability.
---------
Co-authored-by: Steve Yegge <steve.yegge@gmail.com>
The .beads/.gitignore now ignores everything by default and explicitly
whitelists tracked files. This fixes confusion about which files to
commit when using protected branches workflow.
Changes:
- Use `*` to ignore all by default, then `!file` to whitelist
- Fix config.json -> config.yaml (wrong filename in negation)
- Update doctor check to validate new patterns
- Update PROTECTED_BRANCHES.md documentation
- Simplify git add instructions to just `git add .beads/`
Fixes#473🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements the bd reset command for GitHub issue #479:
- CLI command with flags: --hard, --force, --backup, --dry-run, --skip-init, --verbose
- Impact summary showing issues/tombstones to be deleted
- Confirmation prompt (skippable with --force)
- Colored output for better UX
- Unit tests for reset.go and git.go
- Fix: use --force flag in git rm to handle staged files
Part of epic bd-aydr.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove Force from core ResetOptions (CLI concern)
- Clarify file locations (internal/reset/)
- Add ImpactSummary struct with open/closed counts
- Note backup dirs should be gitignored
- Add --verbose flag to CLI spec
- Clarify TDD approach for unit tests
- Add bd-aydr.9 for gitignore template update
Changed Priority from hardcoded 2 to 0 (unset) to distinguish legacy tombstones
from user-set values. IssueType remains TypeTask as empty fails validation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Track legacy deletions.jsonl entries converted to tombstones during import:
- Add Result.ConvertedToTombstone counter
- Add Result.ConvertedTombstoneIDs for the converted IDs
- Update test to verify the new counter
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TestIsExpiredTombstone with edge cases for merge package
- Add TestImportIssues_LegacyDeletionsConvertedToTombstones for importer
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Close bd-6y5 (getLocalSyncBranch tests)
- Include tombstone export logic fix (bd-81x6)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Both findBeadsDir() and findGitRoot() now use filepath.EvalSymlinks()
to resolve to canonical paths before comparison. This fixes the issue
where filepath.Rel() fails on macOS because /var is a symlink to
/private/var, causing path mismatches.
Fixes: TestDatabaseReinitialization failures on macOS
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
bd-2e0 'Add TTL to deletions manifest entries' was accidentally removed
when commit d5a3963 reduced issues.jsonl from 384 to 130 issues.
Root cause analysis:
- metadata.json pointed to 'issues.jsonl' which was deleted
- Database had 65 'open' issues vs 12 in JSONL (zombie resurrection)
- Rebuilt database from correct JSONL
- Recreated the one legitimate open issue (bd-2e0)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add a --readonly flag that blocks all write operations, allowing workers
to read beads state without modifying it. Workers can use:
- bd show, bd list, bd ready (read operations)
Workers cannot use:
- bd create, bd update, bd close, bd sync, etc. (write operations)
The flag can be set via:
- --readonly flag on command line
- BD_READONLY=true environment variable
- readonly: true in config file
This enables swarm workers to see their assigned work from a static
snapshot of the beads database without accidentally modifying it.
Commands protected by readonly mode:
- create, update, close, delete, edit
- sync, import, reopen
- comment add, dep add/remove, label add/remove
- repair-deps, compact, migrate, migrate-hash-ids, migrate-issues
- rename-prefix, validate --fix-all, duplicates --auto-merge
- epic close-eligible, jira sync
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Root cause: metadata.json is tracked in git and contains last_bd_version.
When git operations (pull, checkout, merge) reset metadata.json to the
committed version, the upgrade notification would fire repeatedly.
Fix: Store the last used bd version in .beads/.local_version which is
gitignored, so git operations don't affect version tracking.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
isLikelyHash() required at least one digit to distinguish hashes from
English words, but base36 hashes can be all-letters by chance.
This caused ExtractIssuePrefix("xa-adt-bat") to return "xa" instead
of "xa-adt", breaking import for 20 issues in xa-adapt.
Fix: Accept all-letter suffixes for 3-char only, keep digit requirement
for 4+ chars where word collision probability is low enough (~0.2%).
Rationale:
- 3-char: 36³ = 46K hashes, ~1000 common words = ~2% collision
- 4-char: 36⁴ = 1.6M hashes, ~3000 words = ~0.2% collision
- 5+ char: collision rate negligible
Created issues for remaining multi-clone sync work:
- bd-6l8: Auto-resolve field conflicts in merge.go
- bd-7ch: Auto-push after merge with safety check
- bd-lsa: Mass deletion logging for forensics
- bd-4u8: Config option for mass delete confirmation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
In multi-repo mode, non-primary repos incorrectly wrote ALL issues to their
local issues.jsonl, including foreign issues from other repos. This caused
prefix mismatch errors on subsequent imports.
The fix adds prefix filtering in flushToJSONLWithState() when:
1. Multi-repo mode is configured (repos.primary set)
2. Current repo is not the primary repo
3. The repo has a configured issue_prefix
Issues not matching the local prefix are filtered out before writing to JSONL.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add CLI support for the estimated_minutes field that was already in the
Issue schema but had no way to be set from the command line.
Changes:
- Add --estimate flag to bd create (set estimated time on new issues)
- Add --estimate flag to bd update (modify estimated time on existing issues)
- Add EstimatedMinutes field to RPC CreateArgs and UpdateArgs
- Add handling in daemon RPC handlers for the new field
Example usage:
bd create --title "Task" --estimate 60 # 60 minutes estimate
bd update bd-abc --estimate 120 # update to 2 hours
Fixes GH #443🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Extract shared performSync implementation with skipGit parameter:
- createSyncFunc and createLocalSyncFunc now delegate to performSync
- Follows same pattern as performExport and performAutoImport
- Reduces ~80 lines of duplicated code
Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Add documentation for users experiencing npm postinstall failures in Claude Code web environments due to network restrictions.
Closes: bd-8q0
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix DEPENDENCIES.md: correct parent-child syntax (child depends on parent)
- Update bd show: display Children instead of Blocks for parent-child deps
- Group dependents by type with distinct labels
Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
- Create docs/UNINSTALLING.md with comprehensive uninstall steps
- Add link to UNINSTALLING.md from INSTALLING.md
- Cover: daemon, hooks, merge driver, .beads dir, worktree cleanup
Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
Extract performExport() and performAutoImport() shared implementations:
- createExportFunc() and createLocalExportFunc() now use performExport()
with skipGit parameter
- createAutoImportFunc() and createLocalAutoImportFunc() now use performAutoImport()
with skipGit parameter
- createLocalSyncFunc() kept as-is (different flow from createSyncFunc)
Reduces daemon_sync.go by 89 lines (1003 -> 914) while maintaining
identical behavior and test coverage.
All existing tests pass. New shared functions use conditional logic
to skip git operations when skipGit=true, eliminating the need for
separate implementations.
When a clone gets reset (git reset --hard origin/main), the
git-history-backfill logic was incorrectly marking ALL issues as
deleted since they appeared in git history but not in the current
JSONL. This caused the entire database to be purged.
Fix:
- Add 50% threshold check: abort if git-history-backfill would delete
more than 50% of issues (likely a reset scenario, not deletions)
- Add warning when >10 issues would be deleted via backfill
- Print helpful message about manual deletion if needed
Test:
- Added TestMassDeletionSafetyGuard that simulates JSONL reset and
verifies the safety guard prevents mass deletion
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
When importing JSONL that contains issues in the deletions manifest,
import now:
- Filters out deleted issues before import
- Prints per-issue warning with deletion details (date, actor)
- Shows count of skipped issues in summary
- Suggests --ignore-deletions flag to force import
The new --ignore-deletions flag allows importing issues that are in the
deletions manifest, useful for recovering accidentally deleted issues.
Fixes bd-4zy
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>