diff --git a/.beads/issues.jsonl b/.beads/issues.jsonl index 6ed9beaf..3c9355ff 100644 --- a/.beads/issues.jsonl +++ b/.beads/issues.jsonl @@ -44,6 +44,7 @@ {"id":"bd-15","title":"Write comprehensive collision resolution tests","description":"Test cases: simple collision, multiple collisions, dependency updates, text reference updates, chain dependencies, edge cases (partial ID matches, case sensitivity, triple merges). Add to import_test.go and collision_test.go.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.647268-07:00","closed_at":"2025-10-16T10:07:34.007864-07:00","dependencies":[{"issue_id":"bd-15","depends_on_id":"bd-48","type":"parent-child","created_at":"2025-10-16T21:51:08.917092-07:00","created_by":"renumber"}]} {"id":"bd-150","title":"bd renumber removes issues with different prefix than majority","description":"The 'bd renumber' command appears to remove issues that have a different prefix than the majority of issues.\n\nReproduction:\n1. Database has 115 vc- issues and 2 bd- issues (bd-118, bd-119)\n2. Run: bd renumber --force\n3. Result: Only vc- issues remain, bd-118 and bd-119 are deleted\n\nExpected: All issues should be renumbered, regardless of prefix\nActual: Issues with minority prefix are removed\n\nEvidence:\n- Before renumber: 117 issues total (115 vc-, 2 bd-)\n- After renumber: 115 issues total (115 vc-, 0 bd-)\n- bd-118 was 'Fix compilation errors in mission orchestrator test' (closed)\n- bd-119 was 'Fix bool pointer literal errors' (in_progress)\n\nThis is data loss - active work (bd-119 was in_progress) was silently deleted.","design":"Renumber should handle mixed prefixes:\n1. Group issues by prefix\n2. Renumber each group independently\n3. Or: fail if multiple prefixes detected with helpful error\n4. Or: add --prefix flag to specify which prefix to renumber\n\nNever silently delete issues.","acceptance_criteria":"Renumber preserves all issues regardless of prefix, or fails with clear error message","notes":"Not a bug - mixed prefixes in one database is user error. Filed bd-151 for proper validation instead.","status":"closed","priority":0,"issue_type":"bug","created_at":"2025-10-17T21:43:07.800716-07:00","updated_at":"2025-10-17T21:46:26.813508-07:00","closed_at":"2025-10-17T21:46:26.813512-07:00"} {"id":"bd-151","title":"Validate issue prefix matches database prefix on create","description":"Users can accidentally create issues with the wrong prefix (e.g., creating 'bd-118' in the vc tracker instead of the beads tracker).\n\nThis causes problems:\n- Issues appear in wrong project\n- Renumbering silently removes them (correct behavior, but surprising)\n- Confusion about which tracker owns the issue\n\nEvidence from vc project:\n- bd-118 and bd-119 were created in ~/src/vc/vc/.beads/vc.db (should use vc- prefix)\n- These were silently removed during renumbering (working as intended)\n- But user didn't realize they were in wrong database until too late\n\nRoot cause: User was in vc directory but created issues with bd- prefix, probably because they were beads-related fixes.","design":"Options:\n\n1. **Strict validation (recommended)**:\n - Detect database prefix from existing issues or .beads/*.db filename\n - Reject 'bd create' if prefix doesn't match\n - Error: 'This database uses prefix vc-, but you tried to create bd-X. Use --force to override.'\n\n2. **Auto-correct prefix**:\n - 'bd create' in vc database always uses vc- prefix regardless of what user intended\n - Warning: 'Auto-corrected prefix from bd- to vc-'\n\n3. **Multiple prefix support**:\n - Allow multiple prefixes per database\n - Group by prefix during renumbering\n - Complexity not worth it\n\nPrefer option 1 - fail fast with clear error.","acceptance_criteria":"Creating an issue with wrong prefix fails with helpful error message explaining the mismatch","status":"open","priority":1,"issue_type":"feature","created_at":"2025-10-17T21:46:27.204648-07:00","updated_at":"2025-10-17T21:46:27.204648-07:00"} +{"id":"bd-155","title":"bd delete panics with nil pointer when daemon is running","description":"When the daemon is running (daemonClient != nil), the delete command panics with nil pointer dereference because it tries to use the global store variable which is nil.\n\nThe PersistentPreRun in main.go returns early when daemon is connected (line 104), skipping store initialization. But delete.go:92 calls store.GetIssue() without checking if store is nil or if it should use daemonClient instead.\n\nReproduction:\n1. Start daemon: bd daemon start\n2. Try to delete: bd delete bd-152 --force\n3. Panic: runtime error: invalid memory address or nil pointer dereference\n\nRoot cause: Missing daemon fallback pattern that other commands use (see ready.go:135-143)","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-17T22:06:03.968082-07:00","updated_at":"2025-10-17T22:06:08.606287-07:00","closed_at":"2025-10-17T22:06:08.606287-07:00"} {"id":"bd-16","title":"Update documentation for collision resolution","description":"Update README.md with collision resolution section. Update CLAUDE.md with new workflow. Document --resolve-collisions and --dry-run flags. Add example scenarios showing branch merge workflows.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.648113-07:00","closed_at":"2025-10-16T10:07:34.028648-07:00","dependencies":[{"issue_id":"bd-16","depends_on_id":"bd-48","type":"parent-child","created_at":"2025-10-16T21:51:08.924312-07:00","created_by":"renumber"}]} {"id":"bd-17","title":"bd should auto-detect .beads/*.db in current directory","description":"When bd is run without --db flag, it defaults to beads' own database instead of looking for a .beads/*.db file in the current working directory. This causes confusion when working on other projects that use beads for issue tracking (like vc).\n\nExpected behavior: bd should search for .beads/*.db in cwd and use that if found, before falling back to default beads database.\n\nExample: Running 'bd ready' in /Users/stevey/src/vc/vc/ should automatically find and use .beads/vc.db without requiring --db flag every time.","status":"closed","priority":1,"issue_type":"bug","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.650584-07:00","closed_at":"2025-10-16T10:07:34.046944-07:00"} {"id":"bd-18","title":"Document or automate JSONL sync workflow for git collaboration","description":"When using beads across multiple machines/environments via git, there's a workflow gap:\n\n1. Machine A: Create issues → stored in .beads/project.db\n2. Machine A: bd export -o .beads/issues.jsonl\n3. Machine A: git add .beads/issues.jsonl \u0026\u0026 git commit \u0026\u0026 git push\n4. Machine B: git pull\n5. Machine B: ??? issues.jsonl exists but project.db is empty/stale\n\nThe missing step is: bd import --db .beads/project.db -i .beads/issues.jsonl\n\nThis needs to be either:\na) Documented clearly in workflow docs\nb) Automated (e.g., git hook, or bd auto-imports if jsonl is newer than db)\nc) Both\n\nReal-world impact: User had Claude Code on GCP VM create vc issues from BOOTSTRAP.md. They were exported to issues.jsonl and committed. But on local machine, vc.db was empty until manual import was run.","status":"closed","priority":1,"issue_type":"task","created_at":"2025-10-16T20:46:08.971822-07:00","updated_at":"2025-10-17T01:32:00.651438-07:00","closed_at":"2025-10-14T02:51:52.199766-07:00"} diff --git a/cmd/bd/main.go b/cmd/bd/main.go index 89cc3ce4..db612937 100644 --- a/cmd/bd/main.go +++ b/cmd/bd/main.go @@ -22,6 +22,7 @@ import ( "github.com/steveyegge/beads/internal/storage" "github.com/steveyegge/beads/internal/storage/sqlite" "github.com/steveyegge/beads/internal/types" + "golang.org/x/mod/semver" ) var ( @@ -504,17 +505,23 @@ func checkVersionMismatch() { // Compare versions: warn if binary is older than database if dbVersion != Version { - // Simple string comparison is sufficient for detecting version mismatch - // We're not trying to parse semantic versions, just detect "different" yellow := color.New(color.FgYellow, color.Bold).SprintFunc() fmt.Fprintf(os.Stderr, "\n%s\n", yellow("⚠️ WARNING: Version mismatch detected!")) fmt.Fprintf(os.Stderr, "%s\n", yellow(fmt.Sprintf("⚠️ Your bd binary (v%s) differs from the database version (v%s)", Version, dbVersion))) - // Determine if binary is likely older (heuristic: lower version number) - if Version < dbVersion { + // Use semantic version comparison (requires v prefix) + binaryVer := "v" + Version + dbVer := "v" + dbVersion + + // semver.Compare returns -1 if binaryVer < dbVer, 0 if equal, 1 if binaryVer > dbVer + cmp := semver.Compare(binaryVer, dbVer) + + if cmp < 0 { + // Binary is older than database fmt.Fprintf(os.Stderr, "%s\n", yellow("⚠️ Your binary appears to be OUTDATED.")) fmt.Fprintf(os.Stderr, "%s\n\n", yellow("⚠️ Some features may not work correctly. Rebuild: go build -o bd ./cmd/bd")) - } else { + } else if cmp > 0 { + // Binary is newer than database fmt.Fprintf(os.Stderr, "%s\n", yellow("⚠️ Your binary appears NEWER than the database.")) fmt.Fprintf(os.Stderr, "%s\n\n", yellow("⚠️ The database will be upgraded automatically.")) // Update stored version to current diff --git a/go.mod b/go.mod index b4e60006..2b01d0b2 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/steveyegge/beads -go 1.23.0 +go 1.24.0 require ( github.com/anthropics/anthropic-sdk-go v1.14.0 @@ -24,8 +24,9 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect - golang.org/x/sys v0.34.0 // indirect - golang.org/x/tools v0.34.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/sys v0.36.0 // indirect + golang.org/x/tools v0.37.0 // indirect modernc.org/libc v1.66.3 // indirect modernc.org/mathutil v1.7.1 // indirect modernc.org/memory v1.11.0 // indirect diff --git a/go.sum b/go.sum index 50415b2e..a6a467eb 100644 --- a/go.sum +++ b/go.sum @@ -46,14 +46,21 @@ golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b h1:M2rDM6z3Fhozi9O7NWsxAkg/y golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA= golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k= +golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo= golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= +golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=