diff options
| author | adamelmore <[email protected]> | 2026-02-26 08:53:36 -0600 |
|---|---|---|
| committer | adamelmore <[email protected]> | 2026-02-26 08:53:40 -0600 |
| commit | b4d0090e005e7355b3e8f2594c0ad8538fffe75b (patch) | |
| tree | 56fb22785afde2bc0d18a0ef391e93649b90da19 /packages/app/src | |
| parent | 05ac0a73e15d7a6d230e0a76230104bbe3f5df22 (diff) | |
| download | opencode-b4d0090e005e7355b3e8f2594c0ad8538fffe75b.tar.gz opencode-b4d0090e005e7355b3e8f2594c0ad8538fffe75b.zip | |
chore: fix flaky test
Diffstat (limited to 'packages/app/src')
| -rw-r--r-- | packages/app/src/pages/layout.tsx | 42 | ||||
| -rw-r--r-- | packages/app/src/pages/layout/helpers.test.ts | 76 | ||||
| -rw-r--r-- | packages/app/src/pages/layout/helpers.ts | 5 |
3 files changed, 120 insertions, 3 deletions
diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 62094a6e4..cb194052d 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -61,6 +61,7 @@ import { displayName, errorMessage, getDraggableId, + latestRootSession, sortedRootSessions, syncWorkspaceOrder, workspaceKey, @@ -1093,14 +1094,51 @@ export default function Layout(props: ParentProps) { return meta?.worktree ?? directory } - function navigateToProject(directory: string | undefined) { + async function navigateToProject(directory: string | undefined) { if (!directory) return const root = projectRoot(directory) server.projects.touch(root) + const project = layout.projects.list().find((item) => item.worktree === root) + const dirs = Array.from(new Set([root, ...(store.workspaceOrder[root] ?? []), ...(project?.sandboxes ?? [])])) + const openSession = async (target: { directory: string; id: string }) => { + const resolved = await globalSDK.client.session + .get({ sessionID: target.id }) + .then((x) => x.data) + .catch(() => undefined) + const next = resolved?.directory ? resolved : target + setStore("lastProjectSession", root, { directory: next.directory, id: next.id, at: Date.now() }) + navigateWithSidebarReset(`/${base64Encode(next.directory)}/session/${next.id}`) + } const projectSession = store.lastProjectSession[root] if (projectSession?.id) { - navigateWithSidebarReset(`/${base64Encode(projectSession.directory)}/session/${projectSession.id}`) + await openSession(projectSession) + return + } + + const latest = latestRootSession( + dirs.map((item) => globalSync.child(item, { bootstrap: false })[0]), + Date.now(), + ) + if (latest) { + await openSession(latest) + return + } + + const fetched = latestRootSession( + await Promise.all( + dirs.map(async (item) => ({ + path: { directory: item }, + session: await globalSDK.client.session + .list({ directory: item }) + .then((x) => x.data ?? []) + .catch(() => []), + })), + ), + Date.now(), + ) + if (fetched) { + await openSession(fetched) return } diff --git a/packages/app/src/pages/layout/helpers.test.ts b/packages/app/src/pages/layout/helpers.test.ts index 83d8f4748..7627d9ba1 100644 --- a/packages/app/src/pages/layout/helpers.test.ts +++ b/packages/app/src/pages/layout/helpers.test.ts @@ -1,6 +1,25 @@ import { describe, expect, test } from "bun:test" +import { type Session } from "@opencode-ai/sdk/v2/client" import { collectOpenProjectDeepLinks, drainPendingDeepLinks, parseDeepLink } from "./deep-links" -import { displayName, errorMessage, getDraggableId, syncWorkspaceOrder, workspaceKey } from "./helpers" +import { + displayName, + errorMessage, + getDraggableId, + latestRootSession, + syncWorkspaceOrder, + workspaceKey, +} from "./helpers" + +const session = (input: Partial<Session> & Pick<Session, "id" | "directory">) => + ({ + title: "", + version: "v2", + parentID: undefined, + messageCount: 0, + permissions: { session: {}, share: {} }, + time: { created: 0, updated: 0, archived: undefined }, + ...input, + }) as Session describe("layout deep links", () => { test("parses open-project deep links", () => { @@ -73,6 +92,61 @@ describe("layout workspace helpers", () => { expect(result).toEqual(["/root", "/c", "/b"]) }) + 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, + ) + + expect(result?.id).toBe("workspace") + }) + + 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, + ) + + expect(result?.id).toBe("root") + }) + test("extracts draggable id safely", () => { expect(getDraggableId({ draggable: { id: "x" } })).toBe("x") expect(getDraggableId({ draggable: { id: 42 } })).toBeUndefined() diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts index 6a1e7c012..be4297fbe 100644 --- a/packages/app/src/pages/layout/helpers.ts +++ b/packages/app/src/pages/layout/helpers.ts @@ -28,6 +28,11 @@ export const isRootVisibleSession = (session: Session, directory: string) => 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 latestRootSession = (stores: { session: Session[]; path: { directory: string } }[], now: number) => + stores + .flatMap((store) => store.session.filter((session) => isRootVisibleSession(session, store.path.directory))) + .sort(sortSessions(now))[0] + export const childMapByParent = (sessions: Session[]) => { const map = new Map<string, string[]>() for (const session of sessions) { |
