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>
This commit is contained in:
@@ -895,7 +895,8 @@ func TestCheckMetadataVersionTracking(t *testing.T) {
|
||||
{
|
||||
name: "slightly outdated version",
|
||||
setupVersion: func(beadsDir string) error {
|
||||
return os.WriteFile(filepath.Join(beadsDir, ".local_version"), []byte("0.24.0\n"), 0644)
|
||||
// Use a version that's less than 10 minor versions behind current
|
||||
return os.WriteFile(filepath.Join(beadsDir, ".local_version"), []byte("0.30.0\n"), 0644)
|
||||
},
|
||||
expectedStatus: doctor.StatusOK,
|
||||
expectWarning: false,
|
||||
@@ -903,7 +904,8 @@ func TestCheckMetadataVersionTracking(t *testing.T) {
|
||||
{
|
||||
name: "very old version",
|
||||
setupVersion: func(beadsDir string) error {
|
||||
return os.WriteFile(filepath.Join(beadsDir, ".local_version"), []byte("0.14.0\n"), 0644)
|
||||
// Use a version that's 10+ minor versions behind current (triggers warning)
|
||||
return os.WriteFile(filepath.Join(beadsDir, ".local_version"), []byte("0.24.0\n"), 0644)
|
||||
},
|
||||
expectedStatus: doctor.StatusWarning,
|
||||
expectWarning: true,
|
||||
|
||||
@@ -288,6 +288,17 @@ type VersionChange struct {
|
||||
|
||||
// versionChanges contains agent-actionable changes for recent versions
|
||||
var versionChanges = []VersionChange{
|
||||
{
|
||||
Version: "0.34.0",
|
||||
Date: "2025-12-22",
|
||||
Changes: []string{
|
||||
"NEW: Wisp commands - bd wisp create/list/gc for ephemeral molecule management",
|
||||
"NEW: Chemistry UX - bd pour, bd mol bond --wisp/--pour for phase control",
|
||||
"NEW: Cross-project deps - external:<repo>:<id> syntax, bd ship command",
|
||||
"BREAKING: bd repo add/remove now writes to .beads/config.yaml (not DB)",
|
||||
"FIX: Wisp storage auto-copies issue_prefix from main database",
|
||||
},
|
||||
},
|
||||
{
|
||||
Version: "0.33.2",
|
||||
Date: "2025-12-21",
|
||||
|
||||
@@ -1,109 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetRepoConfig_EmptyValue(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
// Test 1: No config set at all - should return empty map
|
||||
repos, err := getRepoConfig(ctx, store)
|
||||
if err != nil {
|
||||
t.Fatalf("getRepoConfig with no config failed: %v", err)
|
||||
}
|
||||
if len(repos) != 0 {
|
||||
t.Errorf("Expected empty map, got %d entries", len(repos))
|
||||
}
|
||||
|
||||
// Test 2: Empty string value - should return empty map (this was the bug)
|
||||
// This simulates GetConfig returning ("", nil) which caused "unexpected end of JSON input"
|
||||
err = store.SetConfig(ctx, "repos.additional", "")
|
||||
if err != nil {
|
||||
t.Fatalf("SetConfig failed: %v", err)
|
||||
}
|
||||
repos, err = getRepoConfig(ctx, store)
|
||||
if err != nil {
|
||||
t.Fatalf("getRepoConfig with empty value failed: %v", err)
|
||||
}
|
||||
if len(repos) != 0 {
|
||||
t.Errorf("Expected empty map for empty value, got %d entries", len(repos))
|
||||
}
|
||||
|
||||
// Test 3: Valid JSON value - should parse correctly
|
||||
err = store.SetConfig(ctx, "repos.additional", `{"alias1":"/path/to/repo1","alias2":"/path/to/repo2"}`)
|
||||
if err != nil {
|
||||
t.Fatalf("SetConfig with JSON failed: %v", err)
|
||||
}
|
||||
repos, err = getRepoConfig(ctx, store)
|
||||
if err != nil {
|
||||
t.Fatalf("getRepoConfig with valid JSON failed: %v", err)
|
||||
}
|
||||
if len(repos) != 2 {
|
||||
t.Errorf("Expected 2 repos, got %d", len(repos))
|
||||
}
|
||||
if repos["alias1"] != "/path/to/repo1" {
|
||||
t.Errorf("Expected '/path/to/repo1', got '%s'", repos["alias1"])
|
||||
}
|
||||
if repos["alias2"] != "/path/to/repo2" {
|
||||
t.Errorf("Expected '/path/to/repo2', got '%s'", repos["alias2"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetRepoConfig(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
// Set repos and verify round-trip
|
||||
repos := map[string]string{
|
||||
"planning": "/home/user/planning-repo",
|
||||
"shared": "/home/user/shared-repo",
|
||||
}
|
||||
|
||||
err := setRepoConfig(ctx, store, repos)
|
||||
if err != nil {
|
||||
t.Fatalf("setRepoConfig failed: %v", err)
|
||||
}
|
||||
|
||||
// Read back
|
||||
result, err := getRepoConfig(ctx, store)
|
||||
if err != nil {
|
||||
t.Fatalf("getRepoConfig after set failed: %v", err)
|
||||
}
|
||||
|
||||
if len(result) != 2 {
|
||||
t.Errorf("Expected 2 repos, got %d", len(result))
|
||||
}
|
||||
if result["planning"] != "/home/user/planning-repo" {
|
||||
t.Errorf("Expected planning repo path, got '%s'", result["planning"])
|
||||
}
|
||||
if result["shared"] != "/home/user/shared-repo" {
|
||||
t.Errorf("Expected shared repo path, got '%s'", result["shared"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestRepoConfigEmptyMap(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
store, cleanup := setupTestDB(t)
|
||||
defer cleanup()
|
||||
|
||||
// Set empty map
|
||||
repos := make(map[string]string)
|
||||
err := setRepoConfig(ctx, store, repos)
|
||||
if err != nil {
|
||||
t.Fatalf("setRepoConfig with empty map failed: %v", err)
|
||||
}
|
||||
|
||||
// Read back - should work and return empty map
|
||||
result, err := getRepoConfig(ctx, store)
|
||||
if err != nil {
|
||||
t.Fatalf("getRepoConfig after empty set failed: %v", err)
|
||||
}
|
||||
if len(result) != 0 {
|
||||
t.Errorf("Expected empty map, got %d entries", len(result))
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# bd-shim v1
|
||||
# bd-hooks-version: 0.33.2
|
||||
# bd-hooks-version: 0.34.0
|
||||
#
|
||||
# bd (beads) post-checkout hook - thin shim
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# bd-shim v1
|
||||
# bd-hooks-version: 0.33.2
|
||||
# bd-hooks-version: 0.34.0
|
||||
#
|
||||
# bd (beads) post-merge hook - thin shim
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# bd-shim v1
|
||||
# bd-hooks-version: 0.33.2
|
||||
# bd-hooks-version: 0.34.0
|
||||
#
|
||||
# bd (beads) pre-commit hook - thin shim
|
||||
#
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/bin/sh
|
||||
# bd-shim v1
|
||||
# bd-hooks-version: 0.33.2
|
||||
# bd-hooks-version: 0.34.0
|
||||
#
|
||||
# bd (beads) pre-push hook - thin shim
|
||||
#
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
|
||||
var (
|
||||
// Version is the current version of bd (overridden by ldflags at build time)
|
||||
Version = "0.33.2"
|
||||
Version = "0.34.0"
|
||||
// Build can be set via ldflags at compile time
|
||||
Build = "dev"
|
||||
// Commit and branch the git revision the binary was built from (optional ldflag)
|
||||
|
||||
Reference in New Issue
Block a user