docs: add comprehensive JSDoc comments to TUI components

Improves documentation across all TUI files:
- App.tsx: Main component with keyboard shortcuts reference
- index.tsx: Entry point with usage examples
- useSessionManager.ts: Hook with detailed API documentation
- All components: Props, returns, and behavior descriptions
- Helper functions: Parameter and return type documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
arkon
2026-01-21 06:44:06 +01:00
co-authored by Claude Opus 4.5
parent c00ce747c1
commit 1da51c38d8
9 changed files with 304 additions and 55 deletions
+37 -4
View File
@@ -1,9 +1,26 @@
/**
* @fileoverview Main TUI App component
*
* The root component that manages the overall TUI layout:
* - StartScreen: Initial session discovery view
* - Main view: TabBar + Terminal + StatusBar
* The root component that manages the overall TUI layout and navigation.
*
* @description
* Provides two primary views:
* - **StartScreen**: Session discovery and selection interface
* - **Main view**: Active session management with:
* - TabBar: Session tabs with switching
* - TerminalView: Live terminal output display
* - RalphPanel: Inner loop tracking (conditional)
* - StatusBar: Session info and keyboard hints
*
* Keyboard shortcuts are handled globally via Ink's useInput hook.
*
* @example
* ```tsx
* import { render } from 'ink';
* import { App } from './App.js';
*
* render(<App />);
* ```
*/
import React, { useState, useEffect, useCallback } from 'react';
@@ -21,7 +38,23 @@ import type { ScreenSession } from '../types.js';
type ViewMode = 'start' | 'main';
/**
* Main application component
* Main TUI application component.
*
* @description
* Renders either the StartScreen or Main view based on current state.
* Handles all global keyboard shortcuts and manages terminal dimensions.
*
* **Global Shortcuts:**
* - `?` or `Ctrl+H`: Show help overlay
* - `Ctrl+C`: Exit application
* - `Ctrl+Tab/Shift+Tab`: Navigate sessions
* - `Ctrl+1-9`: Direct session access
* - `Ctrl+W`: Close current session
* - `Ctrl+K`: Kill all sessions
* - `Ctrl+N`: Create new session
* - `Escape`: Return to start screen
*
* @returns The rendered TUI application
*/
export function App(): React.ReactElement {
const { exit } = useApp();
+19 -3
View File
@@ -1,8 +1,16 @@
/**
* @fileoverview HelpOverlay component
*
* Full-screen overlay showing all keyboard shortcuts.
* Dismissible with Escape, q, or ?.
* Full-screen help overlay displaying all TUI keyboard shortcuts.
*
* @description
* Shows a comprehensive reference of keyboard shortcuts organized by context:
* - Start Screen: Session list navigation and actions
* - Main View - Navigation: Tab switching and screen navigation
* - Main View - Session Management: Create, close, kill sessions
* - General: Help toggle and exit
*
* Dismissible with Escape, q, or ? keys.
*/
import React from 'react';
@@ -57,7 +65,15 @@ const SHORTCUT_GROUPS: ShortcutGroup[] = [
];
/**
* HelpOverlay component showing keyboard shortcuts
* Help overlay component displaying keyboard shortcuts reference.
*
* @description
* Renders a full-screen overlay with categorized keyboard shortcuts.
* Uses consistent styling with bordered header and grouped sections.
*
* @param props - Component props
* @param props.onClose - Callback invoked when overlay should close
* @returns The help overlay element
*/
export function HelpOverlay({ onClose }: HelpOverlayProps): React.ReactElement {
return (
+35 -7
View File
@@ -1,10 +1,18 @@
/**
* @fileoverview RalphPanel component
*
* Displays Ralph Wiggum loop tracking information:
* - Loop status and completion phrase
* - Todo list with progress
* - Cycle count and elapsed time
* Displays Ralph Wiggum autonomous loop tracking information.
*
* @description
* The Ralph Wiggum loop is an autonomous work mode where Claude
* continues iterating on tasks until completion criteria are met.
* This panel provides visibility into:
* - Loop status (active/idle) and completion phrase
* - Progress through todos with visual indicators
* - Cycle count and elapsed time tracking
*
* @see {@link file://./../../inner-loop-tracker.ts} for detection logic
* @see {@link file://./../../../docs/ralph-wiggum-guide.md} for full documentation
*/
import React from 'react';
@@ -18,7 +26,10 @@ interface RalphPanelProps {
}
/**
* Status icon for todo items
* Returns the visual indicator for a todo item's status.
*
* @param status - The todo status: 'completed', 'in_progress', or 'pending'
* @returns Object with Unicode icon and color name
*/
function getStatusIcon(status: string): { icon: string; color: string } {
switch (status) {
@@ -33,7 +44,10 @@ function getStatusIcon(status: string): { icon: string; color: string } {
}
/**
* Formats elapsed hours to human-readable string
* Formats elapsed hours to a compact human-readable string.
*
* @param hours - Elapsed time in hours (can be fractional)
* @returns Formatted string like "45m" or "2.5h"
*/
function formatElapsed(hours: number | null): string {
if (hours === null) return '-';
@@ -45,7 +59,21 @@ function formatElapsed(hours: number | null): string {
}
/**
* RalphPanel component showing loop tracking
* Panel component displaying Ralph Wiggum loop status and progress.
*
* @description
* Renders a bordered panel with:
* - Header showing loop status and completion phrase
* - Stats row with cycle count, elapsed time, and todo progress
* - Todo list (max 5 visible) with status icons
*
* Only renders when loop is enabled and has relevant data to show.
*
* @param props - Component props
* @param props.loopState - Current loop state from InnerLoopTracker
* @param props.todos - Array of todo items being tracked
* @param props.visible - Whether the panel should be visible (default: true)
* @returns The panel element or null if hidden/disabled
*/
export function RalphPanel({
loopState,
+38 -7
View File
@@ -1,11 +1,16 @@
/**
* @fileoverview StartScreen component
*
* Initial screen shown when TUI launches. Displays:
* - List of existing screen sessions from ~/.claudeman/screens.json
* - Session status (alive/dead), runtime, mode
* - Arrow key navigation with highlighted selection
* - Options to select, create, attach, or refresh sessions
* Session discovery and selection interface for the TUI.
*
* @description
* The initial screen displayed when launching `claudeman tui`:
* - Reads session list from ~/.claudeman/screens.json
* - Shows session name, runtime, status (alive/dead), and mode
* - Arrow key navigation with visual selection highlight
* - Actions: Enter (view), a (attach), d (delete), n (new), r (refresh), q (quit)
*
* This is the "home screen" users return to with Escape from the main view.
*/
import React, { useState } from 'react';
@@ -23,7 +28,10 @@ interface StartScreenProps {
}
/**
* Formats duration from milliseconds to human-readable string
* Formats a duration from milliseconds to a compact human-readable string.
*
* @param ms - Duration in milliseconds
* @returns Formatted string like "45s", "5m", "2h 15m", or "3d 5h"
*/
function formatDuration(ms: number): string {
const seconds = Math.floor(ms / 1000);
@@ -44,7 +52,30 @@ function formatDuration(ms: number): string {
}
/**
* Start screen component showing session list with arrow key navigation
* Start screen component for session discovery and selection.
*
* @description
* Renders a table of available sessions with:
* - Arrow key navigation (wraps at boundaries)
* - Visual selection highlight (blue background)
* - Status indicators (green=alive, red=dead)
* - Runtime and mode information
*
* **Keyboard Shortcuts:**
* - `↑/↓`: Navigate selection
* - `Enter`: View session in TUI
* - `a`: Attach directly to screen (exits TUI)
* - `d/x`: Delete/kill selected session
*
* @param props - Component props
* @param props.sessions - Array of sessions to display
* @param props.onSelectSession - Callback to view session in TUI
* @param props.onAttachSession - Callback to attach directly to screen
* @param props.onDeleteSession - Callback to delete/kill session
* @param props.onCreateSession - Callback to create new session
* @param props.onRefresh - Callback to refresh session list
* @param props.onExit - Callback to exit TUI
* @returns The start screen element
*/
export function StartScreen({
sessions,
+27 -8
View File
@@ -1,12 +1,15 @@
/**
* @fileoverview StatusBar component
*
* Bottom status bar showing:
* - Session status (idle/working)
* - Token count
* - Cost
* - Runtime
* - Quick keyboard shortcuts
* Bottom status bar providing session information and navigation hints.
*
* @description
* Displays real-time session metrics:
* - Session name and connection status (alive/dead)
* - Runtime duration since session creation
* - Session mode (claude/shell)
* - Respawn controller status when enabled
* - Keyboard shortcut hints for quick reference
*/
import React from 'react';
@@ -26,7 +29,10 @@ interface StatusBarProps {
}
/**
* Formats duration from milliseconds to human-readable string
* Formats a duration from milliseconds to a human-readable string.
*
* @param ms - Duration in milliseconds
* @returns Formatted string like "45s", "5m 30s", or "2h 15m"
*/
function formatDuration(ms: number): string {
const seconds = Math.floor(ms / 1000);
@@ -43,7 +49,20 @@ function formatDuration(ms: number): string {
}
/**
* StatusBar component showing session information
* Status bar component displaying session information and keyboard hints.
*
* @description
* Renders a bordered bar at the bottom of the TUI with:
* - Left side: Session name, status indicator, runtime, mode, respawn state
* - Right side: Quick keyboard shortcut reference
*
* When no session is selected, displays a minimal bar with navigation hints.
*
* @param props - Component props
* @param props.session - The currently active session or null
* @param props.inputMode - Whether input mode is active (shows yellow indicator)
* @param props.respawnStatus - Respawn controller status if enabled
* @returns The status bar element
*/
export function StatusBar({ session, inputMode = false, respawnStatus }: StatusBarProps): React.ReactElement {
if (!session) {
+23 -6
View File
@@ -1,11 +1,16 @@
/**
* @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
* Horizontal tab bar for session navigation in the TUI.
*
* @description
* Provides browser-like tab navigation for Claude sessions:
* - Active tab highlighted with blue background
* - Status indicators: green dot (alive) or red dot (dead)
* - Session names truncated to 15 characters
* - Keyboard shortcut hints on the right
*
* Tab switching is handled by parent via keyboard shortcuts (Ctrl+Tab).
*/
import React from 'react';
@@ -19,7 +24,19 @@ interface TabBarProps {
}
/**
* TabBar component for session navigation
* Tab bar component showing all available sessions.
*
* @description
* Renders a horizontal bar with one tab per session, showing:
* - Status indicator (filled/hollow circle for alive/dead)
* - Session name (truncated to 15 chars)
* - Visual highlighting for the active session
*
* @param props - Component props
* @param props.sessions - Array of all sessions to display as tabs
* @param props.activeSessionId - ID of currently active session for highlighting
* @param props.onSelectSession - Callback when a tab is clicked (unused, keyboard nav only)
* @returns The tab bar element
*/
export function TabBar({
sessions,
+21 -6
View File
@@ -1,11 +1,16 @@
/**
* @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
* Primary terminal output display for Claude session monitoring.
*
* @description
* Renders the terminal output from a GNU screen session:
* - Viewport shows last N lines based on available height
* - Line splitting is memoized for performance
* - Visual border color indicates session state (green=active, gray=none)
* - Long lines are truncated to prevent wrapping issues
*
* Output is obtained via screen hardcopy polling in useSessionManager.
*/
import React, { useMemo } from 'react';
@@ -19,7 +24,17 @@ interface TerminalViewProps {
}
/**
* TerminalView component for PTY output display
* Terminal view component for displaying session output.
*
* @description
* Shows the last N lines of terminal output that fit within the given height.
* When no session is selected, displays a placeholder message.
*
* @param props - Component props
* @param props.output - Raw terminal output string from screen hardcopy
* @param props.height - Available height in terminal rows (includes border)
* @param props.session - The active session or null
* @returns The terminal view element
*/
export function TerminalView({
output,
+67 -8
View File
@@ -1,10 +1,26 @@
/**
* @fileoverview useSessionManager hook
*
* Manages session state for the TUI. Connects to:
* - ~/.claudeman/screens.json for session discovery
* - ScreenManager for session operations
* - Session class for terminal output
* Core state management hook for the TUI application.
*
* @description
* This hook provides a complete interface for managing Claude sessions:
* - Session discovery from ~/.claudeman/screens.json
* - Terminal output polling via GNU screen hardcopy
* - Inner loop state tracking for Ralph Wiggum loops
* - Respawn status monitoring via the Claudeman API
*
* @example
* ```tsx
* const {
* sessions,
* activeSession,
* terminalOutput,
* selectSession,
* createSession,
* sendInput,
* } = useSessionManager();
* ```
*/
import { useState, useEffect, useCallback, useRef } from 'react';
@@ -43,7 +59,10 @@ interface SessionManagerState {
}
/**
* Check if a screen session is alive
* Checks if a GNU screen session is currently running.
*
* @param screenName - The name of the screen session to check
* @returns true if the session exists and is alive, false otherwise
*/
function isScreenAlive(screenName: string): boolean {
try {
@@ -55,7 +74,13 @@ function isScreenAlive(screenName: string): boolean {
}
/**
* Load sessions from screens.json
* Loads all sessions from the Claudeman screens registry.
*
* @description
* Reads ~/.claudeman/screens.json and enriches each session with
* its current alive/dead status by checking GNU screen.
*
* @returns Array of screen sessions with updated attached status
*/
function loadSessions(): ScreenSession[] {
try {
@@ -76,7 +101,14 @@ function loadSessions(): ScreenSession[] {
}
/**
* Load inner state for a session
* Loads Ralph Wiggum loop state for a specific session.
*
* @description
* Reads ~/.claudeman/state-inner.json which contains per-session
* tracking of inner loops, todos, and completion phrases.
*
* @param sessionId - The UUID of the session to load state for
* @returns The inner session state or null if not found
*/
function loadInnerState(sessionId: string): InnerSessionState | null {
try {
@@ -92,7 +124,34 @@ function loadInnerState(sessionId: string): InnerSessionState | null {
}
/**
* Hook for managing sessions in the TUI
* React hook for managing Claude sessions in the TUI.
*
* @description
* Provides complete session lifecycle management:
* - Automatic session discovery and status monitoring
* - Terminal output polling (500ms interval)
* - Inner loop state tracking (500ms interval)
* - Respawn status polling via API (2000ms interval)
* - Session CRUD operations via Claudeman API
*
* @returns SessionManagerState object with session data and control methods
*
* @example
* ```tsx
* function MyComponent() {
* const { sessions, selectSession, sendInput } = useSessionManager();
*
* return (
* <Box>
* {sessions.map(s => (
* <Text key={s.sessionId} onClick={() => selectSession(s.sessionId)}>
* {s.name}
* </Text>
* ))}
* </Box>
* );
* }
* ```
*/
export function useSessionManager(): SessionManagerState {
const [sessions, setSessions] = useState<ScreenSession[]>([]);
+37 -6
View File
@@ -1,9 +1,27 @@
/**
* @fileoverview TUI entry point for Claudeman
*
* Renders the terminal user interface using Ink (React for CLI).
* This provides a full-screen TUI similar to the web interface,
* with tabs for sessions and real-time terminal output.
* Entry point for the terminal user interface, providing a full-screen
* session manager similar to the web interface but entirely in the terminal.
*
* @description
* Built with Ink (React for CLI), the TUI offers:
* - Session discovery from ~/.claudeman/screens.json
* - Tab-based session navigation (like browser tabs)
* - Real-time terminal output via screen hardcopy polling
* - Ralph Wiggum loop tracking
* - Respawn status monitoring
*
* @example
* ```bash
* # Start the TUI
* claudeman tui
* # Or via npm
* npm run tui
* ```
*
* @see {@link ./App.tsx} for main application component
* @see {@link ./hooks/useSessionManager.ts} for state management
*/
import React from 'react';
@@ -11,7 +29,13 @@ import { render } from 'ink';
import { App } from './App.js';
/**
* Checks if the terminal supports raw mode (required for TUI)
* Checks if the terminal supports raw mode input.
*
* @description
* Raw mode is required for Ink to capture keyboard input directly.
* This check fails when stdin is piped or redirected (e.g., `echo | claudeman tui`).
*
* @returns true if raw mode is available, false otherwise
*/
function isRawModeSupported(): boolean {
return Boolean(
@@ -21,8 +45,15 @@ function isRawModeSupported(): boolean {
}
/**
* Starts the TUI application
* @returns Promise that resolves when the app exits
* Starts the TUI application in the current terminal.
*
* @description
* Initializes the Ink renderer and displays the TUI.
* The terminal is cleared for a full-screen experience.
* This function blocks until the user exits the TUI.
*
* @throws Exits with code 1 if TTY/raw mode is not supported
* @returns Promise that resolves when the TUI exits
*/
export async function startTUI(): Promise<void> {
// Check if we're in an interactive terminal