2026-01-18 04:50:46 +01:00
# CLAUDE.md
2026-01-18 07:31:19 +01:00
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
2026-01-18 04:50:46 +01:00
2026-01-21 04:44:19 +01:00
## ⚠️ CRITICAL: Screen Session Safety
**You may be running inside a Claudeman-managed screen session.** Before killing ANY screen or Claude process:
1. **Check environment** : `echo $CLAUDEMAN_SCREEN` - if it returns `1` , you're in a managed session
2. **NEVER run** `screen -X quit` , `pkill screen` , or `pkill claude` without first confirming you're not killing yourself
3. **Safe debugging** : Use `screen -ls` to LIST sessions, but don't kill them blindly
4. **If you need to kill screens** : Use the web UI or `./scripts/screen-manager.sh` instead of direct commands
**Why this matters** : Killing your own screen terminates your session mid-work, losing context and potentially corrupting state.
2026-01-18 04:50:46 +01:00
## Project Overview
2026-01-18 05:17:06 +01:00
2026-01-18 07:31:19 +01:00
Claudeman is a Claude Code session manager with a web interface and autonomous Ralph Loop. It spawns Claude CLI processes via PTY, streams output in real-time via SSE, and supports scheduled/timed runs.
2026-01-18 04:50:46 +01:00
2026-01-19 11:19:13 +01:00
**Tech Stack** : TypeScript (ES2022/NodeNext, strict mode), Node.js, Fastify, Server-Sent Events, node-pty
2026-01-18 05:17:06 +01:00
2026-01-19 02:06:37 +01:00
**Requirements** : Node.js 18+, Claude CLI (`claude` ) installed and available in PATH
2026-01-20 08:56:15 +01:00
## First-Time Setup
```bash
npm install
```
2026-01-18 07:31:19 +01:00
## Commands
2026-01-18 05:17:06 +01:00
2026-01-19 19:56:37 +01:00
**CRITICAL** : `npm run dev` runs CLI help, NOT the web server. Use `npx tsx src/index.ts web` for development.
2026-01-19 16:45:32 +01:00
2026-01-18 05:17:06 +01:00
```bash
2026-01-18 07:31:19 +01:00
npm run build # Compile TypeScript + copy static files to dist/web/
2026-01-18 07:38:19 +01:00
npm run clean # Remove dist/
2026-01-18 05:17:06 +01:00
2026-01-19 03:43:59 +01:00
# Start web server (pick one):
npx tsx src/index.ts web # Dev mode - no build needed (RECOMMENDED)
npx tsx src/index.ts web -p 8080 # Dev mode with custom port
2026-01-20 19:43:29 +01:00
npm run web # After npm run build (shorthand)
2026-01-19 03:43:59 +01:00
node dist/index.js web # After npm run build
claudeman web # After npm link
2026-01-21 06:21:25 +01:00
# Start TUI (terminal user interface):
npx tsx src/index.ts tui # Dev mode - full-screen TUI
claudeman tui # After npm link
2026-01-20 08:56:15 +01:00
# Testing (vitest)
# Note: globals: true configured - no imports needed for describe/it/expect
2026-01-19 05:28:45 +01:00
npm run test # Run all tests once
npm run test:watch # Watch mode
npm run test:coverage # With coverage report
npx vitest run test/session.test.ts # Single file
npx vitest run -t "should create session" # By pattern
2026-01-20 08:56:15 +01:00
2026-01-20 17:43:36 +01:00
# Test port allocation (integration tests spawn servers):
# 3099: quick-start.test.ts
2026-01-20 08:56:15 +01:00
# 3102: session.test.ts
2026-01-20 17:43:36 +01:00
# 3105: scheduled-runs.test.ts
# 3107: sse-events.test.ts
# 3110: edge-cases.test.ts
# 3115: integration-flows.test.ts
# 3120: session-cleanup.test.ts
2026-01-21 07:38:31 +01:00
# Unit tests (no port needed): respawn-controller, inner-loop-tracker, pty-interactive, task-queue, task, ralph-loop, session-manager, state-store, types
2026-01-20 08:56:15 +01:00
# Next available: 3122+
2026-01-20 08:40:14 +01:00
# Tests mock PTY - no real Claude CLI spawned
2026-01-20 08:56:15 +01:00
# Test timeout: 30s (configured in vitest.config.ts)
2026-01-19 13:41:27 +01:00
2026-01-20 17:43:36 +01:00
# TypeScript checking
2026-01-19 13:41:27 +01:00
npx tsc --noEmit # Type check without building
2026-01-20 17:43:36 +01:00
# Note: No ESLint/Prettier configured - rely on TypeScript strict mode
2026-01-19 11:19:13 +01:00
# Debugging
screen -ls # List GNU screen sessions
2026-01-20 17:43:36 +01:00
screen -r <name> # Attach to screen session (Ctrl+A D to detach)
2026-01-19 11:19:13 +01:00
curl localhost:3000/api/sessions # Check active sessions
2026-01-20 17:43:36 +01:00
curl localhost:3000/api/status | jq . # Full app state including respawn
2026-01-20 08:56:15 +01:00
cat ~/.claudeman/state.json | jq . # View main state
cat ~/.claudeman/state-inner.json | jq . # View inner loop state
2026-01-20 17:43:36 +01:00
# Kill stuck screen sessions
screen -X -S <name> quit # Graceful quit
pkill -f "SCREEN.*claudeman" # Force kill all claudeman screens
2026-01-18 05:17:06 +01:00
```
2026-01-18 07:31:19 +01:00
## Architecture
2026-01-18 05:17:06 +01:00
2026-01-20 08:56:15 +01:00
### Key Files
2026-01-19 16:45:32 +01:00
2026-01-20 08:56:15 +01:00
| File | Purpose |
|------|---------|
| `src/session.ts` | Core PTY wrapper for Claude CLI. Modes: `runPrompt()` , `startInteractive()` , `startShell()` |
| `src/respawn-controller.ts` | State machine for autonomous session cycling |
| `src/screen-manager.ts` | GNU screen persistence, ghost discovery, 4-strategy kill |
| `src/inner-loop-tracker.ts` | Detects `<promise>PHRASE</promise>` , todos, loop status in output |
| `src/task-tracker.ts` | Parses background task output (agent IDs, status) from Claude CLI |
2026-01-20 17:43:36 +01:00
| `src/session-manager.ts` | Manages session lifecycle, task assignment, and cleanup |
| `src/state-store.ts` | JSON persistence to `~/.claudeman/` with debounced writes |
2026-01-20 08:56:15 +01:00
| `src/web/server.ts` | Fastify REST API + SSE at `/api/events` |
| `src/web/public/app.js` | Frontend: SSE handling, xterm.js, tab management |
2026-01-21 06:21:25 +01:00
| `src/tui/App.tsx` | TUI main component: tabs, terminal viewport, status bar (Ink/React) |
| `src/tui/hooks/useSessionManager.ts` | TUI session state, screen polling, input handling |
2026-01-20 08:56:15 +01:00
| `src/types.ts` | All TypeScript interfaces |
2026-01-19 19:56:37 +01:00
2026-01-18 07:38:19 +01:00
### Data Flow
1. **Session** spawns `claude -p --dangerously-skip-permissions` via `node-pty`
2. PTY output is buffered, ANSI stripped, and parsed for JSON messages
3. **WebServer** broadcasts events to SSE clients at `/api/events`
2026-01-18 07:31:19 +01:00
4. State persists to `~/.claudeman/state.json` via **StateStore**
2026-01-19 18:34:43 +01:00
### Respawn State Machine
```
2026-01-20 17:43:36 +01:00
┌─────────────────────────────────────────────────────────────────────────────────────────────────┐
│ │
▼ │
WATCHING → SENDING_UPDATE → WAITING_UPDATE → SENDING_CLEAR → WAITING_CLEAR │
│ │
▼ │
SENDING_INIT → WAITING_INIT → MONITORING_INIT ──┬──────────────────┘
│
▼ (if no work triggered)
SENDING_KICKSTART → WAITING_KICKSTART
2026-01-19 18:34:43 +01:00
```
2026-01-20 17:43:36 +01:00
**States** : `watching` , `sending_update` , `waiting_update` , `sending_clear` , `waiting_clear` , `sending_init` , `waiting_init` , `monitoring_init` , `sending_kickstart` , `waiting_kickstart` , `stopped`
Steps can be skipped via config (`sendClear: false` , `sendInit: false` ). Optional `kickstartPrompt` triggers if `/init` doesn't start work. Idle detection triggers state transitions.
2026-01-19 18:34:43 +01:00
2026-01-19 16:45:32 +01:00
### Session Modes
Sessions have a `mode` property (`SessionMode` type):
- **`'claude'` **: Runs Claude CLI for AI interactions (default)
- **`'shell'` **: Runs a plain bash shell for debugging/testing
2026-01-21 04:44:19 +01:00
### Screen-Aware Sessions
All Claude sessions spawned by Claudeman receive environment variables indicating they're running in a managed screen:
| Variable | Value | Purpose |
|----------|-------|---------|
| `CLAUDEMAN_SCREEN` | `1` | Indicates session is managed by Claudeman |
| `CLAUDEMAN_SESSION_ID` | `<uuid>` | Unique session identifier |
| `CLAUDEMAN_SCREEN_NAME` | `claudeman-<name>` | GNU screen session name |
This prevents Claude from accidentally killing its own screen session. The default CLAUDE.md template includes guidance about this.
**Implementation** : Set in `screen-manager.ts:createScreen()` for screen-based sessions and `session.ts:startInteractive()` /`startShell()` for PTY-only sessions.
2026-01-18 05:17:06 +01:00
## Code Patterns
2026-01-19 12:52:29 +01:00
### Pre-compiled Regex Patterns
For performance, regex patterns that are used frequently should be compiled once at module level:
```typescript
// Good - compile once
const ANSI_ESCAPE_PATTERN = /\x1b\[[0-9;]*m/g ;
const TOKEN_PATTERN = /(\d+(?:\.\d+)?)\s*([kKmM])?\s*tokens/ ;
// Bad - recompiles on each call
function parse ( line : string ) {
return line . replace ( /\x1b\[[0-9;]*m/g , '' );
}
```
2026-01-18 07:31:19 +01:00
### Claude Message Parsing
Claude CLI outputs newline-delimited JSON. Strip ANSI codes before parsing:
2026-01-18 05:17:06 +01:00
```typescript
2026-01-19 12:52:29 +01:00
const cleanLine = line . replace ( ANSI_ESCAPE_PATTERN , '' );
2026-01-18 07:31:19 +01:00
const msg = JSON . parse ( cleanLine ) as ClaudeMessage ;
2026-01-18 21:37:03 +01:00
// msg.type: 'system' | 'assistant' | 'user' | 'result'
2026-01-18 07:31:19 +01:00
// msg.message?.content: Array<{ type: 'text', text: string }>
// msg.total_cost_usd: number (on result messages)
2026-01-18 05:17:06 +01:00
```
2026-01-18 21:37:03 +01:00
### PTY Spawn Modes
```typescript
2026-01-19 10:36:30 +01:00
// One-shot mode (JSON output for token tracking)
2026-01-19 04:45:51 +01:00
pty . spawn ( 'claude' , [ '-p' , '--dangerously-skip-permissions' , '--output-format' , 'stream-json' , prompt ], { ... })
2026-01-18 21:37:03 +01:00
2026-01-19 10:36:30 +01:00
// Interactive mode (tokens parsed from status line)
2026-01-18 21:37:03 +01:00
pty . spawn ( 'claude' , [ '--dangerously-skip-permissions' ], { ... })
2026-01-19 18:04:50 +01:00
// Shell mode (debugging/testing - no Claude CLI)
pty . spawn ( 'bash' , [], { ... })
2026-01-18 21:37:03 +01:00
```
2026-01-20 08:40:14 +01:00
### Sending Input to Sessions
2026-01-19 16:35:20 +01:00
2026-01-20 08:40:14 +01:00
There are two methods for sending input to Claude sessions:
2026-01-19 16:35:20 +01:00
2026-01-20 08:40:14 +01:00
#### 1. `session.write(data)` - Direct PTY write
Used by the `/api/sessions/:id/input` API endpoint. Writes directly to PTY.
```typescript
session . write ( 'hello world' ); // Text only, no Enter
session . write ( '\r' ); // Enter key separately
2026-01-19 16:35:20 +01:00
```
2026-01-20 08:40:14 +01:00
#### 2. `session.writeViaScreen(data)` - Via GNU screen (RECOMMENDED for programmatic input)
Used by RespawnController, auto-compact, auto-clear. More reliable for Ink/Claude CLI.
```typescript
// Append \r to include Enter - the method handles splitting automatically
session . writeViaScreen ( 'your command here\r' );
session . writeViaScreen ( '/clear\r' );
session . writeViaScreen ( '/init\r' );
```
**How `writeViaScreen` works internally** (in `screen-manager.ts:sendInput` ):
1. Splits input into text and `\r` (carriage return)
2. Sends text first: `screen -S name -p 0 -X stuff "text"`
3. Sends Enter separately: `screen -S name -p 0 -X stuff "$(printf '\015')"`
2026-01-20 17:43:36 +01:00
**Why separate commands?** Claude CLI uses [Ink ](https://github.com/vadimdemedes/ink ) (React for terminals) which requires text and Enter as separate `screen -X stuff` commands. Combining them doesn't work. This is a critical implementation detail when debugging input issues.
2026-01-20 08:40:14 +01:00
#### API Usage
```bash
# Send text (won't submit until Enter is sent)
curl -X POST localhost:3000/api/sessions/:id/input \
-H "Content-Type: application/json" \
-d '{"input": "your prompt here"}'
# Send Enter separately to submit
curl -X POST localhost:3000/api/sessions/:id/input \
-H "Content-Type: application/json" \
-d '{"input": "\r"}'
```
**Note** : The API uses `session.write()` which goes to PTY directly. For reliability with Ink, consider using the respawn controller pattern or adding an API endpoint that uses `writeViaScreen()` .
2026-01-19 16:35:20 +01:00
2026-01-18 07:31:19 +01:00
### Idle Detection
2026-01-19 15:00:49 +01:00
**RespawnController** : Primary `↵ send` indicator, fallback prompt chars (`❯ ` , `⏵` ) + 10s timeout. Working patterns: `Thinking` , `Writing` , `Running` .
**Session** : emits `idle` /`working` events on prompt detection + 2s activity timeout.
2026-01-18 07:31:19 +01:00
2026-01-19 10:36:30 +01:00
### Token Tracking
2026-01-18 21:37:03 +01:00
2026-01-19 10:36:30 +01:00
- **One-shot mode**: Uses `--output-format stream-json` for detailed token usage from JSON
- **Interactive mode**: Parses tokens from Claude's status line (e.g., "123.4k tokens"), estimates 60/40 input/output split
2026-01-18 21:37:03 +01:00
2026-01-19 13:08:53 +01:00
### Auto-Compact & Auto-Clear
2026-01-19 15:00:49 +01:00
| Feature | Default Threshold | Action |
|---------|------------------|--------|
| Auto-Compact | 110k tokens | `/compact` with optional prompt |
| Auto-Clear | 140k tokens | `/clear` to reset context |
2026-01-19 13:08:53 +01:00
2026-01-19 15:00:49 +01:00
Both wait for idle. Configure via `session.setAutoCompact()` / `session.setAutoClear()` .
2026-01-19 13:08:53 +01:00
2026-01-19 13:24:45 +01:00
### Inner Loop Tracking
2026-01-20 08:56:15 +01:00
Detects Ralph loops and todos inside Claude sessions. **Disabled by default** but auto-enables when any of these patterns are detected in terminal output:
2026-01-20 17:43:36 +01:00
- `/ralph-loop:ralph-loop` command
2026-01-19 18:34:43 +01:00
- `<promise>PHRASE</promise>` completion phrases
- `TodoWrite` tool usage
- Iteration patterns (`Iteration 5/50` , `[5/50]` )
- Todo checkboxes (`- [ ]` /`- [x]` ) or indicator icons (`☐` /`◐` /`✓` )
2026-01-20 17:43:36 +01:00
- "All tasks complete" messages
- Individual task completion signals (`Task 8 is done` )
2026-01-19 18:34:43 +01:00
2026-01-20 08:56:15 +01:00
See `inner-loop-tracker.ts:shouldAutoEnable()` for detection logic.
2026-01-20 17:43:36 +01:00
**Completion Detection** : Uses multi-strategy detection:
- 1st occurrence of `<promise>PHRASE</promise>` : Stores as expected phrase (likely in prompt)
- 2nd occurrence: Emits `completionDetected` event (actual completion)
- **Bare phrase detection**: Also detects phrase without tags once expected phrase is known
- **All complete detection**: When "All X files/tasks created/completed" detected, marks all todos complete and emits completion
- If loop is already active (via `/ralph-loop:ralph-loop` ): Emits immediately on first occurrence
**Session Lifecycle** : Each session has its own independent tracker:
- New session → Fresh tracker (no carryover)
- Close tab → Tracker state cleared, UI panel hides
- Switch tabs → Panel shows tracker for active session
- `tracker.reset()` → Clears todos/state, keeps enabled status
- `tracker.fullReset()` → Complete reset to initial state
**API** :
- `GET /api/sessions/:id/inner-state` - Get loop state and todos
- `POST /api/sessions/:id/inner-config` - Configure tracker:
- `{ enabled: boolean }` - Enable/disable
- `{ reset: true }` - Soft reset (keep enabled)
- `{ reset: "full" }` - Full reset
UI: Collapsible panel below tabs, shows progress ring and todo list.
2026-01-19 13:24:45 +01:00
2026-01-19 15:00:49 +01:00
### Terminal Display Fix
2026-01-19 13:24:45 +01:00
2026-01-19 15:00:49 +01:00
Tab switch/new session fix: clear xterm → write buffer → resize PTY → Ctrl+L redraw. Uses `pendingCtrlL` Set, triggered on `session:idle` /`session:working` events.
2026-01-19 11:19:13 +01:00
2026-01-19 05:28:45 +01:00
### SSE Events
2026-01-18 07:31:19 +01:00
2026-01-19 05:28:45 +01:00
All events broadcast to `/api/events` with format: `{ type: string, sessionId?: string, data: any }` .
2026-01-18 07:31:19 +01:00
2026-01-20 08:56:15 +01:00
Event prefixes: `session:` , `task:` , `respawn:` , `scheduled:` , `case:` , `screen:` , `init` .
Key events for frontend handling (see `app.js:handleSSEEvent()` ):
- `session:idle` , `session:working` - Status indicator updates
- `session:terminal` , `session:clearTerminal` - Terminal content
- `session:completion` , `session:autoClear` , `session:autoCompact` - Lifecycle events
- `session:innerLoopUpdate` , `session:innerTodoUpdate` , `session:innerCompletionDetected` - Ralph tracking
2026-01-19 11:19:13 +01:00
### Frontend (app.js)
2026-01-20 08:56:15 +01:00
Vanilla JS + xterm.js. Key functions:
- `handleSSEEvent()` - Dispatches events to appropriate handlers
- `switchToSession()` - Tab management and terminal focus
- `createSessionTab()` - Tab creation and xterm setup
**60fps Rendering Pipeline** :
- Server batches terminal data every 16ms before broadcasting via SSE
- Client uses `requestAnimationFrame` to batch xterm.js writes
- Prevents UI jank during high-throughput Claude output
2026-01-19 05:28:45 +01:00
2026-01-19 15:00:49 +01:00
### State Store
2026-01-19 12:55:08 +01:00
2026-01-20 17:43:36 +01:00
Writes debounced to `~/.claudeman/state.json` . Batches rapid changes.
### Timing Constants
| Constant | Value | Location |
|----------|-------|----------|
| State save debounce | 500ms | `state-store.ts` |
2026-01-21 06:16:31 +01:00
| State update debounce | 500ms | `server.ts` |
2026-01-20 17:43:36 +01:00
| Line buffer flush | 100ms | `session.ts` |
| Terminal batch interval | 16ms | `server.ts` (60fps) |
2026-01-20 19:43:29 +01:00
| Output batch interval | 50ms | `server.ts` |
| Task update batch interval | 100ms | `server.ts` |
2026-01-21 06:16:31 +01:00
| Inner loop event debounce | 50ms | `inner-loop-tracker.ts` |
| Session tabs render debounce | 100ms | `app.js` |
| Inner panel render debounce | 50ms | `app.js` |
| Task panel render debounce | 100ms | `app.js` |
| Input batch interval | 16ms | `app.js` (60fps) |
2026-01-20 17:43:36 +01:00
| Idle activity timeout | 2s | `session.ts` |
| Respawn idle timeout | 5s default | `RespawnConfig.idleTimeoutMs` |
2026-01-19 12:55:08 +01:00
2026-01-20 08:56:15 +01:00
### TypeScript Config
Module resolution: NodeNext. Target: ES2022. Strict mode enabled. See `tsconfig.json` for full settings.
2026-01-19 07:33:33 +01:00
## Adding New Features
2026-01-20 08:56:15 +01:00
- **API endpoint**: Add types in `types.ts` , route in `server.ts:buildServer()` , use `createErrorResponse()` for errors
- **SSE event**: Emit via `broadcast()` in server.ts, handle in `app.js:handleSSEEvent()` switch
- **Session event**: Add to `SessionEvents` interface in `session.ts` , emit via `this.emit()` , subscribe in server.ts, handle in frontend
2026-01-20 17:43:36 +01:00
- **New test file**: Create `test/<name>.test.ts` , pick unique port (next available: 3122+), add to port allocation comment above
### API Error Codes
Use `createErrorResponse(code, details?)` from `types.ts` :
| Code | Use Case |
|------|----------|
| `NOT_FOUND` | Session/resource doesn't exist |
| `INVALID_INPUT` | Bad request parameters |
| `SESSION_BUSY` | Session is currently processing |
| `OPERATION_FAILED` | Action couldn't complete |
| `ALREADY_EXISTS` | Duplicate resource |
| `INTERNAL_ERROR` | Unexpected server error |
2026-01-19 07:33:33 +01:00
2026-01-19 11:31:32 +01:00
## Session Lifecycle & Cleanup
2026-01-21 04:44:19 +01:00
- **Limit**: Web server: `MAX_CONCURRENT_SESSIONS = 50` (`server.ts:56` ), UI tab limit: 20, CLI default: 5 (`types.ts:DEFAULT_CONFIG` )
2026-01-19 15:00:49 +01:00
- **Kill** (`killScreen()` ): child PIDs → process group → screen quit → SIGKILL
- **Ghost discovery**: `reconcileScreens()` finds orphaned screens on startup
- **Cleanup** (`cleanupSession()` ): stops respawn, clears buffers/timers, kills screen
2026-01-19 11:31:32 +01:00
2026-01-19 12:52:29 +01:00
## Buffer Limits
Long-running sessions are supported with automatic trimming:
| Buffer | Max Size | Trim To |
|--------|----------|---------|
| Terminal | 5MB | 4MB |
| Text output | 2MB | 1.5MB |
| Messages | 1000 | 800 |
| Line buffer | 64KB | (flushed every 100ms) |
| Respawn buffer | 1MB | 512KB |
2026-01-19 15:00:49 +01:00
## E2E Testing
2026-01-19 12:55:08 +01:00
2026-01-19 15:00:49 +01:00
Uses `agent-browser` for web UI automation. Full test plan: `.claude/skills/e2e-test.md`
2026-01-19 12:55:08 +01:00
```bash
2026-01-20 08:56:15 +01:00
npx agent-browser open http://localhost:3000
npx agent-browser wait --load networkidle
npx agent-browser snapshot
npx agent-browser find text "Run Claude" click
npx agent-browser close
2026-01-19 12:55:08 +01:00
```
2026-01-19 13:41:27 +01:00
## API Routes Quick Reference
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/events` | SSE stream for real-time updates |
| GET | `/api/status` | Full application state |
| GET/POST/DELETE | `/api/sessions` | List/create/kill-all sessions |
| GET/DELETE | `/api/sessions/:id` | Get/delete specific session |
| POST | `/api/sessions/:id/input` | Send input to session PTY |
| POST | `/api/sessions/:id/resize` | Resize terminal (cols, rows) |
| POST | `/api/sessions/:id/interactive` | Start interactive mode |
| POST | `/api/sessions/:id/respawn/start` | Start respawn controller |
| POST | `/api/sessions/:id/respawn/stop` | Stop respawn controller |
2026-01-19 18:04:50 +01:00
| POST | `/api/sessions/:id/respawn/enable` | Enable respawn with config + optional timer |
2026-01-20 07:48:04 +01:00
| PUT | `/api/sessions/:id/respawn/config` | Update config on running respawn |
2026-01-19 18:04:50 +01:00
| POST | `/api/sessions/:id/inner-config` | Configure Ralph Wiggum loop settings |
| GET | `/api/sessions/:id/inner-state` | Get Ralph loop state + todos |
| POST | `/api/sessions/:id/auto-compact` | Configure auto-compact threshold |
| POST | `/api/sessions/:id/auto-clear` | Configure auto-clear threshold |
2026-01-19 13:41:27 +01:00
| POST | `/api/quick-start` | Create case + start interactive session |
| GET | `/api/cases` | List available cases |
| POST | `/api/cases` | Create new case |
| GET | `/api/screens` | List screen sessions with stats |
2026-01-20 08:56:15 +01:00
## Keyboard Shortcuts
2026-01-19 01:42:47 +01:00
2026-01-20 08:56:15 +01:00
| Shortcut | Action |
|----------|--------|
| `Ctrl+Enter` | Run Claude (create case + interactive session) |
| `Ctrl+W` | Close current session |
| `Ctrl+Tab` | Switch to next session |
| `Ctrl+K` | Kill all sessions |
| `Ctrl+L` | Clear terminal |
| `Ctrl++/-` | Increase/decrease font size |
| `Ctrl+?` | Show keyboard shortcuts help |
| `Escape` | Close panels and modals |
## State Files
| File | Purpose |
|------|---------|
| `~/.claudeman/state.json` | Sessions, tasks, config |
| `~/.claudeman/state-inner.json` | Inner loop/todo state (separate to reduce writes) |
| `~/.claudeman/screens.json` | Screen session metadata |
Cases created in `~/claudeman-cases/` by default.
2026-01-21 04:27:09 +01:00
## Screen Session Manager (CLI Tool)
Interactive bash tool for managing claudeman screen sessions directly from the terminal.
```bash
./scripts/screen-manager.sh # Interactive mode
./scripts/screen-manager.sh list # List all sessions
./scripts/screen-manager.sh attach 1 # Attach to session #1
./scripts/screen-manager.sh kill 2,3 # Kill sessions 2 and 3
./scripts/screen-manager.sh kill-all # Kill all sessions
./scripts/screen-manager.sh info 1 # Show session #1 details
```
**Interactive Controls:**
| Key | Action |
|-----|--------|
| `↑` /`↓` or `j` /`k` | Navigate sessions |
| `Enter` | Attach to selected session |
| `d` | Delete selected session |
| `D` | Delete ALL sessions |
| `i` | Show session info |
| `q` /`Esc` | Quit |
**Features:**
- Reads from `~/.claudeman/screens.json` (claudeman's authoritative source)
- Shows session name, running time, alive/dead status, mode
- Flicker-free navigation (only updates changed rows)
- Requires `jq` and `screen` to be installed
2026-01-20 08:56:15 +01:00
## Documentation
Extended documentation is available in the `docs/` directory:
| Document | Description |
|----------|-------------|
| [`docs/ralph-wiggum-guide.md` ](docs/ralph-wiggum-guide.md ) | Complete Ralph Wiggum loop guide: official plugin reference, best practices, prompt templates, troubleshooting |
| [`docs/claude-code-hooks-reference.md` ](docs/claude-code-hooks-reference.md ) | Official Claude Code hooks documentation: all events, configuration, examples |
### Quick Reference: Ralph Wiggum Loops
**Core Pattern** : `<promise>PHRASE</promise>` - The completion signal that tells the loop to stop.
2026-01-20 17:43:36 +01:00
**Skill Commands** :
2026-01-20 08:56:15 +01:00
```bash
2026-01-20 17:43:36 +01:00
/ralph-loop:ralph-loop # Start Ralph Loop in current session
/ralph-loop:cancel-ralph # Cancel active Ralph Loop
/ralph-loop:help # Show help and usage
2026-01-20 08:56:15 +01:00
```
**Claudeman Implementation** : The `InnerLoopTracker` class (`src/inner-loop-tracker.ts` ) detects Ralph patterns in Claude output and tracks loop state, todos, and completion phrases. It auto-enables when Ralph-related patterns are detected.
2026-01-21 04:27:09 +01:00
See [`docs/ralph-wiggum-guide.md` ](docs/ralph-wiggum-guide.md ) for full documentation on best practices, prompt templates, and troubleshooting.
2026-01-21 04:44:19 +01:00
2026-01-21 06:16:31 +01:00
## Optimization Status
2026-01-21 04:44:19 +01:00
2026-01-21 06:16:31 +01:00
Most critical optimizations have been implemented. See `.claude/optimization-todos.md` for details.
2026-01-21 04:44:19 +01:00
2026-01-21 06:16:31 +01:00
**Completed:**
| Area | Implementation |
|------|----------------|
| Buffer management | `BufferAccumulator` with auto-trimming |
| Pre-compiled regex | Module-level patterns with lastIndex resets |
| Event listener cleanup | `cleanupTrackerListeners()` in session.ts |
| Event debouncing | 50ms debounce in `inner-loop-tracker.ts` |
| State update debouncing | 500ms batching in `server.ts` |
| Regex pre-checks | String.includes() before pattern.test() |
| Frontend render debouncing | 50-100ms for panels, tabs |
| CSS containment | `contain` property on terminal, panels, modals |
| Input batching | 60fps keystroke coalescing |
| Incremental DOM updates | Session tabs and Ralph todos |
**Remaining:**
2026-01-21 04:44:19 +01:00
| Priority | Area | Files |
|----------|------|-------|
2026-01-21 06:16:31 +01:00
| Low | Task lookup optimization | `task-tracker.ts` |
| Low | Buffer pagination API | `server.ts` |
2026-01-21 04:44:19 +01:00
Run `cat .claude/optimization-todos.md` for the full list with file:line references.