@@ -3,7 +3,6 @@ package app
33import (
44 "context"
55 "encoding/json"
6- "os"
76 "path/filepath"
87 "testing"
98
@@ -154,6 +153,123 @@ func TestIngestSessionEnd(t *testing.T) {
154153 }
155154}
156155
156+ func TestIngestClaudeDisplaySlugUsesFirstMeaningfulPrompt (t * testing.T ) {
157+ st := testStore (t )
158+ ctx := context .Background ()
159+ transcriptPath := filepath .Join (t .TempDir (), "claude-session.jsonl" )
160+
161+ _ , err := IngestClaudeEvent (ctx , st , map [string ]any {
162+ "hook_event_name" : "SessionStart" ,
163+ "session_id" : "claude-1" ,
164+ "slug" : "elegant-giggling-flame" ,
165+ "transcript_path" : transcriptPath ,
166+ "cwd" : "/home/user/project" ,
167+ "meta" : map [string ]any {"timestamp" : float64 (1712700000000 )},
168+ })
169+ if err != nil {
170+ t .Fatal (err )
171+ }
172+
173+ _ , err = IngestClaudeEvent (ctx , st , map [string ]any {
174+ "hook_event_name" : "UserPromptSubmit" ,
175+ "session_id" : "claude-1" ,
176+ "slug" : "elegant-giggling-flame" ,
177+ "transcript_path" : transcriptPath ,
178+ "cwd" : "/home/user/project" ,
179+ "prompt" : "<command-name>/clear</command-name>\n <command-message>clear</command-message>" ,
180+ "meta" : map [string ]any {"timestamp" : float64 (1712700001000 )},
181+ })
182+ if err != nil {
183+ t .Fatal (err )
184+ }
185+
186+ _ , err = IngestClaudeEvent (ctx , st , map [string ]any {
187+ "hook_event_name" : "UserPromptSubmit" ,
188+ "session_id" : "claude-1" ,
189+ "slug" : "elegant-giggling-flame" ,
190+ "transcript_path" : transcriptPath ,
191+ "cwd" : "/home/user/project" ,
192+ "prompt" : "investigate the pagination bug\n with full context" ,
193+ "meta" : map [string ]any {"timestamp" : float64 (1712700002000 )},
194+ })
195+ if err != nil {
196+ t .Fatal (err )
197+ }
198+
199+ _ , err = IngestClaudeEvent (ctx , st , map [string ]any {
200+ "hook_event_name" : "UserPromptSubmit" ,
201+ "session_id" : "claude-1" ,
202+ "slug" : "elegant-giggling-flame" ,
203+ "transcript_path" : transcriptPath ,
204+ "cwd" : "/home/user/project" ,
205+ "prompt" : "later follow-up prompt" ,
206+ "meta" : map [string ]any {"timestamp" : float64 (1712700003000 )},
207+ })
208+ if err != nil {
209+ t .Fatal (err )
210+ }
211+
212+ session , err := st .Read ().GetSessionByID (ctx , "claude-1" )
213+ if err != nil {
214+ t .Fatal (err )
215+ }
216+ if session == nil {
217+ t .Fatal ("session not found" )
218+ }
219+ if session .Slug != "investigate the pagination bug" {
220+ t .Fatalf ("display slug=%q, want first meaningful prompt" , session .Slug )
221+ }
222+
223+ events , err := st .Read ().ListEventsForSession (ctx , "claude-1" , model.EventFilter {})
224+ if err != nil {
225+ t .Fatal (err )
226+ }
227+ if len (events ) != 4 {
228+ t .Fatalf ("got %d events, want 4" , len (events ))
229+ }
230+ }
231+
232+ func TestIngestClaudeMeaningfulPromptReplacesLegacyRandomSlug (t * testing.T ) {
233+ st := testStore (t )
234+ ctx := context .Background ()
235+
236+ var projectID int64
237+ err := st .WithTx (ctx , func (q * store.Queries ) error {
238+ var err error
239+ projectID , err = q .CreateProject (ctx , "proj" , "Project" , "/home/user/project" , "" )
240+ if err != nil {
241+ return err
242+ }
243+ return q .UpsertSession (ctx , "claude-legacy" , "" , projectID , "quirky-doodling-zephyr" , "claude" , nil , 1712700000000 , "" )
244+ })
245+ if err != nil {
246+ t .Fatal (err )
247+ }
248+
249+ _ , err = IngestClaudeEvent (ctx , st , map [string ]any {
250+ "hook_event_name" : "UserPromptSubmit" ,
251+ "session_id" : "claude-legacy" ,
252+ "slug" : "quirky-doodling-zephyr" ,
253+ "cwd" : "/home/user/project" ,
254+ "prompt" : "real bug report title" ,
255+ "meta" : map [string ]any {"timestamp" : float64 (1712700001000 )},
256+ })
257+ if err != nil {
258+ t .Fatal (err )
259+ }
260+
261+ session , err := st .Read ().GetSessionByID (ctx , "claude-legacy" )
262+ if err != nil {
263+ t .Fatal (err )
264+ }
265+ if session == nil {
266+ t .Fatal ("session not found" )
267+ }
268+ if session .Slug != "real bug report title" {
269+ t .Fatalf ("display slug=%q, want replaced display slug" , session .Slug )
270+ }
271+ }
272+
157273func TestIngestOpenCodeSessionIdleMarksStopped (t * testing.T ) {
158274 st := testStore (t )
159275 ctx := context .Background ()
@@ -1232,19 +1348,6 @@ func TestExtractProjectDir(t *testing.T) {
12321348 }
12331349}
12341350
1235- func TestLoadSessionSlug (t * testing.T ) {
1236- dir := t .TempDir ()
1237- path := filepath .Join (dir , "session.jsonl" )
1238- os .WriteFile (path , []byte (`{"type":"init"}
1239- {"slug":"my-session-slug","type":"meta"}
1240- ` ), 0o644 )
1241-
1242- slug := loadSessionSlug (path )
1243- if slug != "my-session-slug" {
1244- t .Fatalf ("got slug=%q" , slug )
1245- }
1246- }
1247-
12481351func TestUpsertSessionParentIDUpdatedOnConflict (t * testing.T ) {
12491352 st := testStore (t )
12501353 ctx := context .Background ()
0 commit comments