Fix: Change default JSONL filename from beads.jsonl to issues.jsonl

The canonical beads database name is issues.jsonl. Tens of thousands of users
have issues.jsonl, and beads.jsonl was only used by the Beads project itself
due to git history pollution.

Changes:
- Updated bd doctor to warn about beads.jsonl instead of issues.jsonl
- Changed default config from beads.jsonl to issues.jsonl
- Reversed precedence in checkGitForIssues to prefer issues.jsonl
- Updated git merge driver config to use issues.jsonl
- Updated all tests to expect issues.jsonl as the default

issues.jsonl is now the canonical default; beads.jsonl is legacy

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-11-21 23:34:22 -08:00
parent 3573470d6b
commit c4c5c8063a
16 changed files with 99 additions and 85 deletions

12
.beads/cost_state.json Normal file
View File

@@ -0,0 +1,12 @@
{
"hourly_tokens_used": 84530,
"hourly_cost_used": 0.39143399999999995,
"window_start_time": "2025-11-21T22:59:34.058436-08:00",
"issue_tokens_used": {
"SYSTEM": 50702,
"bd-9f86-baseline-test": 33055
},
"total_tokens_used": 84530,
"total_cost_used": 0.39143399999999995,
"last_updated": "2025-11-21T23:28:18.766601-08:00"
}

View File

@@ -85,10 +85,10 @@ func checkGitForIssues() (int, string) {
return 0, "" return 0, ""
} }
// Try canonical JSONL filenames in precedence order // Try canonical JSONL filenames in precedence order (issues.jsonl is canonical)
candidates := []string{ candidates := []string{
filepath.Join(relBeads, "beads.jsonl"),
filepath.Join(relBeads, "issues.jsonl"), filepath.Join(relBeads, "issues.jsonl"),
filepath.Join(relBeads, "beads.jsonl"),
} }
for _, relPath := range candidates { for _, relPath := range candidates {

View File

@@ -19,8 +19,8 @@ func TestMultiWorkspaceDeletionSync(t *testing.T) {
cloneADir := t.TempDir() cloneADir := t.TempDir()
cloneBDir := t.TempDir() cloneBDir := t.TempDir()
cloneAJSONL := filepath.Join(cloneADir, "beads.jsonl") cloneAJSONL := filepath.Join(cloneADir, "issues.jsonl")
cloneBJSONL := filepath.Join(cloneBDir, "beads.jsonl") cloneBJSONL := filepath.Join(cloneBDir, "issues.jsonl")
cloneADB := filepath.Join(cloneADir, "beads.db") cloneADB := filepath.Join(cloneADir, "beads.db")
cloneBDB := filepath.Join(cloneBDir, "beads.db") cloneBDB := filepath.Join(cloneBDir, "beads.db")
@@ -177,7 +177,7 @@ func TestMultiWorkspaceDeletionSync(t *testing.T) {
// Remote deletes an issue, but local has modified it // Remote deletes an issue, but local has modified it
func TestDeletionWithLocalModification(t *testing.T) { func TestDeletionWithLocalModification(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
jsonlPath := filepath.Join(dir, "beads.jsonl") jsonlPath := filepath.Join(dir, "issues.jsonl")
dbPath := filepath.Join(dir, "beads.db") dbPath := filepath.Join(dir, "beads.db")
ctx := context.Background() ctx := context.Background()
@@ -343,7 +343,7 @@ func TestComputeAcceptedDeletions_LocallyModified(t *testing.T) {
// TestSnapshotManagement tests the snapshot file lifecycle // TestSnapshotManagement tests the snapshot file lifecycle
func TestSnapshotManagement(t *testing.T) { func TestSnapshotManagement(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
jsonlPath := filepath.Join(dir, "beads.jsonl") jsonlPath := filepath.Join(dir, "issues.jsonl")
// Write initial JSONL // Write initial JSONL
content := `{"id":"bd-1","title":"Test"} content := `{"id":"bd-1","title":"Test"}

View File

@@ -103,20 +103,20 @@ func CheckAgentDocumentation(repoPath string) DoctorCheck {
} }
} }
// CheckLegacyJSONLFilename detects if project is using legacy issues.jsonl // CheckLegacyJSONLFilename detects if project is using non-standard beads.jsonl
// instead of the canonical beads.jsonl filename. // instead of the canonical issues.jsonl filename.
func CheckLegacyJSONLFilename(repoPath string) DoctorCheck { func CheckLegacyJSONLFilename(repoPath string) DoctorCheck {
beadsDir := filepath.Join(repoPath, ".beads") beadsDir := filepath.Join(repoPath, ".beads")
var jsonlFiles []string var jsonlFiles []string
hasIssuesJSON := false hasBeadsJSON := false
for _, name := range []string{"issues.jsonl", "beads.jsonl"} { for _, name := range []string{"issues.jsonl", "beads.jsonl"} {
jsonlPath := filepath.Join(beadsDir, name) jsonlPath := filepath.Join(beadsDir, name)
if _, err := os.Stat(jsonlPath); err == nil { if _, err := os.Stat(jsonlPath); err == nil {
jsonlFiles = append(jsonlFiles, name) jsonlFiles = append(jsonlFiles, name)
if name == "issues.jsonl" { if name == "beads.jsonl" {
hasIssuesJSON = true hasBeadsJSON = true
} }
} }
} }
@@ -130,13 +130,13 @@ func CheckLegacyJSONLFilename(repoPath string) DoctorCheck {
} }
if len(jsonlFiles) == 1 { if len(jsonlFiles) == 1 {
// Single JSONL file - check if it's the legacy name // Single JSONL file - check if it's the non-standard name
if hasIssuesJSON { if hasBeadsJSON {
return DoctorCheck{ return DoctorCheck{
Name: "JSONL Files", Name: "JSONL Files",
Status: "warning", Status: "warning",
Message: "Using legacy JSONL filename: issues.jsonl", Message: "Using non-standard JSONL filename: beads.jsonl",
Fix: "Run 'git mv .beads/issues.jsonl .beads/beads.jsonl' to use canonical name (matches beads.db)", Fix: "Run 'git mv .beads/beads.jsonl .beads/issues.jsonl' to use canonical name",
} }
} }
return DoctorCheck{ return DoctorCheck{
@@ -151,6 +151,6 @@ func CheckLegacyJSONLFilename(repoPath string) DoctorCheck {
Name: "JSONL Files", Name: "JSONL Files",
Status: "warning", Status: "warning",
Message: fmt.Sprintf("Multiple JSONL files found: %s", strings.Join(jsonlFiles, ", ")), Message: fmt.Sprintf("Multiple JSONL files found: %s", strings.Join(jsonlFiles, ", ")),
Fix: "Run 'git rm .beads/issues.jsonl' to standardize on beads.jsonl (canonical name)", Fix: "Run 'git rm .beads/beads.jsonl' to standardize on issues.jsonl (canonical name)",
} }
} }

View File

@@ -190,14 +190,14 @@ func TestCheckLegacyJSONLFilename(t *testing.T) {
expectWarning: false, expectWarning: false,
}, },
{ {
name: "canonical beads.jsonl", name: "canonical issues.jsonl",
files: []string{"beads.jsonl"}, files: []string{"issues.jsonl"},
expectedStatus: "ok", expectedStatus: "ok",
expectWarning: false, expectWarning: false,
}, },
{ {
name: "legacy issues.jsonl", name: "non-standard beads.jsonl",
files: []string{"issues.jsonl"}, files: []string{"beads.jsonl"},
expectedStatus: "warning", expectedStatus: "warning",
expectWarning: true, expectWarning: true,
}, },

View File

@@ -812,12 +812,14 @@ func installMergeDriver() error {
} }
// Check if beads merge driver is already configured // Check if beads merge driver is already configured
hasBeadsMerge := strings.Contains(existingContent, ".beads/beads.jsonl") && // Check for either pattern (issues.jsonl is canonical, beads.jsonl is legacy)
hasBeadsMerge := (strings.Contains(existingContent, ".beads/issues.jsonl") ||
strings.Contains(existingContent, ".beads/beads.jsonl")) &&
strings.Contains(existingContent, "merge=beads") strings.Contains(existingContent, "merge=beads")
if !hasBeadsMerge { if !hasBeadsMerge {
// Append beads merge driver configuration // Append beads merge driver configuration (issues.jsonl is canonical)
beadsMergeAttr := "\n# Use bd merge for beads JSONL files\n.beads/beads.jsonl merge=beads\n" beadsMergeAttr := "\n# Use bd merge for beads JSONL files\n.beads/issues.jsonl merge=beads\n"
newContent := existingContent newContent := existingContent
if !strings.HasSuffix(newContent, "\n") && len(newContent) > 0 { if !strings.HasSuffix(newContent, "\n") && len(newContent) > 0 {

View File

@@ -526,7 +526,7 @@ func TestInitMergeDriverAutoConfiguration(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Failed to read .gitattributes: %v", err) t.Fatalf("Failed to read .gitattributes: %v", err)
} }
if !strings.Contains(string(content), ".beads/beads.jsonl merge=beads") { if !strings.Contains(string(content), ".beads/issues.jsonl merge=beads") {
t.Error(".gitattributes should contain merge driver configuration") t.Error(".gitattributes should contain merge driver configuration")
} }
}) })
@@ -633,7 +633,7 @@ func TestInitMergeDriverAutoConfiguration(t *testing.T) {
// Create .gitattributes with merge driver // Create .gitattributes with merge driver
gitattrsPath := filepath.Join(tmpDir, ".gitattributes") gitattrsPath := filepath.Join(tmpDir, ".gitattributes")
initialContent := "# Existing config\n.beads/beads.jsonl merge=beads\n" initialContent := "# Existing config\n.beads/issues.jsonl merge=beads\n"
if err := os.WriteFile(gitattrsPath, []byte(initialContent), 0644); err != nil { if err := os.WriteFile(gitattrsPath, []byte(initialContent), 0644); err != nil {
t.Fatalf("Failed to create .gitattributes: %v", err) t.Fatalf("Failed to create .gitattributes: %v", err)
} }
@@ -661,7 +661,7 @@ func TestInitMergeDriverAutoConfiguration(t *testing.T) {
contentStr := string(content) contentStr := string(content)
// Count occurrences - should only appear once // Count occurrences - should only appear once
count := strings.Count(contentStr, ".beads/beads.jsonl merge=beads") count := strings.Count(contentStr, ".beads/issues.jsonl merge=beads")
if count != 1 { if count != 1 {
t.Errorf("Expected .gitattributes to contain merge config exactly once, found %d times", count) t.Errorf("Expected .gitattributes to contain merge config exactly once, found %d times", count)
} }
@@ -727,13 +727,13 @@ func TestInitMergeDriverAutoConfiguration(t *testing.T) {
} }
// Should contain beads config // Should contain beads config
if !strings.Contains(contentStr, ".beads/beads.jsonl merge=beads") { if !strings.Contains(contentStr, ".beads/issues.jsonl merge=beads") {
t.Error(".gitattributes should contain beads merge config") t.Error(".gitattributes should contain beads merge config")
} }
// Beads config should come after existing content // Beads config should come after existing content
txtIdx := strings.Index(contentStr, "*.txt") txtIdx := strings.Index(contentStr, "*.txt")
beadsIdx := strings.Index(contentStr, ".beads/beads.jsonl") beadsIdx := strings.Index(contentStr, ".beads/issues.jsonl")
if txtIdx >= beadsIdx { if txtIdx >= beadsIdx {
t.Error("Beads config should be appended after existing content") t.Error("Beads config should be appended after existing content")
} }

View File

@@ -177,8 +177,8 @@ func TestAutoFlushJSONLContent(t *testing.T) {
dbPath = filepath.Join(tmpDir, "test.db") dbPath = filepath.Join(tmpDir, "test.db")
// The actual JSONL path - findJSONLPath() will determine this // The actual JSONL path - findJSONLPath() will determine this
// but in tests it appears to be beads.jsonl in the same directory as the db // but in tests it appears to be issues.jsonl in the same directory as the db
expectedJSONLPath := filepath.Join(tmpDir, "beads.jsonl") expectedJSONLPath := filepath.Join(tmpDir, "issues.jsonl")
// Create store // Create store
testStore := newTestStore(t, dbPath) testStore := newTestStore(t, dbPath)

View File

@@ -28,7 +28,7 @@ Designed to work as a git merge driver. Configure with:
git config merge.beads.driver "bd merge %A %O %A %B" git config merge.beads.driver "bd merge %A %O %A %B"
git config merge.beads.name "bd JSONL merge driver" git config merge.beads.name "bd JSONL merge driver"
echo ".beads/beads.jsonl merge=beads" >> .gitattributes echo ".beads/issues.jsonl merge=beads" >> .gitattributes
Or use 'bd init' which automatically configures the merge driver. Or use 'bd init' which automatically configures the merge driver.

View File

@@ -52,7 +52,7 @@ func TestCleanupMergeArtifacts_CommandInjectionPrevention(t *testing.T) {
}, },
{ {
name: "normal backup file", name: "normal backup file",
filename: "beads.jsonl.backup", filename: "issues.jsonl.backup",
wantSafe: true, wantSafe: true,
}, },
{ {
@@ -89,7 +89,7 @@ func TestCleanupMergeArtifacts_CommandInjectionPrevention(t *testing.T) {
} }
// Create output path // Create output path
outputPath := filepath.Join(beadsDir, "beads.jsonl") outputPath := filepath.Join(beadsDir, "issues.jsonl")
if err := os.WriteFile(outputPath, []byte("{}"), 0644); err != nil { if err := os.WriteFile(outputPath, []byte("{}"), 0644); err != nil {
t.Fatalf("Failed to create output file: %v", err) t.Fatalf("Failed to create output file: %v", err)
} }
@@ -129,14 +129,14 @@ func TestCleanupMergeArtifacts_OnlyBackupFiles(t *testing.T) {
// Create various files // Create various files
files := map[string]bool{ files := map[string]bool{
"beads.jsonl": false, // Should NOT be removed "issues.jsonl": false, // Should NOT be removed
"beads.db": false, // Should NOT be removed "beads.db": false, // Should NOT be removed
"backup.jsonl": true, // Should be removed "backup.jsonl": true, // Should be removed
"beads.jsonl.backup": true, // Should be removed "issues.jsonl.backup": true, // Should be removed
"BACKUP_FILE": true, // Should be removed (case-insensitive) "BACKUP_FILE": true, // Should be removed (case-insensitive)
"my_backup_2024.txt": true, // Should be removed "my_backup_2024.txt": true, // Should be removed
"important_data.jsonl": false, // Should NOT be removed "important_data.jsonl": false, // Should NOT be removed
"beads.jsonl.bak": false, // Should NOT be removed (no "backup") "issues.jsonl.bak": false, // Should NOT be removed (no "backup")
} }
for filename := range files { for filename := range files {
@@ -147,7 +147,7 @@ func TestCleanupMergeArtifacts_OnlyBackupFiles(t *testing.T) {
} }
// Create output path // Create output path
outputPath := filepath.Join(beadsDir, "beads.jsonl") outputPath := filepath.Join(beadsDir, "issues.jsonl")
// Run cleanup // Run cleanup
cleanupMergeArtifacts(outputPath, false) cleanupMergeArtifacts(outputPath, false)
@@ -192,7 +192,7 @@ func TestCleanupMergeArtifacts_GitRmSafety(t *testing.T) {
t.Fatalf("Failed to create backup file: %v", err) t.Fatalf("Failed to create backup file: %v", err)
} }
outputPath := filepath.Join(beadsDir, "beads.jsonl") outputPath := filepath.Join(beadsDir, "issues.jsonl")
if err := os.WriteFile(outputPath, []byte("{}"), 0644); err != nil { if err := os.WriteFile(outputPath, []byte("{}"), 0644); err != nil {
t.Fatalf("Failed to create output file: %v", err) t.Fatalf("Failed to create output file: %v", err)
} }

View File

@@ -47,7 +47,7 @@ func testFreshCloneAutoImport(t *testing.T) {
runCmd(t, dir, "git", "config", "user.email", "test@example.com") runCmd(t, dir, "git", "config", "user.email", "test@example.com")
runCmd(t, dir, "git", "config", "user.name", "Test User") runCmd(t, dir, "git", "config", "user.name", "Test User")
// Create .beads directory with beads.jsonl (use forward slashes for git) // Create .beads directory with issues.jsonl (canonical name)
beadsDir := filepath.Join(dir, ".beads") beadsDir := filepath.Join(dir, ".beads")
if err := os.MkdirAll(beadsDir, 0755); err != nil { if err := os.MkdirAll(beadsDir, 0755); err != nil {
t.Fatalf("Failed to create .beads dir: %v", err) t.Fatalf("Failed to create .beads dir: %v", err)
@@ -63,13 +63,13 @@ func testFreshCloneAutoImport(t *testing.T) {
IssueType: types.TypeTask, IssueType: types.TypeTask,
} }
jsonlPath := filepath.Join(beadsDir, "beads.jsonl") jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
if err := writeJSONL(jsonlPath, []*types.Issue{issue}); err != nil { if err := writeJSONL(jsonlPath, []*types.Issue{issue}); err != nil {
t.Fatalf("Failed to write JSONL: %v", err) t.Fatalf("Failed to write JSONL: %v", err)
} }
// Commit to git (use forward slashes for git path) // Commit to git (use forward slashes for git path)
runCmd(t, dir, "git", "add", ".beads/beads.jsonl") runCmd(t, dir, "git", "add", ".beads/issues.jsonl")
runCmd(t, dir, "git", "commit", "-m", "Initial commit") runCmd(t, dir, "git", "commit", "-m", "Initial commit")
// Remove database to simulate fresh clone // Remove database to simulate fresh clone
@@ -88,7 +88,7 @@ func testFreshCloneAutoImport(t *testing.T) {
t.Fatalf("Failed to set prefix: %v", err) t.Fatalf("Failed to set prefix: %v", err)
} }
// Test checkGitForIssues detects beads.jsonl // Test checkGitForIssues detects issues.jsonl
originalDir, _ := os.Getwd() originalDir, _ := os.Getwd()
os.Chdir(dir) os.Chdir(dir)
defer os.Chdir(originalDir) defer os.Chdir(originalDir)
@@ -98,7 +98,7 @@ func testFreshCloneAutoImport(t *testing.T) {
t.Errorf("Expected 1 issue in git, got %d", count) t.Errorf("Expected 1 issue in git, got %d", count)
} }
// Normalize path for comparison (handle both forward and backslash) // Normalize path for comparison (handle both forward and backslash)
expectedPath := normalizeGitPath(".beads/beads.jsonl") expectedPath := normalizeGitPath(".beads/issues.jsonl")
if normalizeGitPath(path) != expectedPath { if normalizeGitPath(path) != expectedPath {
t.Errorf("Expected path %s, got %s", expectedPath, path) t.Errorf("Expected path %s, got %s", expectedPath, path)
} }
@@ -127,7 +127,7 @@ func testDatabaseRemovalScenario(t *testing.T) {
runCmd(t, dir, "git", "config", "user.email", "test@example.com") runCmd(t, dir, "git", "config", "user.email", "test@example.com")
runCmd(t, dir, "git", "config", "user.name", "Test User") runCmd(t, dir, "git", "config", "user.name", "Test User")
// Create .beads directory with beads.jsonl // Create .beads directory with issues.jsonl (canonical name)
beadsDir := filepath.Join(dir, ".beads") beadsDir := filepath.Join(dir, ".beads")
if err := os.MkdirAll(beadsDir, 0755); err != nil { if err := os.MkdirAll(beadsDir, 0755); err != nil {
t.Fatalf("Failed to create .beads dir: %v", err) t.Fatalf("Failed to create .beads dir: %v", err)
@@ -151,13 +151,13 @@ func testDatabaseRemovalScenario(t *testing.T) {
}, },
} }
jsonlPath := filepath.Join(beadsDir, "beads.jsonl") jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
if err := writeJSONL(jsonlPath, issues); err != nil { if err := writeJSONL(jsonlPath, issues); err != nil {
t.Fatalf("Failed to write JSONL: %v", err) t.Fatalf("Failed to write JSONL: %v", err)
} }
// Commit to git // Commit to git
runCmd(t, dir, "git", "add", ".beads/beads.jsonl") runCmd(t, dir, "git", "add", ".beads/issues.jsonl")
runCmd(t, dir, "git", "commit", "-m", "Add issues") runCmd(t, dir, "git", "commit", "-m", "Add issues")
// Simulate rm -rf .beads/ // Simulate rm -rf .beads/
@@ -169,12 +169,12 @@ func testDatabaseRemovalScenario(t *testing.T) {
os.Chdir(dir) os.Chdir(dir)
defer os.Chdir(originalDir) defer os.Chdir(originalDir)
// Test checkGitForIssues finds beads.jsonl (not issues.jsonl) // Test checkGitForIssues finds issues.jsonl (canonical name)
count, path := checkGitForIssues() count, path := checkGitForIssues()
if count != 2 { if count != 2 {
t.Errorf("Expected 2 issues in git, got %d", count) t.Errorf("Expected 2 issues in git, got %d", count)
} }
expectedPath := normalizeGitPath(".beads/beads.jsonl") expectedPath := normalizeGitPath(".beads/issues.jsonl")
if normalizeGitPath(path) != expectedPath { if normalizeGitPath(path) != expectedPath {
t.Errorf("Expected %s, got %s", expectedPath, path) t.Errorf("Expected %s, got %s", expectedPath, path)
} }
@@ -197,8 +197,8 @@ func testDatabaseRemovalScenario(t *testing.T) {
} }
// Verify correct filename was detected // Verify correct filename was detected
if filepath.Base(path) != "beads.jsonl" { if filepath.Base(path) != "issues.jsonl" {
t.Errorf("Should have imported from beads.jsonl, got %s", path) t.Errorf("Should have imported from issues.jsonl, got %s", path)
} }
// Verify stats show >0 issues // Verify stats show >0 issues
@@ -286,7 +286,7 @@ func testLegacyFilenameSupport(t *testing.T) {
} }
} }
// testPrecedenceTest verifies beads.jsonl is preferred over issues.jsonl // testPrecedenceTest verifies issues.jsonl is preferred over beads.jsonl
func testPrecedenceTest(t *testing.T) { func testPrecedenceTest(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
@@ -301,21 +301,21 @@ func testPrecedenceTest(t *testing.T) {
t.Fatalf("Failed to create .beads dir: %v", err) t.Fatalf("Failed to create .beads dir: %v", err)
} }
// Create beads.jsonl with 2 issues // Create issues.jsonl with 2 issues (canonical, should be preferred)
beadsIssues := []*types.Issue{ canonicalIssues := []*types.Issue{
{ID: "test-1", Title: "From beads.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask}, {ID: "test-1", Title: "From issues.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask},
{ID: "test-2", Title: "Also from beads.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask}, {ID: "test-2", Title: "Also from issues.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask},
} }
if err := writeJSONL(filepath.Join(beadsDir, "beads.jsonl"), beadsIssues); err != nil { if err := writeJSONL(filepath.Join(beadsDir, "issues.jsonl"), canonicalIssues); err != nil {
t.Fatalf("Failed to write beads.jsonl: %v", err) t.Fatalf("Failed to write issues.jsonl: %v", err)
} }
// Create issues.jsonl with 1 issue (should be ignored) // Create beads.jsonl with 1 issue (should be ignored)
legacyIssues := []*types.Issue{ legacyIssues := []*types.Issue{
{ID: "test-99", Title: "From issues.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask}, {ID: "test-99", Title: "From beads.jsonl", Status: types.StatusOpen, Priority: 1, IssueType: types.TypeTask},
} }
if err := writeJSONL(filepath.Join(beadsDir, "issues.jsonl"), legacyIssues); err != nil { if err := writeJSONL(filepath.Join(beadsDir, "beads.jsonl"), legacyIssues); err != nil {
t.Fatalf("Failed to write issues.jsonl: %v", err) t.Fatalf("Failed to write beads.jsonl: %v", err)
} }
// Commit both files // Commit both files
@@ -327,14 +327,14 @@ func testPrecedenceTest(t *testing.T) {
os.Chdir(dir) os.Chdir(dir)
defer os.Chdir(originalDir) defer os.Chdir(originalDir)
// Test checkGitForIssues prefers beads.jsonl // Test checkGitForIssues prefers issues.jsonl
count, path := checkGitForIssues() count, path := checkGitForIssues()
if count != 2 { if count != 2 {
t.Errorf("Expected 2 issues (from beads.jsonl), got %d", count) t.Errorf("Expected 2 issues (from issues.jsonl), got %d", count)
} }
expectedPath := normalizeGitPath(".beads/beads.jsonl") expectedPath := normalizeGitPath(".beads/issues.jsonl")
if normalizeGitPath(path) != expectedPath { if normalizeGitPath(path) != expectedPath {
t.Errorf("Expected beads.jsonl to be preferred, got %s", path) t.Errorf("Expected issues.jsonl to be preferred, got %s", path)
} }
} }
@@ -347,7 +347,7 @@ func testInitSafetyCheck(t *testing.T) {
runCmd(t, dir, "git", "config", "user.email", "test@example.com") runCmd(t, dir, "git", "config", "user.email", "test@example.com")
runCmd(t, dir, "git", "config", "user.name", "Test User") runCmd(t, dir, "git", "config", "user.name", "Test User")
// Create .beads directory with beads.jsonl // Create .beads directory with issues.jsonl (canonical name)
beadsDir := filepath.Join(dir, ".beads") beadsDir := filepath.Join(dir, ".beads")
if err := os.MkdirAll(beadsDir, 0755); err != nil { if err := os.MkdirAll(beadsDir, 0755); err != nil {
t.Fatalf("Failed to create .beads dir: %v", err) t.Fatalf("Failed to create .beads dir: %v", err)
@@ -361,13 +361,13 @@ func testInitSafetyCheck(t *testing.T) {
IssueType: types.TypeTask, IssueType: types.TypeTask,
} }
jsonlPath := filepath.Join(beadsDir, "beads.jsonl") jsonlPath := filepath.Join(beadsDir, "issues.jsonl")
if err := writeJSONL(jsonlPath, []*types.Issue{issue}); err != nil { if err := writeJSONL(jsonlPath, []*types.Issue{issue}); err != nil {
t.Fatalf("Failed to write JSONL: %v", err) t.Fatalf("Failed to write JSONL: %v", err)
} }
// Commit to git // Commit to git
runCmd(t, dir, "git", "add", ".beads/beads.jsonl") runCmd(t, dir, "git", "add", ".beads/issues.jsonl")
runCmd(t, dir, "git", "commit", "-m", "Add issue") runCmd(t, dir, "git", "commit", "-m", "Add issue")
// Change to test directory // Change to test directory
@@ -398,7 +398,7 @@ func testInitSafetyCheck(t *testing.T) {
if recheck == 0 { if recheck == 0 {
t.Error("Safety check should have detected issues in git") t.Error("Safety check should have detected issues in git")
} }
expectedPath := normalizeGitPath(".beads/beads.jsonl") expectedPath := normalizeGitPath(".beads/issues.jsonl")
if normalizeGitPath(recheckPath) != expectedPath { if normalizeGitPath(recheckPath) != expectedPath {
t.Errorf("Safety check found wrong path: %s", recheckPath) t.Errorf("Safety check found wrong path: %s", recheckPath)
} }

View File

@@ -33,7 +33,7 @@ func setupTestStore(t *testing.T, dbPath string) *sqlite.SQLiteStorage {
func TestDBNeedsExport_InSync(t *testing.T) { func TestDBNeedsExport_InSync(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "beads.db") dbPath := filepath.Join(tmpDir, "beads.db")
jsonlPath := filepath.Join(tmpDir, "beads.jsonl") jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
store := setupTestStore(t, dbPath) store := setupTestStore(t, dbPath)
defer store.Close() defer store.Close()
@@ -81,7 +81,7 @@ func TestDBNeedsExport_InSync(t *testing.T) {
func TestDBNeedsExport_DBNewer(t *testing.T) { func TestDBNeedsExport_DBNewer(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "beads.db") dbPath := filepath.Join(tmpDir, "beads.db")
jsonlPath := filepath.Join(tmpDir, "beads.jsonl") jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
store := setupTestStore(t, dbPath) store := setupTestStore(t, dbPath)
defer store.Close() defer store.Close()
@@ -132,7 +132,7 @@ func TestDBNeedsExport_DBNewer(t *testing.T) {
func TestDBNeedsExport_CountMismatch(t *testing.T) { func TestDBNeedsExport_CountMismatch(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "beads.db") dbPath := filepath.Join(tmpDir, "beads.db")
jsonlPath := filepath.Join(tmpDir, "beads.jsonl") jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
store := setupTestStore(t, dbPath) store := setupTestStore(t, dbPath)
defer store.Close() defer store.Close()
@@ -189,7 +189,7 @@ func TestDBNeedsExport_CountMismatch(t *testing.T) {
func TestDBNeedsExport_NoJSONL(t *testing.T) { func TestDBNeedsExport_NoJSONL(t *testing.T) {
tmpDir := t.TempDir() tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "beads.db") dbPath := filepath.Join(tmpDir, "beads.db")
jsonlPath := filepath.Join(tmpDir, "beads.jsonl") jsonlPath := filepath.Join(tmpDir, "issues.jsonl")
store := setupTestStore(t, dbPath) store := setupTestStore(t, dbPath)
defer store.Close() defer store.Close()

View File

@@ -242,8 +242,8 @@ func FindJSONLPath(dbPath string) string {
return matches[0] return matches[0]
} }
// Default to beads.jsonl // Default to issues.jsonl
return filepath.Join(dbDir, "beads.jsonl") return filepath.Join(dbDir, "issues.jsonl")
} }
// DatabaseInfo contains information about a discovered beads database // DatabaseInfo contains information about a discovered beads database

View File

@@ -168,9 +168,9 @@ func TestFindJSONLPathDefault(t *testing.T) {
// Create a fake database path (no .jsonl files exist) // Create a fake database path (no .jsonl files exist)
dbPath := filepath.Join(tmpDir, "test.db") dbPath := filepath.Join(tmpDir, "test.db")
// Should return default beads.jsonl // Should return default issues.jsonl
result := FindJSONLPath(dbPath) result := FindJSONLPath(dbPath)
expected := filepath.Join(tmpDir, "beads.jsonl") expected := filepath.Join(tmpDir, "issues.jsonl")
if result != expected { if result != expected {
t.Errorf("Expected '%s', got '%s'", expected, result) t.Errorf("Expected '%s', got '%s'", expected, result)
} }

View File

@@ -17,7 +17,7 @@ type Config struct {
func DefaultConfig() *Config { func DefaultConfig() *Config {
return &Config{ return &Config{
Database: "beads.db", Database: "beads.db",
JSONLExport: "beads.jsonl", JSONLExport: "issues.jsonl",
} }
} }
@@ -89,7 +89,7 @@ func (c *Config) DatabasePath(beadsDir string) string {
func (c *Config) JSONLPath(beadsDir string) string { func (c *Config) JSONLPath(beadsDir string) string {
if c.JSONLExport == "" { if c.JSONLExport == "" {
return filepath.Join(beadsDir, "beads.jsonl") return filepath.Join(beadsDir, "issues.jsonl")
} }
return filepath.Join(beadsDir, c.JSONLExport) return filepath.Join(beadsDir, c.JSONLExport)
} }

View File

@@ -12,9 +12,9 @@ func TestDefaultConfig(t *testing.T) {
if cfg.Database != "beads.db" { if cfg.Database != "beads.db" {
t.Errorf("Database = %q, want beads.db", cfg.Database) t.Errorf("Database = %q, want beads.db", cfg.Database)
} }
if cfg.JSONLExport != "beads.jsonl" { if cfg.JSONLExport != "issues.jsonl" {
t.Errorf("JSONLExport = %q, want beads.jsonl", cfg.JSONLExport) t.Errorf("JSONLExport = %q, want issues.jsonl", cfg.JSONLExport)
} }
} }
@@ -84,8 +84,8 @@ func TestJSONLPath(t *testing.T) {
}{ }{
{ {
name: "default", name: "default",
cfg: &Config{JSONLExport: "beads.jsonl"}, cfg: &Config{JSONLExport: "issues.jsonl"},
want: filepath.Join(beadsDir, "beads.jsonl"), want: filepath.Join(beadsDir, "issues.jsonl"),
}, },
{ {
name: "custom", name: "custom",
@@ -95,7 +95,7 @@ func TestJSONLPath(t *testing.T) {
{ {
name: "empty falls back to default", name: "empty falls back to default",
cfg: &Config{JSONLExport: ""}, cfg: &Config{JSONLExport: ""},
want: filepath.Join(beadsDir, "beads.jsonl"), want: filepath.Join(beadsDir, "issues.jsonl"),
}, },
} }