From dd68d6eb795e4501141c88489e6ecb0624c2b898 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" <219766164+opencode-agent[bot]@users.noreply.github.com> Date: Wed, 30 Sep 2026 14:34:05 +0800 Subject: [PATCH] fix(app): select new-session project by resolved ID (#52230) Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com> --- .../app/src/new-session/project/controller.ts | 1 + .../src/new-session/project/selector.test.tsx | 51 +++++++++++++++++++ .../app/src/new-session/project/selector.tsx | 16 +++--- 3 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 packages/app/src/new-session/project/selector.test.tsx diff --git a/packages/app/src/new-session/project/controller.ts b/packages/app/src/new-session/project/controller.ts index cf803202167..f3a9cc9d0d0 100644 --- a/packages/app/src/new-session/project/controller.ts +++ b/packages/app/src/new-session/project/controller.ts @@ -62,6 +62,7 @@ export function createComposerProjectControls(props: { draftId: string; worktree return createMemo(() => ({ available: projects(), directory: location().directory, + projectID: location().current?.project.id, server: servers.list.length > 1 ? ServerConnection.key(projectServer()) : undefined, select: selectProject, add: addProject, diff --git a/packages/app/src/new-session/project/selector.test.tsx b/packages/app/src/new-session/project/selector.test.tsx new file mode 100644 index 00000000000..952bdc2ea0d --- /dev/null +++ b/packages/app/src/new-session/project/selector.test.tsx @@ -0,0 +1,51 @@ +import { describe, expect, mock, test } from "bun:test" +import { createRoot } from "solid-js" +import type { PromptProjectControls } from "./selector" + +mock.module("@/runtime/i18n/language", () => ({ useLanguage: () => ({ t: (key: string) => key }) })) + +const { createPromptProjectController } = await import("./selector") + +describe("new session project selection", () => { + test("shows the current project's appearance before its worktree inventory loads", () => { + const generic = { id: "other", worktree: "/other" } + const current = { + id: "current", + worktree: "/repo", + name: "My custom name", + icon: { override: "data:image/png;base64,AAAA" }, + } + const controls: PromptProjectControls = { + available: [generic, current], + directory: "/repo/.opencode/worktree/feature", + projectID: "current", + select() {}, + add() {}, + } + + createRoot((dispose) => { + const controller = createPromptProjectController({ controls: () => controls, onDone() {} }) + expect(controller.selected()).toEqual(current) + dispose() + }) + }) + + test("does not select a matching project ID from another server", () => { + const remote = { id: "shared", worktree: "/remote", server: { key: "remote", name: "Remote" } } + const local = { id: "shared", worktree: "/local", server: { key: "local", name: "Local" } } + const controls: PromptProjectControls = { + available: [remote, local], + directory: "/local/feature", + projectID: "shared", + server: "local", + select() {}, + add() {}, + } + + createRoot((dispose) => { + const controller = createPromptProjectController({ controls: () => controls, onDone() {} }) + expect(controller.selected()).toEqual(local) + dispose() + }) + }) +}) diff --git a/packages/app/src/new-session/project/selector.tsx b/packages/app/src/new-session/project/selector.tsx index 99e207ed33e..0845fb12889 100644 --- a/packages/app/src/new-session/project/selector.tsx +++ b/packages/app/src/new-session/project/selector.tsx @@ -31,6 +31,7 @@ export type PromptProject = { export type PromptProjectControls = { available: PromptProject[] directory: string + projectID?: string server?: string select: (worktree: string, server?: string) => void add: (title: string, server?: string) => void @@ -56,14 +57,15 @@ export function createPromptProjectController(input: { let searchRef: HTMLInputElement | undefined const current = () => { - const key = pathKey(input.controls().directory) - return input - .controls() - .available.find( + const controls = input.controls() + const key = pathKey(controls.directory) + const projects = controls.available.filter((project) => !project.server || project.server.key === controls.server) + return ( + projects.find( (project) => - (!project.server || project.server.key === input.controls().server) && - (pathKey(project.worktree) === key || project.sandboxes?.some((sandbox) => pathKey(sandbox) === key)), - ) + pathKey(project.worktree) === key || project.sandboxes?.some((sandbox) => pathKey(sandbox) === key), + ) ?? projects.find((project) => controls.projectID && project.id === controls.projectID) + ) } const selected = () => current() ?? input.controls().available[0] const projects = () => {