Some checks are pending
CI / detect-changes (push) Waiting to run
CI / docs-check (push) Blocked by required conditions
CI / lint (push) Blocked by required conditions
CI / build (push) Blocked by required conditions
CI / integration-tests (push) Blocked by required conditions
CI / windows-portability (push) Blocked by required conditions
CI / rtk-portability (linux, blacksmith-4vcpu-ubuntu-2404) (push) Blocked by required conditions
CI / rtk-portability (macos, macos-15) (push) Blocked by required conditions
CI / rtk-portability (windows, blacksmith-4vcpu-windows-2025) (push) Blocked by required conditions
- doRender() now catches render errors and emits a fallback line - autonomousStatus ANSI formatting extracted to renderAutonomousStatus() with named color constants instead of raw escape strings - parseCellSizeResponse extracted to pure function with proper validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
93 lines
2.5 KiB
TypeScript
93 lines
2.5 KiB
TypeScript
import type { Component } from "../tui.js";
|
|
|
|
/**
|
|
* Snapshot for the autonomous-mode strip above main TUI content.
|
|
*/
|
|
export type AutonomousModeStatus = {
|
|
currentSlice?: string;
|
|
sliceStatus?: string;
|
|
progress?: number;
|
|
totalTasks?: number;
|
|
completedTasks?: number;
|
|
};
|
|
|
|
// Named ANSI color constants for the autonomous status bar
|
|
const DIM = "\x1b[90m";
|
|
const BOLD_WHITE = "\x1b[97m";
|
|
const CYAN = "\x1b[96m";
|
|
const GREEN = "\x1b[92m";
|
|
const YELLOW = "\x1b[93m";
|
|
const MAGENTA = "\x1b[95m";
|
|
const RESET = "\x1b[0m";
|
|
|
|
/**
|
|
* Renders the autonomous-mode status bar as a single terminal line.
|
|
*
|
|
* Purpose: isolate autonomous chrome from `TUI` so `tui.ts` stays smaller and
|
|
* this strip can evolve independently (copy, colors, layout).
|
|
*/
|
|
export class AutonomousStatusBar implements Component {
|
|
private status: AutonomousModeStatus | undefined;
|
|
|
|
setStatus(status: AutonomousModeStatus | undefined): void {
|
|
this.status = status;
|
|
}
|
|
|
|
getStatus(): AutonomousModeStatus | undefined {
|
|
return this.status;
|
|
}
|
|
|
|
invalidate(): void {}
|
|
|
|
/** Format a single status value with ANSI cyan highlighting. */
|
|
private renderAutonomousStatus(status: string): string {
|
|
return `${CYAN}${status}${RESET}`;
|
|
}
|
|
|
|
render(width: number): string[] {
|
|
if (!this.status) return [];
|
|
|
|
const { currentSlice, sliceStatus, progress, totalTasks, completedTasks } =
|
|
this.status;
|
|
const noColor = process.env.NO_COLOR === "1";
|
|
|
|
let statusLine = noColor
|
|
? "│ AUTONOMOUS MODE "
|
|
: `${DIM}│ AUTONOMOUS MODE `;
|
|
|
|
if (currentSlice) {
|
|
statusLine += noColor
|
|
? `Slice: ${currentSlice} `
|
|
: `${BOLD_WHITE}Slice: ${this.renderAutonomousStatus(currentSlice)} `;
|
|
}
|
|
|
|
if (sliceStatus) {
|
|
statusLine += noColor
|
|
? `Status: ${sliceStatus} `
|
|
: `${BOLD_WHITE}Status: ${GREEN}${sliceStatus} `;
|
|
}
|
|
|
|
if (progress !== undefined) {
|
|
const progressBar = createProgressBar(progress, width - 30);
|
|
statusLine += noColor
|
|
? `Progress: ${progressBar} `
|
|
: `${BOLD_WHITE}Progress: ${YELLOW}${progressBar} `;
|
|
}
|
|
|
|
if (totalTasks !== undefined && completedTasks !== undefined) {
|
|
statusLine += noColor
|
|
? `Tasks: ${completedTasks}/${totalTasks} `
|
|
: `${BOLD_WHITE}Tasks: ${MAGENTA}${completedTasks}/${totalTasks} `;
|
|
}
|
|
|
|
statusLine += noColor ? "│" : `${DIM}│${RESET}`;
|
|
return [statusLine];
|
|
}
|
|
}
|
|
|
|
function createProgressBar(progress: number, width: number): string {
|
|
const barWidth = Math.min(20, Math.max(5, width));
|
|
const filled = Math.floor((progress / 100) * barWidth);
|
|
const empty = barWidth - filled;
|
|
return `[${"█".repeat(filled)}${"░".repeat(empty)}] ${progress}%`;
|
|
}
|