UNPKG

capsule-ai-cli

Version:

The AI Model Orchestrator - Intelligent multi-model workflows with device-locked licensing

73 lines 2.77 kB
import chalk from 'chalk'; import path from 'path'; import os from 'os'; export class StatusBar { info; constructor(info = {}) { this.info = { currentDir: process.cwd(), model: 'gpt-4o', provider: 'openai', contextUsage: 0, maxContext: 4096, sandboxMode: false, ...info }; } render() { const terminalWidth = process.stdout.columns || 80; const dirDisplay = this.truncatePath(this.info.currentDir, 30); const leftSection = chalk.cyan(dirDisplay); const centerSection = this.info.sandboxMode ? chalk.red(' no sandbox ') : ''; const contextPercent = Math.round((this.info.contextUsage / this.info.maxContext) * 100); const contextColor = contextPercent > 80 ? 'red' : contextPercent > 60 ? 'yellow' : 'green'; const rightSection = chalk.gray('(') + chalk.blue(this.info.model) + chalk.gray(' | ') + chalk[contextColor](`${contextPercent}% context`) + chalk.gray(')'); const leftLength = this.stripAnsi(leftSection).length; const centerLength = this.stripAnsi(centerSection).length; const rightLength = this.stripAnsi(rightSection).length; const totalContentLength = leftLength + centerLength + rightLength; const padding = Math.max(0, terminalWidth - totalContentLength - 2); const paddingLeft = Math.floor(padding / 2); const paddingRight = Math.ceil(padding / 2); return (leftSection + ' '.repeat(paddingLeft) + centerSection + ' '.repeat(paddingRight) + rightSection); } update(updates) { this.info = { ...this.info, ...updates }; this.redraw(); } redraw() { process.stdout.write('\x1B[s'); process.stdout.write(`\x1B[${process.stdout.rows};1H`); process.stdout.write('\x1B[K'); process.stdout.write(this.render()); process.stdout.write('\x1B[u'); } truncatePath(fullPath, maxLength) { if (fullPath.length <= maxLength) return fullPath; const homedir = os.homedir(); let displayPath = fullPath.replace(homedir, '~'); if (displayPath.length <= maxLength) return displayPath; const parts = displayPath.split(path.sep); if (parts.length > 3) { return `${parts[0]}${path.sep}...${path.sep}${parts[parts.length - 1]}`; } return `...${displayPath.slice(-(maxLength - 3))}`; } stripAnsi(str) { return str.replace(/\x1B\[[0-9;]*m/g, ''); } } export const statusBar = new StatusBar(); //# sourceMappingURL=statusBar.js.map