diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 473555880..8ebc415b4 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -79,6 +79,7 @@ import { } from "./layout/deep-links" import { createInlineEditorController } from "./layout/inline-editor" import { + buildPawworkSidebarSessionRows, pawworkSessionDirectories, sortPawworkSidebarSessions, } from "./layout/pawwork-session-source" @@ -573,12 +574,14 @@ export default function Layout(props: ParentProps) { ) const pawworkSessions = createMemo(() => { - const rows = pawworkSessionWindow().sessions.map((session) => ({ - session, - slug: base64Encode(session.directory), - projectLabel: projectLabelForSession(session), - created: session.time.created, - })) + const rows = buildPawworkSidebarSessionRows(pawworkSessionWindow().sessions, { + slugForDirectory: base64Encode, + projectLabelForSession, + messagesForSession: (session) => { + const [store] = globalSync.child(session.directory, { bootstrap: false, pin: false }) + return store.message[session.id] + }, + }) return sortPawworkSidebarSessions(rows.map((item) => ({ ...item, id: item.session.id }))).map(({ id: _, ...item }) => item) }) diff --git a/packages/app/src/pages/layout/pawwork-session-source.test.ts b/packages/app/src/pages/layout/pawwork-session-source.test.ts index 141b7114b..714e69dc4 100644 --- a/packages/app/src/pages/layout/pawwork-session-source.test.ts +++ b/packages/app/src/pages/layout/pawwork-session-source.test.ts @@ -1,5 +1,6 @@ import { describe, expect, test } from "bun:test" import { + buildPawworkSidebarSessionRows, pawworkSidebarSessionTime, resolvePawworkProjectLabels, sortPawworkSidebarSessions, @@ -130,6 +131,59 @@ describe("sortPawworkSidebarSessions", () => { }) }) +describe("buildPawworkSidebarSessionRows", () => { + test("uses loaded user message time for sidebar rows", () => { + const result = buildPawworkSidebarSessionRows( + [ + { + id: "session-old", + directory: "/repo", + time: { created: 100, updated: 900 }, + }, + ], + { + slugForDirectory: (directory) => `slug:${directory}`, + projectLabelForSession: () => "PawWork", + messagesForSession: () => [ + { id: "msg_1", role: "assistant", time: { created: 950 } }, + { id: "msg_2", role: "user", time: { created: 800 } }, + ], + }, + ) + + expect(result).toEqual([ + { + session: { + id: "session-old", + directory: "/repo", + time: { created: 100, updated: 900 }, + }, + slug: "slug:/repo", + projectLabel: "PawWork", + created: 800, + }, + ]) + }) + + test("falls back to session creation time when messages are missing", () => { + const result = buildPawworkSidebarSessionRows( + [ + { + id: "session-without-cache", + directory: "/repo", + time: { created: 300, updated: 900 }, + }, + ], + { + slugForDirectory: (directory) => `slug:${directory}`, + projectLabelForSession: () => "PawWork", + }, + ) + + expect(result[0].created).toBe(300) + }) +}) + describe("pawworkSidebarSessionTime", () => { test("uses the latest loaded user message time", () => { expect( diff --git a/packages/app/src/pages/layout/pawwork-session-source.ts b/packages/app/src/pages/layout/pawwork-session-source.ts index 8d19ff77e..df863e883 100644 --- a/packages/app/src/pages/layout/pawwork-session-source.ts +++ b/packages/app/src/pages/layout/pawwork-session-source.ts @@ -29,6 +29,11 @@ type MessageTimeLike = { } } +type SidebarRowSessionLike = SessionTimeLike & { + id: string + directory: string +} + const isFiniteNumber = (value: unknown): value is number => typeof value === "number" && Number.isFinite(value) const shortenHome = (value: string, home?: string) => { @@ -74,6 +79,22 @@ export function pawworkSidebarSessionTime(session: SessionTimeLike, messages?: M return isFiniteNumber(sessionCreated) ? sessionCreated : 0 } +export function buildPawworkSidebarSessionRows( + sessions: T[], + input: { + slugForDirectory: (directory: string) => string + projectLabelForSession: (session: T) => string + messagesForSession?: (session: T) => MessageTimeLike[] | undefined + }, +) { + return sessions.map((session) => ({ + session, + slug: input.slugForDirectory(session.directory), + projectLabel: input.projectLabelForSession(session), + created: pawworkSidebarSessionTime(session, input.messagesForSession?.(session)), + })) +} + export function pawworkSessionDirectories(input: { project: LocalProject | undefined activeProjectWorktree?: string