diff --git a/src/tui/App.tsx b/src/tui/App.tsx
index 3dea5f0f..4e442c01 100644
--- a/src/tui/App.tsx
+++ b/src/tui/App.tsx
@@ -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();
+ * ```
*/
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();
diff --git a/src/tui/components/HelpOverlay.tsx b/src/tui/components/HelpOverlay.tsx
index d529ef10..4db56470 100644
--- a/src/tui/components/HelpOverlay.tsx
+++ b/src/tui/components/HelpOverlay.tsx
@@ -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 (
diff --git a/src/tui/components/RalphPanel.tsx b/src/tui/components/RalphPanel.tsx
index d18a7960..49338eb2 100644
--- a/src/tui/components/RalphPanel.tsx
+++ b/src/tui/components/RalphPanel.tsx
@@ -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,
diff --git a/src/tui/components/StartScreen.tsx b/src/tui/components/StartScreen.tsx
index e0b37839..db310713 100644
--- a/src/tui/components/StartScreen.tsx
+++ b/src/tui/components/StartScreen.tsx
@@ -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,
diff --git a/src/tui/components/StatusBar.tsx b/src/tui/components/StatusBar.tsx
index 164c9146..dd604665 100644
--- a/src/tui/components/StatusBar.tsx
+++ b/src/tui/components/StatusBar.tsx
@@ -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) {
diff --git a/src/tui/components/TabBar.tsx b/src/tui/components/TabBar.tsx
index 10ab28b2..f873376b 100644
--- a/src/tui/components/TabBar.tsx
+++ b/src/tui/components/TabBar.tsx
@@ -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,
diff --git a/src/tui/components/TerminalView.tsx b/src/tui/components/TerminalView.tsx
index 7b80745f..99245b55 100644
--- a/src/tui/components/TerminalView.tsx
+++ b/src/tui/components/TerminalView.tsx
@@ -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,
diff --git a/src/tui/hooks/useSessionManager.ts b/src/tui/hooks/useSessionManager.ts
index bb760f82..a352f54b 100644
--- a/src/tui/hooks/useSessionManager.ts
+++ b/src/tui/hooks/useSessionManager.ts
@@ -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 (
+ *
+ * {sessions.map(s => (
+ * selectSession(s.sessionId)}>
+ * {s.name}
+ *
+ * ))}
+ *
+ * );
+ * }
+ * ```
*/
export function useSessionManager(): SessionManagerState {
const [sessions, setSessions] = useState([]);
diff --git a/src/tui/index.tsx b/src/tui/index.tsx
index 30cb2ee3..0c3b8b1d 100644
--- a/src/tui/index.tsx
+++ b/src/tui/index.tsx
@@ -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 {
// Check if we're in an interactive terminal