The "Startup Mode" setting (normal/bypass/allowedTools) was saved to
settings but never read when spawning sessions. All code paths had
--dangerously-skip-permissions hardcoded. Now reads claudeMode from
~/.claudeman/settings.json and passes it through Session → TmuxManager.
Closes#12
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- TaskTracker.getTaskTreeLight(): strips large `output` strings from tasks
in SSE broadcasts (was serializing 5-10MB every 500ms with many subagents)
- session:created broadcasts now use toLightDetailedState() (consistent with
session:updated which already did)
- GET /api/sessions/:id returns light state (no 2-3MB terminal+text buffers)
- Ralph wizard polls /terminal?tail=2048 instead of full session endpoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, when Claude exited inside tmux (exitCode=0 or crash), tmux
destroyed the entire session — losing buffer, history, and causing crash
loops on restart attempts. Now:
- Set remain-on-exit on for all tmux sessions
- Detect dead panes via #{pane_dead} instead of assuming session is gone
- Respawn dead panes with tmux respawn-pane -k (preserves session)
- Applied to both startInteractive and startShell paths
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously, server.stop() called cleanupSession(killMux=false) for all sessions,
which still tore down session state, removed listeners, killed PTY processes via
node-pty SIGHUP, and broadcast session:deleted. This caused Claude sessions
running inside tmux to be disrupted during COM deploys.
Now server shutdown just persists state, removes listeners, and lets the Node.js
process exit naturally. The tmux sessions survive independently, and
restoreMuxSessions() finds them alive on restart.
Also adds defense-in-depth in session.stop(): when killMux=false, skip PTY kill
entirely (just null the reference). And adds 'detached' lifecycle event type for
accurate audit logging.
When Claude exits inside a tmux session, tmux destroys the session
(remain-on-exit is off), but the _muxSession reference persists.
On restart, startInteractive() treats it as a "restored session" and
tries to attach to the dead tmux — causing instant exit code 1.
Now checks tmux has-session before attaching. If the session is gone,
clears the stale reference and creates a fresh tmux session.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Clear teams/teamTasks maps in handleInit() on SSE reconnect
- Fix saveNowAsync() race condition with in-flight promise guard
- Add setMaxListeners() on Session, WebServer, SubagentWatcher,
ImageWatcher, TmuxManager to prevent MaxListenersExceeded warnings
- Debounce persistSessionState() per-session (100ms) to reduce
redundant toState() serialization across 25+ call sites
- Cache getLightSessionsState() with 1s TTL to avoid re-serializing
all sessions on every SSE connect and /api/sessions request
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. handleInit crash: commit cdc822d removed Map initializations for
teammateTerminals, teammatePanesByName, teams, teamTasks, teammateMap
from the constructor but left cleanup code that iterates them.
cleanupAllFloatingWindows() crashed on "not iterable", preventing
ALL frontend data (sessions, subagents) from loading.
2. claudeSessionId null on recovered sessions: only set inside
startInteractive(), never in constructor or persisted. After server
restart, recovered sessions had null claudeSessionId, so the
hasMatchingTab check always failed → no subagent windows.
Fixes:
- Re-add all 5 missing Map initializations in app.js constructor
- Set _claudeSessionId = this.id in Session constructor (Claudeman
always passes --session-id to Claude, so they always match)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added IS_TEST_MODE (process.env.VITEST) guards to every method in TmuxManager and
ScreenManager that touches real tmux/screen sessions. Tests can never create, kill,
discover, or send input to real sessions. Removed broken E2E test suite entirely.
Rewrote test/setup.ts from 459 lines to minimal cleanup. Rewrote tmux-related tests
to verify test-mode safety behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat: interactive teammate tmux pane windows with xterm.js terminals
feat: auto-cleanup teams/subagents/pane windows on session delete
fix: only show agent/teammate windows when matching Claudeman tab exists
fix: UTF-8 encoding in teammate pane terminal output (Uint8Array)
fix: standalone pane window cleanup via subagentParentMap lookup
fix: xterm.js dimensions crash with deferred init + null-safe dispose
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- WebServer: Store session listener refs for explicit cleanup on delete
- RespawnController: Fix clearInterval bug (was using clearTimeout)
- RespawnController: Add try/catch to interval callbacks
- PlanOrchestrator: Guarantee progressInterval cleanup with try/finally
- SubagentWatcher: Guard idle timer against deleted agents
- Session: Add threshold validation for auto-clear/compact (1k-500k)
- Session: Add token sum overflow check in restoreTokens
- Session: Use LRUMap for _recentTaskDescriptions auto-eviction
Commit from flight QR118 in an Airbus A350-1000, stable connection thanks to Starlink!
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend fixes:
- Session: clear _recentTaskDescriptions Map in stop() and clearBuffers()
- Session: null promise callbacks after rejection in runPrompt() catch block
- Server: store subagent/image watcher listener refs and remove on shutdown
Frontend fixes:
- Plan file windows: store drag/resize handlers and clean up on close
- Plan file manager: store drag handler and clean up on close
- cleanupAllFloatingWindows: now cleans up plan file windows
These prevent unbounded memory growth in long-running sessions.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --session-id flag to Claude CLI startup so Claudeman and Claude share the same session ID
- Set claudeSessionId immediately on session start (no waiting for JSON messages)
- Add persistent subagentParentMap to store agent-to-tab associations permanently
- Add /api/subagent-parents endpoints for server-side persistence
- Add fallback: use active session when claudeSessionId matching fails
- Connection lines now reliably connect agent windows to their parent tabs
- Survives page refresh, reconnect, and server restart
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create src/utils/regex-patterns.ts with ANSI_ESCAPE_PATTERN_FULL,
ANSI_ESCAPE_PATTERN_SIMPLE, TOKEN_PATTERN, and helper functions
- Create src/utils/token-validation.ts with MAX_SESSION_TOKENS and
validation utilities
- Update session.ts, respawn-controller.ts, ai-checker-base.ts,
ralph-tracker.ts, state-store.ts to use shared utilities
- Export all new utilities from src/utils/index.ts
Reduces code duplication while maintaining pre-compiled patterns
for performance.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add _awaitingIdleConfirmation flag to prevent status bar redraws from
resetting the 2-second idle detection timeout
- Strip ANSI/OSC escape sequences before checking working patterns to
avoid false positives from window titles like '3 File Reading Task'
- Reset _awaitingIdleConfirmation on PTY exit for proper cleanup
chore: bump version to 0.1412
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace local BufferAccumulator in session.ts with shared utility
- Replace local BufferAccumulator in respawn-controller.ts with shared utility
- Import buffer constants from config/buffer-limits.ts
- Reduces code duplication and centralizes buffer management
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- SSE event listener cleanup: Track all listeners and remove on reconnect
to prevent listener accumulation (60+ listeners per connect cycle)
- Floating window cleanup: Remove drag listeners, ResizeObservers on close
- Session creation mutex: Prevent race conditions from concurrent requests
- Screen kill verification: Confirm processes are dead after kill signals
- State store circuit breaker: Prevent cascading failures with backup/recovery
- PTY spawn error handling: Wrap all spawn calls with proper error emission
- SSE graceful shutdown: Notify clients before server stops
- Async file writes: Replace blocking writeFileSync in hot paths
- DocumentFragment optimization: Batch DOM updates for plan rendering
- Timer cleanup: Clear notification/countdown timers on SSE reconnect
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix screen creation failing when using cpulimit/nice (env vars were passed
as command args instead of shell variables)
- Fix session status never becoming 'idle' after startInteractive()
- Add automatic state file cleanup on startup (removes orphaned sessions)
- Add /api/cleanup-state endpoint for manual cleanup
- Make frontend session readiness check more robust (20 attempts, multiple checks)
- Add fallback to direct PTY write if writeViaScreen fails
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CPU Limiting:
- Add CpuLimitConfig type and settings in App Settings
- Use nice command for process priority (-20 to 19)
- Optional cpulimit integration for hard CPU limits (if installed)
- Applied to new sessions via screen-manager and session modules
Ralph Loop Wizard:
- 3-step wizard: Describe → Plan → Launch
- New /api/generate-plan endpoint generates implementation steps via Claude
- Plan editor with checkboxes, priorities (P0/P1/P2), reordering
- Skip plan option for manual workflows
- Compact wizard modal layout
UI Updates:
- Form section headers for grouped settings
- CPU limit status indicator (cpulimit availability)
- Wizard modal wider layout and inline fields
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 Ralph enhancement implementation:
- Parse RALPH_STATUS blocks from Claude output (status, tasks, files, tests)
- Circuit breaker state machine (CLOSED → HALF_OPEN → OPEN) for stuck detection
- Dual-condition exit gate (completion indicators >= 2 AND EXIT_SIGNAL)
- Frontend: circuit breaker badge (yellow warning, red stuck), status block display
- API: circuit breaker reset endpoint, ralph status endpoint
- Notifications when circuit breaker opens or exit gate is met
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Session creation now parallelized (3x faster for multiple tabs)
- Minimized agents badge: compact, hover-triggered, auto-hide
- Removed "Minimized Agents" header, status dots instead of text
- Click to pin dropdown open, hover for quick access
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add max 500k tokens per session limit (Claude's context is ~200k)
- Add max 100k tokens per update to prevent sudden jumps from parsing errors
- Reject "M" suffix values > 0.5M to prevent false matches in output text
- Add validation to restoreTokens() to reject corrupted values from state.json
- Add validation to addToGlobalStats() for negative and absurd values
- Fix daily sessions count: track unique session IDs instead of incrementing
on every 5-minute recording interval
- Pass sessionId to recordDailyUsage() for accurate session counting
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add parseTaskDescriptionsFromTerminalData() to parse raw terminal data in
interactive sessions (not just one-shot mode)
- Strip ANSI codes before regex matching since terminal output has embedded
codes like [1mExplore[0m
- Fix getTaskDescriptionForSubagent() to check ALL sessions with matching
project hash (not just the first one found) since multiple sessions can
share the same working directory
- Add tool_result event forwarding for subagent SSE broadcasts
The pattern Explore(Description) in terminal output is now correctly parsed
and used as the subagent window title instead of extracting from the prompt.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Subagents (Task tool background agents) are autonomous and cannot
receive input mid-execution. They complete and return results to
the parent session. Removed the input UI and API endpoint.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 300-char rolling window to catch working patterns split across PTY chunks
- Check completion message BEFORE working patterns (priority fix)
- Clear rolling window on completion message (transition point)
- Increase working pattern absence threshold from 3s to 8s
- Add Session.isWorking safety check before confirming idle
- Add 20+ more working patterns (Compiling, Building, Processing, etc.)
- Make AI idle checker prompt more conservative (err toward WORKING)
- Update documentation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Stack timers row vertically (timers on top, action log below)
- Reduce action log height to 60px since it's now full width
- Filter action log to show only important entries:
- Commands sent to console
- Plan-check with action taken
- Step completions
- Skip timer starts/cancels, detection updates, ai-check status
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>