diff --git a/web/workspace/src/lib/workspace/console/model.test.ts b/web/workspace/src/lib/workspace/console/model.test.ts index 5d75353c..840ff822 100644 --- a/web/workspace/src/lib/workspace/console/model.test.ts +++ b/web/workspace/src/lib/workspace/console/model.test.ts @@ -422,9 +422,11 @@ Deno.test("projectConsole streams distinct Bash stdout and stderr through termin const [line] = projection.lines.filter((line) => line.kind === "tool"); assert(line.body.includes("Bash — failed (exit 7)"), line.body); - assert(line.body.includes("elapsed 300ms"), line.body); - assert(line.body.includes("stdout:\nready\n"), line.body); + assert(!line.body.includes("elapsed"), line.body); + assert(!line.body.includes("stdout:"), line.body); + assert(line.body.includes("ready\n"), line.body); assert(line.body.includes("stderr:\nwarn\n"), line.body); + assert(line.detail?.includes("command: elapsed 300ms"), line.detail ?? ""); assertEquals(line.streaming, false); assertEquals(line.error, true); }); @@ -462,12 +464,13 @@ Deno.test("snapshot restores bounded in-flight Bash command output", () => { const projection = projectConsole([{ eventId: "snapshot-command", event: snapshot }]); const [line] = projection.lines.filter((line) => line.kind === "tool"); assert(line.body.includes("Bash — running…"), line.body); + assert(!line.body.includes("elapsed"), line.body); + assert(!line.body.includes("stdout:"), line.body); + assert(line.body.includes("[… earlier stdout omitted]\ntail\n"), line.body); assert( - line.body.includes("elapsed 250ms · last output at +200ms"), - line.body, + line.detail?.includes("command: elapsed 250ms · last output at +200ms"), + line.detail ?? "", ); - assert(line.body.includes("[stdout tail; earlier output omitted]"), line.body); - assert(line.body.includes("stdout:\ntail\n"), line.body); assertEquals(line.streaming, true); }); diff --git a/web/workspace/src/lib/workspace/console/model.ts b/web/workspace/src/lib/workspace/console/model.ts index 064e1189..b4f695f8 100644 --- a/web/workspace/src/lib/workspace/console/model.ts +++ b/web/workspace/src/lib/workspace/console/model.ts @@ -1505,7 +1505,6 @@ function renderBashTool(toolCall: ToolCallView): string { return compactLines([ `Bash — ${commandStateSuffix(toolCall)}`, command ? `$ ${command}` : argsText(toolCall), - commandTiming(toolCall.command), ["done", "error"].includes(toolCall.state) ? cappedDisplaySection(resultText(toolCall), 10) : renderLiveCommandOutput(toolCall.command), @@ -1549,11 +1548,17 @@ function durationLabel(milliseconds: number): string { function renderLiveCommandOutput(command?: CommandSnapshot): string | undefined { if (!command) return undefined; + const stdout = compactLines([ + command.stdout.truncated ? "[… earlier stdout omitted]" : undefined, + command.stdout.content, + ]); + const stderr = compactLines([ + command.stderr.truncated ? "[… earlier stderr omitted]" : undefined, + command.stderr.content, + ]); return compactLines([ - command.stdout.truncated ? "[stdout tail; earlier output omitted]" : undefined, - command.stdout.content ? `stdout:\n${command.stdout.content}` : undefined, - command.stderr.truncated ? "[stderr tail; earlier output omitted]" : undefined, - command.stderr.content ? `stderr:\n${command.stderr.content}` : undefined, + stdout, + stderr ? `stderr:\n${stderr}` : undefined, ]); } @@ -1569,6 +1574,7 @@ function toolCallDetail(toolCall: ToolCallView): string { return compactLines([ `id: ${toolCall.id}`, `state: ${stateSuffix(toolCall.state)}`, + toolCall.command ? `command: ${commandTiming(toolCall.command)}` : undefined, toolCall.summary ? `summary: ${ normalizeKnownToolResult(toolCall.name, toolCall.summary, toolCall.cwd)