- ASCII art mosaic windmill: 4 colored tiles (blue, purple, teal, amber) with pink center, matching the Mosaic Stack brand - 3-line info block (Claude Code style): Line 1: 'Mosaic Stack v0.0.0' Line 2: model (context) · thinking · agent name Line 3: ● host connection status - Remove bordered box in favor of open layout with icon
83 lines
2.3 KiB
TypeScript
83 lines
2.3 KiB
TypeScript
import React from 'react';
|
|
import { Box, useApp, useInput } from 'ink';
|
|
import { TopBar } from './components/top-bar.js';
|
|
import { BottomBar } from './components/bottom-bar.js';
|
|
import { MessageList } from './components/message-list.js';
|
|
import { InputBar } from './components/input-bar.js';
|
|
import { useSocket } from './hooks/use-socket.js';
|
|
import { useGitInfo } from './hooks/use-git-info.js';
|
|
|
|
export interface TuiAppProps {
|
|
gatewayUrl: string;
|
|
conversationId?: string;
|
|
sessionCookie?: string;
|
|
}
|
|
|
|
export function TuiApp({ gatewayUrl, conversationId, sessionCookie }: TuiAppProps) {
|
|
const { exit } = useApp();
|
|
const gitInfo = useGitInfo();
|
|
|
|
const socket = useSocket({
|
|
gatewayUrl,
|
|
sessionCookie,
|
|
initialConversationId: conversationId,
|
|
});
|
|
|
|
useInput((ch, key) => {
|
|
if (key.ctrl && ch === 'c') {
|
|
exit();
|
|
}
|
|
// Ctrl+T: cycle thinking level
|
|
if (key.ctrl && ch === 't') {
|
|
const levels = socket.availableThinkingLevels;
|
|
if (levels.length > 0) {
|
|
const currentIdx = levels.indexOf(socket.thinkingLevel);
|
|
const nextIdx = (currentIdx + 1) % levels.length;
|
|
const next = levels[nextIdx];
|
|
if (next) {
|
|
socket.setThinkingLevel(next);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
|
|
return (
|
|
<Box flexDirection="column" height="100%">
|
|
<TopBar
|
|
gatewayUrl={gatewayUrl}
|
|
version="0.0.0"
|
|
modelName={socket.modelName}
|
|
thinkingLevel={socket.thinkingLevel}
|
|
contextWindow={socket.tokenUsage.contextWindow}
|
|
agentName="default"
|
|
connected={socket.connected}
|
|
connecting={socket.connecting}
|
|
/>
|
|
|
|
<MessageList
|
|
messages={socket.messages}
|
|
isStreaming={socket.isStreaming}
|
|
currentStreamText={socket.currentStreamText}
|
|
currentThinkingText={socket.currentThinkingText}
|
|
activeToolCalls={socket.activeToolCalls}
|
|
/>
|
|
|
|
<InputBar
|
|
onSubmit={socket.sendMessage}
|
|
isStreaming={socket.isStreaming}
|
|
connected={socket.connected}
|
|
/>
|
|
|
|
<BottomBar
|
|
gitInfo={gitInfo}
|
|
tokenUsage={socket.tokenUsage}
|
|
connected={socket.connected}
|
|
connecting={socket.connecting}
|
|
modelName={socket.modelName}
|
|
providerName={socket.providerName}
|
|
thinkingLevel={socket.thinkingLevel}
|
|
/>
|
|
</Box>
|
|
);
|
|
}
|