summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages/layout
diff options
context:
space:
mode:
authorLuke Parker <[email protected]>2026-04-30 08:39:19 +1000
committerGitHub <[email protected]>2026-04-29 22:39:19 +0000
commitd7b7be1909d614a4022b345bdbeef0c1ec32e159 (patch)
treeb25640c571a0333b62cf7f06a0ee7ea24b8d3c68 /packages/app/src/pages/layout
parenta740d2c66782ef3371146cd55d70920ae9b94daf (diff)
downloadopencode-d7b7be1909d614a4022b345bdbeef0c1ec32e159.tar.gz
opencode-d7b7be1909d614a4022b345bdbeef0c1ec32e159.zip
fix(desktop): Path mismatches cause sessions missing + strong ID + existing data fix (#25013)
Diffstat (limited to 'packages/app/src/pages/layout')
-rw-r--r--packages/app/src/pages/layout/helpers.test.ts16
-rw-r--r--packages/app/src/pages/layout/helpers.ts17
-rw-r--r--packages/app/src/pages/layout/sidebar-workspace.tsx5
3 files changed, 16 insertions, 22 deletions
diff --git a/packages/app/src/pages/layout/helpers.test.ts b/packages/app/src/pages/layout/helpers.test.ts
index 988332ab7..9cf302482 100644
--- a/packages/app/src/pages/layout/helpers.test.ts
+++ b/packages/app/src/pages/layout/helpers.test.ts
@@ -14,8 +14,8 @@ import {
errorMessage,
hasProjectPermissions,
latestRootSession,
- workspaceKey,
} from "./helpers"
+import { pathKey } from "@/utils/path-key"
const session = (input: Partial<Session> & Pick<Session, "id" | "directory">) =>
({
@@ -104,16 +104,16 @@ describe("layout deep links", () => {
describe("layout workspace helpers", () => {
test("normalizes trailing slash in workspace key", () => {
- expect(workspaceKey("/tmp/demo///")).toBe("/tmp/demo")
- expect(workspaceKey("C:\\tmp\\demo\\\\")).toBe("C:/tmp/demo")
+ expect(String(pathKey("/tmp/demo///"))).toBe("/tmp/demo")
+ expect(String(pathKey("C:\\tmp\\demo\\\\"))).toBe("C:/tmp/demo")
})
test("preserves posix and drive roots in workspace key", () => {
- expect(workspaceKey("/")).toBe("/")
- expect(workspaceKey("///")).toBe("/")
- expect(workspaceKey("C:\\")).toBe("C:/")
- expect(workspaceKey("C://")).toBe("C:/")
- expect(workspaceKey("C:///")).toBe("C:/")
+ expect(String(pathKey("/"))).toBe("/")
+ expect(String(pathKey("///"))).toBe("/")
+ expect(String(pathKey("C:\\"))).toBe("C:/")
+ expect(String(pathKey("C://"))).toBe("C:/")
+ expect(String(pathKey("C:///"))).toBe("C:/")
})
test("keeps local first while preserving known order", () => {
diff --git a/packages/app/src/pages/layout/helpers.ts b/packages/app/src/pages/layout/helpers.ts
index 4bc5254d9..d53381e40 100644
--- a/packages/app/src/pages/layout/helpers.ts
+++ b/packages/app/src/pages/layout/helpers.ts
@@ -1,19 +1,12 @@
import { getFilename } from "@opencode-ai/core/util/path"
import { type Session } from "@opencode-ai/sdk/v2/client"
+import { pathKey } from "@/utils/path-key"
type SessionStore = {
session?: Session[]
path: { directory: string }
}
-export const workspaceKey = (directory: string) => {
- const value = directory.replaceAll("\\", "/")
- const drive = value.match(/^([A-Za-z]:)\/+$/)
- if (drive) return `${drive[1]}/`
- if (/^\/+$/i.test(value)) return "/"
- return value.replace(/\/+$/, "")
-}
-
function sortSessions(now: number) {
const oneMinuteAgo = now - 60 * 1000
return (a: Session, b: Session) => {
@@ -29,7 +22,7 @@ function sortSessions(now: number) {
}
const isRootVisibleSession = (session: Session, directory: string) =>
- workspaceKey(session.directory) === workspaceKey(directory) && !session.parentID && !session.time?.archived
+ pathKey(session.directory) === pathKey(directory) && !session.parentID && !session.time?.archived
export const roots = (store: SessionStore) =>
(store.session ?? []).filter((session) => isRootVisibleSession(session, store.path.directory))
@@ -72,11 +65,11 @@ export const errorMessage = (err: unknown, fallback: string) => {
}
export const effectiveWorkspaceOrder = (local: string, dirs: string[], persisted?: string[]) => {
- const root = workspaceKey(local)
+ const root = pathKey(local)
const live = new Map<string, string>()
for (const dir of dirs) {
- const key = workspaceKey(dir)
+ const key = pathKey(dir)
if (key === root) continue
if (!live.has(key)) live.set(key, dir)
}
@@ -85,7 +78,7 @@ export const effectiveWorkspaceOrder = (local: string, dirs: string[], persisted
const result = [local]
for (const dir of persisted) {
- const key = workspaceKey(dir)
+ const key = pathKey(dir)
if (key === root) continue
const match = live.get(key)
if (!match) continue
diff --git a/packages/app/src/pages/layout/sidebar-workspace.tsx b/packages/app/src/pages/layout/sidebar-workspace.tsx
index 0a3fc7f41..d2e887b44 100644
--- a/packages/app/src/pages/layout/sidebar-workspace.tsx
+++ b/packages/app/src/pages/layout/sidebar-workspace.tsx
@@ -16,8 +16,9 @@ import { type Session } from "@opencode-ai/sdk/v2/client"
import { type LocalProject } from "@/context/layout"
import { loadSessionsQuery, useGlobalSync } from "@/context/global-sync"
import { useLanguage } from "@/context/language"
+import { pathKey } from "@/utils/path-key"
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
-import { sortedRootSessions, workspaceKey } from "./helpers"
+import { sortedRootSessions } from "./helpers"
import { useQuery } from "@tanstack/solid-query"
type InlineEditorComponent = (props: {
@@ -309,7 +310,7 @@ export const SortableWorkspace = (props: {
const slug = createMemo(() => base64Encode(props.directory))
const sessions = createMemo(() => sortedRootSessions(workspaceStore, props.sortNow()))
const local = createMemo(() => props.directory === props.project.worktree)
- const active = createMemo(() => workspaceKey(props.ctx.currentDir()) === workspaceKey(props.directory))
+ const active = createMemo(() => pathKey(props.ctx.currentDir()) === pathKey(props.directory))
const workspaceValue = createMemo(() => {
const branch = workspaceStore.vcs?.branch
const name = branch ?? getFilename(props.directory)