-
Notifications
You must be signed in to change notification settings - Fork 108
🤖 feat: add UI styling for background bash processes #923
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
cd9fe36
🤖 feat: add background bash process execution with SSH support
ethanndickson 97ac438
feat: enable background bash execution on Windows
ethanndickson cc16389
fix: SSH background spawn env vars and tilde path expansion
ethanndickson 9db7d21
refactor: remove nullable handle from BackgroundProcess
ethanndickson b665cfb
fix: use polling instead of fixed delays in background process tests
ethanndickson 14491fc
fix: revert double-quoting of SSH background spawn paths
ethanndickson e277809
fix: use platform temp dir for background process output
ethanndickson 8e55187
fix: support tilde paths in SSH bgOutputDir
ethanndickson a12c8ed
fix: use bash shell for POSIX commands on Windows
ethanndickson 798ced5
fix: quote bash path and validate SSH cwd in spawnBackground
ethanndickson 656c68d
docs: clarify in-memory process tracking scope
ethanndickson 2bb296b
fix: expand tilde in SSH terminate exitCodePath
ethanndickson 2f3cbb1
fix: convert Windows paths to POSIX for Git Bash commands
ethanndickson 352ded9
fix: Windows path handling and MSYS2 process termination
ethanndickson 4b9128f
fix: add quotePath to buildTerminateCommand for SSH tilde support
ethanndickson a3b971b
🤖 refactor: simplify SSHRuntime tilde resolution to single cached method
ethanndickson f0575a7
🤖 feat: add display_name field for background processes
ethanndickson 2c09936
🤖 fix: use PGID for Windows MSYS2 process termination (no /proc on ma…
ethanndickson 6d815be
🤖 fix: update backgroundCommands test for new PID PGID output format
ethanndickson a1e7320
🤖 docs: improve background process tool descriptions for clarity
ethanndickson f6ac07c
🤖 test: skip flaky AI-dependent background bash integration tests
ethanndickson 5dbc14c
Revert "🤖 test: skip flaky AI-dependent background bash integration t…
ethanndickson 211d10c
fix: background bash tests can't start with sleep command
ethanndickson 38f629c
fix: toolOutputContains should check message field for terminate result
ethanndickson 846b365
🤖 refactor: universal PGID lookup and terminate for background processes
ethanndickson 6becd7f
🤖 fix: use set -m for process group isolation
ethanndickson df15f39
refactor: simplify background process - remove PGID lookup
ethanndickson 384ff92
fix: write exit code after process exits in terminate command
ethanndickson 68dd866
fix: check process group instead of parent PID in terminate
ethanndickson 13ed15c
docs: clarify PID === PGID in SSHBackgroundHandle comment
ethanndickson 63dfc3a
fix: address Copilot review comments
ethanndickson badae77
test: add process group termination and display_name tests
ethanndickson 228d927
fix: background bash tests can't start with sleep command
ethanndickson b5b7e19
🤖 feat: add UI styling for background bash processes
ethanndickson 58e30ea
refactor: extract shared tool primitives (ToolIcon, ErrorBox, OutputP…
ethanndickson 76ae329
refactor: migrate existing tool components to shared primitives
ethanndickson 64b0842
refactor: use OutputPaths compact mode in BashBackgroundListToolCall
ethanndickson 144a77f
🤖 fix: count only running processes in background list header
ethanndickson 32ee67b
Merge remote-tracking branch 'origin/main' into bash-background-ui-st…
ethanndickson 10b3b09
🤖 fix: use process_id as React key for uniqueness
ethanndickson File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
125 changes: 125 additions & 0 deletions
125
src/browser/components/tools/BashBackgroundListToolCall.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import React from "react"; | ||
| import type { | ||
| BashBackgroundListArgs, | ||
| BashBackgroundListResult, | ||
| BashBackgroundListProcess, | ||
| } from "@/common/types/tools"; | ||
| import { | ||
| ToolContainer, | ||
| ToolHeader, | ||
| ExpandIcon, | ||
| StatusIndicator, | ||
| ToolDetails, | ||
| DetailSection, | ||
| LoadingDots, | ||
| ToolIcon, | ||
| ErrorBox, | ||
| OutputPaths, | ||
| } from "./shared/ToolPrimitives"; | ||
| import { | ||
| useToolExpansion, | ||
| getStatusDisplay, | ||
| formatDuration, | ||
| type ToolStatus, | ||
| } from "./shared/toolUtils"; | ||
| import { cn } from "@/common/lib/utils"; | ||
|
|
||
| interface BashBackgroundListToolCallProps { | ||
| args: BashBackgroundListArgs; | ||
| result?: BashBackgroundListResult; | ||
| status?: ToolStatus; | ||
| } | ||
|
|
||
| function getProcessStatusStyle(status: BashBackgroundListProcess["status"]) { | ||
| switch (status) { | ||
| case "running": | ||
| return "bg-success text-on-success"; | ||
| case "exited": | ||
| return "bg-[hsl(0,0%,40%)] text-white"; | ||
| case "killed": | ||
| case "failed": | ||
| return "bg-danger text-on-danger"; | ||
| } | ||
| } | ||
|
|
||
| export const BashBackgroundListToolCall: React.FC<BashBackgroundListToolCallProps> = ({ | ||
| args: _args, | ||
| result, | ||
| status = "pending", | ||
| }) => { | ||
| const { expanded, toggleExpanded } = useToolExpansion(false); | ||
|
|
||
| const processes = result?.success ? result.processes : []; | ||
| const runningCount = processes.filter((p) => p.status === "running").length; | ||
|
|
||
| return ( | ||
| <ToolContainer expanded={expanded}> | ||
| <ToolHeader onClick={toggleExpanded}> | ||
| <ExpandIcon expanded={expanded}>▶</ExpandIcon> | ||
| <ToolIcon emoji="📋" toolName="bash_background_list" /> | ||
| <span className="text-text-secondary"> | ||
| {result?.success | ||
| ? runningCount === 0 | ||
| ? "No background processes" | ||
| : `${runningCount} background process${runningCount !== 1 ? "es" : ""}` | ||
| : "Listing background processes"} | ||
| </span> | ||
| <StatusIndicator status={status}>{getStatusDisplay(status)}</StatusIndicator> | ||
| </ToolHeader> | ||
|
|
||
| {expanded && ( | ||
| <ToolDetails> | ||
| {result?.success === false && ( | ||
| <DetailSection> | ||
| <ErrorBox>{result.error}</ErrorBox> | ||
| </DetailSection> | ||
| )} | ||
|
|
||
| {result?.success && processes.length > 0 && ( | ||
| <DetailSection> | ||
| <div className="space-y-2"> | ||
| {processes.map((proc) => ( | ||
| <div | ||
| key={proc.display_name ?? proc.process_id} | ||
| className="bg-code-bg rounded px-2 py-1.5 text-[11px]" | ||
| > | ||
| <div className="mb-1 flex items-center gap-2"> | ||
| <span className="text-text font-mono"> | ||
| {proc.display_name ?? proc.process_id} | ||
| </span> | ||
| <span | ||
| className={cn( | ||
| "inline-block rounded px-1.5 py-0.5 text-[9px] font-medium uppercase", | ||
| getProcessStatusStyle(proc.status) | ||
| )} | ||
| > | ||
| {proc.status} | ||
| {proc.exitCode !== undefined && ` (${proc.exitCode})`} | ||
| </span> | ||
| <span className="text-text-secondary ml-auto"> | ||
| {formatDuration(proc.uptime_ms)} | ||
| </span> | ||
| </div> | ||
| <div className="text-text-secondary truncate font-mono" title={proc.script}> | ||
| {proc.script} | ||
| </div> | ||
| <OutputPaths stdout={proc.stdout_path} stderr={proc.stderr_path} compact /> | ||
| </div> | ||
| ))} | ||
| </div> | ||
| </DetailSection> | ||
| )} | ||
|
|
||
| {status === "executing" && !result && ( | ||
| <DetailSection> | ||
| <div className="text-[11px]"> | ||
| Listing processes | ||
| <LoadingDots /> | ||
| </div> | ||
| </DetailSection> | ||
| )} | ||
| </ToolDetails> | ||
| )} | ||
| </ToolContainer> | ||
| ); | ||
| }; | ||
39 changes: 39 additions & 0 deletions
39
src/browser/components/tools/BashBackgroundTerminateToolCall.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import React from "react"; | ||
| import type { | ||
| BashBackgroundTerminateArgs, | ||
| BashBackgroundTerminateResult, | ||
| } from "@/common/types/tools"; | ||
| import { ToolContainer, ToolHeader, StatusIndicator, ToolIcon } from "./shared/ToolPrimitives"; | ||
| import { getStatusDisplay, type ToolStatus } from "./shared/toolUtils"; | ||
|
|
||
| interface BashBackgroundTerminateToolCallProps { | ||
| args: BashBackgroundTerminateArgs; | ||
| result?: BashBackgroundTerminateResult; | ||
| status?: ToolStatus; | ||
| } | ||
|
|
||
| export const BashBackgroundTerminateToolCall: React.FC<BashBackgroundTerminateToolCallProps> = ({ | ||
| args, | ||
| result, | ||
| status = "pending", | ||
| }) => { | ||
| const statusDisplay = getStatusDisplay(status); | ||
|
|
||
| return ( | ||
| <ToolContainer expanded={false}> | ||
| <ToolHeader> | ||
| <ToolIcon emoji="⏹️" toolName="bash_background_terminate" /> | ||
| <span className="text-text font-mono"> | ||
| {result?.success === true ? (result.display_name ?? args.process_id) : args.process_id} | ||
| </span> | ||
| {result?.success === true && ( | ||
| <span className="text-text-secondary text-[10px]">terminated</span> | ||
| )} | ||
| {result?.success === false && ( | ||
| <span className="text-danger text-[10px]">{result.error}</span> | ||
| )} | ||
| <StatusIndicator status={status}>{statusDisplay}</StatusIndicator> | ||
| </ToolHeader> | ||
| </ToolContainer> | ||
| ); | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.