mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-09-30 12:39:42 +02:00
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>
12 KiB
12 KiB
Claudeman TUI Implementation Plan
Overview
Build a full terminal user interface (TUI) for Claudeman that mirrors the web interface functionality. The TUI will allow users to:
- See all running screen sessions as tabs
- Switch between sessions with keyboard shortcuts
- View real-time terminal output from each Claude session
- Create, manage, and kill sessions
- Control respawn and Ralph loop features
Technology Choice: Ink (React for CLI)
Why Ink over alternatives:
- Component-based: Familiar React patterns, composable UI
- Already in ecosystem: Claude CLI uses Ink (explains the screen input workaround)
- TypeScript native: First-class TS support
- Active maintenance: Regular updates, good community
- Handles PTY well: Built for terminal apps with real-time output
Alternatives considered:
blessed/blessed-contrib: Legacy, unmaintained, complex APIterminal-kit: Lower-level, more boilerplate- Raw ANSI: Too low-level for complex UIs
- Existing bash script: Not extensible enough
Architecture
src/
├── tui/
│ ├── index.ts # Entry point, CLI command
│ ├── App.tsx # Main TUI app component
│ ├── components/
│ │ ├── TabBar.tsx # Session tabs at top
│ │ ├── Terminal.tsx # PTY output display
│ │ ├── StatusBar.tsx # Bottom status bar
│ │ ├── SessionInfo.tsx # Session details panel
│ │ ├── HelpOverlay.tsx # Keyboard shortcuts help
│ │ ├── RalphPanel.tsx # Inner loop/todo tracking
│ │ └── StartScreen.tsx # Initial session discovery
│ ├── hooks/
│ │ ├── useSession.ts # Session management hook
│ │ ├── useTerminal.ts # Terminal output handling
│ │ └── useKeyboard.ts # Global keyboard shortcuts
│ └── store/
│ └── tui-state.ts # TUI-specific state
Implementation Steps
Phase 1: Foundation (Core Infrastructure)
Step 1.1: Add Dependencies
npm install ink ink-text-input ink-spinner ink-box react
npm install -D @types/react
Step 1.2: Create Entry Point (src/tui/index.ts)
- Add
tuicommand to CLI insrc/cli.ts - Create Ink render entry point
- Handle graceful shutdown (restore terminal)
Step 1.3: Create Main App Component (src/tui/App.tsx)
- Full-screen layout with Ink's
Boxcomponents - Three regions: TabBar (top), Terminal (center), StatusBar (bottom)
- Global keyboard event handling
Phase 2: Start Screen & Session Discovery
Step 2.1: Create StartScreen Component
On launch, the TUI should:
- Read
~/.claudeman/screens.jsonfor existing sessions - Check which screens are alive (
screen -ls) - Display list of sessions with status
- Allow user to:
- Select and attach to existing session
- Create new session
- Kill dead sessions
Step 2.2: Session List Display
╔═══════════════════════════════════════════════════════════╗
║ Claudeman TUI ║
╠═══════════════════════════════════════════════════════════╣
║ Existing Sessions: ║
║ ║
║ [1] ● testcase 2h 15m idle claude ║
║ [2] ● another-case 45m working claude ║
║ [3] ○ old-session 3d dead claude ║
║ ║
║ ─────────────────────────────────────────────────────────║
║ [n] New session [1-9] Select [d] Delete [q] Quit ║
╚═══════════════════════════════════════════════════════════╝
Phase 3: Tab System
Step 3.1: TabBar Component
- Horizontal tab bar at top of screen
- Shows session name + status indicator (● idle, ◐ working)
- Keyboard navigation: Ctrl+Tab (next), Ctrl+Shift+Tab (prev), Ctrl+1-9 (direct)
- Visual indication of active tab
Step 3.2: Tab State Management
- Track active session ID
- Track tab order (array of session IDs)
- Handle session creation/deletion (add/remove tabs)
- Persist tab order to state
Phase 4: Terminal Display
Step 4.1: Terminal Component
- Display PTY output for active session
- Scrollable viewport (show last N lines that fit)
- ANSI color support (Ink handles this)
- Handle terminal resize
Step 4.2: Output Integration
Connect to existing Session class:
// Subscribe to session events
session.on('terminal', (data) => {
// Append to display buffer
});
session.on('clearTerminal', () => {
// Clear display buffer
});
Step 4.3: Input Handling
- Capture keyboard input when terminal focused
- Send to session via
session.write()orsession.writeViaScreen() - Handle special keys (Ctrl+C, Ctrl+D, etc.)
- Distinguish between TUI commands and session input
Phase 5: Status Bar
Step 5.1: StatusBar Component
Display at bottom:
- Session status (idle/working)
- Token count
- Cost
- Respawn status (if enabled)
- Ralph loop status (if active)
Step 5.2: System Stats (Optional)
- CPU/Memory usage (like web UI)
- Poll periodically from
/proc
Phase 6: Session Management
Step 6.1: New Session Creation
- Prompt for case name (or use default)
- Create case folder if needed
- Start interactive Claude session
- Add to tab bar
Step 6.2: Session Operations
- Close session (Ctrl+W): Kill screen, remove tab
- Kill all (Ctrl+Shift+K): Confirm dialog, kill all screens
Phase 7: Advanced Features
Step 7.1: Ralph Panel
When Ralph loop active, show:
- Progress ring (iteration count)
- Todo list with status
- Completion phrase status
Step 7.2: Help Overlay
- Press
?orF1to show - List all keyboard shortcuts
- Dismiss with Escape
Step 7.3: Respawn Banner
When respawn enabled:
- Show current state
- Cycle count
- Controls (pause/resume)
Keyboard Shortcuts
| Key | Action |
|---|---|
Ctrl+Tab |
Next tab |
Ctrl+Shift+Tab |
Previous tab |
Ctrl+1-9 |
Go to tab N |
Ctrl+N |
New session |
Ctrl+W |
Close current session |
Ctrl+Shift+K |
Kill all sessions |
Ctrl+L |
Clear terminal |
? or F1 |
Show help |
Escape |
Close overlay/panel |
Ctrl+C |
Exit TUI (with confirm) |
Data Flow
┌──────────────────────────────────────────────────────────────┐
│ TUI App │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ TabBar │ │
│ │ [testcase ●] [another ◐] [+] │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ │ │
│ │ Terminal Viewport │ │
│ │ │ │
│ │ (PTY output from active session) │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ StatusBar: idle | 45.2k tokens | $0.82 | respawn: off │ │
│ └─────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
│ │
│ events │ input
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Session │◄───│ PTY (node-pty) │
│ (existing) │ └─────────────────┘
└─────────────────┘
Files to Create
| File | Purpose | LOC Est. |
|---|---|---|
src/tui/index.ts |
Entry point | 30 |
src/tui/App.tsx |
Main app | 150 |
src/tui/components/TabBar.tsx |
Tab navigation | 80 |
src/tui/components/Terminal.tsx |
Output display | 120 |
src/tui/components/StatusBar.tsx |
Status display | 60 |
src/tui/components/StartScreen.tsx |
Initial view | 100 |
src/tui/components/HelpOverlay.tsx |
Help modal | 50 |
src/tui/components/RalphPanel.tsx |
Loop tracking | 80 |
src/tui/hooks/useSession.ts |
Session management | 100 |
src/tui/hooks/useTerminal.ts |
Terminal handling | 80 |
src/tui/hooks/useKeyboard.ts |
Key shortcuts | 60 |
src/tui/store/tui-state.ts |
State management | 50 |
Total: ~960 lines of new code
Files to Modify
| File | Change |
|---|---|
src/cli.ts |
Add tui command |
src/index.ts |
Export TUI if needed |
package.json |
Add Ink dependencies |
tsconfig.json |
Add JSX support for TSX files |
Testing Strategy
- Unit tests: Component rendering with Ink's test utilities
- Integration tests: Session creation, tab switching
- Manual testing: Real Claude sessions, screen attach/detach
Risks & Mitigations
| Risk | Mitigation |
|---|---|
| Terminal resize handling | Use Ink's built-in resize detection |
| PTY output performance | Reuse existing batching from Session class |
| Input conflicts (TUI vs session) | Clear mode distinction, Escape to exit input mode |
| Screen attachment complexity | Reuse existing screen-manager.ts logic |
Success Criteria
- Launch TUI and see existing sessions from
screens.json - Switch between sessions with tabs
- See real-time Claude output in terminal
- Send input to active session
- Create new sessions
- Kill sessions
- Responsive keyboard navigation
- Clean exit (restore terminal state)
Implementation Order
- Week 1: Phases 1-2 (Foundation + Start Screen)
- Week 2: Phases 3-4 (Tabs + Terminal)
- Week 3: Phases 5-6 (Status + Session Management)
- Week 4: Phase 7 (Advanced Features)
Commands
After implementation:
# Start TUI
claudeman tui
# Or via npm/tsx
npx tsx src/index.ts tui
npm run tui # After adding script