feat(cli): TUI complete overhaul — components, sidebar, search, branding (#157)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
Co-authored-by: Jason Woltje <jason@diversecanvas.com> Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #157.
This commit is contained in:
99
packages/cli/src/tui/components/top-bar.tsx
Normal file
99
packages/cli/src/tui/components/top-bar.tsx
Normal file
@@ -0,0 +1,99 @@
|
||||
import React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
|
||||
export interface TopBarProps {
|
||||
gatewayUrl: string;
|
||||
version: string;
|
||||
modelName: string | null;
|
||||
thinkingLevel: string;
|
||||
contextWindow: number;
|
||||
agentName: string;
|
||||
connected: boolean;
|
||||
connecting: boolean;
|
||||
}
|
||||
|
||||
/** Compact the URL — strip protocol */
|
||||
function compactHost(url: string): string {
|
||||
return url.replace(/^https?:\/\//, '');
|
||||
}
|
||||
|
||||
function formatContextWindow(n: number): string {
|
||||
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(0)}M`;
|
||||
if (n >= 1_000) return `${(n / 1_000).toFixed(0)}k`;
|
||||
return String(n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mosaic 3×3 icon — brand tiles with black gaps (windmill cross pattern)
|
||||
*
|
||||
* Layout:
|
||||
* blue ·· purple
|
||||
* ·· pink ··
|
||||
* amber ·· teal
|
||||
*/
|
||||
// Two-space gap between tiles (extracted to avoid prettier collapse)
|
||||
const GAP = ' ';
|
||||
|
||||
function MosaicIcon() {
|
||||
return (
|
||||
<Box flexDirection="column" marginRight={2}>
|
||||
<Text>
|
||||
<Text color="#2f80ff">██</Text>
|
||||
<Text>{GAP}</Text>
|
||||
<Text color="#8b5cf6">██</Text>
|
||||
</Text>
|
||||
<Text>
|
||||
<Text>{GAP}</Text>
|
||||
<Text color="#ec4899">██</Text>
|
||||
</Text>
|
||||
<Text>
|
||||
<Text color="#f59e0b">██</Text>
|
||||
<Text>{GAP}</Text>
|
||||
<Text color="#14b8a6">██</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export function TopBar({
|
||||
gatewayUrl,
|
||||
version,
|
||||
modelName,
|
||||
thinkingLevel,
|
||||
contextWindow,
|
||||
agentName,
|
||||
connected,
|
||||
connecting,
|
||||
}: TopBarProps) {
|
||||
const host = compactHost(gatewayUrl);
|
||||
const connectionIndicator = connected ? '●' : '○';
|
||||
const connectionColor = connected ? 'green' : connecting ? 'yellow' : 'red';
|
||||
|
||||
// Build model description line like: "claude-opus-4-6 (1M context) · default"
|
||||
const modelDisplay = modelName ?? 'awaiting model';
|
||||
const contextStr = contextWindow > 0 ? ` (${formatContextWindow(contextWindow)} context)` : '';
|
||||
const thinkingStr = thinkingLevel !== 'off' ? ` · ${thinkingLevel}` : '';
|
||||
|
||||
return (
|
||||
<Box paddingX={1} paddingY={0} marginBottom={1}>
|
||||
<MosaicIcon />
|
||||
<Box flexDirection="column" flexGrow={1}>
|
||||
<Text>
|
||||
<Text bold color="#56a0ff">
|
||||
Mosaic Stack
|
||||
</Text>
|
||||
<Text dimColor> v{version}</Text>
|
||||
</Text>
|
||||
<Text dimColor>
|
||||
{modelDisplay}
|
||||
{contextStr}
|
||||
{thinkingStr} · {agentName}
|
||||
</Text>
|
||||
<Text>
|
||||
<Text color={connectionColor}>{connectionIndicator}</Text>
|
||||
<Text dimColor> {host}</Text>
|
||||
</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user