diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index ba299fe3650d..dc8be2070c1b 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -1,7 +1,6 @@ import type { Message, Session } from "@opencode-ai/sdk/v2/client" import { showToast } from "@opencode-ai/ui/toast" import { base64Encode } from "@opencode-ai/util/encode" -import { Binary } from "@opencode-ai/util/binary" import { useNavigate, useParams } from "@solidjs/router" import type { Accessor } from "solid-js" import type { FileSelection } from "@/context/file" @@ -13,6 +12,7 @@ import { usePermission } from "@/context/permission" import { type ContextItem, type ImageAttachmentPart, type Prompt, usePrompt } from "@/context/prompt" import { useSDK } from "@/context/sdk" import { useSync } from "@/context/sync" +import { compareSessionRecent } from "@/context/global-sync/session-trim" import { Identifier } from "@/utils/id" import { Worktree as WorktreeState } from "@/utils/worktree" import { buildRequestParts } from "./build-request-parts" @@ -270,13 +270,14 @@ export function createPromptSubmit(input: PromptSubmitInput) { const seed = (dir: string, info: Session) => { const [, setStore] = globalSync.child(dir) setStore("session", (list: Session[]) => { - const result = Binary.search(list, info.id, (item) => item.id) - const next = [...list] - if (result.found) { - next[result.index] = info + const next = list.filter((item) => item.id !== info.id) + if (info.parentID) { + next.push(info) return next } - next.splice(result.index, 0, info) + + const index = next.findIndex((item) => !!item.parentID || compareSessionRecent(info, item) < 0) + next.splice(index === -1 ? next.length : index, 0, info) return next }) } diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index c84098869286..578ee8a5d007 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -205,10 +205,7 @@ function createGlobalSync() { list: (query) => globalSDK.client.session.list(query), }) .then((x) => { - const nonArchived = (x.data ?? []) - .filter((s) => !!s?.id) - .filter((s) => !s.time?.archived) - .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0)) + const nonArchived = (x.data ?? []).filter((s) => !!s?.id).filter((s) => !s.time?.archived) const limit = store.limit const childSessions = store.session.filter((s) => !!s.parentID) const sessions = trimSessions([...nonArchived, ...childSessions], { diff --git a/packages/app/src/context/global-sync/event-reducer.ts b/packages/app/src/context/global-sync/event-reducer.ts index b8eda0573f7b..a668b062f314 100644 --- a/packages/app/src/context/global-sync/event-reducer.ts +++ b/packages/app/src/context/global-sync/event-reducer.ts @@ -12,7 +12,7 @@ import type { Todo, } from "@opencode-ai/sdk/v2/client" import type { State, VcsCache } from "./types" -import { trimSessions } from "./session-trim" +import { compareSessionRecent, trimSessions } from "./session-trim" import { dropSessionCaches } from "./session-cache" export function applyGlobalEvent(input: { @@ -93,6 +93,26 @@ export function applyDirectoryEvent(input: { vcsCache?: VcsCache setSessionTodo?: (sessionID: string, todos: Todo[] | undefined) => void }) { + const sessionIndex = (sessionID: string) => input.store.session.findIndex((s) => s.id === sessionID) + const upsertSession = (info: Session) => { + const next = input.store.session.filter((session) => session.id !== info.id) + if (!info.parentID) { + const index = next.findIndex((session) => !!session.parentID || compareSessionRecent(info, session) < 0) + next.splice(index === -1 ? next.length : index, 0, info) + return next + } + + const start = next.findIndex((session) => !!session.parentID) + if (start === -1) { + next.push(info) + return next + } + + const offset = next.slice(start).findIndex((session) => compareSessionRecent(info, session) < 0) + next.splice(offset === -1 ? next.length : start + offset, 0, info) + return next + } + const event = input.event switch (event.type) { case "server.instance.disposed": { @@ -101,28 +121,23 @@ export function applyDirectoryEvent(input: { } case "session.created": { const info = (event.properties as { info: Session }).info - const result = Binary.search(input.store.session, info.id, (s) => s.id) - if (result.found) { - input.setStore("session", result.index, reconcile(info)) - break - } - const next = input.store.session.slice() - next.splice(result.index, 0, info) + const found = sessionIndex(info.id) !== -1 + const next = upsertSession(info) const trimmed = trimSessions(next, { limit: input.store.limit, permission: input.store.permission }) input.setStore("session", reconcile(trimmed, { key: "id" })) cleanupDroppedSessionCaches(input.store, input.setStore, trimmed, input.setSessionTodo) - if (!info.parentID) input.setStore("sessionTotal", (value) => value + 1) + if (!found && !info.parentID) input.setStore("sessionTotal", (value) => value + 1) break } case "session.updated": { const info = (event.properties as { info: Session }).info - const result = Binary.search(input.store.session, info.id, (s) => s.id) + const index = sessionIndex(info.id) if (info.time.archived) { - if (result.found) { + if (index !== -1) { input.setStore( "session", produce((draft) => { - draft.splice(result.index, 1) + draft.splice(index, 1) }), ) } @@ -131,12 +146,7 @@ export function applyDirectoryEvent(input: { input.setStore("sessionTotal", (value) => Math.max(0, value - 1)) break } - if (result.found) { - input.setStore("session", result.index, reconcile(info)) - break - } - const next = input.store.session.slice() - next.splice(result.index, 0, info) + const next = upsertSession(info) const trimmed = trimSessions(next, { limit: input.store.limit, permission: input.store.permission }) input.setStore("session", reconcile(trimmed, { key: "id" })) cleanupDroppedSessionCaches(input.store, input.setStore, trimmed, input.setSessionTodo) @@ -144,12 +154,12 @@ export function applyDirectoryEvent(input: { } case "session.deleted": { const info = (event.properties as { info: Session }).info - const result = Binary.search(input.store.session, info.id, (s) => s.id) - if (result.found) { + const index = sessionIndex(info.id) + if (index !== -1) { input.setStore( "session", produce((draft) => { - draft.splice(result.index, 1) + draft.splice(index, 1) }), ) } diff --git a/packages/app/src/context/global-sync/session-trim.test.ts b/packages/app/src/context/global-sync/session-trim.test.ts index be12c074b5dc..3ce91d33f9e9 100644 --- a/packages/app/src/context/global-sync/session-trim.test.ts +++ b/packages/app/src/context/global-sync/session-trim.test.ts @@ -49,11 +49,23 @@ describe("trimSessions", () => { }) expect(result.map((x) => x.id)).toEqual([ - "child-kept-by-permission", - "child-kept-by-recency", - "child-kept-by-root", "root-1", "root-2", + "child-kept-by-root", + "child-kept-by-permission", + "child-kept-by-recency", ]) }) + + test("preserves fetched root order instead of reshaping by id", () => { + const now = 20_000_000 + const list = [ + session({ id: "z", created: now - 20_000_000, updated: now - 20_000_000 }), + session({ id: "a", created: now - 19_000_000, updated: now - 19_000_000 }), + session({ id: "m", created: now - 18_000_000, updated: now - 18_000_000 }), + ] + + const result = trimSessions(list, { limit: 2, permission: {}, now }) + expect(result.map((item) => item.id)).toEqual(["z", "a"]) + }) }) diff --git a/packages/app/src/context/global-sync/session-trim.ts b/packages/app/src/context/global-sync/session-trim.ts index 800ba74a6849..fc948ea787c9 100644 --- a/packages/app/src/context/global-sync/session-trim.ts +++ b/packages/app/src/context/global-sync/session-trim.ts @@ -22,10 +22,8 @@ export function takeRecentSessions(sessions: Session[], limit: number, cutoff: n if (seen.has(session.id)) continue seen.add(session.id) if (sessionUpdatedAt(session) <= cutoff) continue - const index = selected.findIndex((x) => compareSessionRecent(session, x) < 0) - if (index === -1) selected.push(session) - if (index !== -1) selected.splice(index, 0, session) - if (selected.length > limit) selected.pop() + selected.push(session) + if (selected.length >= limit) break } return selected } @@ -36,10 +34,15 @@ export function trimSessions( ) { const limit = Math.max(0, options.limit) const cutoff = (options.now ?? Date.now()) - SESSION_RECENT_WINDOW + const seen = new Set() const all = input .filter((s) => !!s?.id) .filter((s) => !s.time?.archived) - .sort((a, b) => cmp(a.id, b.id)) + .filter((s) => { + if (seen.has(s.id)) return false + seen.add(s.id) + return true + }) const roots = all.filter((s) => !s.parentID) const children = all.filter((s) => !!s.parentID) const base = roots.slice(0, limit) @@ -52,5 +55,5 @@ export function trimSessions( if (perms.length > 0) return true return sessionUpdatedAt(s) > cutoff }) - return [...keepRoots, ...keepChildren].sort((a, b) => cmp(a.id, b.id)) + return [...keepRoots, ...keepChildren] } diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 04bc2fdaaaf3..7acac633cd6a 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -7,7 +7,6 @@ import { useGlobalSync } from "./global-sync" import { usePlatform } from "@/context/platform" import { useLanguage } from "@/context/language" import { useSettings } from "@/context/settings" -import { Binary } from "@opencode-ai/util/binary" import { base64Encode } from "@opencode-ai/util/encode" import { decode64 } from "@/utils/base64" import { EventSessionError } from "@opencode-ai/sdk/v2" @@ -208,8 +207,8 @@ export const { use: useNotification, provider: NotificationProvider } = createSi const lookup = async (directory: string, sessionID?: string) => { if (!sessionID) return undefined const [syncStore] = globalSync.child(directory, { bootstrap: false }) - const match = Binary.search(syncStore.session, sessionID, (s) => s.id) - if (match.found) return syncStore.session[match.index] + const session = syncStore.session.find((item) => item.id === sessionID) + if (session) return session return globalSDK.client.session .get({ directory, sessionID }) .then((x) => x.data) diff --git a/packages/app/src/context/sync.tsx b/packages/app/src/context/sync.tsx index 0f2008723456..5b887ef78de6 100644 --- a/packages/app/src/context/sync.tsx +++ b/packages/app/src/context/sync.tsx @@ -9,6 +9,7 @@ import { getSessionPrefetchPromise, setSessionPrefetch, } from "./global-sync/session-prefetch" +import { compareSessionRecent } from "./global-sync/session-trim" import { useGlobalSync } from "./global-sync" import { useSDK } from "./sdk" import type { Message, Part } from "@opencode-ai/sdk/v2/client" @@ -194,9 +195,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ const getSession = (sessionID: string) => { const store = current()[0] - const match = Binary.search(store.session, sessionID, (s) => s.id) - if (match.found) return store.session[match.index] - return undefined + return store.session.find((session) => session.id === sessionID) } const setOptimistic = (directory: string, sessionID: string, item: OptimisticItem) => { @@ -456,7 +455,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ } } - const hasSession = Binary.search(store.session, sessionID, (s) => s.id).found + const hasSession = store.session.some((session) => session.id === sessionID) const cached = store.message[sessionID] !== undefined && meta.limit[key] !== undefined if (cached && hasSession && !opts?.force) return @@ -471,12 +470,19 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ setStore( "session", produce((draft) => { - const match = Binary.search(draft, sessionID, (s) => s.id) - if (match.found) { - draft[match.index] = data + const index = draft.findIndex((session) => session.id === sessionID) + if (index !== -1) { + draft[index] = data return } - draft.splice(match.index, 0, data) + if (data.parentID) { + draft.push(data) + return + } + const next = draft.findIndex( + (session) => !!session.parentID || compareSessionRecent(data, session) < 0, + ) + draft.splice(next === -1 ? draft.length : next, 0, data) }), ) }) @@ -585,10 +591,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ const [store, setStore] = globalSync.child(directory) setStore("limit", (x) => x + count) await client.session.list().then((x) => { - const sessions = (x.data ?? []) - .filter((s) => !!s?.id) - .sort((a, b) => cmp(a.id, b.id)) - .slice(0, store.limit) + const sessions = (x.data ?? []).filter((s) => !!s?.id).slice(0, store.limit) setStore("session", reconcile(sessions, { key: "id" })) }) }, @@ -600,8 +603,8 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({ await client.session.update({ sessionID, time: { archived: Date.now() } }) setStore( produce((draft) => { - const match = Binary.search(draft.session, sessionID, (s) => s.id) - if (match.found) draft.session.splice(match.index, 1) + const index = draft.session.findIndex((s) => s.id === sessionID) + if (index !== -1) draft.session.splice(index, 1) }), ) }, diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index ab2687dcab93..f978e7c6edbf 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -145,7 +145,6 @@ export default function Layout(props: ParentProps) { hoverProject: undefined as string | undefined, scrollSessionKey: undefined as string | undefined, nav: undefined as HTMLElement | undefined, - sortNow: Date.now(), sizing: false, peek: undefined as string | undefined, peeked: false, @@ -167,16 +166,7 @@ export default function Layout(props: ParentProps) { } const isBusy = (directory: string) => !!state.busyWorkspaces[workspaceKey(directory)] const navLeave = { current: undefined as number | undefined } - const sortNow = () => state.sortNow let sizet: number | undefined - let sortNowInterval: ReturnType | undefined - const sortNowTimeout = setTimeout( - () => { - setState("sortNow", Date.now()) - sortNowInterval = setInterval(() => setState("sortNow", Date.now()), 60_000) - }, - 60_000 - (Date.now() % 60_000), - ) const aim = createAim({ enabled: () => !layout.sidebar.opened(), @@ -191,8 +181,6 @@ export default function Layout(props: ParentProps) { onCleanup(() => { if (navLeave.current !== undefined) clearTimeout(navLeave.current) - clearTimeout(sortNowTimeout) - if (sortNowInterval) clearInterval(sortNowInterval) if (sizet !== undefined) clearTimeout(sizet) if (peekt !== undefined) clearTimeout(peekt) aim.reset() @@ -657,14 +645,13 @@ export default function Layout(props: ParentProps) { }) const currentSessions = createMemo(() => { - const now = Date.now() const dirs = visibleSessionDirs() if (dirs.length === 0) return [] as Session[] const result: Session[] = [] for (const dir of dirs) { const [dirStore] = globalSync.child(dir, { bootstrap: true }) - const dirSessions = sortedRootSessions(dirStore, now) + const dirSessions = sortedRootSessions(dirStore) result.push(...dirSessions) } return result @@ -977,8 +964,8 @@ export default function Layout(props: ParentProps) { }) setStore( produce((draft) => { - const match = Binary.search(draft.session, session.id, (s) => s.id) - if (match.found) draft.session.splice(match.index, 1) + const index = draft.session.findIndex((s) => s.id === session.id) + if (index !== -1) draft.session.splice(index, 1) }), ) if (session.id === params.id) { @@ -1277,10 +1264,7 @@ export default function Layout(props: ParentProps) { clearLastProjectSession(root) } - const latest = latestRootSession( - dirs.map((item) => globalSync.child(item, { bootstrap: false })[0]), - Date.now(), - ) + const latest = latestRootSession(dirs.map((item) => globalSync.child(item, { bootstrap: false })[0])) if (latest && (await openSession(latest))) { return } @@ -1295,7 +1279,6 @@ export default function Layout(props: ParentProps) { .catch(() => []), })), ), - Date.now(), ) if (fetched && (await openSession(fetched))) { return @@ -2136,7 +2119,6 @@ export default function Layout(props: ParentProps) { @@ -2181,7 +2163,6 @@ export default function Layout(props: ParentProps) { ctx={workspaceSidebarCtx} directory={directory} project={project()!} - sortNow={sortNow} mobile={panelProps.mobile} popover={popover()} /> @@ -2244,9 +2225,7 @@ export default function Layout(props: ParentProps) { opened={() => layout.sidebar.opened()} aimMove={aim.move} projects={projects} - renderProject={(project) => ( - - )} + renderProject={(project) => } handleDragStart={handleDragStart} handleDragEnd={handleDragEnd} handleDragOver={handleDragOver} diff --git a/packages/app/src/pages/layout/helpers.test.ts b/packages/app/src/pages/layout/helpers.test.ts index 9dbc6c72d2fd..192dd42b0f53 100644 --- a/packages/app/src/pages/layout/helpers.test.ts +++ b/packages/app/src/pages/layout/helpers.test.ts @@ -13,6 +13,7 @@ import { errorMessage, hasProjectPermissions, latestRootSession, + sortedRootSessions, workspaceKey, } from "./helpers" @@ -121,29 +122,41 @@ describe("layout workspace helpers", () => { }) test("finds the latest root session across workspaces", () => { - const result = latestRootSession( - [ - { - path: { directory: "/root" }, - session: [session({ id: "root", directory: "/root", time: { created: 1, updated: 1, archived: undefined } })], - }, - { - path: { directory: "/workspace" }, - session: [ - session({ - id: "workspace", - directory: "/workspace", - time: { created: 2, updated: 2, archived: undefined }, - }), - ], - }, - ], - 120_000, - ) + const result = latestRootSession([ + { + path: { directory: "/root" }, + session: [session({ id: "root", directory: "/root", time: { created: 1, updated: 1, archived: undefined } })], + }, + { + path: { directory: "/workspace" }, + session: [ + session({ + id: "workspace", + directory: "/workspace", + time: { created: 2, updated: 2, archived: undefined }, + }), + ], + }, + ]) expect(result?.id).toBe("workspace") }) + test("preserves visible root session order from the store", () => { + const result = sortedRootSessions({ + path: { directory: "/workspace" }, + session: [ + session({ id: "z", directory: "/workspace", time: { created: 1, updated: 1, archived: undefined } }), + session({ id: "child", directory: "/workspace", parentID: "z" }), + session({ id: "a", directory: "/workspace", time: { created: 2, updated: 2, archived: undefined } }), + session({ id: "archived", directory: "/workspace", time: { created: 3, updated: 3, archived: 3 } }), + session({ id: "other", directory: "/other", time: { created: 4, updated: 4, archived: undefined } }), + ], + }) + + expect(result.map((item) => item.id)).toEqual(["z", "a"]) + }) + test("detects project permissions with a filter", () => { const result = hasProjectPermissions( { @@ -168,32 +181,29 @@ describe("layout workspace helpers", () => { }) test("ignores archived and child sessions when finding latest root session", () => { - const result = latestRootSession( - [ - { - path: { directory: "/workspace" }, - session: [ - session({ - id: "archived", - directory: "/workspace", - time: { created: 10, updated: 10, archived: 10 }, - }), - session({ - id: "child", - directory: "/workspace", - parentID: "parent", - time: { created: 20, updated: 20, archived: undefined }, - }), - session({ - id: "root", - directory: "/workspace", - time: { created: 30, updated: 30, archived: undefined }, - }), - ], - }, - ], - 120_000, - ) + const result = latestRootSession([ + { + path: { directory: "/workspace" }, + session: [ + session({ + id: "archived", + directory: "/workspace", + time: { created: 10, updated: 10, archived: 10 }, + }), + session({ + id: "child", + directory: "/workspace", + parentID: "parent", + time: { created: 20, updated: 20, archived: undefined }, + }), + session({ + id: "root", + directory: "/workspace", + time: { created: 30, updated: 30, archived: undefined }, + }), + ], + }, + ]) expect(result?.id).toBe("root") }) diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts index be4ce9f57423..2a2e0da00bfd 100644 --- a/packages/app/src/pages/layout/helpers.ts +++ b/packages/app/src/pages/layout/helpers.ts @@ -8,30 +8,25 @@ export const workspaceKey = (directory: string) => { return directory.replace(/[\\/]+$/, "") } -function sortSessions(now: number) { - const oneMinuteAgo = now - 60 * 1000 +function sortSessions() { return (a: Session, b: Session) => { const aUpdated = a.time.updated ?? a.time.created const bUpdated = b.time.updated ?? b.time.created - const aRecent = aUpdated > oneMinuteAgo - const bRecent = bUpdated > oneMinuteAgo - if (aRecent && bRecent) return a.id < b.id ? -1 : a.id > b.id ? 1 : 0 - if (aRecent && !bRecent) return -1 - if (!aRecent && bRecent) return 1 - return bUpdated - aUpdated + if (aUpdated !== bUpdated) return bUpdated - aUpdated + return a.id < b.id ? -1 : a.id > b.id ? 1 : 0 } } const isRootVisibleSession = (session: Session, directory: string) => workspaceKey(session.directory) === workspaceKey(directory) && !session.parentID && !session.time?.archived -export const sortedRootSessions = (store: { session: Session[]; path: { directory: string } }, now: number) => - store.session.filter((session) => isRootVisibleSession(session, store.path.directory)).sort(sortSessions(now)) +export const sortedRootSessions = (store: { session: Session[]; path: { directory: string } }) => + store.session.filter((session) => isRootVisibleSession(session, store.path.directory)) -export const latestRootSession = (stores: { session: Session[]; path: { directory: string } }[], now: number) => +export const latestRootSession = (stores: { session: Session[]; path: { directory: string } }[]) => stores .flatMap((store) => store.session.filter((session) => isRootVisibleSession(session, store.path.directory))) - .sort(sortSessions(now))[0] + .sort(sortSessions())[0] export function hasProjectPermissions( request: Record, diff --git a/packages/app/src/pages/layout/sidebar-project.tsx b/packages/app/src/pages/layout/sidebar-project.tsx index a26bc1831188..b63dda672b41 100644 --- a/packages/app/src/pages/layout/sidebar-project.tsx +++ b/packages/app/src/pages/layout/sidebar-project.tsx @@ -273,7 +273,6 @@ export const SortableProject = (props: { project: LocalProject mobile?: boolean ctx: ProjectSidebarContext - sortNow: Accessor }): JSX.Element => { const globalSync = useGlobalSync() const language = useLanguage() @@ -319,11 +318,11 @@ export const SortableProject = (props: { } const projectStore = createMemo(() => globalSync.child(props.project.worktree, { bootstrap: false })[0]) - const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow())) + const projectSessions = createMemo(() => sortedRootSessions(projectStore())) const projectChildren = createMemo(() => childMapByParent(projectStore().session)) const workspaceSessions = (directory: string) => { const [data] = globalSync.child(directory, { bootstrap: false }) - return sortedRootSessions(data, props.sortNow()) + return sortedRootSessions(data) } const workspaceChildren = (directory: string) => { const [data] = globalSync.child(directory, { bootstrap: false }) diff --git a/packages/app/src/pages/layout/sidebar-workspace.tsx b/packages/app/src/pages/layout/sidebar-workspace.tsx index 86ede774e634..220925768c21 100644 --- a/packages/app/src/pages/layout/sidebar-workspace.tsx +++ b/packages/app/src/pages/layout/sidebar-workspace.tsx @@ -305,7 +305,6 @@ export const SortableWorkspace = (props: { ctx: WorkspaceSidebarContext directory: string project: LocalProject - sortNow: Accessor mobile?: boolean popover?: boolean }): JSX.Element => { @@ -320,7 +319,7 @@ export const SortableWorkspace = (props: { pendingRename: false, }) const slug = createMemo(() => base64Encode(props.directory)) - const sessions = createMemo(() => sortedRootSessions(workspaceStore, props.sortNow())) + const sessions = createMemo(() => sortedRootSessions(workspaceStore)) const children = createMemo(() => childMapByParent(workspaceStore.session)) const local = createMemo(() => props.directory === props.project.worktree) const active = createMemo(() => props.ctx.currentDir() === props.directory) @@ -458,7 +457,6 @@ export const SortableWorkspace = (props: { export const LocalWorkspace = (props: { ctx: WorkspaceSidebarContext project: LocalProject - sortNow: Accessor mobile?: boolean popover?: boolean }): JSX.Element => { @@ -469,7 +467,7 @@ export const LocalWorkspace = (props: { return { store, setStore } }) const slug = createMemo(() => base64Encode(props.project.worktree)) - const sessions = createMemo(() => sortedRootSessions(workspace().store, props.sortNow())) + const sessions = createMemo(() => sortedRootSessions(workspace().store)) const children = createMemo(() => childMapByParent(workspace().store.session)) const booted = createMemo((prev) => prev || workspace().store.status === "complete", false) const loading = createMemo(() => !booted() && sessions().length === 0)