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-27 23:15:25 +01:00
## CRITICAL: Screen Session Safety
2026-01-21 04:44:19 +01:00
**You may be running inside a Claudeman-managed screen session.** Before killing ANY screen or Claude process:
2026-01-27 23:15:25 +01:00
1. Check: `echo $CLAUDEMAN_SCREEN` - if `1` , you're in a managed session
2. **NEVER** run `screen -X quit` , `pkill screen` , or `pkill claude` without confirming
3. Use the web UI or `./scripts/screen-manager.sh` instead of direct kill commands
2026-01-21 04:44:19 +01:00
2026-01-27 23:15:25 +01:00
## COM Shorthand (Deployment)
2026-01-25 18:09:25 +01:00
2026-01-26 21:27:08 +01:00
When user says "COM":
2026-01-27 23:15:25 +01:00
1. Increment version in BOTH `package.json` AND `CLAUDE.md`
2026-01-26 21:27:08 +01:00
2. Run: `git add -A && git commit -m "chore: bump version to X.XXXX" && git push && npm run build && systemctl --user restart claudeman-web`
2026-01-28 03:33:41 +01:00
**Version** : 0.1409 (must match `package.json` )
2026-01-25 18:09:25 +01:00
2026-01-18 04:50:46 +01:00
## Project Overview
2026-01-18 05:17:06 +01:00
2026-01-27 23:15:25 +01:00
Claudeman is a Claude Code session manager with web interface and autonomous Ralph Loop. Spawns Claude CLI via PTY, streams via SSE, supports respawn cycling for 24+ hour autonomous runs.
2026-01-18 04:50:46 +01:00
2026-01-28 00:45:37 +01:00
**Tech Stack** : TypeScript (ES2022/NodeNext, strict mode), Node.js, Fastify, node-pty, xterm.js
2026-01-28 02:31:58 +01:00
**TypeScript Strictness** (see `tsconfig.json` ): `noUnusedLocals` , `noUnusedParameters` , `noImplicitReturns` , `noImplicitOverride` , `noFallthroughCasesInSwitch` , `allowUnreachableCode: false` , `allowUnusedLabels: false`
2026-01-27 00:41:00 +01:00
2026-01-27 23:15:25 +01:00
**Requirements** : Node.js 18+, Claude CLI, GNU Screen
2026-01-20 08:56:15 +01:00
2026-01-18 07:31:19 +01:00
## Commands
2026-01-18 05:17:06 +01:00
2026-01-27 23:15:25 +01:00
**CRITICAL** : `npm run dev` shows CLI help, NOT the web server.
2026-01-25 04:57:09 +01:00
2026-01-18 05:17:06 +01:00
```bash
2026-01-27 23:15:25 +01:00
# Development
npx tsx src/index.ts web # Dev server (RECOMMENDED)
npx tsx src/index.ts web --https # With TLS for notifications
2026-01-28 00:45:37 +01:00
npm run typecheck # Type check
2026-01-18 05:17:06 +01:00
2026-01-27 23:15:25 +01:00
# Testing
npx vitest run # All tests
npx vitest run test/<file>.test.ts # Single file
2026-01-28 00:45:37 +01:00
npm run test:coverage # With coverage report
npm run test:e2e # Browser E2E (run `npx playwright install chromium` first)
2026-01-25 04:57:09 +01:00
2026-01-27 23:15:25 +01:00
# Production
npm run build
systemctl --user restart claudeman-web
journalctl --user -u claudeman-web -f
2026-01-21 23:55:16 +01:00
```
2026-01-28 00:45:37 +01:00
## Binaries
| Binary | Purpose |
|--------|---------|
| `claudeman` | Main CLI and web server |
| `claudeman-mcp` | MCP server for Claude Desktop integration |
2026-01-18 07:31:19 +01:00
## Architecture
2026-01-18 05:17:06 +01:00
2026-01-27 23:15:25 +01:00
### Core Files
2026-01-19 16:45:32 +01:00
2026-01-25 18:09:25 +01:00
| File | Purpose |
|------|---------|
2026-01-27 23:15:25 +01:00
| `src/session.ts` | PTY wrapper: `runPrompt()` , `startInteractive()` , `startShell()` |
| `src/screen-manager.ts` | GNU screen persistence, ghost discovery |
| `src/session-manager.ts` | Session lifecycle, cleanup |
| `src/respawn-controller.ts` | State machine for autonomous cycling |
| `src/ralph-tracker.ts` | Detects `<promise>PHRASE</promise>` , todos |
| `src/plan-orchestrator.ts` | Multi-agent plan generation |
2026-01-20 08:56:15 +01:00
| `src/web/server.ts` | Fastify REST API + SSE at `/api/events` |
2026-01-27 23:15:25 +01:00
| `src/web/public/app.js` | Frontend: xterm.js, tab management, subagent windows |
| `src/types.ts` | All TypeScript interfaces |
2026-01-19 19:56:37 +01:00
2026-01-18 07:38:19 +01:00
### Data Flow
2026-01-27 23:15:25 +01:00
1. Session spawns `claude --dangerously-skip-permissions` via node-pty
2. PTY output buffered, ANSI stripped, parsed for JSON messages
3. WebServer broadcasts to SSE clients at `/api/events`
4. State persists to `~/.claudeman/state.json` via StateStore
2026-01-18 07:31:19 +01:00
2026-01-27 23:15:25 +01:00
### Key Patterns
2026-01-19 18:34:43 +01:00
2026-01-27 23:15:25 +01:00
**Input to sessions** : Use `session.writeViaScreen()` for programmatic input (respawn, auto-compact). Text and Enter sent as separate `screen -X stuff` commands due to Ink's requirements. All prompts must be single-line.
2026-01-19 18:34:43 +01:00
2026-01-27 23:15:25 +01:00
**Idle detection** : Multi-layer (completion message → AI check → output silence → token stability). See `docs/respawn-state-machine.md` .
2026-01-22 21:36:43 +01:00
2026-01-27 23:15:25 +01:00
**Token tracking** : Interactive mode parses status line ("123.4k tokens"), estimates 60/40 input/output split.
2026-01-23 10:20:37 +01:00
2026-01-27 23:15:25 +01:00
**Memory leak prevention** : Frontend runs long; clear all Maps/timers on SSE reconnect in `handleInit()` .
2026-01-23 10:20:37 +01:00
2026-01-27 23:15:25 +01:00
## Adding Features
2026-01-19 13:41:27 +01:00
2026-01-27 23:15:25 +01:00
- **API endpoint**: Types in `types.ts` , route in `server.ts:buildServer()` , use `createErrorResponse()`
- **SSE event**: Emit via `broadcast()` , handle in `app.js:handleSSEEvent()`
- **Session setting**: Add to `SessionState` in `types.ts` , include in `session.toState()` , call `persistSessionState()`
- **New test**: Pick unique port (see below), add port comment to test file header
2026-01-21 09:54:42 +01:00
2026-01-20 08:56:15 +01:00
## State Files
| File | Purpose |
|------|---------|
2026-01-27 23:15:25 +01:00
| `~/.claudeman/state.json` | Sessions, settings, tokens, respawn config |
| `~/.claudeman/screens.json` | Screen metadata for recovery |
| `~/.claudeman/settings.json` | User preferences |
2026-01-22 20:49:09 +01:00
2026-01-27 23:15:25 +01:00
## Testing
2026-01-20 08:56:15 +01:00
2026-01-28 00:09:22 +01:00
**Port allocation** : E2E tests use centralized ports in `test/e2e/e2e.config.ts` (E2E_PORTS: 3183-3190). Unit/integration tests pick unique ports manually (3099-3157). Search `const PORT =` or `TEST_PORT` in test files to see used ports. **Next available: 3192**
2026-01-21 19:49:44 +01:00
2026-01-27 23:15:25 +01:00
**E2E tests** : Use Playwright. Run `npx playwright install chromium` first. See `test/e2e/fixtures/` for helpers. E2E config provides ports, timeouts, and helpers.
2026-01-22 22:43:09 +01:00
2026-01-28 02:31:58 +01:00
**Test config** : Vitest runs with `globals: true` (no imports needed for `describe` /`it` /`expect` ) and `fileParallelism: false` (files run sequentially to respect screen limits). Unit test timeout is 30s, teardown timeout is 60s. E2E tests have longer timeouts defined in `test/e2e/e2e.config.ts` (90s test, 30s session creation).
2026-01-21 19:49:44 +01:00
2026-01-27 23:15:25 +01:00
**Test safety** : `test/setup.ts` provides:
- Screen concurrency limiter (max 10)
- Pre-existing screen protection (never kills screens present before tests)
- Tracked resource cleanup (only kills screens/processes tests register)
- Safe to run from within Claudeman-managed sessions
2026-01-21 04:27:09 +01:00
2026-01-27 23:15:25 +01:00
Respawn tests use MockSession to avoid spawning real Claude processes.
2026-01-21 04:27:09 +01:00
2026-01-27 23:15:25 +01:00
## Debugging
2026-01-26 11:06:35 +01:00
2026-01-20 08:56:15 +01:00
```bash
2026-01-27 23:15:25 +01:00
screen -ls # List screens
screen -r <name> # Attach (Ctrl+A D to detach)
curl localhost:3000/api/sessions # Check sessions
curl localhost:3000/api/status | jq # Full app state
cat ~/.claudeman/state.json | jq # View persisted state
2026-01-20 08:56:15 +01:00
```
2026-01-27 23:15:25 +01:00
## Performance Constraints
2026-01-27 17:46:43 +01:00
2026-01-27 23:15:25 +01:00
The app must stay fast with 20 sessions and 50 agent windows:
- 60fps terminal (16ms batching + `requestAnimationFrame` )
- Auto-trimming buffers (2MB terminal max)
- Debounced state persistence (500ms)
- SSE batching (16ms)
2026-01-27 17:46:43 +01:00
2026-01-27 23:15:25 +01:00
## Buffer Limits
2026-01-27 18:16:19 +01:00
2026-01-27 23:15:25 +01:00
| Buffer | Max | Trim To |
|--------|-----|---------|
| Terminal | 2MB | 1.5MB |
| Text output | 1MB | 768KB |
| Messages | 1000 | 800 |
2026-01-27 18:16:19 +01:00
2026-01-27 23:15:25 +01:00
## Where to Find More Information
2026-01-27 18:16:19 +01:00
2026-01-27 23:15:25 +01:00
| Topic | Location |
|-------|----------|
| **Respawn state machine** | `docs/respawn-state-machine.md` |
| **Spawn agent protocol** | `docs/spawn-protocol.md` |
| **Ralph Loop guide** | `docs/ralph-wiggum-guide.md` |
| **Claude Code hooks** | `docs/claude-code-hooks-reference.md` |
| **Browser/E2E testing** | `docs/browser-testing-guide.md` |
| **API routes** | `src/web/server.ts:buildServer()` or README.md |
| **SSE events** | Search `broadcast(` in `server.ts` |
| **CLI commands** | `claudeman --help` |
| **Frontend patterns** | `src/web/public/app.js` (subagent windows, notifications) |
| **Session modes** | `SessionMode` type in `src/types.ts` |
| **Error codes** | `createErrorResponse()` in `src/types.ts` |
| **Test fixtures** | `test/e2e/fixtures/` |
| **Test utilities** | `test/respawn-test-utils.ts` |
| **Keyboard shortcuts** | README.md or App Settings in web UI |