mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-09 00:49:41 +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,70 @@
|
||||
/**
|
||||
* @fileoverview TabBar component
|
||||
*
|
||||
* Horizontal tab bar showing all active sessions.
|
||||
* Features:
|
||||
* - Visual indication of active tab
|
||||
* - Status indicator (idle/working)
|
||||
* - Tab truncation for long names
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import type { ScreenSession } from '../../types.js';
|
||||
|
||||
interface TabBarProps {
|
||||
sessions: ScreenSession[];
|
||||
activeSessionId: string | null;
|
||||
onSelectSession: (sessionId: string) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* TabBar component for session navigation
|
||||
*/
|
||||
export function TabBar({
|
||||
sessions,
|
||||
activeSessionId,
|
||||
}: TabBarProps): React.ReactElement {
|
||||
if (sessions.length === 0) {
|
||||
return (
|
||||
<Box borderStyle="single" borderColor="gray" paddingX={1}>
|
||||
<Text dimColor>No sessions</Text>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box borderStyle="single" borderColor="cyan" paddingX={1}>
|
||||
{sessions.map((session, index) => {
|
||||
const isActive = session.sessionId === activeSessionId;
|
||||
const name = (session.name || 'unnamed').slice(0, 15);
|
||||
// Status indicator: filled circle for alive, hollow for dead
|
||||
const statusIcon = session.attached ? '\u25CF' : '\u25CB';
|
||||
const statusColor = session.attached ? 'green' : 'red';
|
||||
|
||||
return (
|
||||
<Box key={session.sessionId} marginRight={1}>
|
||||
{isActive ? (
|
||||
<Text backgroundColor="blue" color="white" bold>
|
||||
{' '}
|
||||
<Text color={statusColor}>{statusIcon}</Text> {name}{' '}
|
||||
</Text>
|
||||
) : (
|
||||
<Text>
|
||||
{' '}
|
||||
<Text color={statusColor}>{statusIcon}</Text>{' '}
|
||||
<Text dimColor>{name}</Text>{' '}
|
||||
</Text>
|
||||
)}
|
||||
{index < sessions.length - 1 && <Text dimColor>|</Text>}
|
||||
</Box>
|
||||
);
|
||||
})}
|
||||
|
||||
{/* Shortcut hint */}
|
||||
<Box flexGrow={1} justifyContent="flex-end">
|
||||
<Text dimColor>Ctrl+Tab: switch | Ctrl+W: close</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user