Commit Graph

937 Commits

Author SHA1 Message Date
Steve Yegge
2e9b5a5870 Merge bd-xoyh-morsov: GH#517 2025-12-16 01:17:18 -08:00
Steve Yegge
60ae6586e7 Merge bd-zbyb-gusher: GH#509 worktrees 2025-12-16 01:16:46 -08:00
Steve Yegge
b3fef08fd4 Merge bd-bscs-driller: GH#403 doctor --fix 2025-12-16 01:15:51 -08:00
Steve Yegge
40c6893f33 Merge bd-er7r-derrick: GH#444 status naming 2025-12-16 01:15:36 -08:00
Steve Yegge
11c3bb4fdb Merge bd-0yzm-ace: GH#522 --type flag for bd update 2025-12-16 01:15:11 -08:00
Steve Yegge
eac8ecc667 fix(doctor): remove circular error message in --fix mode
When `bd doctor --fix` fails to apply a fix, it was showing
"Manual fix: Run 'bd doctor --fix' ..." which is circular and unhelpful.

Now extracts just the manual command from the fix message:
- "..., or manually: <cmd>" -> extracts <cmd>
- "bd doctor --fix or <alt>" -> extracts <alt>
- No alternative available -> shows nothing

Closes GH#403

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:08:20 -08:00
Steve Yegge
7d35ced5ae feat(update): add --type flag to bd update command (GH#522)
Allow changing an issue type (bug, feature, task, epic, chore) via the
bd update command. The storage layer already supported issue_type in
allowedUpdateFields, this just exposes it through the CLI.

Changes:
- Add --type/-t flag to updateCmd in show.go
- Add IssueType field to UpdateArgs in protocol.go
- Handle issue_type in updatesFromArgs in server_issues_epics.go
- Add validation using ParseIssueType before update

Example usage:
  bd update ab-xyz --type epic

Fixes: #522
2025-12-16 01:08:11 -08:00
Steve Yegge
0c9e78f42e fix: improve priority format documentation and error message (GH#517)
Claude was using word-based priorities like "medium" instead of numeric
values (0-4 or P0-P4), causing bd create commands to fail in a loop.

Changes:
- Update bd prime output to clearly document priority format with example
- Add explicit note: NOT "high"/"medium"/"low"
- Improve error message to mention that words are not valid

Closes #517

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:07:55 -08:00
Steve Yegge
de75e5181c feat(sync): improve divergence recovery UX (bd-vckm)
When sync branch diverges significantly from remote, provide clear
recovery options instead of a confusing rebase conflict error.

- Add CheckDivergence() to detect and report sync branch divergence
- Add ResetToRemote() to reset local sync branch to remote state
- Add --reset-remote and --force-push flags for recovery
- Improve error message when rebase fails to include recovery steps

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:07:34 -08:00
Steve Yegge
4bf369a618 fix(docs): use consistent in_progress status naming (GH#444)
Changed all user-facing documentation and help text to use `in_progress`
(underscore) instead of `in-progress` (hyphen) to match the canonical
status value.

Files updated:
- cmd/bd/ready.go - Short description
- cmd/bd/status.go - Long description
- commands/stats.md - Action suggestion
- README.md - Workflow description

Note: CSS class names, HTML IDs, and GitHub label mappings intentionally
kept with hyphens as they follow different conventions.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 01:07:33 -08:00
Steve Yegge
2c86404d65 fix: resolve P2 sync noise and cleanup issues
- 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>
2025-12-16 00:56:06 -08:00
Steve Yegge
8c45069228 fix(doctor,sync): clean up deletions manifest and reduce sync noise
- 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>
2025-12-16 00:42:36 -08:00
Steve Yegge
171f7de250 Merge pull request #584 from rsnodgrass/repair-hashes
fix(rename-prefix): use hash IDs instead of sequential in --repair mode
2025-12-16 00:42:32 -08:00
Steve Yegge
4657ec7640 Merge pull request #569 from crcatala/feature/daemon-status-config
feat(daemon): show configuration in `bd daemon --status` output
2025-12-16 00:35:07 -08:00
Steve Yegge
07fc9bf094 Merge pull request #564 from deblasis/fix-daemon-stale-cache
fix(daemon): detect external db file replacement
2025-12-16 00:34:57 -08:00
Ryan Snodgrass
421d41dfa0 docs: add detailed comments explaining ID formats and merge deletion logic
Document the intent and nuances of recent fixes:

internal/importer/utils.go:
- RenameImportedIssuePrefixes: explain the three ID formats (sequential,
  hash-based, hierarchical) and how prefix renaming preserves identity
- isValidIDSuffix: document why dots are allowed (hierarchical parent-child
  relationships) and what characters are rejected

cmd/bd/deletion_tracking.go:
- isIssueNotFoundError: explain why "not found" is success during merge
  (issue may be tombstoned, never existed locally, or manually deleted)
- Deletion loop: document what "accepted deletions" means and why we
  tolerate missing issues during the pruning phase
2025-12-16 00:17:40 -08:00
Ryan Snodgrass
e3d8119f8e fix(sync): tolerate "issue not found" during 3-way merge deletion
During sync, the 3-way merge logic tries to delete issues that were
removed remotely. If an issue is already gone (tombstoned or never
existed locally), that shouldn't be an error - the goal is just to
ensure the issue is deleted.

Changes:
- Add isIssueNotFoundError helper to detect missing issue errors
- Skip "issue not found" errors during merge deletion (count as success)
- Update stats output to show already-gone count when relevant
2025-12-16 00:15:35 -08:00
Brennon Bortz
68135806c6 feat(show): Display status for all dependent issues (#583)
Update bd show command to include status information for all dependency
types (children, blocks, related, discovered). Issues now display with
format [P1 - closed] instead of just [P1].

This provides better visibility into the state of dependent issues
without needing to run bd show on each individual issue.

Changes:
- Updated daemon mode formatting for all dependency types (lines 208, 214, 220, 226)
- Updated direct mode formatting for all dependency types (lines 400, 406, 412, 418)
- Changed format from "[P%d]" to "[P%d - %s]" with dash separator

Example output:
Children (9):
  ↳ pma-an8: Create config.py module [P1 - closed]
  ↳ pma-38g: Create utils.py module [P1 - open]

Blocks (1):
  ← pma-uzm: Adapt validate_outputs.py [P1 - blocked]

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-12-16 00:13:51 -08:00
Charles P. Cross
a69e94a958 Auto-disable daemon in git worktrees for safety (#567)
* feat: auto-disable daemon in git worktrees for safety

Implement worktree daemon compatibility as proposed in the analysis.
The daemon is now automatically disabled when running in a git worktree
unless sync-branch is configured.

Git worktrees share the same .beads directory, and the daemon commits
to whatever branch its working directory has checked out. This causes
commits to go to the wrong branch when using daemon in worktrees.

- Add shouldDisableDaemonForWorktree() helper that checks:
  1. If current directory is a git worktree (via git rev-parse)
  2. If sync-branch is configured (env var or config.yaml)
- Modify shouldAutoStartDaemon() to call the helper
- Modify daemon connection logic in main.go to skip connection
- Add FallbackWorktreeSafety constant for daemon status reporting
- Update warnWorktreeDaemon() to skip warning when sync-branch configured

- In worktree WITHOUT sync-branch: daemon auto-disabled, direct mode used
- In worktree WITH sync-branch: daemon enabled (commits go to dedicated branch)
- In regular repo: no change (daemon works as before)

- Added comprehensive unit tests for shouldDisableDaemonForWorktree()
- Added integration tests for shouldAutoStartDaemon() in worktree contexts
- Manual E2E testing verified correct behavior

- Updated WORKTREES.md with new automatic safety behavior
- Updated DAEMON.md with Git Worktrees section

* feat: check database config for sync-branch in worktree safety logic

Previously, the worktree daemon safety check only looked at:
- BEADS_SYNC_BRANCH environment variable
- sync-branch in config.yaml

This meant users who configured sync-branch via `bd config set sync-branch`
(which stores in the database) would still have daemon disabled in worktrees.

Now the check also reads sync.branch from the database config table,
making daemon work in worktrees when sync-branch is configured via any method.

Changes:
- Add IsConfiguredWithDB() function that checks env, config.yaml, AND database
- Add findBeadsDB() to locate database (worktree-aware via git-common-dir)
- Add getMainRepoRoot() helper using git rev-parse
- Add getConfigFromDB() for lightweight database reads
- Update shouldDisableDaemonForWorktree() to use IsConfiguredWithDB()
- Update warnWorktreeDaemon() to use IsConfiguredWithDB()
- Add test case for database config path

* refactor: use existing beads.FindDatabasePath() instead of duplicating code

Remove duplicate getMainRepoRoot() and findBeadsDB() functions from
syncbranch.go and use the existing beads.FindDatabasePath() which is
already worktree-aware.

Changes:
- Replace custom findBeadsDB() with beads.FindDatabasePath()
- Remove duplicate getMainRepoRoot() (git.GetMainRepoRoot() exists)
- Remove unused imports (exec, strings, filepath)
- Clean up debug logging in tests

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-16 00:06:19 -08:00
Ryan Snodgrass
fa566a9700 fix(rename-prefix): use hash IDs instead of sequential in --repair mode
The --repair flag was generating sequential IDs (sageox-9895, sageox-9896)
instead of hash-based IDs (sageox-jwnv, sageox-urtm). This fix uses the
proper GenerateIssueID function from sqlite package to generate consistent
hash-based IDs during prefix repair operations.

Changes:
- Import sqlite package for hash ID generation
- Add generateRepairHashID helper that uses sqlite.GenerateIssueID
- Track used IDs within batch to avoid collisions
- Update test to verify hash IDs instead of sequential
2025-12-15 23:59:21 -08:00
Alessandro De Blasis
78c248a17a fix(daemon): detect external db file replacement
When git merge replaces the .beads/beads.db file, the daemon's
SQLite connection becomes stale (still reading deleted inode).
This adds FreshnessChecker that detects file replacement via
inode/mtime comparison and triggers automatic reconnection.

Implementation:
- freshness.go: monitors db file for replacement
- store.go: adds EnableFreshnessChecking() and reconnect()
- queries.go: calls checkFreshness() on GetIssue/SearchIssues
- daemon.go: enables freshness checking at startup
- freshness_test.go: comprehensive tests including merge scenario

Code quality (per review):
- Extract configureConnectionPool() helper to reduce duplication
- Handle Close() error in reconnect() (log but continue)
- Use t.Cleanup() pattern in tests per project conventions
- Rename setupFreshnessTest() per naming conventions

Overhead: ~2.6μs per read op (~0.8% of total query time)

Signed-off-by: Alessandro De Blasis <alex@deblasis.net>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-16 06:29:59 +01:00
Steve Yegge
0745bd69c8 fix(doctor): make --fix automatically migrate tombstones
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>
2025-12-15 21:05:45 -08:00
cc-vps
4e87ae18e5 feat: show daemon config in 'bd daemon --status' output
Add auto-commit, auto-push, local mode, sync interval, and daemon mode
to the status output when querying a running daemon.

This helps users understand the current daemon configuration without
having to check logs or remember what flags were used at startup.

Changes:
- Add config fields to StatusResponse in protocol.go
- Add SetConfig() method to Server for daemon to set its config
- Update handleStatus() to include config in response
- Update showDaemonStatus() to query and display config via RPC
- Add comprehensive test coverage for new functionality

Co-authored-by: Christian Catalan <crcatala@gmail.com>
2025-12-15 09:03:20 -08:00
Steve Yegge
bc3e8f6359 chore: Bump version to 0.30.0
Updated all component versions:
- bd CLI: 0.29.0 → 0.30.0
- Plugin: 0.29.0 → 0.30.0
- MCP server: 0.29.0 → 0.30.0
- npm package: 0.29.0 → 0.30.0
- Documentation: 0.29.0 → 0.30.0

Generated by scripts/bump-version.sh
2025-12-15 00:10:54 -08:00
Steve Yegge
3a186a69d6 docs: prepare v0.30.0 changelog and whats-new entry
- Add comprehensive CHANGELOG entry for v0.30.0 (tombstone architecture)
- Add v0.30.0 to versionChanges in info.go for `bd info --whats-new`
- Acknowledge 13 community contributors

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-15 00:10:40 -08:00
Steve Yegge
8e58c306a7 fix(sync,blocked): add safety guards for issue deletion and include status=blocked in bd blocked
GH#464: Add safety guards to prevent deletion of open/in_progress issues during sync:
- Safety guard in git-history-backfill (importer.go)
- Safety guard in deletions manifest processing
- Warning when uncommitted changes detected before pull (daemon_sync.go)
- Enhanced repo ID mismatch error message

GH#545: Fix bd blocked to show status=blocked issues (sqlite/ready.go):
- Changed from INNER JOIN to LEFT JOIN to include issues without dependencies
- Added WHERE clause to include both status=blocked AND dependency-blocked issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 23:07:54 -08:00
Steve Yegge
db3e22fef9 Merge pull request #561 from steveyegge/bd-6xfz-furiosa
fix(prime): document priority format to prevent Claude using 'medium'
2025-12-14 23:00:11 -08:00
Steve Yegge
7535dc88d2 fix(lint): resolve all golangci-lint errors
- Mark unused ctx parameter with underscore in getRepoRootForWorktree
- Replace exec.Command("test", "-d") with os.Stat for directory check
- Handle file.Close() errors properly in compact.go and migrate_tombstones.go
- Explicitly ignore cleanup errors with _ assignment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 22:36:51 -08:00
Steve Yegge
1e20d702f2 fix(doctor): include tombstones in getCurrentJSONLIDs to prevent corruption (#552)
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>
2025-12-14 17:33:07 -08:00
Steve Yegge
82dc06eb84 feat(update): add --type flag to bd update command
Allows changing issue type (task/epic/bug/feature/chore) via bd update --type.
Storage layer already supported it, this adds CLI and RPC support.

Fixes GH#522.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 17:22:42 -08:00
Steve Yegge
17389d0eb4 fix(sync): handle sync.branch == current branch (GH#519)
When sync.branch is configured to the same branch as the current branch,
git worktree creation fails because the same branch cannot be checked out
in multiple locations.

This fix detects when sync.branch equals the current branch and falls back
to direct commits on the current branch instead of using the worktree-based
approach.

Changes:
- Add IsSyncBranchSameAsCurrent() helper in syncbranch package
- Add GetCurrentBranch() helper function
- Update sync.go to detect this case and skip worktree operations
- Add unit tests for the new functionality

Closes #519

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 17:20:47 -08:00
Steve Yegge
76568e8802 fix(prime): document priority format to prevent Claude using 'medium'
GH#517: Claude uses 'medium' instead of P2/2 for priority, causing
infinite error loops. The bd prime output didn't show the --priority
flag or explain the valid format.

Fix: Add --priority=2 to the create example and add a clear note
explaining that priority must be 0-4 or P0-P4, NOT 'high/medium/low'.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 17:19:06 -08:00
Steve Yegge
a60972cd6a Merge remote-tracking branch 'origin/main' into performance-fix 2025-12-14 14:53:30 -08:00
cbro
2651620a4c fix(storage): persist close_reason to issues table on close (#551)
CloseIssue was storing the reason only in the events table, not in the
issues.close_reason column. This caused `bd show --json` to return an
empty close_reason even when one was provided.

- Update CloseIssue in queries.go and transaction.go to set close_reason
- Clear close_reason when reopening issues (in manageClosedAt)
- Add tests for close_reason in storage and CLI JSON output
- Document the dual-storage of close_reason (issues + events tables)
2025-12-14 14:18:01 -08:00
Steve Yegge
3a4da4e08d fix(lint): address errcheck and De Morgan's law violations in doctor/fix
- 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
2025-12-14 14:12:13 -08:00
matt wilkie
a22d949cbd Fix bd-in7q: prevent migrate-tombstones from corrupting deletions manifest (#554)
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'
2025-12-14 14:11:27 -08:00
Ryan Snodgrass
f88a0d015b feat(cli): add 'bd thanks' command to thank contributors
Adds a new command that displays a thank you page listing all human
contributors to the beads project. Features:

- Static list of contributors (compiled into binary)
- Top 20 featured contributors displayed in columns
- Additional contributors in wrapped list
- Styled output using lipgloss (colored box, sections)
- Dynamic width based on content
- JSON output support (--json flag)
- Excludes bots and AI agents by email pattern
2025-12-14 12:40:32 -08:00
Steve Yegge
3a9749279a fix(sync): protect locally exported issues from sanitization (bd-3ee1)
The sync sanitize process was incorrectly removing newly created issues
when they happened to have IDs matching entries in the deletions manifest.
This could occur with hash-based IDs when content is similar to previously
deleted issues.

The fix adds protection for issues that were in the left snapshot (local
export before pull). These represent local work and should not be removed
by sanitize, even if they match entries in the deletions manifest.

Changes:
- Load left snapshot in sanitizeJSONLWithDeletions() to build protection set
- Add protection check before removing issues from JSONL
- Add ProtectedCount/ProtectedIDs to SanitizeResult for tracking
- Log protected issues during sync for visibility
- Add comprehensive test coverage for the fix

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 00:55:55 -08:00
Steve Yegge
a61ca252ae fix(cleanup): resolve CHECK constraint failure and add tombstone pruning
- Fix bd-tnsq: executeDelete now sets closed_at=NULL when creating
  tombstones, satisfying the CHECK constraint that requires
  closed_at IS NULL when status != 'closed'

- Fix bd-08ea: cleanup command now also prunes expired tombstones
  (older than 30 days) after converting closed issues to tombstones

- Add regression test for batch deletion of closed issues

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 00:37:54 -08:00
Steve Yegge
9db756f8b6 fix(memory): implement GetReadyWork/GetBlockedIssues + child counters
Fixes #543, #544, #545, #546 (no-db mode regressions)

Memory backend fixes:
- GetReadyWork now properly excludes issues with open blocks dependencies
- GetBlockedIssues now includes issues with status=blocked (even with 0 blockers)
- LoadFromIssues initializes hierarchical child counters from existing IDs
  so repeated --parent creates bd-xxx.1, bd-xxx.2, etc.

JSONL path discovery:
- findJSONLPath works in no-db mode when dbPath is empty
- Honors BEADS_JSONL environment variable override
- Falls back to locating .beads directory

Based on PR #547 by @joelklabo - cherry-picked core fixes.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-13 23:22:10 -08:00
Steve Yegge
6c84d36592 fix: bd onboard hangs on Windows (GH #531)
Added onboard and hooks commands to the noDbCommands list so they
skip database and daemon initialization. These commands don't need
database access - they just output documentation or manage git hooks.

On Windows, if no .beads directory exists, the PersistentPreRun
would attempt database discovery (including git worktree detection)
which could hang due to git command issues.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:09:34 -08:00
Steve Yegge
fc23dca7fb feat(cli): add --lock-timeout flag for SQLite busy_timeout control (#536)
Implements single-shot mode improvements for Windows and Docker scenarios:

- Add --lock-timeout global flag (default 30s, 0 = fail immediately)
- Add config file support: lock-timeout: 100ms
- Parameterize SQLite busy_timeout via NewWithTimeout() function
- In --sandbox mode: default lock-timeout to 100ms
- In --sandbox mode: skip FlushManager creation (no background goroutines)

This addresses bd.exe hanging on Windows and locking conflicts when
using beads across host + Docker containers.

Closes: bd-59er, bd-r4od, bd-dh8a

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:07:49 -08:00
Steve Yegge
45328d6bfe fix(doctor): detect sync-branch hook incompatibility (#532)
Add new bd doctor check that detects when sync-branch is configured
but the pre-push hook is too old (< 0.29.0) to support it. This causes
circular "bd sync" failures where the hook recommends running bd sync
but the user is already running bd sync.

The check:
- Returns error when hook version < 0.29.0 with sync-branch configured
- Returns warning for custom (non-bd) hooks that can't be verified
- Returns OK when hook is compatible or sync-branch not configured

Also adds checkSyncBranchHookQuick() for --check-health mode.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 18:05:49 -08:00
Steve Yegge
5d71ca6356 fix: improve JSONL-only mode detection and error messages (GH #534)
- 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>
2025-12-13 12:50:33 -08:00
matt wilkie
e01b7412d9 feat: add Git worktree compatibility (PR #478)
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
2025-12-13 12:50:33 -08:00
Steve Yegge
de7b511765 fix(stealth): use project-specific paths in global gitignore (#538)
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>
2025-12-13 10:58:23 -08:00
Charles P. Cross
eb988fcb21 Fix daemon auto-sync delete mutation not reflected in sync branch (#537)
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
2025-12-13 10:53:09 -08:00
Steve Yegge
947e7188aa fix(sync): support external BEADS_DIR in separate git repository
When BEADS_DIR environment variable points to a separate git repository,
bd sync previously failed with "fatal: 'main' is already used by worktree"
because it computed repoRoot from cwd instead of the beads directory.

This fix detects when beads dir is in a different git repo than cwd and
uses direct git operations (add/commit/push/pull) instead of worktree-based
sync, bypassing the problematic worktree creation entirely.

Cherry-picked from PR #533 (cleaned up unrelated changes).

Co-Authored-By: dand-oss <dand-oss@users.noreply.github.com>
2025-12-13 10:44:58 -08:00
Steve Yegge
e5068df3aa fix(sync): preserve tombstones in sanitizeJSONLWithDeletions (bd-kzxd)
The sanitizeJSONLWithDeletions function was incorrectly removing ALL issues
whose ID appeared in deletions.jsonl, including tombstones. This caused:

1. Second sync after delete: tombstone removed from JSONL by sanitize
2. Import sees ID in deletions.jsonl but no tombstone in JSONL
3. Import creates new tombstone via convertDeletionToTombstone
4. UNIQUE constraint error: tombstone already exists in DB

The fix checks the issue status and only removes non-tombstone issues.
Tombstones are the proper representation of deletions and must be preserved.

Added test: TestSanitizeJSONLWithDeletions_PreservesTombstones

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-13 10:21:54 -08:00
Steve Yegge
a0f4a9cacd feat(doctor): add tombstone health checks (bd-s3v)
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>
2025-12-13 10:16:45 -08:00