diff --git a/packages/tui/src/app.tsx b/packages/tui/src/app.tsx index d3736574893..9bbef09c3ce 100644 --- a/packages/tui/src/app.tsx +++ b/packages/tui/src/app.tsx @@ -646,6 +646,7 @@ function App(props: { pair?: DialogPairCredentials }) { run: () => { route.navigate({ type: "home", + location: route.data.type === "session" ? data.session.get(route.data.sessionID)?.location : undefined, }) dialog.clear() }, diff --git a/packages/tui/src/component/prompt/index.tsx b/packages/tui/src/component/prompt/index.tsx index 2d554a49b15..525e384a976 100644 --- a/packages/tui/src/component/prompt/index.tsx +++ b/packages/tui/src/component/prompt/index.tsx @@ -240,7 +240,6 @@ export function Prompt(props: PromptProps) { return undefined }) if (!location) return - move.setDirectory(location.directory, location.directory !== location.project.directory) currentLocation.set(location) return } @@ -963,7 +962,10 @@ export function Prompt(props: PromptProps) { const directory = await move.getDirectory() if (move.pending() && !directory) return false finishMoveProgress = Boolean(move.progress()) - const location = data.location.default() + // The location context is where the next session is created: seeded by the home + // route (launch cwd, inherited session location, or picked project) and updated + // by /cd before a session exists. + const location = currentLocation.ref ?? data.location.default() const created = await client.api.session .create({ @@ -1299,7 +1301,12 @@ export function Prompt(props: PromptProps) { return `Ask anything... "${list()[store.placeholder % list().length]}"` }) const locationLabel = createMemo(() => { - if (!props.sessionID || status() !== "idle") return + if (!props.sessionID) { + // No session yet: show where the next session will be created. + const directory = currentLocation.ref?.directory ?? data.location.default().directory + return abbreviateHome(directory, paths.home) + } + if (status() !== "idle") return const directory = data.session.get(props.sessionID)?.location.directory return directory ? abbreviateHome(directory, paths.home) : undefined }) diff --git a/packages/tui/src/context/location.tsx b/packages/tui/src/context/location.tsx index c539d950137..141d4b89d94 100644 --- a/packages/tui/src/context/location.tsx +++ b/packages/tui/src/context/location.tsx @@ -5,6 +5,8 @@ import { useData } from "./data" const context = createContext<{ readonly current: LocationGetOutput | undefined + // The target location as set, available before the server-synced info in `current` arrives. + readonly ref: LocationRef | undefined set: (location?: LocationRef) => void }>() @@ -37,6 +39,9 @@ export function LocationProvider(props: ParentProps) { get current() { return current() }, + get ref() { + return ref() + }, set, }} > diff --git a/packages/tui/src/context/route.tsx b/packages/tui/src/context/route.tsx index 42025eb239f..869e459506d 100644 --- a/packages/tui/src/context/route.tsx +++ b/packages/tui/src/context/route.tsx @@ -7,6 +7,7 @@ import { useTuiStartup } from "./runtime" export type HomeRoute = { type: "home" prompt?: PromptInfo + // Location carried over from the previous session or project picker so a new session lands there. location?: LocationRef } diff --git a/packages/tui/src/routes/home.tsx b/packages/tui/src/routes/home.tsx index 922151d889c..1a27dd94bf0 100644 --- a/packages/tui/src/routes/home.tsx +++ b/packages/tui/src/routes/home.tsx @@ -1,5 +1,5 @@ import { Prompt, type PromptRef } from "../component/prompt" -import { createEffect, createMemo, createSignal, onMount, Show } from "solid-js" +import { createEffect, createMemo, createSignal, onMount, Show, untrack } from "solid-js" import { Logo } from "../component/logo" import { useArgs } from "../context/args" import { useRouteData } from "../context/route" @@ -31,7 +31,13 @@ export function Home() { const forms = createMemo(() => data.session.form.list("global", currentLocation()) ?? []) let sent = false - createEffect(() => location.set(currentLocation())) + // Track only the route location and (when absent) the default location; location.set + // reads other signals internally and tracking them would re-assert the route location + // after the user overrides it with /cd. + createEffect(() => { + const target = currentLocation() + untrack(() => location.set(target)) + }) onMount(() => { editor.clearSelection()