Просмотр исходного кода

feat(tui): inherit session directory when creating a new session (#39753)

Kit Langton 2 недель назад
Родитель
Сommit
a460f02f67

+ 1 - 0
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()
         },

+ 10 - 3
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
   })

+ 5 - 0
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,
       }}
     >

+ 1 - 0
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
 }
 

+ 8 - 2
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()