diff --git a/client/src/components/run/RunHistory.tsx b/client/src/components/run/RunHistory.tsx index bdbf02b..a39eee6 100644 --- a/client/src/components/run/RunHistory.tsx +++ b/client/src/components/run/RunHistory.tsx @@ -125,7 +125,7 @@ export function ActiveRunsSwitcher({ cwd: r.cwd || "", model: r.model, status: r.status, - promptPreview: "", + promptPreview: r.promptPreview || "", startedAt: r.startedAt ? new Date(r.startedAt).getTime() : 0, endedAt: null, isLive: r.status === "running", diff --git a/client/src/components/run/__tests__/RunHistory.test.tsx b/client/src/components/run/__tests__/RunHistory.test.tsx index 3cd2ad2..8f389fa 100644 --- a/client/src/components/run/__tests__/RunHistory.test.tsx +++ b/client/src/components/run/__tests__/RunHistory.test.tsx @@ -33,6 +33,7 @@ const activeRuns = { model: "claude-opus-5", status: "running", startedAt: "2000-01-01T00:50:00Z", + promptPreview: "the live prompt", endedAt: null, }, ], diff --git a/client/src/lib/api.ts b/client/src/lib/api.ts index c8e5cc4..2c7bfec 100644 --- a/client/src/lib/api.ts +++ b/client/src/lib/api.ts @@ -2466,6 +2466,8 @@ export interface RunHandle { sessionId: string | null; /** ISO timestamp the tmux session was created. */ startedAt: string | null; + /** Initial prompt preview (first 500 chars), null when not provided. */ + promptPreview: string | null; } /** Response shape of GET /api/run. */ diff --git a/client/src/pages/Workspace.tsx b/client/src/pages/Workspace.tsx index b4246c7..61067ba 100644 --- a/client/src/pages/Workspace.tsx +++ b/client/src/pages/Workspace.tsx @@ -50,6 +50,7 @@ import type { RunHandle, RunListResponse, RunMode, + RunStartArgs, } from "../lib/api"; import type { Session, @@ -606,7 +607,7 @@ export function Workspace() { }, [binaryStatus, prompt, cwd, busy, handle, start]); const onStartFromSetup = useCallback( - async (args: any) => { + async (args: RunStartArgs) => { if (busy) return; setBusy("start"); setError(null); @@ -621,29 +622,30 @@ export function Workspace() { throw new Error(t("errors.cwdRequired")); } - let targetLaneId = args.laneId; - if (!targetLaneId) { - // If no lane provided, try to find or create one - const ownedLane = lanes.find((l) => l.cwd === effectiveCwd); - if (ownedLane) { - targetLaneId = ownedLane.id; - setSelectedLaneId(ownedLane.id); - } else { - try { - const ensureResult = await api.lanes.ensure({ cwd: effectiveCwd }); - targetLaneId = ensureResult.lane.id; - setSelectedLaneId(ensureResult.lane.id); - setLanes((prev) => { - const exists = prev.some((l) => l.id === ensureResult.lane.id); - return exists ? prev : [...prev, ensureResult.lane]; - }); - } catch (err) { - throw new Error( - t("errors.laneCreateFailed", { - message: err instanceof Error ? err.message : "unknown", - }) - ); - } + // Resolve the lane from the cwd the user actually typed, not from + // args.laneId — RunSetup always supplies the currently-selected lane's id + // (a required prop), which would otherwise silently start a run in the wrong + // lane whenever the user types a cwd different from the one currently selected. + const ownedLane = lanes.find((l) => l.cwd === effectiveCwd); + let targetLaneId: number; + if (ownedLane) { + targetLaneId = ownedLane.id; + if (ownedLane.id !== args.laneId) setSelectedLaneId(ownedLane.id); + } else { + try { + const ensureResult = await api.lanes.ensure({ cwd: effectiveCwd }); + targetLaneId = ensureResult.lane.id; + setSelectedLaneId(ensureResult.lane.id); + setLanes((prev) => { + const exists = prev.some((l) => l.id === ensureResult.lane.id); + return exists ? prev : [...prev, ensureResult.lane]; + }); + } catch (err) { + throw new Error( + t("errors.laneCreateFailed", { + message: err instanceof Error ? err.message : "unknown", + }) + ); } } diff --git a/client/src/pages/__tests__/__snapshots__/screens.snapshot.test.tsx.snap b/client/src/pages/__tests__/__snapshots__/screens.snapshot.test.tsx.snap index 21503cd..e2d4a45 100644 --- a/client/src/pages/__tests__/__snapshots__/screens.snapshot.test.tsx.snap +++ b/client/src/pages/__tests__/__snapshots__/screens.snapshot.test.tsx.snap @@ -4722,6 +4722,671 @@ exports[`screen snapshots > Claude Config 1`] = ` `; +exports[`screen snapshots > Dashboard 1`] = ` +
+ Real-time overview of Claude Code agent activity +
++ Agents will appear here when a Claude Code session is running. +
++ Events from Claude Code sessions will stream here in real-time. +
+