diff --git a/.beads/beads.jsonl b/.beads/beads.jsonl index db5b9806..d08a33ba 100644 --- a/.beads/beads.jsonl +++ b/.beads/beads.jsonl @@ -25,7 +25,7 @@ {"id":"bd-9li4","content_hash":"7ae7b885e82a2de333584c01f690dbc3ecb924603f18e316f5c91cc44e2256f8","title":"Create Docker image for Agent Mail","description":"Containerize Agent Mail server for easy deployment.\n\nAcceptance Criteria:\n- Dockerfile with Python 3.14\n- Health check endpoint\n- Volume mount for storage\n- Environment variable configuration\n- Multi-arch builds (amd64, arm64)\n\nFile: deployment/agent-mail/Dockerfile","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.231964-08:00","updated_at":"2025-11-07T22:43:43.231964-08:00","source_repo":"."} {"id":"bd-9lwr","content_hash":"1fe4b1e3a507ef7f658edbcf02d5c72efd2ff1070ff0947da6e6159bf9ce8541","title":"Document inconsistent error handling strategy across codebase","description":"**Scope:** Cross-cutting pattern across cmd/bd (create.go, init.go, sync.go, daemon_sync.go)\n\n**Issue:** Three different error handling patterns used inconsistently:\n\n**Pattern A: Exit immediately**\n```go\nif err := store.CreateIssue(...) {\n fmt.Fprintf(os.Stderr, \"Error: %v\\n\", err)\n os.Exit(1)\n}\n```\n\n**Pattern B: Warn and continue**\n```go\nif err := createConfigYaml(...) {\n fmt.Fprintf(os.Stderr, \"Warning: %v\\n\", err)\n // Non-fatal - continue anyway\n}\n```\n\n**Pattern C: Silent ignore**\n```go\n_ = store.Close()\n```\n\n**Impact:**\n- Makes error handling non-deterministic\n- Hard to test error paths\n- Inconsistent user experience\n\n**Task:**\n1. Document when each pattern should be used\n2. Add decision tree/flowchart to developer docs\n3. Consider creating error handling helpers to enforce consistency\n4. Audit codebase and refactor outliers","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-23T19:46:52.861673-08:00","updated_at":"2025-11-23T19:46:52.861673-08:00","source_repo":"."} {"id":"bd-9msn","content_hash":"69ef2ebc5a847eb407c37e9039391d8ebc761a4cee3b60537de4f5a12011bec3","title":"Add monitoring and alerting","description":"Observability for production Agent Mail server.\n\nAcceptance Criteria:\n- Health check endpoint (/health)\n- Prometheus metrics export\n- Grafana dashboard\n- Alerts for server downtime\n- Alerts for high error rate\n- Log aggregation config\n\nFile: deployment/agent-mail/monitoring/","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-07T22:43:43.354117-08:00","updated_at":"2025-11-07T22:43:43.354117-08:00","source_repo":".","dependencies":[{"issue_id":"bd-9msn","depends_on_id":"bd-z3s3","type":"blocks","created_at":"2025-11-07T23:04:28.050074-08:00","created_by":"daemon"}]} -{"id":"bd-afd","content_hash":"267edacade844944abef9fe4ef85541ee21fd87e46a7c36098992a696edc0a21","title":"bd doctor --fix should auto-fix metadata.json jsonl_export mismatch","description":"## Root Cause\n\nThe version tracking code (cmd/bd/version_tracking.go:33-38) auto-recreates metadata.json using DefaultConfig() if it doesn't exist. DefaultConfig() hardcodes jsonl_export to 'issues.jsonl', but many repos (including beads itself) use 'beads.jsonl'.\n\nWhen metadata.json goes missing (git clean, merge conflict, rebase, etc.), the next bd command recreates it with the wrong filename, causing a mismatch with the actual JSONL file.\n\n## Impact\n\nThis affects ANY user whose metadata.json gets deleted and who uses a non-default JSONL filename. Normal git operations can trigger this.\n\n## Fix Requirements\n\n1. bd doctor --fix should auto-detect and fix the mismatch (check which .jsonl file exists, update metadata.json)\n2. Version tracking should detect actual JSONL file instead of using hardcoded default\n3. DefaultConfig() should scan for existing .jsonl files before defaulting\n4. Daemon should auto-detect config changes without restart\n\n## Related Code\n\n- internal/configfile/configfile.go:18-23 (DefaultConfig hardcodes issues.jsonl)\n- cmd/bd/version_tracking.go:33-38 (auto-creates config with default) \n- internal/beads/beads.go:245-246 (FindJSONLPath defaults to issues.jsonl)","status":"open","priority":2,"issue_type":"bug","created_at":"2025-11-23T22:57:34.03414-08:00","updated_at":"2025-11-23T23:04:40.21073-08:00","source_repo":"."} +{"id":"bd-afd","content_hash":"46a8ca9dad1de72d3cd2903ea0bf908622eb3a62bb2de4bba0816da5434a3d23","title":"bd doctor --fix should auto-fix metadata.json jsonl_export mismatch","description":"## Root Cause\n\nThe version tracking code (cmd/bd/version_tracking.go:33-38) auto-recreates metadata.json using DefaultConfig() if it doesn't exist. DefaultConfig() hardcodes jsonl_export to 'issues.jsonl', but many repos (including beads itself) use 'beads.jsonl'.\n\nWhen metadata.json goes missing (git clean, merge conflict, rebase, etc.), the next bd command recreates it with the wrong filename, causing a mismatch with the actual JSONL file.\n\n## Impact\n\nThis affects ANY user whose metadata.json gets deleted and who uses a non-default JSONL filename. Normal git operations can trigger this.\n\n## Fix Requirements\n\n1. bd doctor --fix should auto-detect and fix the mismatch (check which .jsonl file exists, update metadata.json)\n2. Version tracking should detect actual JSONL file instead of using hardcoded default\n3. DefaultConfig() should scan for existing .jsonl files before defaulting\n4. Daemon should auto-detect config changes without restart\n\n## Related Code\n\n- internal/configfile/configfile.go:18-23 (DefaultConfig hardcodes issues.jsonl)\n- cmd/bd/version_tracking.go:33-38 (auto-creates config with default) \n- internal/beads/beads.go:245-246 (FindJSONLPath defaults to issues.jsonl)","status":"in_progress","priority":2,"issue_type":"bug","created_at":"2025-11-23T22:57:34.03414-08:00","updated_at":"2025-11-23T23:06:04.135751-08:00","source_repo":"."} {"id":"bd-b0c8","content_hash":"87b423a42d509b9405b52b089b2ba92b33a90ad472d6d9094986b48715399a99","title":"Research hooks/skills approach for enforcing issue descriptions","description":"## Solution: Hooks/Skills (mentioned in discussion)\n\nResearch the hooks/skills system mentioned by riordanpawley in discussion #366:\nhttps://www.reddit.com/r/ClaudeAI/s/wrn2tjkMHX\n\n## Investigation Tasks\n\n1. Review the Reddit post to understand the approach\n2. Determine if beads hooks can enforce validation\n3. Check if Claude Code skills/hooks can intercept MCP calls\n4. Assess feasibility and user burden\n\n## Notes\n\nFrom discussion #366:\n\u003e I'm using a skills/hooks system to get Claude to do that kind of thing right similar to https://www.reddit.com/r/ClaudeAI/s/wrn2tjkMHX\n\nThis might be a client-side solution rather than server-side.\n\n## Deliverable\n\nDocument findings in issue notes, with recommendation on whether to pursue this approach.","status":"open","priority":3,"issue_type":"task","created_at":"2025-11-23T14:01:01.57079-08:00","updated_at":"2025-11-23T14:01:01.57079-08:00","source_repo":"."} {"id":"bd-b55e2ac2","content_hash":"44122b61b1dcd06407ecf36f57577ea72c5df6dc8cc2a8c1b173b37d16a10267","title":"Fix autoimport tests for content-hash collision scoring","description":"## Overview\nThree autoimport tests are failing after bd-cbed9619.4 because they expect behavior based on the old reference-counting collision resolution, but the system now uses deterministic content-hash scoring.\n\n## Failing Tests\n1. `TestAutoImportMultipleCollisionsRemapped` - expects local versions preserved\n2. `TestAutoImportAllCollisionsRemapped` - expects local versions preserved \n3. `TestAutoImportCollisionRemapMultipleFields` - expects specific collision resolution behavior\n\n## Root Cause\nThese tests were written when ScoreCollisions used reference counting to determine which version to keep. Now it uses content-hash comparison (introduced in commit 2e87329), which produces different but deterministic results.\n\n## Example\nOld behavior: Issue with more references would be kept\nNew behavior: Issue with lexicographically lower content hash is kept\n\n## Solution\nUpdate each test to:\n1. Verify the new content-hash based behavior is correct\n2. Check that the remapped issue (not necessarily local/remote) has the expected content\n3. Ensure dependencies are preserved on the correct remapped issue\n\n## Acceptance Criteria\n- All three autoimport tests pass\n- Tests verify content-hash determinism (same collision always resolves the same way)\n- Tests check dependency preservation on remapped issues\n- Test documentation explains content-hash scoring expectations\n\n## Files to Modify\n- `cmd/bd/autoimport_collision_test.go`\n\n## Testing\nRun: `go test ./cmd/bd -run \"TestAutoImport.*Collision\" -v`","status":"open","priority":2,"issue_type":"task","created_at":"2025-10-28T19:17:28.358028-07:00","updated_at":"2025-10-30T17:12:58.179059-07:00","source_repo":"."} {"id":"bd-bt6y","content_hash":"462f08aa379cf2f196b4c0ca096271fa47ab5e1a18c5663c28d2d86fd02115cf","title":"Improve compact/daemon/merge documentation and UX","description":"Multiple documentation and UX issues encountered:\n1. \"bd compact --analyze\" fails with misleading \"requires SQLite storage\" error when daemon is running. Needs --no-daemon or better error.\n2. \"bd merge\" help text is outdated (refers to 3-way merge instead of issue merging).\n3. Daemon mode purpose isn't clear to local-only users.\n4. Compact/cleanup commands are hard to discover.\n\nProposed fixes:\n- Fix compact+daemon interaction or error message.\n- Update \"bd merge\" help text.\n- Add \"when to use daemon\" section to docs.\n- Add maintenance section to quickstart.\n","status":"open","priority":2,"issue_type":"task","created_at":"2025-11-20T18:55:43.637047-05:00","updated_at":"2025-11-20T18:55:43.637047-05:00","source_repo":"."} diff --git a/cmd/bd/doctor.go b/cmd/bd/doctor.go index f3d5c842..58250c00 100644 --- a/cmd/bd/doctor.go +++ b/cmd/bd/doctor.go @@ -198,6 +198,8 @@ func applyFixes(result doctorResult) { err = fix.MergeDriver(result.Path) case "Sync Branch Config": err = fix.SyncBranchConfig(result.Path) + case "Database Config": + err = fix.DatabaseConfig(result.Path) default: fmt.Printf(" ⚠ No automatic fix available for %s\n", check.Name) fmt.Printf(" Manual fix: %s\n", check.Fix) diff --git a/cmd/bd/doctor/fix/database_config.go b/cmd/bd/doctor/fix/database_config.go new file mode 100644 index 00000000..d07649d7 --- /dev/null +++ b/cmd/bd/doctor/fix/database_config.go @@ -0,0 +1,164 @@ +package fix + +import ( + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/steveyegge/beads/internal/configfile" +) + +// DatabaseConfig auto-detects and fixes metadata.json database/JSONL config mismatches. +// This fixes the issue where metadata.json gets recreated with wrong JSONL filename. +// +// bd-afd: bd doctor --fix should auto-fix metadata.json jsonl_export mismatch +func DatabaseConfig(path string) error { + if err := validateBeadsWorkspace(path); err != nil { + return err + } + + beadsDir := filepath.Join(path, ".beads") + + // Load existing config + cfg, err := configfile.Load(beadsDir) + if err != nil { + return fmt.Errorf("failed to load config: %w", err) + } + if cfg == nil { + // No config exists - nothing to fix + return fmt.Errorf("no metadata.json found") + } + + fixed := false + + // Check if configured JSONL exists + if cfg.JSONLExport != "" { + jsonlPath := cfg.JSONLPath(beadsDir) + if _, err := os.Stat(jsonlPath); os.IsNotExist(err) { + // Config points to non-existent file - try to find actual JSONL + actualJSONL := findActualJSONLFile(beadsDir) + if actualJSONL != "" { + fmt.Printf(" Updating jsonl_export: %s → %s\n", cfg.JSONLExport, actualJSONL) + cfg.JSONLExport = actualJSONL + fixed = true + } + } + } + + // Check if configured database exists + if cfg.Database != "" { + dbPath := cfg.DatabasePath(beadsDir) + if _, err := os.Stat(dbPath); os.IsNotExist(err) { + // Config points to non-existent file - try to find actual database + actualDB := findActualDBFile(beadsDir) + if actualDB != "" { + fmt.Printf(" Updating database: %s → %s\n", cfg.Database, actualDB) + cfg.Database = actualDB + fixed = true + } + } + } + + if !fixed { + return fmt.Errorf("no configuration mismatches detected") + } + + // Save updated config + if err := cfg.Save(beadsDir); err != nil { + return fmt.Errorf("failed to save config: %w", err) + } + + return nil +} + +// findActualJSONLFile scans .beads/ for the actual JSONL file in use. +// Prefers beads.jsonl over issues.jsonl, skips backups and merge artifacts. +func findActualJSONLFile(beadsDir string) string { + entries, err := os.ReadDir(beadsDir) + if err != nil { + return "" + } + + var candidates []string + for _, entry := range entries { + if entry.IsDir() { + continue + } + name := entry.Name() + + // Must end with .jsonl + if !strings.HasSuffix(name, ".jsonl") { + continue + } + + // Skip merge artifacts and backups + lowerName := strings.ToLower(name) + if strings.Contains(lowerName, "backup") || + strings.Contains(lowerName, ".orig") || + strings.Contains(lowerName, ".bak") || + strings.Contains(lowerName, "~") || + strings.HasPrefix(lowerName, "backup_") { + continue + } + + candidates = append(candidates, name) + } + + if len(candidates) == 0 { + return "" + } + + // Prefer beads.jsonl over issues.jsonl (canonical name) + for _, name := range candidates { + if name == "beads.jsonl" { + return name + } + } + + // Fall back to first candidate + return candidates[0] +} + +// findActualDBFile scans .beads/ for the actual database file in use. +// Prefers beads.db (canonical name), skips backups and vc.db. +func findActualDBFile(beadsDir string) string { + entries, err := os.ReadDir(beadsDir) + if err != nil { + return "" + } + + var candidates []string + for _, entry := range entries { + if entry.IsDir() { + continue + } + name := entry.Name() + + // Must end with .db + if !strings.HasSuffix(name, ".db") { + continue + } + + // Skip backups and vc.db + if strings.Contains(name, "backup") || name == "vc.db" { + continue + } + + candidates = append(candidates, name) + } + + if len(candidates) == 0 { + return "" + } + + // Prefer beads.db (canonical name) + for _, name := range candidates { + if name == "beads.db" { + return name + } + } + + // Fall back to first candidate + return candidates[0] +} diff --git a/cmd/bd/doctor/fix/database_config_test.go b/cmd/bd/doctor/fix/database_config_test.go new file mode 100644 index 00000000..e7b470f5 --- /dev/null +++ b/cmd/bd/doctor/fix/database_config_test.go @@ -0,0 +1,124 @@ +package fix + +import ( + "os" + "path/filepath" + "testing" + + "github.com/steveyegge/beads/internal/configfile" +) + +// TestDatabaseConfigFix_JSONLMismatch tests that DatabaseConfig fixes JSONL mismatches. +// bd-afd: Verify auto-fix for metadata.json jsonl_export mismatch +func TestDatabaseConfigFix_JSONLMismatch(t *testing.T) { + // Create temporary directory + tmpDir := t.TempDir() + beadsDir := filepath.Join(tmpDir, ".beads") + if err := os.Mkdir(beadsDir, 0755); err != nil { + t.Fatalf("Failed to create .beads dir: %v", err) + } + + // Create beads.jsonl file (actual JSONL) + jsonlPath := filepath.Join(beadsDir, "beads.jsonl") + if err := os.WriteFile(jsonlPath, []byte(`{"id":"test-123"}`), 0644); err != nil { + t.Fatalf("Failed to create beads.jsonl: %v", err) + } + + // Create metadata.json with wrong JSONL filename (issues.jsonl) + cfg := &configfile.Config{ + Database: "beads.db", + JSONLExport: "issues.jsonl", // Wrong - should be beads.jsonl + } + if err := cfg.Save(beadsDir); err != nil { + t.Fatalf("Failed to save config: %v", err) + } + + // Run the fix + if err := DatabaseConfig(tmpDir); err != nil { + t.Fatalf("DatabaseConfig failed: %v", err) + } + + // Verify the config was updated + updatedCfg, err := configfile.Load(beadsDir) + if err != nil { + t.Fatalf("Failed to load updated config: %v", err) + } + + if updatedCfg.JSONLExport != "beads.jsonl" { + t.Errorf("Expected JSONLExport to be 'beads.jsonl', got %q", updatedCfg.JSONLExport) + } +} + +// TestDatabaseConfigFix_PrefersBeadsJSONL tests that DatabaseConfig prefers beads.jsonl over issues.jsonl. +func TestDatabaseConfigFix_PrefersBeadsJSONL(t *testing.T) { + // Create temporary directory + tmpDir := t.TempDir() + beadsDir := filepath.Join(tmpDir, ".beads") + if err := os.Mkdir(beadsDir, 0755); err != nil { + t.Fatalf("Failed to create .beads dir: %v", err) + } + + // Create both beads.jsonl and issues.jsonl + beadsJSONL := filepath.Join(beadsDir, "beads.jsonl") + if err := os.WriteFile(beadsJSONL, []byte(`{"id":"test-123"}`), 0644); err != nil { + t.Fatalf("Failed to create beads.jsonl: %v", err) + } + + issuesJSONL := filepath.Join(beadsDir, "issues.jsonl") + if err := os.WriteFile(issuesJSONL, []byte(`{"id":"test-456"}`), 0644); err != nil { + t.Fatalf("Failed to create issues.jsonl: %v", err) + } + + // Create metadata.json with wrong JSONL filename (old.jsonl) + cfg := &configfile.Config{ + Database: "beads.db", + JSONLExport: "old.jsonl", // Wrong - should prefer beads.jsonl + } + if err := cfg.Save(beadsDir); err != nil { + t.Fatalf("Failed to save config: %v", err) + } + + // Run the fix + if err := DatabaseConfig(tmpDir); err != nil { + t.Fatalf("DatabaseConfig failed: %v", err) + } + + // Verify the config was updated to beads.jsonl (not issues.jsonl) + updatedCfg, err := configfile.Load(beadsDir) + if err != nil { + t.Fatalf("Failed to load updated config: %v", err) + } + + if updatedCfg.JSONLExport != "beads.jsonl" { + t.Errorf("Expected JSONLExport to be 'beads.jsonl', got %q", updatedCfg.JSONLExport) + } +} + +// TestFindActualJSONLFile_SkipsBackups tests that backup files are skipped. +func TestFindActualJSONLFile_SkipsBackups(t *testing.T) { + // Create temporary directory + tmpDir := t.TempDir() + + // Create beads.jsonl and various backup files + files := []string{ + "beads.jsonl", + "beads.jsonl.backup", + "backup_beads.jsonl", + "beads.jsonl.orig", + "beads.jsonl.bak", + "beads.jsonl~", + } + + for _, name := range files { + path := filepath.Join(tmpDir, name) + if err := os.WriteFile(path, []byte(`{"id":"test"}`), 0644); err != nil { + t.Fatalf("Failed to create %s: %v", name, err) + } + } + + // findActualJSONLFile should return beads.jsonl (not backups) + result := findActualJSONLFile(tmpDir) + if result != "beads.jsonl" { + t.Errorf("Expected 'beads.jsonl', got %q", result) + } +} diff --git a/cmd/bd/doctor/legacy.go b/cmd/bd/doctor/legacy.go index 6ad7f631..dafec81f 100644 --- a/cmd/bd/doctor/legacy.go +++ b/cmd/bd/doctor/legacy.go @@ -252,7 +252,7 @@ func CheckDatabaseConfig(repoPath string) DoctorCheck { Status: "warning", Message: "Configuration mismatch detected", Detail: strings.Join(issues, "\n "), - Fix: "Update configuration in .beads/metadata.json:\n" + + Fix: "Run 'bd doctor --fix' to auto-detect and fix mismatches, or manually:\n" + " 1. Check which files are actually being used\n" + " 2. Update metadata.json to match the actual filenames\n" + " 3. Or rename the files to match the configuration", diff --git a/cmd/bd/version_tracking.go b/cmd/bd/version_tracking.go index ab8dae13..815c4b2d 100644 --- a/cmd/bd/version_tracking.go +++ b/cmd/bd/version_tracking.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "os" + "strings" "github.com/steveyegge/beads/internal/beads" "github.com/steveyegge/beads/internal/configfile" @@ -34,6 +35,13 @@ func trackBdVersion() { // No config file yet - create one with current version cfg = configfile.DefaultConfig() cfg.LastBdVersion = Version + + // bd-afd: Auto-detect actual JSONL file instead of using hardcoded default + // This prevents mismatches when metadata.json gets deleted (git clean, merge conflict, etc.) + if actualJSONL := findActualJSONLFile(beadsDir); actualJSONL != "" { + cfg.JSONLExport = actualJSONL + } + _ = cfg.Save(beadsDir) // Best effort return } @@ -175,6 +183,57 @@ func findSubstring(haystack, needle string) int { return -1 } +// findActualJSONLFile scans .beads/ for the actual JSONL file in use. +// Prefers beads.jsonl over issues.jsonl, skips backups and merge artifacts. +// Returns empty string if no JSONL file is found. +// +// bd-afd: Auto-detect JSONL file to prevent metadata.json mismatches +func findActualJSONLFile(beadsDir string) string { + entries, err := os.ReadDir(beadsDir) + if err != nil { + return "" + } + + var candidates []string + for _, entry := range entries { + if entry.IsDir() { + continue + } + name := entry.Name() + + // Must end with .jsonl + if !strings.HasSuffix(name, ".jsonl") { + continue + } + + // Skip merge artifacts and backups + lowerName := strings.ToLower(name) + if strings.Contains(lowerName, "backup") || + strings.Contains(lowerName, ".orig") || + strings.Contains(lowerName, ".bak") || + strings.Contains(lowerName, "~") || + strings.HasPrefix(lowerName, "backup_") { + continue + } + + candidates = append(candidates, name) + } + + if len(candidates) == 0 { + return "" + } + + // Prefer beads.jsonl over issues.jsonl (canonical name) + for _, name := range candidates { + if name == "beads.jsonl" { + return name + } + } + + // Fall back to first candidate (including issues.jsonl if present) + return candidates[0] +} + // autoMigrateOnVersionBump automatically migrates the database when CLI version changes. // This function is best-effort - failures are silent to avoid disrupting commands. // Called from PersistentPreRun after daemon check but before opening DB for main operation. diff --git a/internal/beads/beads.go b/internal/beads/beads.go index a5dd52e5..24541e06 100644 --- a/internal/beads/beads.go +++ b/internal/beads/beads.go @@ -222,7 +222,7 @@ func FindBeadsDir() string { // FindJSONLPath returns the expected JSONL file path for the given database path. // It searches for existing *.jsonl files in the database directory and returns -// the first one found, or defaults to "beads.jsonl". +// the first one found, preferring beads.jsonl over issues.jsonl (bd-afd). // // This function does not create directories or files - it only discovers paths. // Use this when you need to know where bd stores its JSONL export. @@ -238,12 +238,18 @@ func FindJSONLPath(dbPath string) string { pattern := filepath.Join(dbDir, "*.jsonl") matches, err := filepath.Glob(pattern) if err == nil && len(matches) > 0 { - // Return the first .jsonl file found + // bd-afd: Prefer beads.jsonl over issues.jsonl (canonical name) + for _, match := range matches { + if filepath.Base(match) == "beads.jsonl" { + return match + } + } + // Return the first .jsonl file found if beads.jsonl not present return matches[0] } - // Default to issues.jsonl - return filepath.Join(dbDir, "issues.jsonl") + // bd-afd: Default to beads.jsonl (was issues.jsonl) + return filepath.Join(dbDir, "beads.jsonl") } // DatabaseInfo contains information about a discovered beads database diff --git a/internal/configfile/configfile.go b/internal/configfile/configfile.go index 7e22f782..54407efa 100644 --- a/internal/configfile/configfile.go +++ b/internal/configfile/configfile.go @@ -18,7 +18,7 @@ type Config struct { func DefaultConfig() *Config { return &Config{ Database: "beads.db", - JSONLExport: "issues.jsonl", + JSONLExport: "beads.jsonl", // Default to canonical name (was issues.jsonl) } } diff --git a/internal/configfile/configfile_test.go b/internal/configfile/configfile_test.go index 8545cef5..03f8bdb2 100644 --- a/internal/configfile/configfile_test.go +++ b/internal/configfile/configfile_test.go @@ -13,8 +13,9 @@ func TestDefaultConfig(t *testing.T) { t.Errorf("Database = %q, want beads.db", cfg.Database) } - if cfg.JSONLExport != "issues.jsonl" { - t.Errorf("JSONLExport = %q, want issues.jsonl", cfg.JSONLExport) + // bd-afd: Default changed from issues.jsonl to beads.jsonl (canonical name) + if cfg.JSONLExport != "beads.jsonl" { + t.Errorf("JSONLExport = %q, want beads.jsonl", cfg.JSONLExport) } }