Skip to content

Commit fa718ef

Browse files
wesmclaude
andcommitted
fix: only dedup bare copilot files against dirs with events.jsonl
Two fixes from code review: 1. Discovery dedup was checking for any same-stem directory, even if it lacked events.jsonl. A bare session would be silently dropped when an invalid directory existed. Now only directories with events.jsonl suppress the bare file. 2. FindCopilotSourceFile checked bare format first, but discovery prefers directory format. Reversed the check order so both paths use consistent directory-first precedence. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent ad15510 commit fa718ef

2 files changed

Lines changed: 63 additions & 19 deletions

File tree

internal/sync/discovery.go

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -429,11 +429,18 @@ func DiscoverCopilotSessions(
429429
return nil
430430
}
431431

432-
// Collect directory entries first so we can skip bare
433-
// files that also have a directory counterpart.
432+
// Collect directories that actually contain events.jsonl
433+
// so we can skip bare files that have a valid directory
434+
// counterpart.
434435
dirs := make(map[string]struct{})
435436
for _, entry := range entries {
436-
if entry.IsDir() {
437+
if !entry.IsDir() {
438+
continue
439+
}
440+
eventsPath := filepath.Join(
441+
stateDir, entry.Name(), "events.jsonl",
442+
)
443+
if _, err := os.Stat(eventsPath); err == nil {
437444
dirs[entry.Name()] = struct{}{}
438445
}
439446
}
@@ -485,17 +492,18 @@ func FindCopilotSourceFile(
485492

486493
stateDir := filepath.Join(copilotDir, "session-state")
487494

488-
// Check bare format first.
489-
bare := filepath.Join(stateDir, rawID+".jsonl")
490-
if _, err := os.Stat(bare); err == nil {
491-
return bare
492-
}
493-
494-
// Check directory format.
495+
// Check directory format first (matches discovery
496+
// precedence which prefers directory over bare).
495497
dirFmt := filepath.Join(stateDir, rawID, "events.jsonl")
496498
if _, err := os.Stat(dirFmt); err == nil {
497499
return dirFmt
498500
}
499501

502+
// Fall back to bare format.
503+
bare := filepath.Join(stateDir, rawID+".jsonl")
504+
if _, err := os.Stat(bare); err == nil {
505+
return bare
506+
}
507+
500508
return ""
501509
}

internal/sync/sync_test.go

Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,42 @@ func TestDiscoverCopilotSessions_Mixed(t *testing.T) {
494494
}
495495
}
496496

497+
func TestDiscoverCopilotSessions_BareWithInvalidDir(
498+
t *testing.T,
499+
) {
500+
// A directory without events.jsonl should not suppress
501+
// the bare file with the same stem.
502+
dir := t.TempDir()
503+
stateDir := filepath.Join(dir, "session-state")
504+
if err := os.MkdirAll(stateDir, 0o755); err != nil {
505+
t.Fatalf("mkdir: %v", err)
506+
}
507+
508+
uuid := "invalid-dir-uuid"
509+
if err := os.WriteFile(
510+
filepath.Join(stateDir, uuid+".jsonl"),
511+
[]byte("{}"), 0o644,
512+
); err != nil {
513+
t.Fatalf("write bare: %v", err)
514+
}
515+
// Directory exists but has no events.jsonl.
516+
if err := os.MkdirAll(
517+
filepath.Join(stateDir, uuid), 0o755,
518+
); err != nil {
519+
t.Fatalf("mkdir dir: %v", err)
520+
}
521+
522+
files := DiscoverCopilotSessions(dir)
523+
if len(files) != 1 {
524+
t.Fatalf("got %d files, want 1", len(files))
525+
}
526+
wantPath := filepath.Join(stateDir, uuid+".jsonl")
527+
if files[0].Path != wantPath {
528+
t.Errorf("path = %q, want %q",
529+
files[0].Path, wantPath)
530+
}
531+
}
532+
497533
func TestDiscoverCopilotSessions_DedupBareAndDir(
498534
t *testing.T,
499535
) {
@@ -639,19 +675,19 @@ func TestFindCopilotSourceFile_EmptyDir(t *testing.T) {
639675
}
640676
}
641677

642-
func TestFindCopilotSourceFile_BarePreferred(t *testing.T) {
643-
// When both bare and directory format exist, bare is
644-
// checked first.
678+
func TestFindCopilotSourceFile_DirPreferred(t *testing.T) {
679+
// When both bare and directory format exist, directory is
680+
// preferred (matching discovery precedence).
645681
dir := t.TempDir()
646682
stateDir := filepath.Join(dir, "session-state")
647683

648684
// Create bare file
649685
if err := os.MkdirAll(stateDir, 0o755); err != nil {
650686
t.Fatalf("mkdir: %v", err)
651687
}
652-
barePath := filepath.Join(stateDir, "dual-1.jsonl")
653688
if err := os.WriteFile(
654-
barePath, []byte("{}"), 0o644,
689+
filepath.Join(stateDir, "dual-1.jsonl"),
690+
[]byte("{}"), 0o644,
655691
); err != nil {
656692
t.Fatalf("write: %v", err)
657693
}
@@ -661,15 +697,15 @@ func TestFindCopilotSourceFile_BarePreferred(t *testing.T) {
661697
if err := os.MkdirAll(sessDir, 0o755); err != nil {
662698
t.Fatalf("mkdir: %v", err)
663699
}
700+
dirPath := filepath.Join(sessDir, "events.jsonl")
664701
if err := os.WriteFile(
665-
filepath.Join(sessDir, "events.jsonl"),
666-
[]byte("{}"), 0o644,
702+
dirPath, []byte("{}"), 0o644,
667703
); err != nil {
668704
t.Fatalf("write: %v", err)
669705
}
670706

671707
got := FindCopilotSourceFile(dir, "dual-1")
672-
if got != barePath {
673-
t.Errorf("got %q, want bare path %q", got, barePath)
708+
if got != dirPath {
709+
t.Errorf("got %q, want dir path %q", got, dirPath)
674710
}
675711
}

0 commit comments

Comments
 (0)