Commit Graph

5340 Commits

Author SHA1 Message Date
quartz
563f7e875d fix(merge): preserve close_reason field during merge/sync (GH#891)
The close_reason and closed_by_session fields were being silently dropped
during 3-way merge operations because the simplified Issue struct in
internal/merge/merge.go was missing these fields.

Changes:
- Add CloseReason and ClosedBySession fields to merge.Issue struct
- Implement merge logic that preserves these fields when status is closed
- Use timestamp-based conflict resolution (later closed_at wins)
- Clear close metadata when status becomes non-closed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 11:33:32 -08:00
beads/witness
abffa75c4b bd sync: 2026-01-04 11:31:27 2026-01-04 11:31:27 -08:00
beads/witness
79e763dd2f bd sync: 2026-01-04 11:29:47 2026-01-04 11:29:47 -08:00
jasper
c848c0fce2 fix(npm): add retry logic for Windows zip extraction
On Windows, the downloaded ZIP file may remain locked by antivirus
software or Node.js file handle release delays. This causes
Expand-Archive to fail with "being used by another process" errors.

Added exponential backoff retry logic (5 attempts, 500ms-8s delays)
that detects file lock errors and retries the extraction. Non-lock
errors still fail immediately.

Fixes GH#889 (bd-5dlz)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 11:28:23 -08:00
beads/witness
e0db42404c bd sync: 2026-01-04 11:27:36 2026-01-04 11:27:36 -08:00
beads/refinery
c2d7f2a0c9 bd sync: 2026-01-04 11:25:27 2026-01-04 11:25:27 -08:00
beads/crew/grip
df66ecfe9e fix(worktree): disable sparse checkout on main repo after worktree creation (GH#886)
Git 2.38+ enables core.sparseCheckout on the main repo as a side effect
of worktree creation, causing confusing git status message:
"You are in a sparse checkout with 100% of tracked files present."

The fix explicitly disables sparse checkout on the main repo after
creating the beads worktree. This doesn't affect the worktree's sparse
checkout functionality since the patterns are already applied during
checkout.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 11:24:47 -08:00
beads/crew/grip
6609c049de bd sync: 2026-01-04 11:24:30 2026-01-04 11:24:30 -08:00
biantaishabi2
b3d64d47b3 fix: prevent event storm when gitRefsPath is empty (#883)
When gitRefsPath is empty (not in a git repo), strings.HasPrefix(path, "")
always returns true, causing every file write in .beads/ directory
(including daemon.log) to trigger debouncer and create an event storm.

This fix adds a check to ensure gitRefsPath is not empty before the
HasPrefix comparison.

Fixes the issue where daemon.log grows rapidly (17MB+) due to the
self-triggering loop: write log -> detect change -> write log -> ...

Co-authored-by: Test User <test@example.com>
2026-01-04 11:14:36 -08:00
kustrun
28b44edd13 fix(doctor): detect missing git repo and improve daemon startup message (#890)
When not in a git repository:
- Daemon startup now shows clear message immediately instead of waiting
  5 seconds: "Note: No git repository initialized — running without
  background sync"
- Added new doctor check "Git Sync Setup" that explains the situation

Doctor check now shows three states:
1. No git repo → Warning with fix: "Run 'git init' to enable background sync"
2. Git repo, no sync-branch → OK with hint about team collaboration benefits
3. Git repo + sync-branch → OK, fully configured

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 11:13:48 -08:00
web3dev1337
661556ae62 feat: add multi-prefix support via allowed_prefixes config (#881)
feat: add multi-prefix support via allowed_prefixes config

Adds support for allowing multiple prefixes in a beads database via the
allowed_prefixes config key. This is needed for Gas Town which uses different
prefixes for different purposes (hq-, gt-, rig-specific prefixes).

Usage: bd config set allowed_prefixes "gt,hq,hmc"

PR #881 by @web3dev1337
2026-01-04 11:13:44 -08:00
kustrun
16af63dc73 fix(rename-prefix): sync JSONL before and after prefix rename (#893)
- Pull from sync-branch before rename if configured
- Import all issues from JSONL before rename to prevent data loss
- Export directly to JSONL after rename (don't rely on flushManager)
- Apply same pattern to --repair mode
- Add newSilentLogger() for production use (not test-only)
- Add comprehensive tests for JSONL update scenarios

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

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 10:53:31 -08:00
wolf
3acf899c8c bd sync: 2026-01-04 10:42:36 2026-01-04 10:42:36 -08:00
wolf
9880eaf734 feat(config): support daemon.auto_* settings in config.yaml (GH#871)
Allow team-wide auto-sync configuration via config.yaml instead of SQLite.
This enables teams to share auto-commit/auto-push settings through version control.

Changes:
- Add daemon.auto_commit, daemon.auto_push, daemon.auto_pull to YamlOnlyKeys
- Add daemon.* prefix to YAML-only prefixes
- Update daemon startup to read from config.yaml first, then fall back to SQLite
- Update bd init --team to write daemon settings to config.yaml

Usage:
  # In .beads/config.yaml (version controlled, shared by team)
  daemon.auto_commit: true
  daemon.auto_push: true

  # Or via bd config set
  bd config set daemon.auto_commit true

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 10:42:22 -08:00
emma
c6ee9cf3bc bd sync: 2026-01-04 10:42:07 2026-01-04 10:42:07 -08:00
emma
4468ff030f feat(sync): add BD_DEBUG_SYNC env for protection debugging
Adds debug logging when timestamp-aware protection triggers, controlled
by BD_DEBUG_SYNC environment variable. Helps diagnose sync issues.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 10:41:57 -08:00
beads/crew/grip
4021f49445 feat(prime): add PRIME.md override for workflow customization (GH#876)
Users can now place a .beads/PRIME.md file to fully customize the
workflow instructions output by `bd prime`. The --export flag outputs
the default content for use as a starting template.

Local .beads/PRIME.md is checked first, then redirected location,
allowing clone-specific customization even with shared beads.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 21:49:40 -08:00
dave
7df6004605 fix: code review improvements for GH#870
Review findings addressed:
1. Fixed HasSyncBranchGitignoreFlags() - now correctly returns (hasAnyFlag,
   hasSkipWorktree) since skip-worktree takes precedence in git ls-files -v
2. Added interactions.jsonl to list of files to hide (was only issues.jsonl)
3. Added idempotency check - skips setting flags if already set (checks for S)
4. Made output conditional - only prints when flags actually changed
5. Fixed addToGitExclude() pattern matching - now uses exact line match
   instead of substring to prevent false positives
6. Refactored to use setGitIndexFlags() helper to reduce duplication

🤖 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
2026-01-03 21:19:02 -08:00
matt wilkie
625ac5dff2 Add repository guards to deployment workflows (#877)
- Guard deploy-docs job to only run in canonical repository
- Guard goreleaser job to only run in canonical repository
- Guard update-homebrew job to only run in canonical repository
- Guard test-pypi job to only run in canonical repository

Prevents fork workflows from attempting to deploy, release, or publish to external services.
2026-01-03 21:16:09 -08:00
dave
35e6e3319d bd sync: 2026-01-03 21:08:09 2026-01-03 21:08:09 -08:00
dave
6a5c289af3 fix: hide issues.jsonl from git status when sync.branch configured (GH#870)
When sync.branch is configured, issues.jsonl appears modified in git status
even though changes go to the sync branch. This is confusing for users and
risks accidental commits to the wrong branch.

Implementation:
- Added SyncBranchGitignore() to set git index flags (assume-unchanged,
  skip-worktree) on issues.jsonl when sync.branch is configured
- For untracked files, adds to .git/info/exclude instead
- Called automatically from bd sync after successful sync-branch sync
- Added bd doctor check and fix for this issue
- Added HasSyncBranchGitignoreFlags() to check current flag state
- Added ClearSyncBranchGitignore() to remove flags when sync.branch disabled

Fixes: GH#870 (duplicate of GH#797, GH#801)

🤖 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
2026-01-03 21:07:32 -08:00
emma
5e7163d590 bd sync: 2026-01-03 13:28:01 2026-01-03 13:28:01 -08:00
emma
62e4eaf7c1 fix(sync): make snapshot protection timestamp-aware (GH#865)
The --protect-left-snapshot mechanism was protecting ALL local issues
by ID alone, ignoring timestamps. This caused newer remote changes to
be incorrectly skipped during cross-worktree sync.

Changes:
- Add BuildIDToTimestampMap() to SnapshotManager for timestamp-aware
  snapshot reading
- Change ProtectLocalExportIDs from map[string]bool to map[string]time.Time
- Add shouldProtectFromUpdate() helper that compares timestamps
- Only protect if local snapshot is newer than incoming; allow update
  if incoming is newer

This fixes data loss scenarios where:
1. Main worktree closes issue at 11:31
2. Test worktree syncs and incorrectly skips the update
3. Test worktree then pushes stale open state, overwriting mains changes

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:27:36 -08:00
grip
a5d9793ecd fix(agent): support hyphenated rig names in parseAgentIDFields (GH#868)
Complements the validation fix from c6fe9d71 - the parseAgentIDFields
function now also scans right-to-left for known role tokens instead
of using fixed position parsing.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:25:15 -08:00
dave
82bda63fe5 bd sync: 2026-01-03 13:24:54 2026-01-03 13:24:54 -08:00
dave
6c4b67f65d fix: respect sync.remote config in bd sync (GH#872, bd-ypvj)
The sync.remote config was being set via `bd config set sync.remote <name>`
but `bd sync` was still using 'origin' for git pull/push operations.

Changes:
- Updated gitPull() and gitPush() in sync_git.go to accept a configuredRemote
  parameter that takes precedence over git's branch tracking config
- Updated sync.go to read sync.remote config and pass it to gitPull/gitPush
- Updated daemon_sync.go to read sync.remote config for all daemon sync ops
- Added user-facing messages to show which remote is being used

🤖 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
2026-01-03 13:24:28 -08:00
wolf
30cf997cbf bd sync: 2026-01-03 13:23:11 2026-01-03 13:23:11 -08:00
wolf
631b067c1c fix(daemon): normalize paths for case-insensitive filesystem comparison (GH#869)
On macOS and Windows, filesystems are typically case-insensitive, so
/Users/foo/Desktop and /Users/foo/desktop refer to the same directory.
The daemon registry and discovery code was doing direct string comparison,
causing path mismatches when the casing differed.

Fix:
- Add NormalizePathForComparison() and PathsEqual() to internal/utils/path.go
- These resolve symlinks and lowercase paths on darwin/windows
- Update all workspace path comparisons in registry.go, discovery.go, and
  daemons.go to use PathsEqual()

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 13:22:52 -08:00
grip
309ade5d0d bd sync: 2026-01-03 13:22:20 2026-01-03 13:22:20 -08:00
Jordan Docherty
a791991103 Update link to install script (#867) 2026-01-03 12:53:58 -08:00
wolf
f156e16da3 feat(template): propagate gate fields through template cloning
Ensures AwaitType, AwaitID, and Timeout fields are carried over when
cloning template subgraphs, enabling async coordination in instantiated
molecules.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 12:44:16 -08:00
wolf
c6fe9d71ca fix(validation): support hyphenated rig names in agent IDs (GH#854)
Rewrites ValidateAgentID to scan right-to-left for known role tokens
instead of relying on fixed position parsing. This allows rig names
containing hyphens (e.g., ob-my-project-witness).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 12:44:09 -08:00
kustrun
079b346b5d fix(agent): add routing support for cross-repo agent resolution (#864)
The bd agent state, heartbeat, and show commands now respect
routes.jsonl for cross-repo lookups, matching the behavior of
bd show.

Previously, these commands used utils.ResolvePartialID directly,
which bypassed routing. Now they use resolveAndGetIssueWithRouting
and needsRouting checks, consistent with show.go.
2026-01-03 11:53:14 -08:00
Graeme Foster
e623746e60 fix(config): normalize keys in GetYamlConfig to match SetYamlConfig (#874)
GetYamlConfig was not normalizing key aliases (e.g., sync.branch ->
sync-branch), causing 'bd config get sync.branch' to return 'not set'
even when the value was correctly stored.

SetYamlConfig already normalized keys, but GetYamlConfig did not,
leading to a confusing mismatch where set appeared to work but get
could not find the value.

Added TestGetYamlConfig_KeyNormalization to verify the fix.

Fixes #873
2026-01-03 11:51:01 -08:00
furiosa
0c7dcee3ac feat(slot): Add merge-slot gate for serialized conflict resolution
Adds a new slot bead type and merge-slot commands for serializing
conflict resolution in the merge queue. This prevents "monkey knife
fights" where multiple polecats race to resolve conflicts.

- Add TypeSlot to bead types
- Add Holder field to Issue struct
- Add bd merge-slot create/check/acquire/release commands
- Add Holder field to UpdateArgs in RPC protocol

(gt-4u49x)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 18:03:27 -08:00
beads/crew/emma
b8f9dabcb5 feat: add /handoff slash command for user invocation (bd-xwvo)
Beads only had the skill version (Claude-only). This adds the command
version so users can type /handoff directly like in gastown.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 17:32:23 -08:00
beads/crew/wolf
820ec8852e bd sync: 2026-01-02 17:31:06 2026-01-02 17:31:06 -08:00
beads/crew/wolf
d416d672db bench(sqlite): add isolated cache rebuild benchmarks (bd-zw72)
Add BenchmarkRebuildBlockedCache_Large and _XLarge to measure cache
rebuild performance in isolation.

Results show cache rebuild takes ~773ms at 10K issues and ~1.3s at 20K,
significantly slower than the ~50ms originally estimated in the issue.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 17:30:58 -08:00
beads/crew/grip
32a4a9e060 perf: batch external dep checks by project (bd-687v)
Optimize CheckExternalDeps to group refs by project and open each
external DB only once, checking all capabilities in a single query.

Before: If 10 issues depend on external:gastown:cap1, we opened
gastown's DB 10 times.

After: We open each external project's DB once, query for all
capabilities needed from that project, then close.

Also added deduplication in filterByExternalDeps to collect all
unique refs before checking, avoiding redundant checks for the
same ref across multiple issues.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 17:17:47 -08:00
beads/crew/grip
6ed4f0dcce bd sync: 2026-01-02 17:17:35 2026-01-02 17:17:35 -08:00
beads/crew/emma
eca43efe15 bd sync: 2026-01-02 17:14:57 2026-01-02 17:14:57 -08:00
beads/crew/emma
5f9c94a8c3 bd sync: 2026-01-02 17:10:52 2026-01-02 17:10:52 -08:00
beads/crew/emma
939f222c35 fix: pass event/mol/time fields through --rig flag (bd-xwvo)
createInRig was missing event fields (event_kind, actor, target, payload),
molecule/agent fields (mol_type, role_type, rig), and time scheduling
fields (due_at, defer_until). Now extracts these from cmd.Flags() directly.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 17:10:43 -08:00
beads/crew/dave
1ffd1431b7 docs: update skill names from /bd-* to /beads:* (#862)
The Claude Code plugin uses beads:* prefix for slash commands, not bd-*.
Updated all documentation to reflect actual installed command names.

Files updated:
- docs/PLUGIN.md
- docs/INSTALLING.md
- website/docs/integrations/claude-code.md
- website/static/llms-full.txt
- commands/init.md, stats.md, workflow.md

🤖 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
2026-01-02 17:07:49 -08:00
beads/crew/dave
4e2cfc7a10 bd sync: 2026-01-02 17:04:19 2026-01-02 17:04:19 -08:00
opal
e2931317c0 feat(formula): add gate-aware beads-release.formula v2 (bd-r24e)
Rewrite the beads release formula with gate syntax for async waits:

- Phase 1 (Prep & Push): preflight through push-tag
- Gate: await-ci step with gh:run gate on release.yml
- Phase 2 (Verify): parallel verify-github, verify-npm, verify-pypi
- Phase 3 (Install): fan-in at local-install, then daemons restart

Key improvements:
- Polecat does not sit idle during CI (5-10 min wait)
- Clean phase handoff via gt done --phase-complete
- Refinery auto-discovers and closes gate when CI completes
- Parallel verification runs concurrently after gate

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 16:53:38 -08:00
jasper
d7246a1f2d feat(gate): add add-waiter and show commands for phase handoff
- Add `bd gate add-waiter <gate-id> <waiter>` command to register
  agents as waiters on a gate bead using the native Waiters field
- Add `bd gate show <gate-id>` command to display gate details
  including waiters (used by gt gate wake)
- Add Waiters field to UpdateArgs in RPC protocol
- Update server to handle waiters field in updates

This is part of the polecat phase handoff feature (bd-quw1).
The corresponding gastown changes (gt done --phase-complete) are
tracked separately.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 16:40:47 -08:00
onyx
a89f47cdf2 feat(gate): add bd gate discover for gh:run await_id auto-discovery (bd-z6kw)
Implements automatic discovery of GitHub workflow run IDs for gates
awaiting CI/CD completion. This enables the Refinery patrol to
auto-populate await_id for gh:run gates that were created without one.

Changes:
- Add `bd gate discover` command that:
  - Finds open gh:run gates without await_id
  - Queries recent GitHub workflow runs via gh CLI
  - Matches runs to gates using heuristics (branch, commit, time)
  - Updates gates with discovered run IDs

- Add `--await-id` flag to `bd update` for manual setting
- Add AwaitID to UpdateArgs in RPC protocol
- Add await_id to allowedUpdateFields in storage layer

Matching heuristics (scored, highest match wins):
- Commit SHA match: +100 points
- Branch match: +50 points
- Time proximity (<5min: +30, <10min: +20, <30min: +10)
- In-progress/queued status: +5 points

Usage:
  bd gate discover           # Auto-discover for all matching gates
  bd gate discover --dry-run # Preview without updating
  bd gate discover --branch main --limit 10

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 16:14:35 -08:00
mayor
2f96795f85 fix(daemon): propagate startup failure reason to user (GH#863)
When daemon fails to start due to legacy database or fingerprint validation,
the error was only logged to daemon.log. Users saw "Daemon took too long"
with no hint about the actual problem.

Changes:
- Write validation errors to .beads/daemon-error file before daemon exits
- Check for daemon-error file in autostart and display contents on timeout
- Elevate legacy database check in bd doctor from warning to error

Now when daemon fails due to legacy database, users see:
  "LEGACY DATABASE DETECTED!
   ...
   Run 'bd migrate --update-repo-id' to add fingerprint"

Instead of just "Daemon took too long to start".

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-02 16:06:09 -08:00
beads/crew/grip
0e8467ca6d bd sync: 2026-01-02 16:04:48 2026-01-02 16:04:48 -08:00