The fix for GH#709 updated FindJSONLInDir to skip interactions.jsonl,
but the doctor check in CheckLegacyJSONLFilename was not updated.
This caused `bd doctor` to warn about multiple JSONL files when
both issues.jsonl and interactions.jsonl exist (which is normal
after `bd init`).
Also skip molecules.jsonl which is another system file that shouldn't
be counted as a duplicate issue database.
This prevents a common mistake where users add dependencies from child
issues to their parent epics. This creates a deadlock:
- Child can't start (blocked by open parent)
- Parent can't close (children not done)
Changes:
- dep.go: Reject child→parent deps at creation time with clear error
- server_labels_deps_comments.go: Same check for daemon RPC
- doctor/validation.go: New check detects existing bad deps
- doctor/fix/validation.go: Auto-fix removes bad deps
- doctor.go: Wire up check and fix handler
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When 'bd doctor --fix' detects DB has more issues than JSONL, it runs
'bd export' to sync them. However, 'bd export' without -o flag outputs
to stdout instead of writing to .beads/issues.jsonl, making the fix a
no-op.
Add -o .beads/issues.jsonl --force to the export command to ensure the
JSONL file is actually updated.
feat(doctor): add count-based database size check
Adds CheckDatabaseSize (Check 29) that warns when closed issues exceed a configurable threshold (default: 5000). The check is informational only - no auto-fix since pruning is destructive.
Also improves fix guidance for sync-branch hook compatibility and legacy JSONL filename checks.
PR #724 by @rsnodgrass
- Add _ = prefix for ignored Close/Remove return values
- Fix unused cmd parameter in runMoleculeReady
- Add nolint:misspell for intentional British "cancelled" spelling
- Update comments to use US spelling where not intentional
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new Maintenance category to bd doctor with checks for:
- Stale closed issues (older than 30 days)
- Expired tombstones (older than TTL)
- Compaction candidates (info only)
Add fix handlers for cleanup and tombstone pruning via bd doctor --fix.
Add deprecation hints to cleanup, compact, and detect-pollution commands
suggesting users try bd doctor instead.
This consolidation reduces cognitive load - users just need to remember
'bd doctor' for health checks and 'bd doctor --fix' for maintenance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(daemon): add periodic remote sync to event-driven mode
The event-driven daemon mode only triggered imports when the local JSONL
file changed (via file watcher) or when the fallback ticker fired (only
if watcher failed). This meant the daemon wouldn't see updates pushed
by other clones until something triggered a local file change.
Bug scenario:
1. Clone A creates an issue and daemon pushes to sync branch
2. Clone B's daemon only watched local file changes
3. Clone B would not see the new issue until something triggered local change
4. With this fix: Clone B's daemon periodically calls doAutoImport
This fix adds a 30-second periodic remote sync ticker that calls
doAutoImport(), which includes syncBranchPull() to fetch and import
updates from the remote sync branch.
This is essential for multi-clone workflows where:
- Clone A creates an issue and daemon pushes to sync branch
- Clone B's daemon needs to periodically pull to see the new issue
- Without periodic sync, Clone B would only see updates if its local
JSONL file happened to change
The 30-second interval balances responsiveness with network overhead.
Adds integration test TestEventDrivenLoop_PeriodicRemoteSync that
verifies the event-driven loop starts with periodic sync support.
* feat(daemon): add configurable interval for periodic remote sync
- Add BEADS_REMOTE_SYNC_INTERVAL environment variable to configure
the interval for periodic remote sync (default: 30s)
- Add getRemoteSyncInterval() function to parse the env var
- Minimum interval is 5s to prevent excessive load
- Setting to 0 disables periodic sync (not recommended)
- Add comprehensive integration tests for the configuration
Valid duration formats:
- "30s" (30 seconds)
- "1m" (1 minute)
- "5m" (5 minutes)
Tests added:
- TestEventDrivenLoop_HasRemoteSyncTicker
- TestGetRemoteSyncInterval_Default
- TestGetRemoteSyncInterval_CustomValue
- TestGetRemoteSyncInterval_MinimumEnforced
- TestGetRemoteSyncInterval_InvalidValue
- TestGetRemoteSyncInterval_Zero
- TestSyncBranchPull_FetchesRemoteUpdates
* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)
Cherry-picked linting fixes to ensure CI passes.
* feat(daemon): add config.yaml support for remote-sync-interval
- Add remote-sync-interval to .beads/config.yaml as alternative to
BEADS_REMOTE_SYNC_INTERVAL environment variable
- Environment variable takes precedence over config.yaml (follows
existing pattern for flush-debounce)
- Add config binding in internal/config/config.go
- Update getRemoteSyncInterval() to use config.GetDuration()
- Add doctor validation for remote-sync-interval in config.yaml
Configuration sources (in order of precedence):
1. BEADS_REMOTE_SYNC_INTERVAL environment variable
2. remote-sync-interval in .beads/config.yaml
3. DefaultRemoteSyncInterval (30s)
Example config.yaml:
remote-sync-interval: "1m"
---------
Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
The interactions.jsonl file is an append-only audit log that should be
tracked in git (synced with bd sync), but it was missing from the
negation patterns in .beads/.gitignore.
This adds !interactions.jsonl alongside !issues.jsonl and !metadata.json
for consistency and clarity that this file should be committed.
Co-authored-by: Christian Catalan <crcatala@gmail.com>
* fix(doctor): UX improvements for diagnostics and daemon
- Add Repo Fingerprint check to detect when database belongs to a
different repository (copied .beads dir or git remote URL change)
- Add interactive fix for repo fingerprint with options: update repo ID,
reinitialize database, or skip
- Add visible warning when daemon takes >5s to start, recommending
'bd doctor' for diagnosis
- Detect install method (Homebrew vs script) and show only relevant
upgrade command
- Improve WARNINGS section:
- Add icons (⚠ or ✖) next to each item
- Color numbers by severity (yellow for warnings, red for errors)
- Render entire error lines in red
- Sort by severity (errors first)
- Fix alignment with checkmarks above
- Use heavier fail icon (✖) for better visibility
- Add integration and validation tests for doctor fixes
* fix(lint): address errcheck and gosec warnings
- mol_bond.go: explicitly ignore ephStore.Close() error
- beads.go: add nosec for .gitignore file permissions (0644 is standard)
- Add CheckOrphanedIssues to detect issues referenced in commits but still open
- Pattern matches (prefix-xxx) in git log against open issues in database
- Reports warning with issue IDs and commit hashes
- Add 8 comprehensive tests for the new check
Also:
- Add tests for mol spawn --attach functionality (bd-f7p1)
- Document commit message convention in AGENT_INSTRUCTIONS.md
- Fix CheckpointWAL to use wrapDBError for consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Modified fix.DBJSONLSync() to detect which direction to sync:
- If DB > JSONL: run 'bd export' to sync JSONL (DB has newer data)
- If JSONL > DB: run 'bd sync --import-only' to import (JSONL is source of truth)
- If equal but different timestamps: use file mtime to decide direction
- Updated CheckDatabaseJSONLSync() error messages to recommend correct fix direction:
- Shows different guidance based on whether DB or JSONL has more issues
- Added helper functions:
- countDatabaseIssues() to count issues in SQLite
- countJSONLIssues() to count issues in JSONL (local, avoids circular import)
- Added tests for countJSONLIssues() with edge cases
Fixes issue where 'bd doctor --fix' would recommend 'bd sync --import-only'
when DB > JSONL, which would be a no-op since JSONL hasn't changed.
The doctor's version tracking check was looking at metadata.json:LastBdVersion,
but version tracking was moved to .local_version file (gitignored). This caused
the "LastBdVersion field is empty" warning to persist even after running bd
commands, because those commands update .local_version but not metadata.json.
- Update CheckMetadataVersionTracking to read from .local_version
- Rename check from "Metadata Version Tracking" to "Version Tracking"
- Update tests to use .local_version instead of metadata.json
- Remove unused configfile import
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds configuration options for beads git commits:
- git.author: Override commit author (e.g., "beads-bot <beads@example.com>")
- git.no-gpg-sign: Disable GPG signing for beads commits
This is useful for users with Touch ID commit signing (like Secretive)
who get prompted for every beads auto-commit.
Config example:
```yaml
git:
author: "beads-bot <beads@example.com>"
no-gpg-sign: true
```
Environment variables: BD_GIT_AUTHOR, BD_GIT_NO_GPG_SIGN
Closes#600🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* test(doctor): add comprehensive tests for fix and check functions
Add edge case tests, e2e tests, and improve test coverage for:
- database_test.go: database integrity and sync checks
- git_test.go: git hooks, merge driver, sync branch tests
- gitignore_test.go: gitignore validation
- prefix_test.go: ID prefix handling
- fix/fix_test.go: fix operations
- fix/e2e_test.go: end-to-end fix scenarios
- fix/fix_edge_cases_test.go: edge case handling
* docs: add testing philosophy and anti-patterns guide
- Create TESTING_PHILOSOPHY.md covering test pyramid, priority matrix,
what NOT to test, and 5 anti-patterns with code examples
- Add cross-reference from README_TESTING.md
- Document beads-specific guidance (well-covered areas vs gaps)
- Include target metrics (test-to-code ratio, execution time targets)
* chore: revert .beads/ to upstream/main state
* refactor(doctor): add category grouping and Ayu theme colors
- Add Category field to DoctorCheck for organizing checks by type
- Define category constants: Core, Git, Runtime, Data, Integration, Metadata
- Update thanks command to use shared Ayu color palette from internal/ui
- Simplify test fixtures by removing redundant test cases
* fix(doctor): prevent test fork bomb and fix test failures
- Add ErrTestBinary guard in getBdBinary() to prevent tests from
recursively executing the test binary when calling bd subcommands
- Update claude_test.go to use new check names (CLI Availability,
Prime Documentation)
- Fix syncbranch test path comparison by resolving symlinks
(/var vs /private/var on macOS)
- Fix permissions check to use exact comparison instead of bitmask
- Fix UntrackedJSONL to use git commit --only to preserve staged changes
- Fix MergeDriver edge case test by making both .git dir and config
read-only
- Add skipIfTestBinary helper for E2E tests that need real bd binary
* test(doctor): skip read-only config test in CI environments
GitHub Actions containers may have CAP_DAC_OVERRIDE or similar
capabilities that allow writing to read-only files, causing
the test to fail. Skip the test when CI=true or GITHUB_ACTIONS=true.
The bd doctor command was pointing to a non-existent README anchor
(#claude-code-plugin). Updated to point to docs/PLUGIN.md which
contains the actual plugin installation instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The schema_probe.go and doctor/database.go had different column lists
for validating database schemas. Neither included the pinned column
added in migration 023, causing:
- Doctor to report "All required tables and columns present" on
databases missing the pinned column
- Potential failures when using `gt mail send` on databases without
the pinned column
Changes:
- Add pinned, sender, ephemeral to doctor's criticalChecks
- Add metadata, thread_id to dependencies check
- Add all missing columns to schema_probe.go's expectedSchema:
source_repo, close_reason, deleted_at, deleted_by, delete_reason,
original_type, sender, ephemeral, pinned
Fixes: beads-9yc
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor(doctor): split doctor.go into modular package files
Split the 3,171-line doctor.go into logical sub-files within the
cmd/bd/doctor/ package, reducing the main file to 834 lines (74% reduction).
New package structure:
- types.go: DoctorCheck struct and status constants
- installation.go: CheckInstallation, CheckMultipleDatabases, CheckPermissions
- git.go: CheckGitHooks, CheckMergeDriver, CheckSyncBranch* checks
- database.go: CheckDatabaseVersion, CheckSchemaCompatibility, CheckDatabaseJSONLSync
- version.go: CheckCLIVersion, CheckMetadataVersionTracking, CompareVersions
- integrity.go: CheckIDFormat, CheckDependencyCycles, CheckTombstones
- daemon.go: CheckDaemonStatus, CheckVersionMismatch
- quick.go: Quick checks for sync-branch and hooks
Updated tests to use exported doctor.CheckXxx() functions and
doctor.StatusXxx constants.
* fix(doctor): suppress gosec G204 false positives
Add #nosec G204 comments to exec.Command calls in CheckSyncBranchHealth
where variables come from trusted sources (config files or hardcoded
values like "main"/"master"/"origin"), not untrusted user input.
Fixes Windows build by adding platform-specific inode handling via build tags. Also fixes gosec lint warnings in migrate_tombstones.go.
Thanks @deblasis!
- bd-6pni: Auto-filter tombstoned issues with mismatched prefixes during
import instead of failing. Tombstones from contributor PRs with different
test prefixes are pollution and safe to ignore.
- bd-ffr9: Stop recreating deletions.jsonl after tombstone migration.
Added IsTombstoneMigrationComplete() check to all code paths that write
to the legacy deletions manifest.
- bd-admx: Fix perpetual "JSONL file hash mismatch" warning. Now clears
both export_hashes AND jsonl_file_hash when mismatch detected, so the
warning doesn't repeat.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- bd-8v5o: When doctor --fix hydrates issues from git history, also
remove them from the deletions manifest to prevent perpetual skip
warnings during sync
- bd-wsqt: Remove verbose per-issue "Skipping bd-xxx" messages during
sync. Caller already shows summary of skipped issues.
Added RemoveDeletions() function to deletions package with tests.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When bd doctor detects legacy deletions.jsonl, --fix now runs the
tombstone migration automatically instead of requiring users to
manually run bd migrate-tombstones.
This makes the migration smoother for multi-clone scenarios where
only one clone needs to do the actual migration, but other clones
may still have local deletions.jsonl files that need cleanup.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The previous bd-in7q fix had backwards logic - by EXCLUDING tombstones
from currentIDs, they appeared missing when compared to historicalIDs,
causing HydrateDeletionsManifest to erroneously add them to deletions.jsonl.
This corruption manifested when:
1. Issues were migrated to tombstones via migrate-tombstones
2. Doctor hydration ran (directly or via sync)
3. Tombstones were seen as deleted and re-added to deletions.jsonl
4. Next import skipped thousands of issues with in deletions manifest
Fix: Include ALL issues (including tombstones) in currentIDs. Tombstones
represent migrated deletions that ARE accounted for - they should not
trigger new deletion records.
Generated with Claude Code
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for claude.local.md and .claude/claude.local.md as local-only
alternatives to CLAUDE.md. These files are intended to be gitignored for
personal customizations that should not be committed to the repo.
Changes:
- Update CheckAgentDocumentation to detect claude.local.md files
- Update CheckLegacyBeadsSlashCommands to check claude.local.md files
- Update CheckDocumentationBdPrimeReference to check claude.local.md files
- Add fix message mentioning claude.local.md as an option
- Add test cases for claude.local.md support
Closes#488🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Handle file.Close() errors in deletions.go and deletions_test.go
- Simplify boolean logic to apply De Morgan's law in common.go
- All golangci-lint checks now pass
Root cause: bd doctor hydrate was re-adding migrated tombstones to the
deletions manifest because getCurrentJSONLIDs() included all issues,
including tombstones. When compared against git history, tombstones
appeared as 'deleted' and were incorrectly added to the manifest as new
deletions, corrupting the database on next sync.
Fix: Skip tombstone-status issues in getCurrentJSONLIDs() so they don't
participate in deletion detection. Tombstones represent already-recorded
deletions/migrations and shouldn't be treated as active issues.
Changes:
- cmd/bd/doctor/fix/deletions.go: Skip tombstones in getCurrentJSONLIDs()
- cmd/bd/doctor/fix/deletions_test.go: New tests for tombstone skipping
- cmd/bd/migrate_tombstones_test.go: Test that tombstones are valid
This fixes the bug where 'bd migrate-tombstones' followed by 'bd sync'
would add thousands of deletion records with author 'bd-doctor-hydrate'
Adds comprehensive Git worktree support for beads issue tracking:
Core changes:
- New internal/git/gitdir.go package for worktree detection
- GetGitDir() returns proper .git location (main repo, not worktree)
- Updated all hooks to use git.GetGitDir() instead of local helper
- BeadsDir() now prioritizes main repository's .beads directory
Features:
- Hooks auto-install in main repo when run from worktree
- Shared .beads directory across all worktrees
- Config option no-install-hooks to disable auto-install
- New bd worktree subcommand for diagnostics
Documentation:
- New docs/WORKTREES.md with setup instructions
- Updated CHANGELOG.md and AGENT_INSTRUCTIONS.md
Testing:
- Updated tests to use exported git.GetGitDir()
- Added worktree detection tests
Co-authored-by: Claude <noreply@anthropic.com>
Closes: #478
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>
These tests fail on Windows because:
- os.Symlink requires elevated privileges
- Unix-style permissions (0700, 0600) don't apply
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive validation for config values in bd doctor:
YAML config (config.yaml) validations:
- actor: alphanumeric with dashes, underscores, dots, @
- db: valid database extension (.db, .sqlite, .sqlite3)
- Boolean flags: json, no-daemon, no-auto-flush, no-auto-import,
no-db, auto-start-daemon validate as true/false/yes/no/1/0/on/off
- sync.require_confirmation_on_mass_delete: boolean validation
- repos.primary: must be a directory if path exists
- repos.additional: paths must be directories if they exist
Database config validations:
- status.custom: validates custom status names are lowercase
alphanumeric with underscores, checks for conflicts with built-in
statuses (open, in_progress, blocked, closed)
- sync.branch (legacy): validates as git branch name
Includes tests for all new validation functions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: use os.Lstat for symlink-safe mtime and permission checks
On NixOS and other systems using symlinks heavily (e.g., home-manager),
os.Stat follows symlinks and returns the target's metadata. This causes:
1. False staleness detection when JSONL is symlinked - mtime of target
changes unpredictably when symlinks are recreated
2. os.Chmod failing or changing wrong file's permissions when target
is in read-only location (e.g., /nix/store)
3. os.Chtimes modifying target's times instead of the symlink itself
Changes:
- autoimport.go: Use Lstat for JSONL mtime in CheckStaleness()
- import.go: Use Lstat in TouchDatabaseFile() for JSONL mtime
- export.go: Skip chmod for symlinked files
- multirepo.go: Use Lstat for JSONL mtime cache
- multirepo_export.go: Use Lstat for mtime, skip chmod for symlinks
- doctor/fix/permissions.go: Skip permission fixes for symlinked paths
These changes are safe cross-platform:
- On systems without symlinks, Lstat behaves identically to Stat
- Symlink permission bits are ignored on Unix anyway
- The extra Lstat syscall overhead is negligible
Fixes symlink-related data loss on NixOS. See GitHub issue #379.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
* test: add symlink behavior tests for NixOS compatibility
Add tests that verify symlink handling behavior:
- TestCheckStaleness_SymlinkedJSONL: verifies mtime detection uses
symlink's own mtime (os.Lstat), not target's mtime (os.Stat)
- TestPermissions_SkipsSymlinkedBeadsDir: verifies chmod is skipped
for symlinked .beads directories
- TestPermissions_SkipsSymlinkedDatabase: verifies chmod is skipped
for symlinked database files while still fixing .beads dir perms
Also adds devShell to flake.nix for local development with go, gopls,
golangci-lint, and sqlite tools.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
The beads plugin now provides SessionStart and PreCompact hooks directly
via plugin.json. Users no longer need to run 'bd setup claude' when using
the plugin - hooks are automatically available.
Changes:
- Add hooks section to .claude-plugin/plugin.json with SessionStart and
PreCompact hooks that run 'bd prime'
- Update doctor/claude.go to recognize plugin-provided hooks as valid
- Update tips.go to check for plugin installation when determining if
Claude integration is complete
- Update messaging to recommend plugin installation as primary option
The 'bd setup claude' command remains available for CLI-only users who
do not want to install the plugin.
Closes#462🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#460 - .local_version was added for version tracking but not
included in the gitignore template, causing it to show as untracked.
Co-Authored-By: Claude <noreply@anthropic.com>
Add ability to save doctor diagnostics to a JSON file for historical
analysis and bug reporting. The export includes timestamp and platform
info (OS, Go version, SQLite version) for tracking intermittent issues.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add a new Config Values check to bd doctor that validates:
- flush-debounce: must be a valid duration (e.g., 30s, 1m)
- issue-prefix: must start with letter, alphanumeric with dashes/underscores
- routing.mode: must be auto, maintainer, or contributor
- sync-branch: must be a valid git branch name
- routing paths: warns if configured paths do not exist
- metadata.json database: should be filename (not path), with db extension
- metadata.json jsonl_export: should have .jsonl extension
- deletions_retention_days: must be non-negative if set
This catches misconfigurations before they cause runtime errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add 'Sync Branch Health' check that detects:
1. Local sync branch diverged from remote (after force-push reset)
2. Sync branch significantly behind main on source files (20+ commits, 50+ files)
Add --fix support that:
- Handles worktree case (resets within worktree)
- Handles regular branch case (deletes and recreates from main)
- Pushes the reset branch to remote
This helps contributors whose local beads-sync becomes orphaned after
someone else resets the branch.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, bd init blocked when JSONL existed with issues but no database,
telling users to run 'bd doctor --fix'. But doctor --fix just ran bd migrate
which requires an existing database - creating a circular dependency.
Now:
- bd init allows fresh clones (JSONL exists, no database) to proceed
- bd init creates the database and imports from JSONL automatically
- bd doctor --fix runs bd init (not migrate) when there's no database
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>