From 28e24b29aea4ab6a60ad2d66f6fffa290b18b9f1 Mon Sep 17 00:00:00 2001 From: vshulcz Date: Sat, 1 Aug 2026 20:25:24 +0300 Subject: [PATCH] fix: point at the stores when a search finds an empty index "Fewer words" cannot help when nothing is indexed; last, blame and the brief already say where deja looked. Closes #832. --- cmd/deja/empty_store_search_test.go | 49 +++++++++++++++++++++++++++++ cmd/deja/main.go | 7 +++++ 2 files changed, 56 insertions(+) create mode 100644 cmd/deja/empty_store_search_test.go diff --git a/cmd/deja/empty_store_search_test.go b/cmd/deja/empty_store_search_test.go new file mode 100644 index 0000000..46cf20d --- /dev/null +++ b/cmd/deja/empty_store_search_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +// An empty store is not a query problem: "fewer words" cannot help when +// nothing is indexed, and last, blame and the brief all say what to do +// instead. Search is the command a new machine reaches for first (#832). +func TestSearchOnAnEmptyStorePointsAtTheStores(t *testing.T) { + hermeticEnv(t) + + out, err := captureRunStderr(t, "anything") + if err != nil { + t.Fatal(err) + } + if !strings.Contains(out, "no agent history was found on this machine") { + t.Errorf("an empty machine still gets query advice:\n%s", out) + } + if strings.Contains(out, "try fewer words") { + t.Errorf("advice that cannot be followed is still printed:\n%s", out) + } + + // With history indexed, an ordinary miss keeps the ordinary answer. + store := filepath.Join(os.Getenv("DEJA_CLAUDE_ROOT"), "-proj") + if err := os.MkdirAll(store, 0o755); err != nil { + t.Fatal(err) + } + line := `{"type":"user","message":{"role":"user","content":"the hydraulic pump bearing failed"},"timestamp":"2026-07-01T10:00:00Z","sessionId":"a1","cwd":"/proj"}` + if err := os.WriteFile(filepath.Join(store, "a.jsonl"), []byte(line+"\n"), 0o644); err != nil { + t.Fatal(err) + } + if _, err := captureRunStderr(t, "index"); err != nil { + t.Fatal(err) + } + miss, err := captureRunStderr(t, "zzzqqq") + if err != nil { + t.Fatal(err) + } + if !strings.Contains(miss, "no matches in 1 indexed session") { + t.Errorf("an ordinary miss lost its answer:\n%s", miss) + } + if strings.Contains(miss, "no agent history") { + t.Errorf("a store with history was called empty:\n%s", miss) + } +} diff --git a/cmd/deja/main.go b/cmd/deja/main.go index b8f013e..89a0e2f 100644 --- a/cmd/deja/main.go +++ b/cmd/deja/main.go @@ -647,6 +647,13 @@ func termCountLine(dir, q string) string { // their query missed. It fired on every ordinary miss, so the signature could // not be used to recognise the failure it was written for (#637). func printNoMatches(w io.Writer, dir, q string) { + // An empty store is not a query problem: "fewer words" cannot help when + // nothing is indexed, and `last`, `blame` and the brief all say what to do + // instead. Search is the command a new machine reaches for first (#832). + if n, err := index.SessionCount(dir); err == nil && n == 0 { + fmt.Fprintln(w, emptyIndexHint(fmt.Sprintf("no matches for %q", q))) + return + } // Nothing to look up: very short tokens are dropped and punctuation is // trimmed, so this query never reached the index. "Try fewer words" // cannot be followed with one word, or none (#828). The message does not