-
+
-
-
-
- }
- >
-
(
+
+
+ props.location({
+ onWorkspace: (value) => {
+ if (value !== "main") setOnboarding("used", true)
+ },
+ })
+ }
/>
-
-
+
+ {(branch) => (
+
+ )}
+
+
+ )}
@@ -243,3 +258,71 @@ function NewSessionTips(props: {
)
}
+
+function NewSessionLocationTrigger(props: {
+ project: PromptProject
+ /** "main", "create", or a worktree directory. */
+ workspace: string
+ root: string
+ onboarding: boolean
+ onClick: () => void
+}) {
+ const language = useLanguage()
+
+ const path = () => {
+ if (props.workspace === "main") return props.root
+ if (props.workspace === "create") return language.t("workspace.new")
+
+ return props.workspace
+ }
+
+ return (
+
+
+
+ {language.t("workspace.onboarding.title")}
+
+ {language.t("workspace.onboarding.description")}
+
+ ) : (
+ language.t("session.new.workspace.trigger.tooltip")
+ )
+ }
+ contentClass={props.onboarding ? "max-w-[280px]" : undefined}
+ class="min-w-0"
+ >
+
+
+ )
+}
diff --git a/packages/app/src/new-session/workspace/controller.ts b/packages/app/src/new-session/workspace/controller.ts
index 8a3043587b0..89f2b0d4728 100644
--- a/packages/app/src/new-session/workspace/controller.ts
+++ b/packages/app/src/new-session/workspace/controller.ts
@@ -14,6 +14,7 @@ import {
isWorkspaceSelection,
workspaceDefaultSelection,
workspaceSelectionDestination,
+ workspaceSelectionDirectories,
} from "@/workspaces/paths"
export function resolveNewSessionWorktree(input: { enabled: boolean; selected?: string; fallback?: string }) {
@@ -53,7 +54,6 @@ export function createNewSessionWorkspaceController(input: {
selectedBranch: () => string | undefined
setSelectedWorktree: (worktree: string | undefined) => void
setSelectedBranch: (branch: string | undefined) => void
- onViewAll: () => void
}) {
const sdk = useWorkspaceLocation()
const serverSDK = useServerSDK()
@@ -119,15 +119,7 @@ export function createNewSessionWorkspaceController(input: {
if (!project) return []
- const directories = [
- ...worktreeItems().map((item) => item.directory),
- ...project.worktrees.map((item) => item.directory),
- ...(project.sandboxes ?? []),
- ]
-
- return directories
- .filter((directory) => !sameDirectory(project.worktree, directory))
- .filter((directory, index, items) => items.findIndex((item) => sameDirectory(item, directory)) === index)
+ return workspaceSelectionDirectories(project, worktreeItems())
})
const managedWorktrees = createMemo(() => {
@@ -186,8 +178,8 @@ export function createNewSessionWorkspaceController(input: {
const [branches] = createResource(
() => (visible() ? { directory: projectRoot(), search: state.search } : undefined),
({ directory, search }) =>
- serverSDK.api.vcs
- .branch.list({ location: { directory }, search, limit: 50 })
+ serverSDK.api.vcs.branch
+ .list({ location: { directory }, search, limit: 50 })
.then((response) => ({ directory, search, data: response.data }))
.catch(() => ({ directory, search, data: [] })),
)
@@ -295,7 +287,6 @@ export function createNewSessionWorkspaceController(input: {
].slice(0, 50)
},
searchBranches,
- openAll: input.onViewAll,
},
bar: {
visible,
diff --git a/packages/app/src/new-session/workspace/selector.tsx b/packages/app/src/new-session/workspace/selector.tsx
index 11935c47fb2..6ee542596e2 100644
--- a/packages/app/src/new-session/workspace/selector.tsx
+++ b/packages/app/src/new-session/workspace/selector.tsx
@@ -1,351 +1,120 @@
-import { createMemo, createSignal, For, Show } from "solid-js"
+import { createSignal, For, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import { Menu } from "@opencode/ui/menu"
import { Tooltip } from "@opencode/ui/tooltip"
import { Icon } from "@opencode/ui/icon"
-import { getFilename, sameDirectory } from "@opencode/util/path"
import { useLanguage } from "@/runtime/i18n/language"
-import { WorkspaceSubmenu } from "@/workspaces/submenu"
-export function PromptWorkspaceSelector(props: {
- value: string
- projectRoot: string
- workspaces: string[]
+/** The base branch for a new worktree. */
+export function PromptBranchSelector(props: {
+ branch: string
branches: string[]
- branch?: string
- onboarding?: boolean
- variant?: "inline" | "summary"
- onChange: (value: string) => void
onCreate: (branch: string) => void
onSearch: (search: string) => void
onDone?: () => void
- onViewAll: () => void
}) {
const language = useLanguage()
- const summary = () => props.variant === "summary"
-
- const placement = createMemo(() =>
- summary() ? (language.direction() === "rtl" ? "right-start" : "left-start") : "bottom",
- )
-
const [search, setSearch] = createStore({ branches: "" })
- let branchSearchInput: HTMLInputElement | undefined
- const branchTruncation = createTruncatedText()
-
- let pending: { type: "select"; value: string } | { type: "create"; branch: string } | { type: "viewAll" } | undefined
- const selected = () => (sameDirectory(props.value, props.projectRoot) ? "main" : props.value)
-
- const icon = () => {
- if (selected() === "main") return "monitor"
-
- if (selected() === "create") return "plus"
-
- return "outline-worktree"
- }
-
- const select = (value: string) => {
- pending = { type: "select", value }
- }
-
- const onOpenChange = (open: boolean) => {
- if (open) {
- setSearch({ branches: "" })
- props.onSearch("")
-
- return
- }
-
- const action = pending
- pending = undefined
-
- if (action?.type === "select") props.onChange(action.value)
-
- if (action?.type === "create") props.onCreate(action.branch)
-
- if (action?.type === "viewAll") {
- props.onViewAll()
-
- return
- }
-
- props.onDone?.()
- }
-
- const label = () => {
- if (selected() === "main")
- return language.t(summary() ? "session.new.workspace.local" : "session.new.workspace.triggerLocal")
-
- if (props.value === "create") return language.t("workspace.new")
-
- return getFilename(props.value)
- }
-
- return (
- <>
-
- /
-
-
-
-
- {language.t("workspace.onboarding.title")}
-
- {language.t("workspace.onboarding.description")}
-
- ) : (
- language.t("session.new.workspace.trigger.tooltip")
- )
- }
- contentClass={props.onboarding ? "max-w-[280px]" : undefined}
- class={summary() ? "min-w-0 w-full" : "min-w-0"}
- >
-