mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-21 00:04:49 +00:00
Add green borders around bash execution component
This commit is contained in:
parent
bd0d0676d4
commit
d5200b4f1c
1 changed files with 32 additions and 22 deletions
|
|
@ -6,6 +6,7 @@ import { Container, Loader, Spacer, Text, type TUI } from "@mariozechner/pi-tui"
|
||||||
import stripAnsi from "strip-ansi";
|
import stripAnsi from "strip-ansi";
|
||||||
import { theme } from "../theme/theme.js";
|
import { theme } from "../theme/theme.js";
|
||||||
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from "../tools/truncate.js";
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, type TruncationResult, truncateTail } from "../tools/truncate.js";
|
||||||
|
import { DynamicBorder } from "./dynamic-border.js";
|
||||||
|
|
||||||
// Preview line limit when not expanded (matches tool execution behavior)
|
// Preview line limit when not expanded (matches tool execution behavior)
|
||||||
const PREVIEW_LINES = 20;
|
const PREVIEW_LINES = 20;
|
||||||
|
|
@ -18,24 +19,28 @@ export class BashExecutionComponent extends Container {
|
||||||
private loader: Loader;
|
private loader: Loader;
|
||||||
private truncationResult?: TruncationResult;
|
private truncationResult?: TruncationResult;
|
||||||
private fullOutputPath?: string;
|
private fullOutputPath?: string;
|
||||||
private contentText: Text;
|
|
||||||
private statusText: Text | null = null;
|
|
||||||
private expanded = false;
|
private expanded = false;
|
||||||
|
private contentContainer: Container;
|
||||||
|
|
||||||
constructor(command: string, ui: TUI) {
|
constructor(command: string, ui: TUI) {
|
||||||
super();
|
super();
|
||||||
this.command = command;
|
this.command = command;
|
||||||
|
|
||||||
|
const borderColor = (str: string) => theme.fg("bashMode", str);
|
||||||
|
|
||||||
// Add spacer
|
// Add spacer
|
||||||
this.addChild(new Spacer(1));
|
this.addChild(new Spacer(1));
|
||||||
|
|
||||||
|
// Top border
|
||||||
|
this.addChild(new DynamicBorder(borderColor));
|
||||||
|
|
||||||
|
// Content container (holds dynamic content between borders)
|
||||||
|
this.contentContainer = new Container();
|
||||||
|
this.addChild(this.contentContainer);
|
||||||
|
|
||||||
// Command header
|
// Command header
|
||||||
const header = new Text(theme.fg("bashMode", theme.bold(`$ ${command}`)), 1, 0);
|
const header = new Text(theme.fg("bashMode", theme.bold(`$ ${command}`)), 1, 0);
|
||||||
this.addChild(header);
|
this.contentContainer.addChild(header);
|
||||||
|
|
||||||
// Output area (will be updated)
|
|
||||||
this.contentText = new Text("", 1, 0);
|
|
||||||
this.addChild(this.contentText);
|
|
||||||
|
|
||||||
// Loader
|
// Loader
|
||||||
this.loader = new Loader(
|
this.loader = new Loader(
|
||||||
|
|
@ -44,7 +49,10 @@ export class BashExecutionComponent extends Container {
|
||||||
(text) => theme.fg("muted", text),
|
(text) => theme.fg("muted", text),
|
||||||
"Running... (esc to cancel)",
|
"Running... (esc to cancel)",
|
||||||
);
|
);
|
||||||
this.addChild(this.loader);
|
this.contentContainer.addChild(this.loader);
|
||||||
|
|
||||||
|
// Bottom border
|
||||||
|
this.addChild(new DynamicBorder(borderColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -83,9 +91,8 @@ export class BashExecutionComponent extends Container {
|
||||||
this.truncationResult = truncationResult;
|
this.truncationResult = truncationResult;
|
||||||
this.fullOutputPath = fullOutputPath;
|
this.fullOutputPath = fullOutputPath;
|
||||||
|
|
||||||
// Stop and remove loader
|
// Stop loader
|
||||||
this.loader.stop();
|
this.loader.stop();
|
||||||
this.removeChild(this.loader);
|
|
||||||
|
|
||||||
this.updateDisplay();
|
this.updateDisplay();
|
||||||
}
|
}
|
||||||
|
|
@ -106,19 +113,23 @@ export class BashExecutionComponent extends Container {
|
||||||
const displayLines = availableLines.slice(-maxDisplayLines); // Show last N lines (tail)
|
const displayLines = availableLines.slice(-maxDisplayLines); // Show last N lines (tail)
|
||||||
const hiddenLineCount = availableLines.length - displayLines.length;
|
const hiddenLineCount = availableLines.length - displayLines.length;
|
||||||
|
|
||||||
let displayText = "";
|
// Rebuild content container
|
||||||
|
this.contentContainer.clear();
|
||||||
|
|
||||||
|
// Command header
|
||||||
|
const header = new Text(theme.fg("bashMode", theme.bold(`$ ${this.command}`)), 1, 0);
|
||||||
|
this.contentContainer.addChild(header);
|
||||||
|
|
||||||
|
// Output
|
||||||
if (displayLines.length > 0) {
|
if (displayLines.length > 0) {
|
||||||
displayText = displayLines.map((line) => theme.fg("muted", line)).join("\n");
|
const displayText = displayLines.map((line) => theme.fg("muted", line)).join("\n");
|
||||||
|
this.contentContainer.addChild(new Text("\n" + displayText, 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.contentText.setText(displayText ? "\n" + displayText : "");
|
// Loader or status
|
||||||
|
if (this.status === "running") {
|
||||||
// Update/add status text if complete
|
this.contentContainer.addChild(this.loader);
|
||||||
if (this.status !== "running") {
|
} else {
|
||||||
if (this.statusText) {
|
|
||||||
this.removeChild(this.statusText);
|
|
||||||
}
|
|
||||||
|
|
||||||
const statusParts: string[] = [];
|
const statusParts: string[] = [];
|
||||||
|
|
||||||
// Show how many lines are hidden (collapsed preview)
|
// Show how many lines are hidden (collapsed preview)
|
||||||
|
|
@ -139,8 +150,7 @@ export class BashExecutionComponent extends Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (statusParts.length > 0) {
|
if (statusParts.length > 0) {
|
||||||
this.statusText = new Text("\n" + statusParts.join("\n"), 1, 0);
|
this.contentContainer.addChild(new Text("\n" + statusParts.join("\n"), 1, 0));
|
||||||
this.addChild(this.statusText);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue