Phase 2 of Dolt integration - enables runtime backend selection:
- Add --backend flag to bd init (sqlite|dolt)
- Create storage factory for backend instantiation
- Update daemon and main.go to use factory with config detection
- Update database discovery to find Dolt backends via metadata.json
- Fix Dolt schema init to split statements for MySQL compatibility
- Add ReadOnly mode to skip schema init for read-only commands
Usage: bd init --backend dolt --prefix myproject
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add witness, deacon, refinery role templates
- Ignore bd_test binary (bd-test was already ignored)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a complete Dolt storage backend that mirrors the SQLite implementation
with MySQL-compatible syntax and adds version control capabilities.
Key features:
- Full Storage interface implementation (~50 methods)
- Version control operations: commit, push, pull, branch, merge, checkout
- History queries via AS OF and dolt_history_* tables
- Cell-level merge instead of line-level JSONL merge
- SQL injection protection with input validation
Bug fixes applied during implementation:
- Added missing quality_score, work_type, source_system to scanIssue
- Fixed Status() to properly parse boolean staged column
- Added validation to CreateIssues (was missing in batch create)
- Made RenameDependencyPrefix transactional
- Expanded GetIssueHistory to return more complete data
Test coverage: 17 tests covering CRUD, dependencies, labels, search,
comments, events, statistics, and SQL injection protection.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add deprecation notice explaining:
- SQLite → Dolt migration removes custom table support
- External integrations should use standalone sync tools
- Point to jira-beads-sync as the model
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Apply same fix as #1091 to isMCPServerInstalled(): check all three
settings locations (user-level, project-level, and project-local).
- Extract checkMCPInSettings() helper function
- Check ~/.claude/settings.json, .claude/settings.json, and
.claude/settings.local.json
- Add TestIsMCPServerInstalledProjectLevel with positive and negative cases
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The variable was declared and set but never actually used for anything,
just assigned to blank identifier. Clean up dead code from PR #1088.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): detect beads plugin in project-level settings
isBeadsPluginInstalled() now checks project-level settings files
(.claude/settings.json and .claude/settings.local.json) in addition
to user-level settings (~/.claude/settings.json).
This fixes the contradictory bd doctor output where the plugin check
passes but the integration check warns "Not configured" when the
plugin is enabled at project scope.
Fixes#1090
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(doctor): detect Claude hooks in project-level settings.json
hasClaudeHooks() was missing .claude/settings.json - it only checked
.claude/settings.local.json for project-level hooks.
Now checks all three locations:
- ~/.claude/settings.json (user-level)
- .claude/settings.json (project-level)
- .claude/settings.local.json (project-level, gitignored)
Also uses filepath.Join consistently for cross-platform compatibility.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
When using `bd create --id=<id>` where the ID matches an existing
tombstone (from `bd delete --hard --force`), the creation now succeeds
by first deleting the tombstone and all related records.
This enables use cases like polecat respawn where a worker needs to
recreate an issue with the same ID.
Changes:
- queries.go: Check for tombstone before insert, delete it if found
(cleans up events, labels, dependencies, comments, dirty_issues)
- tombstone_test.go: Add regression test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
When a crew worker's .beads/ is redirected to another repo, bd sync
now detects this and skips all git operations (sync-branch worktree
manipulation). Instead, it just exports to JSONL and lets the target
repo's owner handle the git sync.
Changes:
- sync.go: Detect redirect early, skip git operations when active
- beads.go: Update GetRedirectInfo() to check git repo even when
BEADS_DIR is pre-set (findLocalBdsDirInRepo helper)
- validation.go: Add doctor check for redirect + sync-branch conflict
- doctor.go: Register new check, remove undefined CheckMisclassifiedWisps
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
The bd edit command opens an interactive editor ($EDITOR) which AI agents
cannot use. Added warnings to AGENTS.md, AGENT_INSTRUCTIONS.md, and
cmd/bd/AGENTS.md directing agents to use bd update with flags instead.
Fixes: bd-3ft33
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update SKILL.md version from 0.43.0 to 0.47.1
- Update prerequisites from v0.34.0+ to v0.43.0+
- Add v0.47.0+ row to README.md version compatibility table
- Update CLI_REFERENCE.md version from 0.21.0+ to 0.47.0+
- Document new v0.47 features:
- bd list --ready flag (v0.47.1)
- bd ready --gated for gate-resume discovery
- bd create --dry-run for previewing issue creation
- bd resolve-conflicts for JSONL merge conflict resolution
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add witness, deacon, refinery role templates
- Ignore bd_test binary (bd-test was already ignored)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When beads directory is redirected to a different repository (via bd-arjb),
gitCommitBeadsDir() was running git add from the current working directory's
repo root instead of the beads directory's repo root, causing exit status 128.
This fix adds the same redirect handling already present in gitHasBeadsChanges()
and gitHasUncommittedBeadsChanges() - checking GetRedirectInfo() and using
filepath.Dir(beadsDir) as the repo root when redirected.
Fixes: git add failed: exit status 128 errors during bd sync
The --children flag would produce no output for issues without children.
Initialize the map entry in processIssue so the display loop can show
"No children found" message.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a --children flag to the bd show command that displays only the
children of the specified issue. This is useful for quickly viewing
child steps of an epic without the full issue details.
The flag supports:
- Default mode: shows children with full dependency line formatting
- --short mode: shows compact one-liner per child
- --json mode: outputs children in JSON format
Fixes gt-lzf3.5
Co-authored-by: toast <julianknutsen@users.noreply.github>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Add support for JetBrains Junie AI agent:
- Create .junie/guidelines.md with workflow instructions
- Create .junie/mcp/mcp.json for MCP server configuration
- Add 'junie' to BuiltinRecipes in recipes.go
- Add runJunieRecipe() handler in setup.go
- Add website documentation
- Add integrations/junie/README.md
Usage: bd setup junie
Add daemonClient.ResolveID() calls before AddComment and ListComments
operations in daemon mode, following the pattern from update.go.
Previously, short IDs (e.g., "5wbm") worked with most bd commands but
failed with `comments add` and `comments list` when using the daemon.
The short ID was passed directly to the RPC server which expected full
IDs (e.g., "prefix-5wbm").
Changes:
- cmd/bd/comments.go: Add ID resolution before daemon RPC calls
- internal/rpc/comments_test.go: Update tests to reflect client-side
resolution pattern (RPC server expects full IDs, CLI resolves first)
Fixes: https://github.com/steveyegge/beads/issues/1070
Add tests demonstrating that `bd comments add` and `bd comments list`
don't accept short IDs in daemon mode, while other commands do.
Tests added:
- TestCLI_CommentsAddShortID (cli_fast_test.go)
- Tests short ID, partial ID, and comment alias in direct mode (passes)
- TestCommentAddWithShortID (internal/rpc/comments_test.go)
- Tests RPC layer with short ID (FAILS - demonstrates bug)
- TestCommentListWithShortID (internal/rpc/comments_test.go)
- Tests listing comments with short ID (FAILS - demonstrates bug)
The fix should add daemonClient.ResolveID() before AddComment/ListComments,
following the pattern in update.go and label.go.
Refs: https://github.com/steveyegge/beads/issues/1070
Previously, displayGates() always showed 'Open Gates' header even when
closed gates were included via --all flag. Also, closed gates would
appear mixed with open gates under the misleading 'Open Gates' header.
Changes:
- Modified displayGates() to accept showAll parameter
- Separates gates into 'Open Gates' and 'Closed Gates' sections
- Closed gates only shown when --all flag is used
- Fixed handleGateList RPC handler to use ExcludeStatus instead of
Status filter for consistency with CLI behavior
Fixes gas-town issue go-47m
The test guard was flagging false positives when SQLite shm/wal files
had their mtime updated from read-only operations (config loading, etc.)
without any actual content modification.
Now only reports when file size changes, which indicates actual content
modification rather than just file access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add multiple layers of defense against misclassified wisps:
- Importer auto-detects -wisp- pattern and sets ephemeral flag
- GetReadyWork excludes -wisp- IDs via SQL LIKE clause
- Doctor check 26d detects misclassified wisps in JSONL
This addresses recurring issue where wisps with missing ephemeral
flag would pollute bd ready output after JSONL import.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- sync_git_test.go: getCurrentBranchOrHEAD now returns 1 value (not 2)
- daemon_basics_test.go: getPIDFileForSocket uses dbPath not socketPath
- daemon_autostart.go: mark unused socketPath param with underscore
These tests were broken by recent refactors that changed function signatures
but didn't update the corresponding test files.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: comprehensive NixOS support improvements
This commit adds full NixOS support and automates Nix package maintenance:
## Static Linux Binaries for NixOS
Changes .goreleaser.yml to create static Linux binaries:
- Set CGO_ENABLED=0 for Linux amd64 and arm64 builds
- Remove cross-compiler dependencies (aarch64-linux-gnu-gcc)
- Simplifies build process while fixing NixOS compatibility
Static binaries work on all Linux distributions including NixOS, Alpine,
and musl-based distros without dynamic linker dependencies.
## Automated default.nix Version Management
Adds default.nix to the version bump workflow:
- Updates default.nix version field in bump-version.sh (new step 9)
- Adds default.nix to version verification checks
- Prevents version drift (was 5 releases behind: 0.42.0 vs 0.47.0)
- Updates README.md to remove glibc 2.32+ requirement
## Automated vendorHash Management
Creates scripts/update-nix-vendorhash.sh to automate vendorHash updates:
- Automatically detects correct hash by triggering Nix build error
- Extracts hash from error message and updates default.nix
- Verifies update with clean build
- Eliminates error-prone manual copy-paste workflow
- Works with local Nix OR Docker (uses nixos/nix image automatically)
Integrates vendorHash check into bump-version.sh:
- Detects when go.mod or go.sum have changed
- Prompts to run vendorHash update script interactively
- Catches synchronization issues at release time
## Documentation
Updates AGENTS.md with Nix package maintenance guide:
- Documents when and how to update vendorHash
- Recommends automated script as primary method
- Provides manual and alternative methods as fallback
- Notes Docker fallback for maintainers without Nix
## Impact
- NixOS users can now install via standard methods
- Nix package version stays synchronized automatically
- vendorHash updates work without Nix installed (via Docker)
- vendorHash updates are caught during release workflow
- All Linux users benefit from more portable binaries
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address PR review feedback for NixOS support
Fixes three issues identified in PR review:
1. Replace undefined log_* functions in bump-version.sh with existing
echo pattern (log_warning, log_info, log_success, log_error were
called but not defined)
2. Update default.nix version from 0.42.0 to 0.47.0 to fix version
drift with cmd/bd/version.go
3. Remove Nix Package Maintenance section from AGENTS.md per beads
architecture (use bd prime for dynamic context, keep AGENTS.md
minimal)
* fix: update versions to 0.47.1 after merge with main
- Update claude-plugin plugin.json to 0.47.1
- Update default.nix to 0.47.1
- Fixes version check failures after merging latest main branch
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
When using short socket paths (workspaces with paths >103 chars),
filepath.Dir(socketPath) returns /tmp/beads-XXXXX/ instead of the
actual .beads/ directory. This caused TryDaemonLock to look in the
wrong location, always return false, clean up the startlock, and
recurse infinitely causing stack overflow.
Changed 4 occurrences in acquireStartLock, handleStaleLock,
handleExistingSocket, and getPIDFileForSocket to use
filepath.Dir(dbPath) which correctly points to .beads/.
Fixes: gt-qlt
Co-authored-by: furiosa <mayor@gastown.local>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The function always returns nil for error since it is designed to
return HEAD on detached HEAD state. Simplify signature to just
return string.
Fixes golangci-lint unparam warning.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add bd doctor check that detects legacy gastown merge queue JSON files
in .beads/mq/. These files are local-only remnants from the old mrqueue
implementation and can safely be deleted since gt done already creates
merge-request wisps in beads.
- CheckStaleMQFiles() detects .beads/mq/*.json files
- FixStaleMQFiles() removes the entire mq directory
- Comprehensive tests for check and fix
This is the first step toward removing the mrqueue side-channel from
gastown. The follow-up convoy will update Refinery/Witness to use
beads exclusively.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add insertIssuesStrict function that uses plain INSERT instead of
INSERT OR IGNORE. Update bulkInsertIssues and transactional CreateIssues
to use the strict variant.
This fixes a race condition where INSERT OR IGNORE could silently skip
duplicate insertions, but the code would still attempt to record events
for those "inserted" issues, causing FOREIGN KEY constraint failures.
The strict INSERT will now fail explicitly if a duplicate is encountered,
which should never happen since checkForExistingIDs runs first within
the same transaction.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add bd doctor check that warns if .beads/last-touched is tracked by git.
This file is local runtime state that should never be committed, as it
causes spurious diffs in other clones.
- CheckLastTouchedNotTracked() detects if file is git-tracked
- FixLastTouchedTracking() untracks with git rm --cached
- Comprehensive tests for all scenarios
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The plugin.json was left at 0.47.0 while all other version files
were bumped to 0.47.1, causing CI failures on all PRs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>