fix(workspace): keep the console cwd on the selected lane's own folder

The cwd was synced only when laneId changed, but a pane can render before
GET /api/lanes has answered — split view restores its pane lanes from
localStorage, and layout 1 paints before the list loads. With no lane
resolved the field fell back to the home suggestion, and since laneId never
changed afterwards it stayed there. RunSetup submits that string verbatim to
POST /api/lanes/:id/start, so the run was started in the wrong folder.

Track the cwd in its own effect keyed on the resolved lane path rather than
on laneId, so it re-syncs as soon as the lane is known. The home default now
applies only while no lane is selected at all.
This commit is contained in:
2026-08-18 11:33:31 +07:00
parent 37adf983e3
commit ab6d6410d5
4 changed files with 184 additions and 2 deletions
@@ -161,6 +161,19 @@ describe("LaneConsolePane", () => {
await waitFor(() => expect(screen.queryByTestId("terminal-view")).not.toBeInTheDocument());
});
it("adopts the lane's cwd when the lane list arrives after the pane mounted", async () => {
// Split view restores its pane lanes from localStorage, so a pane can
// render with a laneId before GET /api/lanes has answered. laneId never
// changes afterwards — only the resolved lane does.
const props = { ...baseProps(), lanes: [], defaultCwd: "/home/tester" };
const { rerender } = render(<LaneConsolePane {...props} />);
const cwdInput = screen.getByPlaceholderText(/type to search/i) as HTMLInputElement;
expect(cwdInput.value).toBe("/home/tester");
rerender(<LaneConsolePane {...props} lanes={[LANE]} />);
await waitFor(() => expect(cwdInput.value).toBe(LANE.cwd));
});
it("shows a lane dropdown only when showLaneSelector is true", () => {
const { rerender } = render(<LaneConsolePane {...baseProps()} showLaneSelector />);
expect(screen.getByTestId("pane-lane-select")).toBeInTheDocument();