- Add daemon_autostart.go, doctor/fix/sync_branch.go to G304 exclusions
- Add setup.go to G306 exclusions (config files need 0644)
- Add gate.go, gate_discover.go to G204 exclusions (gh/gt CLI calls)
- Add misspell exclusion for "cancelled" in gate.go (matches GitHub API)
- Increase Windows test timeout to 30m (was timing out at 20m)
These exclusions complement the #nosec annotations already in the code.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract inode function to platform-specific files (inode_unix.go,
inode_windows.go) to fix syscall.Stat_t compile error on Windows
- Add skipOnWindows helper and skip Unix permission/symlink tests
on Windows where chmod semantics differ
- Increase Windows test timeout from 10m to 20m since full test
suite runs slower without race detector
Fixes Windows CI failures introduced when PR #904 expanded Windows
testing from smoke tests to full test suite.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(daemon): unify auto-sync config for simpler agent workflows
## Problem
Agents running `bd sync` at session end caused delays in the Claude Code
"event loop", slowing development. The daemon was already auto-exporting
DB→JSONL instantly, but auto-commit and auto-push weren't enabled by
default when sync-branch was configured - requiring manual `bd sync`.
Additionally, having three separate config options (auto-commit, auto-push,
auto-pull) was confusing and could get out of sync.
## Solution
Simplify to two intuitive sync modes:
1. **Read/Write Mode** (`daemon.auto-sync: true` or `BEADS_AUTO_SYNC=true`)
- Enables auto-commit + auto-push + auto-pull
- Full bidirectional sync - eliminates need for manual `bd sync`
- Default when sync-branch is configured
2. **Read-Only Mode** (`daemon.auto-pull: true` or `BEADS_AUTO_PULL=true`)
- Only receives updates from team
- Does NOT auto-publish changes
- Useful for experimental work or manual review before sharing
## Benefits
- **Faster agent workflows**: No more `bd sync` delays at session end
- **Simpler config**: Two modes instead of three separate toggles
- **Backward compatible**: Legacy auto_commit/auto_push settings still work
(treated as auto-sync=true)
- **Adaptive `bd prime`**: Session close protocol adapts when daemon is
auto-syncing (shows simplified 4-step git workflow, no `bd sync`)
- **Doctor warnings**: `bd doctor` warns about deprecated legacy config
## Changes
- cmd/bd/daemon.go: Add loadDaemonAutoSettings() with unified config logic
- cmd/bd/doctor.go: Add CheckLegacyDaemonConfig call
- cmd/bd/doctor/daemon.go: Add CheckDaemonAutoSync, CheckLegacyDaemonConfig
- cmd/bd/init_team.go: Use daemon.auto-sync in team wizard
- cmd/bd/prime.go: Detect daemon auto-sync, adapt session close protocol
- cmd/bd/prime_test.go: Add stubIsDaemonAutoSyncing for testing
* docs: add comprehensive daemon technical analysis
Add daemon-summary.md documenting the beads daemon architecture,
memory analysis (explaining the 30-35MB footprint), platform support
comparison, historical problems and fixes, and architectural guidance
for other projects implementing similar daemon patterns.
Key sections:
- Architecture deep dive with component diagrams
- Memory breakdown (SQLite WASM runtime is the main contributor)
- Platform support matrix (macOS/Linux full, Windows partial)
- Historical bugs and their fixes with reusable patterns
- Analysis of daemon usefulness without database (verdict: low value)
- Expert-reviewed improvement proposals (3 recommended, 3 skipped)
- Technical design patterns for other implementations
* feat: add cross-platform CI matrix and dual-mode test framework
Cross-Platform CI:
- Add Windows, macOS, Linux matrix to catch platform-specific bugs
- Linux: full tests with race detector and coverage
- macOS: full tests with race detector
- Windows: full tests without race detector (performance)
- Catches bugs like GH#880 (macOS path casing) and GH#387 (Windows daemon)
Dual-Mode Test Framework (cmd/bd/dual_mode_test.go):
- Runs tests in both direct mode and daemon mode
- Prevents recurring bug pattern (GH#719, GH#751, bd-fu83)
- Provides DualModeTestEnv with helper methods for common operations
- Includes 5 example tests demonstrating the pattern
Documentation:
- Add dual-mode testing section to CONTRIBUTING.md
- Document RunDualModeTest API and available helpers
Test Fixes:
- Fix sync_local_only_test.go gitPull/gitPush calls
- Add gate_no_daemon_test.go for beads-70c4 investigation
* fix(test): isolate TestFindBeadsDir tests with BEADS_DIR env var
The tests were finding the real project's .beads directory instead of
the temp directory because FindBeadsDir() walks up the directory tree.
Using BEADS_DIR env var provides proper test isolation.
* fix(test): stop daemon before running test suite guard
The test suite guard checks that tests don't modify the real repo's .beads
directory. However, a background daemon running auto-sync would touch
issues.jsonl during test execution, causing false positives.
Changes:
- Set BEADS_NO_DAEMON=1 to prevent daemon auto-start from tests
- Stop any running daemon for the repo before taking the "before" snapshot
- Uses exec to call `bd daemon --stop` to avoid import cycle issues
* chore: revert .beads/issues.jsonl to upstream/main
Per CONTRIBUTING.md, .beads/issues.jsonl should not be modified in PRs.
Add config parsing for .pre-commit-config.yaml to detect if bd hooks are
configured. pre-commit is popular enough to warrant full support alongside
lefthook and husky.
Changes:
- Add CheckPrecommitBdIntegration() function to parse YAML config
- Check hooks.*.entry field for 'bd hooks run' pattern
- Handle stages field to determine which git hooks are configured
- Support legacy stage names (commit -> pre-commit, push -> pre-push)
- Add pre-commit to checkManagerBdIntegration switch statement
- Add comprehensive tests for all scenarios
Now supported managers with deep integration checks:
- lefthook (YAML, TOML, JSON)
- husky (.husky/ scripts)
- pre-commit (.pre-commit-config.yaml)
Detection-only managers (cannot verify config):
- overcommit, yorkie, simple-git-hooks
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When bd doctor detects hook managers we can't fully check (pre-commit,
overcommit, yorkie, simple-git-hooks), it now shows an informational
message instead of a warning:
✓ pre-commit detected (cannot verify bd integration)
└─ Ensure your hook config calls 'bd hooks run <hook>'
Previously it incorrectly warned that these managers were "not calling bd"
when we simply couldn't verify their config.
Changes:
- Add DetectionOnly field to HookIntegrationStatus
- Set DetectionOnly=true for unsupported managers in CheckExternalHookManagerIntegration
- Update CheckGitHooks and CheckSyncBranchHookCompatibility to show
informational message for detection-only managers
- Add test coverage for DetectionOnly behavior
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
feat: added android support for running with termux
Adds GOOS=android arm64 build to goreleaser and platform detection in npm postinstall.
Tested by contributor on Termux where os.platform() returns 'android' and Linux binaries fail due to bionic vs glibc.
When running from a crew directory with .beads/redirect pointing to a shared
beads directory in another repo, git status commands would fail with:
fatal: /path/to/mayor/rig/.beads: is outside repository
The fix detects when beadsDir is redirected and runs git commands from the
directory containing the actual .beads/ using git -C <targetRepoDir>.
Updated functions:
- gitHasBeadsChanges(): checks redirect and runs git from target repo
- gitHasUncommittedBeadsChanges(): same fix for pre-flight check
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add detection for external git hook managers (lefthook, husky, pre-commit,
overcommit, yorkie, simple-git-hooks) and check if they have bd hooks
integration configured.
- Detect manager config files in various locations/formats
- Parse lefthook YAML/TOML/JSON to check for `bd hooks run` commands
- Check husky hook scripts for bd integration
- Report which hooks have bd integration vs missing
- Use --chain flag in `bd doctor --fix` when external managers detected
- Detect active manager from git hooks when multiple present
Executed-By: mayor
Role: mayor
bd update now uses resolveAndGetIssueWithRouting in direct mode,
matching bd show's prefix routing behavior. This enables cross-rig
issue updates from any directory using prefix-based routing.
Changes:
- Use resolveAndGetIssueWithRouting for ID resolution with routing
- Iterate over original args instead of pre-resolved IDs
- Use routed store (issueStore) and resolved ID throughout
- Remove early ID resolution that was blocking routing in direct mode
- Add proper result.Close() calls for resource cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Problem:
- Sync branch configuration was not consistently saved across storage types
- State divergence between database and config.yaml files
Solution:
- Update Set to write configuration to both yaml and database backends
- Add regression test for yaml configuration persistence
Impact:
- Guarantees configuration consistency across system reboots
- Prevents sync settings from being lost when reading from yaml
- Exclude closed issues from duplicate detection (previously only excluded tombstones)
- Use full content hash: title + description + design + acceptanceCriteria + status
- Add comprehensive test coverage for duplicate detection edge cases
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The sync_divergence check was querying the wrong table. The sync code
writes last_import_time to the metadata table, but doctor was looking
in config. This caused spurious "No last_import_time recorded" warnings
even when sync was working correctly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Replace tool-specific setup commands with a generic recipe-based system.
New tools become config entries, not code changes.
Changes:
- Add internal/recipes/ package with Recipe type and built-in recipes
- Add --list flag to show available recipes
- Add --print flag to output template to stdout
- Add -o flag to write template to arbitrary path
- Add --add flag to save custom recipes to .beads/recipes.toml
- Add built-in recipes: windsurf, cody, kilocode (new)
- Legacy recipes (cursor, claude, gemini, aider, factory) continue to work
The recipe system enables:
- Adding new tool support without code changes
- User-defined recipes in .beads/recipes.toml
- Shared template across all file-based integrations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
The external_ref field was stored correctly and visible in --json
output, but missing from the human-readable text display.
Added External Ref line after other metadata fields in both daemon
and direct mode paths. Added tests for external_ref display.
The RPC server's handleReady() was explicitly setting Status to
StatusOpen, which overrode the intended behavior where an empty Status
field matches both 'open' and 'in_progress' issues.
Removed the Status field assignment so it remains empty (zero value),
allowing the SQLite storage layer to correctly return both statuses
as documented in the help text.
Fixes #5aml
The --blocks flag handler duplicated cycle detection warning logic from
depAddCmd. Extract to a shared helper function.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The bug: initializeNoDbMode() was setting the legacy global storeActive
but not cmdCtx.StoreActive. When ensureStoreActive() checked
isStoreActive(), it used cmdCtx.StoreActive (which was false), causing
the JSONL-only mode error even when --no-db was passed.
The fix: Use accessor functions (lockStore, setStore, setStoreActive,
unlockStore) which set both the legacy globals and cmdCtx fields.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add alreadyExported flag to skip redundant export. When
gitHasUncommittedBeadsChanges() detects uncommitted changes, we export
at line 175. The flag prevents the normal flow from exporting again
at line 293.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>