@@ -141,6 +141,11 @@ type bashInput struct {
Background bool `json:"background,omitempty"`
}
+// BashDisplayData is the display data sent to the UI for bash tool results.
+type BashDisplayData struct {
+ WorkingDir string `json:"workingDir"`
+}
+
type BackgroundResult struct {
PID int
OutFile string
@@ -203,13 +208,15 @@ func (b *BashTool) Run(ctx context.Context, m json.RawMessage) llm.ToolOut {
timeout := req.timeout(b.Timeouts)
+ display := BashDisplayData{WorkingDir: wd}
+
// If Background is set to true, use executeBackgroundBash
if req.Background {
result, err := b.executeBackgroundBash(ctx, req, timeout)
if err != nil {
return llm.ErrorToolOut(err)
}
- return llm.ToolOut{LLMContent: llm.TextContent(result.XMLish())}
+ return llm.ToolOut{LLMContent: llm.TextContent(result.XMLish()), Display: display}
}
// For foreground commands, use executeBash
@@ -217,7 +224,7 @@ func (b *BashTool) Run(ctx context.Context, m json.RawMessage) llm.ToolOut {
if execErr != nil {
return llm.ErrorToolOut(execErr)
}
- return llm.ToolOut{LLMContent: llm.TextContent(out)}
+ return llm.ToolOut{LLMContent: llm.TextContent(out), Display: display}
}
const maxBashOutputLength = 131072
@@ -87,6 +87,15 @@ func TestBashTool(t *testing.T) {
if len(result) == 0 || result[0].Text != expected {
t.Errorf("Expected %q, got %q", expected, result[0].Text)
}
+
+ // Verify Display data contains working directory
+ display, ok := toolOut.Display.(BashDisplayData)
+ if !ok {
+ t.Fatalf("Expected Display to be BashDisplayData, got %T", toolOut.Display)
+ }
+ if display.WorkingDir != "/" {
+ t.Errorf("Expected WorkingDir to be '/', got %q", display.WorkingDir)
+ }
})
// Test with arguments
@@ -1,6 +1,11 @@
import React, { useState } from "react";
import { LLMContent } from "../types";
+// Display data from the bash tool backend
+interface BashDisplayData {
+ workingDir: string;
+}
+
interface BashToolProps {
// For tool_use (pending state)
toolInput?: unknown;
@@ -10,11 +15,28 @@ interface BashToolProps {
toolResult?: LLMContent[];
hasError?: boolean;
executionTime?: string;
+ display?: unknown;
}
-function BashTool({ toolInput, isRunning, toolResult, hasError, executionTime }: BashToolProps) {
+function BashTool({
+ toolInput,
+ isRunning,
+ toolResult,
+ hasError,
+ executionTime,
+ display,
+}: BashToolProps) {
const [isExpanded, setIsExpanded] = useState(false);
+ // Extract working directory from display data
+ const displayData: BashDisplayData | null =
+ display &&
+ typeof display === "object" &&
+ "workingDir" in display &&
+ typeof display.workingDir === "string"
+ ? (display as BashDisplayData)
+ : null;
+
// Extract command from toolInput
const command =
typeof toolInput === "object" &&
@@ -51,6 +73,11 @@ function BashTool({ toolInput, isRunning, toolResult, hasError, executionTime }:
<div className="bash-tool-summary">
<span className={`bash-tool-emoji ${isRunning ? "running" : ""}`}>🛠️</span>
<span className="bash-tool-command">{displayCommand}</span>
+ {displayData?.workingDir && (
+ <span className="bash-tool-cwd" title={displayData.workingDir}>
+ in {displayData.workingDir}
+ </span>
+ )}
{isComplete && isCancelled && <span className="bash-tool-cancelled">✗ cancelled</span>}
{isComplete && hasError && !isCancelled && <span className="bash-tool-error">✗</span>}
{isComplete && !hasError && <span className="bash-tool-success">✓</span>}
@@ -84,6 +111,12 @@ function BashTool({ toolInput, isRunning, toolResult, hasError, executionTime }:
{isExpanded && (
<div className="bash-tool-details">
+ {displayData?.workingDir && (
+ <div className="bash-tool-section">
+ <div className="bash-tool-label">Working Directory:</div>
+ <pre className="bash-tool-code bash-tool-code-cwd">{displayData.workingDir}</pre>
+ </div>
+ )}
<div className="bash-tool-section">
<div className="bash-tool-label">Command:</div>
<pre className="bash-tool-code">{command}</pre>
@@ -1004,6 +1004,19 @@ button {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
+ flex-shrink: 1;
+ min-width: 0;
+}
+
+.bash-tool-cwd {
+ font-family: var(--font-mono);
+ font-size: 0.75rem;
+ color: var(--text-tertiary);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ flex-shrink: 0;
+ max-width: 30%;
}
.bash-tool-running {