mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 08:59:40 +02:00
feat(tui): add terminal user interface with Ink
Add a full TUI for Claudeman using Ink (React for CLI): - StartScreen: Shows existing sessions from screens.json - TabBar: Session tabs with status indicators - TerminalView: PTY output display with scrolling - StatusBar: Session info and keyboard shortcuts - HelpOverlay: Full keyboard shortcut reference Features: - Session discovery from ~/.claudeman/screens.json - Tab navigation (Ctrl+Tab, Ctrl+1-9) - Create new sessions (connects to web API) - Kill sessions via screen commands - Keyboard-driven navigation Usage: claudeman tui Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* @fileoverview TerminalView component
|
||||
*
|
||||
* Displays PTY output from the active session.
|
||||
* Features:
|
||||
* - Scrollable viewport showing last N lines
|
||||
* - ANSI color support (handled by Ink)
|
||||
* - Visual border indicating focus
|
||||
*/
|
||||
|
||||
import React, { useMemo } from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import type { ScreenSession } from '../../types.js';
|
||||
|
||||
interface TerminalViewProps {
|
||||
output: string;
|
||||
height: number;
|
||||
session: ScreenSession | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TerminalView component for PTY output display
|
||||
*/
|
||||
export function TerminalView({
|
||||
output,
|
||||
height,
|
||||
session,
|
||||
}: TerminalViewProps): React.ReactElement {
|
||||
// Split output into lines and get the last N lines that fit
|
||||
const displayLines = useMemo(() => {
|
||||
if (!output) return [];
|
||||
|
||||
const lines = output.split('\n');
|
||||
// Reserve 2 lines for border
|
||||
const visibleLines = height - 2;
|
||||
|
||||
if (lines.length <= visibleLines) {
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Return last N lines
|
||||
return lines.slice(-visibleLines);
|
||||
}, [output, height]);
|
||||
|
||||
if (!session) {
|
||||
return (
|
||||
<Box
|
||||
flexDirection="column"
|
||||
borderStyle="single"
|
||||
borderColor="gray"
|
||||
height={height}
|
||||
paddingX={1}
|
||||
>
|
||||
<Box flexGrow={1} alignItems="center" justifyContent="center">
|
||||
<Text dimColor>No session selected</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
flexDirection="column"
|
||||
borderStyle="single"
|
||||
borderColor="green"
|
||||
height={height}
|
||||
paddingX={1}
|
||||
overflow="hidden"
|
||||
>
|
||||
{/* Terminal content */}
|
||||
<Box flexDirection="column" flexGrow={1}>
|
||||
{displayLines.length === 0 ? (
|
||||
<Text dimColor>Waiting for output...</Text>
|
||||
) : (
|
||||
displayLines.map((line, index) => (
|
||||
<Text key={index} wrap="truncate">
|
||||
{line}
|
||||
</Text>
|
||||
))
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user