fix(daemon): socket path shortening for long workspace paths
Fixes GH#1001 where long workspace paths (e.g., pytest temp directories) caused
socket path mismatches. The daemon now uses rpc.ShortSocketPath() consistently
with the client.
Changes:
- daemon.go: Use rpc.ShortSocketPath() + EnsureSocketDir() for daemon socket
- daemon_config.go: Update getSocketPathForPID() to use rpc.ShortSocketPath()
- Added tests for long path handling and client-daemon socket path agreement
Co-Authored-By: Eugene Sukhodolin <sukhodolin@users.noreply.github.com>
Update documentation and scripts to reflect the plugin move from
root level to claude-plugin/ subdirectory:
- Fix command links in docs/DAEMON.md, docs/SYNC.md, examples/
- Update plugin.json path references in RELEASING.md, AGENT_INSTRUCTIONS.md
- Update scripts/bump-version.sh and scripts/check-versions.sh
- Update skill documentation paths in claude-plugin/skills/beads/
The marketplace.json correctly stays at .claude-plugin/ (root level)
while plugin.json moved to claude-plugin/.claude-plugin/.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Tests were failing because beads.FindDatabasePath() follows the
project's .beads/redirect file, causing tests to find unexpected
databases. Fixed by:
- Setting BEADS_DIR in tests that need isolation from git repo detection
- Clearing BEADS_DIR in TestMain to prevent global contamination
- Updating migration test schema to include owner column
This ensures tests work correctly in crew directories that have
redirect files pointing to shared .beads directories.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Merges schema additions from crew/fang, crew/giles, crew/grip, and crew/wolf:
- crystallizes: bool field for work economics (compounds vs evaporates)
- work_type: WorkType field for assignment model (mutex vs open_competition)
- source_system: string field for federation adapter tracking
- quality_score: *float32 for aggregate quality (0.0-1.0)
- delegated-from: new dependency type for work delegation chains
Migrations properly sequenced as 037-040 (after existing 036 owner_column).
Also fixes test compilation errors for removed TypeRig and IsBuiltIn references.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
When a repo has a .beads/redirect file pointing to a shared beads
directory, restoreBeadsDirFromBranch would fail because it runs
git checkout from the local repo but with a path outside that repo.
Skip the restore when the beads directory is redirected since the
beads dir is managed by a different repo anyway.
Fixes: bd-lmqhe
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add checkForExistingIDs check to transaction-based batch creation
(sqliteTxStorage.CreateIssues) before calling insertIssues. This
prevents INSERT OR IGNORE from silently skipping duplicate IDs,
which would cause FK constraint failures when recording events
for issues that weren't actually inserted.
Also fixes unrelated test bug: renamed parseCommaSeparated to
parseCommaSeparatedList in validators_test.go.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add two tests to verify that issue blocking/dependencies are enforced
when closing issues via the RPC handler:
- TestHandleClose_BlockerCheck: Verifies closing a blocked issue fails
when blocker is still open, and --force flag overrides the check
- TestHandleClose_BlockerCheck_ClosedBlocker: Verifies close succeeds
once the blocking issue is closed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TypeRig constant to IssueType enum
- Add IsBuiltIn() method to IssueType for multi-repo hydration trust logic
- Fix parseCommaSeparated -> parseCommaSeparatedList function name in test
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add tests for gitHasBeadsChanges and gitHasUncommittedBeadsChanges
functions when .beads directory is redirected to another repo:
- Test non-redirected case (baseline functionality)
- Test redirected case with no changes (clean target repo)
- Test redirected case with changes (modified file in target)
These tests cover the redirect detection logic added in a61cbde6
that uses `git -C <targetRepoDir>` when beadsDir is redirected.
Closes: bd-hxcf
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add three new bd doctor checks for redirect configuration health:
1. CheckRedirectTargetValid - Verifies redirect target exists and
contains a valid beads database
2. CheckRedirectTargetSyncWorktree - Verifies redirect target has
beads-sync worktree when using sync-branch mode
3. CheckNoVestigialSyncWorktrees - Detects unused .beads-sync
worktrees in redirected repos that waste space
These checks help diagnose redirect configuration issues in
multi-clone setups like Gas Town polecats and crew workspaces.
Closes bd-b88x3
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add new DependencyType 'attests' for skill attestations. Enables:
Entity X attests that Entity Y has skill Z at level N.
- Add DepAttests constant to dependency types
- Add AttestsMeta struct for skill, level, date, evidence, notes
- Update IsWellKnown() to include attests
- Add test cases for the new edge type
Foundation for HOP skill portability.
Closes: bd-2papc
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Add 'owner' field to Issue struct for tracking the human responsible
for the issue, distinct from 'created_by' which tracks the executor.
Owner is populated from git author email (GIT_AUTHOR_EMAIL or git
config user.email), per Decision 008 for CV accumulation.
Changes:
- Add Owner field to types.Issue with omitempty JSON tag
- Include Owner in content hash computation
- Add owner column migration (036_owner_column.go)
- Update all SQL queries to include owner field
- Add getOwner() helper using git author email fallback chain
- Populate owner in bd create command
- Add owner to RPC CreateArgs protocol
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Follow-up fixes to PR #1006:
- Silence deprecation warnings when --json flag is set (agent ergonomics)
- Remove unused outputStatusJSON() function
- Remove unused encoding/json import from daemon_status.go
Agents parsing JSON output dont need deprecation warnings cluttering stderr.
The subcommand syntax (bd daemon start) remains the documented path forward.
See bd-ntl3b for deduplication work, bd-kpa7c for type consolidation.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Merging with plan to address in follow-up commits:
- Deduplicate daemon_start.go validation logic (call startDaemon())
- Silence deprecation warnings in --json mode for agent ergonomics
- Consolidate DaemonStatusReport with DaemonHealthReport
- Remove unused outputStatusJSON()
- Add tests for new subcommands
* fix: respect hierarchy.max-depth config setting (GH#995)
The hierarchy.max-depth config setting was being ignored because storage
implementations had the depth limit hardcoded to 3. This fix:
- Registers hierarchy.max-depth default (3) in config initialization
- Adds hierarchy.max-depth to yaml-only keys for config.yaml storage
- Updates SQLite and Memory storage to read max depth from config
- Adds validation to reject hierarchy.max-depth values < 1
- Adds tests for configurable hierarchy depth
Users can now set deeper hierarchies:
bd config set hierarchy.max-depth 10
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* refactor: extract shared CheckHierarchyDepth function (GH#995)
- Extract duplicated depth-checking logic to types.CheckHierarchyDepth()
- Update sqlite and memory storage backends to use shared function
- Add t.Cleanup() for proper test isolation in sqlite test
- Add equivalent test coverage for memory storage backend
- Add comprehensive unit tests for CheckHierarchyDepth function
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
reqCtx() now applies the server's requestTimeout (default 30s) to the
context returned for request handlers. This prevents bd list and other
commands from hanging indefinitely when database operations stall.
The fix ensures:
- All RPC handlers get a context with a deadline
- Database operations (using QueryContext) honor context cancellation
- reconnectMu read locks are released when context times out
Fixes: bd-p76kv
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Same fix as PR #991 for FindBeadsDir() - the loop condition
dir != "/" && dir != "." doesn't handle Windows drive roots.
On Windows, filepath.Dir("C:\\") returns "C:\\", not "/" or ".".
Changed both functions to check parent == dir to detect filesystem root,
which works correctly on both Unix and Windows.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Insert git config user.name in fallback chain before final $USER default
- Consolidate duplicate actor resolution logic into single function
- Add BEADS_ACTOR as env var alias for MCP compatibility
- Add tests for actor resolution priority
- Update CONFIG.md with Actor Identity Resolution section
The new fallback order is:
--actor flag > BD_ACTOR > BEADS_ACTOR > git user.name > $USER > "unknown"
Co-authored-by: Ohffs <ohffsnotnow@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
On Unix systems, socket paths are limited to 104 chars (macOS) or 108 chars
(Linux). Deep workspace paths like /Volumes/External Drive/Dropbox/...
would exceed this limit and cause daemon startup failures.
This fix:
- Adds ShortSocketPath() which computes /tmp/beads-{hash}/bd.sock for
paths that would exceed the limit
- Keeps backward compatibility: short paths still use .beads/bd.sock
- Updates daemon discovery to check both locations
- Uses SHA256 hash of canonical workspace path for unique directories
Closes GH#1001
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
warnIfCyclesExist was called with nil storage when using daemon mode.
Add nil check to skip cycle warning in daemon mode (daemon handles it).
Fixes#998
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds ability to burn multiple molecules in a single command:
bd mol burn bd-a1 bd-b2 bd-c3
Changes:
- Accept multiple molecule IDs as arguments
- Add BatchBurnResult struct for aggregated results
- Implement burnMultipleMolecules for batch efficiency
- Wisps deleted in single batch call
- Maintains backward compatibility for single ID
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use SearchIssues with filter.IDs instead of GetIssue in ResolvePartialID.
This fixes inconsistencies where bd list could find issues that bd show
could not, due to subtle query differences between the two code paths.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When removing all hooks from an event, the key was being set to null
instead of being deleted. Claude Code expects arrays, not null values,
causing startup failures with 'Expected array, but received null'.
Changes:
- removeHookCommand now deletes the event key when no hooks remain
- installClaude cleans up any existing null values from buggy removal
- Added tests for null value prevention and cleanup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
On Windows, the daemon stop command was failing with "exit status 1" because
`taskkill` without `/F` flag does not work for console processes that do not
have windows to receive close messages.
Changes:
- Use `os.Process.Kill()` which calls Windows `TerminateProcess` API
- This is the reliable way to terminate processes on Windows
- The graceful RPC shutdown is already attempted before falling back to kill
- Updated error messages to be platform-agnostic (removed SIGTERM/SIGKILL)
The fix uses Go cross-platform process APIs instead of shelling out to
external commands, which is more reliable and portable.
Closes#992
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Auto-detect WSL2 environment with Windows filesystem paths (/mnt/c/, etc.)
and fall back to DELETE journal mode instead of WAL. SQLite WAL mode
does not work reliably across the WSL2/Windows 9P filesystem boundary
due to shared-memory limitations.
Detection checks:
1. Path matches /mnt/[a-z]/ pattern (Windows drive mount)
2. /proc/version contains microsoft or wsl
Fixes#920
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
The sync command was closing the daemon connection without initializing
the direct store, leaving store=nil. This caused errors in post-checkout
hook when running bd sync --import-only.
Fixed by using fallbackToDirectMode() which properly closes daemon and
initializes the store.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move all plugin content to claude-plugin/ subdirectory for cleaner
separation from core beads functionality:
- claude-plugin/.claude-plugin/plugin.json - plugin manifest
- claude-plugin/commands/ - all slash commands
- claude-plugin/agents/ - task-agent (now in correct location)
- claude-plugin/skills/beads/ - beads skill with resources
Root .claude-plugin/ now only contains marketplace.json pointing
to ./claude-plugin.
Note: After updating, users may need to clear plugin cache:
rm -rf ~/.claude/plugins/cache/beads-marketplace/
Fixes#985
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Root cause: CreateIssue used INSERT OR IGNORE which could silently skip
the insert (e.g., on duplicate ID from hash collision), then fail with
FOREIGN KEY constraint error when trying to record the creation event.
Fix: Add insertIssueStrict() that uses plain INSERT (fails on duplicates)
and use it for CreateIssue in both queries.go and transaction.go. The
existing insertIssue() with INSERT OR IGNORE is preserved for import
scenarios where duplicates are expected.
Added test TestCreateIssueDuplicateID to verify duplicate IDs are properly
rejected instead of silently ignored.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added IsBlocked method to Storage interface that checks if an issue is
in the blocked_issues_cache and returns the blocking issue IDs.
The close command now checks for blockers before allowing an issue to
be closed:
- If an issue has open blockers, closing is blocked with an error message
- The --force flag overrides this check
- Works in both daemon mode (RPC) and direct storage mode
- Also handles cross-rig routed IDs
This addresses the bug where agents could close a bead even when it
depends on an open bug/issue.
Closes#962
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add support for lefthook v1.10.0+ jobs array syntax in addition to
the older commands map syntax. Both syntaxes are now checked for
bd hooks run integration.
Fixes#981
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Parse $EDITOR value to handle editors that need flags like
"zeditor --wait" or "code --wait". Previously the entire string
was treated as the executable name.
Fixes#987
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
v0.46.0 removed these types breaking gt install/doctor/sling/convoy commands.
This restores them as built-in types so `bd create --type=agent` works again.
Fixes GH#941
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a diagnostic check that discovers and reports custom types
used by child repos in multi-repo setups. This is the 'discover'
part of the 'trust + discover' pattern for federation.
The check:
- Lists custom types found in each child repo's config/DB
- Warns about hydrated issues using types not found anywhere
- Is informational only (doesn't fail overall doctor check)
Part of epic: bd-9ji4z
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements federation trust model for multi-repo type validation:
- Built-in types are validated (catch typos)
- Non-built-in types trusted from source repos
Changes:
- Add IssueType.IsBuiltIn() method
- Add Issue.ValidateForImport() for trust-based validation
- Update upsertIssueInTx to use ValidateForImport
Closes: bd-dqwuf, bd-alpw2 | Epic: bd-9ji4z
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When database is stale and a read-only command runs in --no-daemon mode,
auto-import from JSONL instead of returning an error. This fixes `gt sling`
failing with 'not a valid bead' after git pull.
Root cause: `ensureDatabaseFresh` would return an error when DB was stale,
but read-only commands like `bd show` should be able to auto-import and
proceed rather than blocking the user.
Changes:
- Modify ensureDatabaseFresh to call autoImportIfNewer() when stale
- Only error if --no-auto-import flag is explicitly set
- Add comprehensive tests for all staleness scenarios
Fixes: bd-9dao
Co-authored-by: Claude <noreply@anthropic.com>
After devcontainer restart (cold-start), `bd --no-daemon show` failed to
find beads because:
1. Read-only commands skipped auto-import
2. Newly created DB had no issue_prefix set, causing import to fail
This fix enables seamless cold-start recovery by:
- Allowing read-only commands (show, list, etc.) to auto-bootstrap when
JSONL exists but DB doesn't
- Setting needsBootstrap flag when falling back from read-only to
read-write mode for missing DB
- Auto-detecting and setting issue_prefix from JSONL during auto-import
when DB is uninitialized
Fixes: gt-b09
Co-authored-by: Claude <noreply@anthropic.com>
* fix(doctor): add .sync.lock and sync_base.jsonl to gitignore
Problem:
- .sync.lock and sync_base.jsonl were missing from GitignoreTemplate
- Files introduced in PR #918 (pull-first sync) appeared as untracked
Solution:
- Add patterns to GitignoreTemplate with explanatory comment
- Add patterns to requiredPatterns for bd doctor validation
Impact:
- Existing users get warning via bd doctor, fix via bd doctor --fix
- New repos get correct gitignore on bd init
Fixes: GH#974
* docs(sync): fix sync_base.jsonl tracking status and add tests
Problem:
- SYNC.md incorrectly documented sync_base.jsonl as "git-tracked"
- No tests validated sync state file gitignore patterns
Solution:
- Update Files Reference table: sync_base.jsonl is "not tracked, per-machine"
- Add TestGitignoreTemplate_ContainsSyncStateFiles
- Add TestRequiredPatterns_ContainsSyncStatePatterns
Relates to: GH#974
Two issues caused `bd migrate sync` to fail when run from a git worktree:
1. Used GetGitDir() instead of GetGitCommonDir() for worktree path
- GetGitDir() returns the worktree-specific path (.bare/worktrees/main)
- GetGitCommonDir() returns the shared git dir (.bare) where new
worktrees can actually be created
2. Used strings.Index instead of LastIndex in GetRepoRoot()
- When user paths contain "worktrees" (e.g., ~/Development/worktrees/),
Index finds the first occurrence and incorrectly strips the path
- LastIndex finds git's internal /worktrees/ directory
Added GetGitCommonDir() to internal/git/gitdir.go for reuse.
Fixes GH#639 (remaining unfixed callsite in migrate_sync.go)
When running `bd sync --import-only` while the daemon is connected, the command
fails with "no database store available for inline import".
Root cause:
1. PersistentPreRun connects to daemon and returns early without initializing
the store global
2. sync command closes the daemon connection (for consistency)
3. sync --import-only calls importFromJSONLInline which requires store != nil
4. Without ensureStoreActive(), the store is never initialized after daemon disconnect
Fix: Call ensureStoreActive() after closing the daemon connection in sync.go.
This ensures the local SQLite store is initialized for all sync operations
that need direct database access.
- Add ensureStoreActive() call after daemon disconnect in sync.go
- Add test documenting the bug and verifying the fix
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add AllowStale field to ListArgs struct to support resilient hook detection.
When set, callers signal they accept potentially stale data rather than
failing on staleness check errors.
This enables gastown checkSlungWork() to fall back gracefully when the
beads database is out of sync with JSONL (common after concurrent agent syncs).
- Add AllowStale bool to ListArgs in internal/rpc/protocol.go
- Pass --allow-stale flag through to RPC in cmd/bd/list.go
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
Add new command to find molecules where a gate has closed and the workflow
is ready to resume:
- `bd ready --gated` - Flag on existing ready command
- `bd mol ready` - Subcommand for discoverability
The command finds molecules where:
1. A gate bead (type=gate) has been closed
2. The step blocked by that gate is now ready
3. The molecule is not currently hooked by any agent
This enables the Deacon patrol to discover and dispatch gate-ready
molecules without explicit waiter tracking, supporting async molecule
resume workflows.
Includes 5 tests verifying:
- No false positives when no gates exist
- Detection of molecules with closed gates
- Filtering out molecules with open gates
- Filtering out already-hooked molecules
- Handling multiple gate-ready molecules
Part of epic bd-ka761 (Gate-based async molecule resume).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Executed-By: beads/crew/dave
Rig: beads
Role: crew
bd list --tree:
- Use actual parent-child dependencies instead of dotted ID hierarchy
- Treat epic dependencies as parent-child relationships
- Sort children by priority (P0 first)
- Fix tree display in daemon mode with read-only store access
bd graph:
- Add --all flag to show dependency graph of all open issues
- Add --compact flag for tree-style rendering (reduces 44+ lines to 13)
- Fix "needs:N" cognitive noise by using semantic colors
- Add blocks:N indicator with semantic red coloring
bd show:
- Tufte-aligned header with status icon, priority, and type badges
- Add glamour markdown rendering with auto light/dark mode detection
- Cap markdown line width at 100 chars for readability
- Mute entire row for closed dependencies (work done, no attention needed)
Design system:
- Add shared status icons (○ ◐ ● ✓ ❄) with semantic colors
- Implement priority colors: P0 red, P1 orange, P2 muted gold, P3-P4 neutral
- Add TrueColor profile for distinct hex color rendering
- Type badges for epic (purple) and bug (red)
Design principles:
- Semantic colors only for actionable items
- Closed items fade (muted gray)
- Icons > text labels for better scanability
Co-Authored-By: SageOx <ox@sageox.ai>
- resolve_conflicts.go: Mark unused `num` parameter with `_`
- .golangci.yml: Add resolve_conflicts.go to G306 exclusion (JSONL files use 0644)
- .golangci.yml: Add doctor/git.go to G304 exclusion (safe path construction)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Problem:
- When dbPath is set to relative fallback (".beads/beads.db"),
findJSONLPath() returns a relative path
- daemon_sync_branch.go calls filepath.Rel(absolutePath, relativePath)
which fails with: "Rel: can't make .beads/issues.jsonl relative to ..."
Solution:
- Canonicalize dbPath at assignment in main.go:471 (source fix)
- Add defensive guard in findJSONLPath() (defense-in-depth)
- Use utils.CanonicalizePath() for OS-agnostic handling
(symlinks, case normalization on macOS)
Testing:
- Add TestFindJSONLPath_RelativeDbPath (tracer bullet for bug)
- Add edge case tests for BEADS_JSONL and empty dbPath
- All sync mode tests pass including daemon E2E