Commit Graph

3697 Commits

Author SHA1 Message Date
Steve Yegge
62bbae9c78 feat(types): add HOP entity tracking types (bd-7pwh)
- Add EntityRef type for structured entity references with URI support
- Add Creator field to Issue for tracking who created work
- Add Validation type and Validations field for proof-of-stake approvals
- Fix RemoveDependency FK violation on external deps (bd-a3sj)
- Include all new fields in content hash computation
- Full test coverage for all new types

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-22 20:10:09 -08:00
Steve Yegge
6a2909c686 Add Claude Code settings for zoey crew worker 2025-12-22 18:01:44 -08:00
Steve Yegge
808c33b7a0 feat: add molecule navigation commands (bd-sal9, bd-ieyy)
Add bd mol current: Shows current position in molecule workflow
- Displays all steps with status indicators (done/current/ready/blocked/pending)
- Infers molecule from in_progress issues when no ID given
- Supports --for flag to check another agent's molecules

Add bd close --continue: Auto-advances to next molecule step
- After closing, finds parent molecule and next ready step
- Auto-claims next step by default (--no-auto to skip)
- Shows molecule completion message when all steps closed

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 17:37:23 -08:00
Steve Yegge
11dd84a579 bd sync: 2025-12-22 17:36:38 2025-12-22 17:36:38 -08:00
Steve Yegge
8097cd653b bd sync: 2025-12-22 17:04:03 2025-12-22 17:04:03 -08:00
Steve Yegge
dd9fcd9e36 feat(scripts): add --all, --mcp-local, --restart-daemons flags to bump-version.sh
Improves the version bump workflow with missing local installation steps:

- --install: Now installs bd to BOTH ~/go/bin AND ~/.local/bin
- --mcp-local: Install beads-mcp from local source via uv/pip
- --restart-daemons: Restart all bd daemons to pick up new version
- --all: Shorthand for --install --mcp-local --restart-daemons

Also updated RELEASING.md with flag documentation and recommended workflow.

Closes bd-of2p

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 16:02:29 -08:00
Steve Yegge
014efbbd3f bd sync: 2025-12-22 16:02:19 2025-12-22 16:02:19 -08:00
Steve Yegge
3f3bc326a1 bd sync: 2025-12-22 15:48:42 2025-12-22 15:50:50 -08:00
Steve Yegge
07e941a65d bd sync: 2025-12-22 15:40:07 2025-12-22 15:50:50 -08:00
Steve Yegge
8d697a2c21 bd sync: 2025-12-22 14:53:43 2025-12-22 15:50:50 -08:00
Steve Yegge
4c38075520 refactor(cmd): replace map[string]interface{} with typed JSON response structs (bd-u2sc.1)
Added typed response structs for JSON output in CLI commands:

compact.go:
- CompactDryRunResponse, CompactSuccessResponse
- CompactNoCandidatesResponse, CompactBatchSuccessResponse
- CompactStatsResponse, CompactTierStats
- CompactApplyResponse, TombstonePrunedInfo

cleanup.go:
- CleanupEmptyResponse

daemons.go:
- DaemonStopResponse, DaemonRestartResponse
- DaemonLogsResponse, DaemonKillallEmptyResponse
- DaemonHealthResponse, DaemonHealthReport

daemon_lifecycle.go:
- DaemonStatusResponse

Benefits:
- Compile-time type checking for JSON output
- IDE autocompletion for response fields
- Self-documenting API structure
- Easier refactoring

Note: RPC args and storage update maps remain as-is (require
interface changes for internal APIs).

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:48:36 -08:00
Steve Yegge
e67712dcd4 refactor(cmd): migrate sort.Slice to slices.SortFunc (bd-u2sc.2)
Modernize sorting code to use Go 1.21+ slices package:
- Replace sort.Slice with slices.SortFunc across 16 files
- Use cmp.Compare for orderable types (strings, ints)
- Use time.Time.Compare for time comparisons
- Use cmp.Or for multi-field sorting
- Use slices.SortStableFunc where stability matters

Benefits: cleaner 3-way comparison, slightly better performance,
modern idiomatic Go.

Part of GH#692 refactoring epic.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:39:55 -08:00
Charles P. Cross
82cbd98e50 fix(daemon): include tombstones in exportToJSONLWithStore for sync propagation (#696)
* fix(daemon): include tombstones in exportToJSONLWithStore for sync propagation

The daemon's exportToJSONLWithStore() function was using an empty
IssueFilter which defaults to IncludeTombstones: false. This caused
deleted issues (tombstones) to be excluded from JSONL exports during
daemon sync cycles.

Bug scenario:
1. User runs `bd delete <issue>` with daemon active
2. Database correctly marks issue as tombstone
3. Main .beads/issues.jsonl correctly shows status:"tombstone"
4. But sync branch worktree JSONL still showed status:"open"
5. Other clones would not see the deletion

The fix adds IncludeTombstones: true to match the behavior of
exportToJSONL() in sync.go, ensuring tombstones propagate to other
clones and prevent resurrection of deleted issues.

Adds regression test TestExportToJSONLWithStore_IncludesTombstones
that verifies tombstones are included in daemon JSONL exports.

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:18:10 -08:00
Charles P. Cross
ee016bbb25 fix(daemon): handle diverged sync branch with fetch-rebase-retry on push (#697)
* fix(daemon): handle diverged sync branch with fetch-rebase-retry on push

When pushing to the sync branch, if the remote has newer commits that
the local worktree doesn't have, the push would fail with "fetch first"
error and the daemon would log the failure without recovery.

Bug scenario:
1. Clone A pushes commit X to sync branch
2. Clone B has local commit Y (not based on X)
3. Clone B's push fails with "fetch first" error
4. Without this fix: daemon logs failure and stops
5. With this fix: daemon fetches, rebases Y on X, and retries push

This fix adds fetch-rebase-retry logic to gitPushFromWorktree():
1. Detect push rejection due to remote having newer commits
2. Fetch the latest remote sync branch
3. Rebase local commits on top of remote
4. Retry the push

If rebase fails (e.g., due to conflicts), the rebase is aborted and
an error is returned with helpful context.

This allows multiple clones to push to the same sync branch without
manual intervention, as long as the changes don't conflict.

Adds integration test TestGitPushFromWorktree_FetchRebaseRetry that
verifies the fetch-rebase-retry behavior with diverged branches.

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:17:26 -08:00
Charles P. Cross
737e65afbd fix(daemon): add periodic remote sync to event-driven mode (#698)
* fix(daemon): add periodic remote sync to event-driven mode

The event-driven daemon mode only triggered imports when the local JSONL
file changed (via file watcher) or when the fallback ticker fired (only
if watcher failed). This meant the daemon wouldn't see updates pushed
by other clones until something triggered a local file change.

Bug scenario:
1. Clone A creates an issue and daemon pushes to sync branch
2. Clone B's daemon only watched local file changes
3. Clone B would not see the new issue until something triggered local change
4. With this fix: Clone B's daemon periodically calls doAutoImport

This fix adds a 30-second periodic remote sync ticker that calls
doAutoImport(), which includes syncBranchPull() to fetch and import
updates from the remote sync branch.

This is essential for multi-clone workflows where:
- Clone A creates an issue and daemon pushes to sync branch
- Clone B's daemon needs to periodically pull to see the new issue
- Without periodic sync, Clone B would only see updates if its local
  JSONL file happened to change

The 30-second interval balances responsiveness with network overhead.

Adds integration test TestEventDrivenLoop_PeriodicRemoteSync that
verifies the event-driven loop starts with periodic sync support.

* feat(daemon): add configurable interval for periodic remote sync

- Add BEADS_REMOTE_SYNC_INTERVAL environment variable to configure
  the interval for periodic remote sync (default: 30s)
- Add getRemoteSyncInterval() function to parse the env var
- Minimum interval is 5s to prevent excessive load
- Setting to 0 disables periodic sync (not recommended)
- Add comprehensive integration tests for the configuration

Valid duration formats:
- "30s" (30 seconds)
- "1m" (1 minute)
- "5m" (5 minutes)

Tests added:
- TestEventDrivenLoop_HasRemoteSyncTicker
- TestGetRemoteSyncInterval_Default
- TestGetRemoteSyncInterval_CustomValue
- TestGetRemoteSyncInterval_MinimumEnforced
- TestGetRemoteSyncInterval_InvalidValue
- TestGetRemoteSyncInterval_Zero
- TestSyncBranchPull_FetchesRemoteUpdates

* fix: resolve all golangci-lint errors (cherry-pick from fix/linting-errors)

Cherry-picked linting fixes to ensure CI passes.

* feat(daemon): add config.yaml support for remote-sync-interval

- Add remote-sync-interval to .beads/config.yaml as alternative to
  BEADS_REMOTE_SYNC_INTERVAL environment variable
- Environment variable takes precedence over config.yaml (follows
  existing pattern for flush-debounce)
- Add config binding in internal/config/config.go
- Update getRemoteSyncInterval() to use config.GetDuration()
- Add doctor validation for remote-sync-interval in config.yaml

Configuration sources (in order of precedence):
1. BEADS_REMOTE_SYNC_INTERVAL environment variable
2. remote-sync-interval in .beads/config.yaml
3. DefaultRemoteSyncInterval (30s)

Example config.yaml:
  remote-sync-interval: "1m"

---------

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:15:33 -08:00
Steve Yegge
6cc8926e59 chore(nix): update vendorHash for go-sqlite3 0.30.4 and wazero 1.11.0
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:12:33 -08:00
dependabot[bot]
0a527e6390 chore(deps): bump github.com/tetratelabs/wazero from 1.10.1 to 1.11.0 (#702)
Bumps [github.com/tetratelabs/wazero](https://github.com/tetratelabs/wazero) from 1.10.1 to 1.11.0.
- [Release notes](https://github.com/tetratelabs/wazero/releases)
- [Commits](https://github.com/tetratelabs/wazero/compare/v1.10.1...v1.11.0)

---
updated-dependencies:
- dependency-name: github.com/tetratelabs/wazero
  dependency-version: 1.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-22 14:11:57 -08:00
dependabot[bot]
8a788970e2 chore(deps): bump github.com/ncruces/go-sqlite3 from 0.30.3 to 0.30.4 (#703)
Bumps [github.com/ncruces/go-sqlite3](https://github.com/ncruces/go-sqlite3) from 0.30.3 to 0.30.4.
- [Release notes](https://github.com/ncruces/go-sqlite3/releases)
- [Commits](https://github.com/ncruces/go-sqlite3/compare/v0.30.3...v0.30.4)

---
updated-dependencies:
- dependency-name: github.com/ncruces/go-sqlite3
  dependency-version: 0.30.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-22 14:11:42 -08:00
Charles P. Cross
e360a74b61 fix: resolve all golangci-lint errors (#699)
Fix 12 linting issues that were causing CI failures:

errcheck (8 fixes):
- cmd/bd/mol_burn.go: wrap wispStore.Close() in defer func
- cmd/bd/mol_burn.go: handle fmt.Scanln() return value
- cmd/bd/mol_squash.go: wrap wispStore.Close() in defer func (2 locations)
- cmd/bd/wisp.go: wrap wispStore.Close() in defer func (3 locations)
- internal/beads/beads.go: wrap mainStore.Close() and wispStore.Close()

gosec G104 (2 fixes):
- internal/storage/sqlite/multirepo.go: handle rows.Close() errors

misspell (1 fix):
- cmd/bd/mol_burn.go: change "Cancelled" to "Canceled"

unparam (1 fix):
- cmd/bd/mol_squash.go: use blank identifier for unused cmd parameter

All fixes follow existing patterns in the codebase:
- defer func() { _ = store.Close() }() for deferred closes
- _ = rows.Close() for explicit closes with ignored errors
- _, _ = fmt.Scanln() for ignored return values

Co-authored-by: Charles P. Cross <cpdata@users.noreply.github.com>
2025-12-22 14:06:45 -08:00
Steve Yegge
7f5fa23a6b fixed an install script bug 2025-12-22 13:16:22 -08:00
Steve Yegge
dca5292cbc bd sync: 2025-12-22 13:13:48 2025-12-22 13:13:48 -08:00
Steve Yegge
512cbc0ef2 bd sync: 2025-12-22 12:32:30 2025-12-22 12:32:30 -08:00
Steve Yegge
d578eb80d6 bd sync: 2025-12-22 12:17:24 2025-12-22 12:17:24 -08:00
Steve Yegge
85ad0a2bdc chore: add .beads-wisp/ to gitignore 2025-12-22 12:11:36 -08:00
Steve Yegge
bbe12032d4 bd sync: 2025-12-22 12:10:56 2025-12-22 12:11:36 -08:00
Steve Yegge
199def9fed release: v0.34.0
## Added
- Wisp commands - bd wisp create/list/gc for ephemeral molecule management
- Chemistry UX - bd pour, bd mol bond --wisp/--pour for phase control
- Cross-project deps - external:<repo>:<id> syntax, bd ship command
- Orphan detection in bd doctor

## Changed
- Multi-repo config uses YAML - bd repo add/remove writes to .beads/config.yaml

## Fixed
- Wisp storage auto-copies issue_prefix from main database
- Prefix validation in multi-repo mode
- Remove orphaned repo_test.go
- Update version tests for 0.34.0 thresholds

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 03:18:55 -08:00
Steve Yegge
32181fd5a2 docs: add chemistry commands documentation (bd-hhv3)
Document new molecular chemistry UX commands:
- bd pour (proto → persistent mol)
- bd wisp create (proto → ephemeral wisp)
- bd hook (inspect pinned work)
- bd pin --for/--start (work assignment)
- bd mol bond --pour/--wisp (phase control)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 02:56:06 -08:00
Steve Yegge
9102cdb825 bd sync: 2025-12-22 02:55:55 2025-12-22 02:55:55 -08:00
Steve Yegge
11f3acdb8d bd sync: 2025-12-22 02:22:48 2025-12-22 02:23:07 -08:00
Steve Yegge
cadf798b23 feat: implement molecular chemistry UX commands
Add chemistry-inspired commands for the molecular work metaphor:

New commands:
- bd pour <proto>: Instantiate proto as persistent mol (liquid phase)
- bd wisp create <proto>: Instantiate proto as ephemeral wisp (vapor)
- bd hook: Inspect what's pinned to an agent's hook

Enhanced commands:
- bd mol spawn: Add --pour flag, deprecate --persistent
- bd mol bond: Add --pour flag (force liquid on wisp target)
- bd pin: Add --for <agent> and --start flags

Phase transitions:
  Proto (solid) --pour--> Mol (liquid) --squash--> Digest
  Proto (solid) --wisp--> Wisp (vapor) --burn--> (nothing)

Design docs: gastown/mayor/rig/docs/molecular-chemistry.md

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 02:21:40 -08:00
Steve Yegge
8f8e9516df fix: bd repo commands write to YAML and cleanup on remove (#683)
- bd repo add/remove now writes to .beads/config.yaml instead of database
- bd repo remove deletes hydrated issues from the removed repo
- Added internal/config/repos.go for YAML config manipulation
- Added DeleteIssuesBySourceRepo for cleanup on remove

Fixes config disconnect where bd repo add wrote to DB but hydration read from YAML.

Breaking change: bd repo add no longer accepts optional alias argument.

Co-authored-by: Dylan Conlin <dylan.conlin@gmail.com>

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 01:26:45 -08:00
Ryan
a11b20960a fix(doctor): UX improvements for diagnostics and daemon (#687)
* fix(doctor): UX improvements for diagnostics and daemon

- Add Repo Fingerprint check to detect when database belongs to a
  different repository (copied .beads dir or git remote URL change)
- Add interactive fix for repo fingerprint with options: update repo ID,
  reinitialize database, or skip
- Add visible warning when daemon takes >5s to start, recommending
  'bd doctor' for diagnosis
- Detect install method (Homebrew vs script) and show only relevant
  upgrade command
- Improve WARNINGS section:
  - Add icons (⚠ or ✖) next to each item
  - Color numbers by severity (yellow for warnings, red for errors)
  - Render entire error lines in red
  - Sort by severity (errors first)
  - Fix alignment with checkmarks above
- Use heavier fail icon (✖) for better visibility
- Add integration and validation tests for doctor fixes

* fix(lint): address errcheck and gosec warnings

- mol_bond.go: explicitly ignore ephStore.Close() error
- beads.go: add nosec for .gitignore file permissions (0644 is standard)
2025-12-22 01:25:23 -08:00
Gero Hillebrandt
9d30e80fdf fix: skip prefix validation in multi-repo mode (GH#686) (#688)
Issues from additional repos have their own prefixes, which is expected.
Skip validation when multi-repo config is present.
2025-12-22 01:25:19 -08:00
dylan-conlin
2c5acc9060 fix: handle empty config values in getRepoConfig() (#684)
Previously, bd repo commands (list, add, remove, sync) failed with
'unexpected end of JSON input' when repos.additional config key
had an empty value. GetConfig() returns ('', nil) for missing keys,
and json.Unmarshal fails on empty strings.

Added empty value check before JSON parsing to return empty map
in this case. Added tests for repo config helper functions.
2025-12-22 01:25:07 -08:00
matt wilkie
025045bdb2 Add DeepWiki badge to README (#689)
DeepWiki provides up-to-date documentation people can talk to, for every public repo in the world (after being added to it's index). Adding this badge to a repository Readme tells DeepWiki to refresh it's docs automatically.

The DeepWiki link for Beads is
https://deepwiki.com/steveyegge/beads
2025-12-22 01:24:52 -08:00
Steve Yegge
f27b1f3102 feat: add wisp commands (bd-kwjh)
Implements wisp management commands for ephemeral molecules:
- bd wisp list: List wisps with stale detection
- bd wisp gc: Garbage collect orphaned wisps
- bd mol burn: Delete wisp without creating digest

Wisps are ephemeral molecules stored in .beads-wisp/ for patrol cycles
and operational loops that shouldn't accumulate in permanent storage.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 01:13:50 -08:00
Steve Yegge
b8715708b2 bd sync: 2025-12-22 01:13:15 2025-12-22 01:13:15 -08:00
Steve Yegge
69911070f0 feat: add cross-store wisp→digest squash (bd-kwjh.4)
- Add wisp detection in mol squash: checks wisp storage if not in main
- squashWispToPermanent: creates digest in permanent, deletes from wisp
- Fix directory naming: .beads-wisps → .beads-wisp (singular, matches doc)
- Add comprehensive tests for wisp squash scenarios

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:54:35 -08:00
Steve Yegge
1d3c9e6a83 bd sync: 2025-12-22 00:54:24 2025-12-22 00:54:24 -08:00
Steve Yegge
065dd23a12 bd sync: 2025-12-22 00:32:37 2025-12-22 00:32:45 -08:00
Steve Yegge
a49b924794 refactor: rename ephemeral → wisp throughout (bd-ldb0)
Standardize terminology for ephemeral molecule storage:
- .beads-ephemeral/ → .beads-wisps/
- --ephemeral flag → --wisp flag
- All Ephemeral* functions → Wisp*

Wisps are the "steam" in Gas Town's engine metaphor - ephemeral
molecules that evaporate after squash.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:32:18 -08:00
Steve Yegge
22eee81f42 feat: add --ephemeral flag to bd mol bond (bd-kwjh.3)
When --ephemeral is set:
- Spawned molecules go to .beads-ephemeral/ instead of .beads/
- Ephemeral directory is automatically gitignored
- No auto-flush (ephemeral does not sync)
- Proto+proto bonding ignores flag (templates stay in permanent storage)

Updated help text to document wisp workflow (bond then squash/burn).

Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:19:18 -08:00
Steve Yegge
2d719b189d feat: add ephemeral storage backend for wisps (bd-kwjh.2)
Add .beads-ephemeral/ storage support for ephemeral molecule tracking:

- FindEphemeralDir: locate ephemeral directory (sibling to .beads/)
- FindEphemeralDatabasePath: get DB path, create directory if needed
- NewEphemeralStorage: open ephemeral SQLite database
- EnsureEphemeralGitignore: add .beads-ephemeral/ to .gitignore
- IsEphemeralDatabase: check if a path is ephemeral storage

Part of the wisp storage epic for Gas Town patrol cycles.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 00:19:18 -08:00
Steve Yegge
7f0a5982dc bd sync: 2025-12-22 00:18:00 2025-12-22 00:18:00 -08:00
Steve Yegge
a111b2d6cd bd sync: 2025-12-22 00:13:58 2025-12-22 00:13:58 -08:00
Steve Yegge
cd2cee9473 bd sync: 2025-12-22 00:08:34 2025-12-22 00:08:34 -08:00
Steve Yegge
e952219c3d bd sync: 2025-12-22 00:05:28 2025-12-22 00:05:28 -08:00
Steve Yegge
468751d5e3 bd sync: 2025-12-22 00:02:25 2025-12-22 00:02:25 -08:00
Steve Yegge
5fb254fb08 bd sync: 2025-12-21 23:45:42 2025-12-21 23:45:42 -08:00
Steve Yegge
b3da7b4489 bd sync: 2025-12-21 23:42:29 2025-12-21 23:42:29 -08:00