Smart Respawn Integration (2.5):
- Check circuit breaker OPEN state before respawn (blocks cycle)
- Check RALPH_STATUS EXIT_SIGNAL=true to stop respawn
- Check STATUS=BLOCKED to pause respawn for human intervention
- Use RECOMMENDATION from RALPH_STATUS in update prompt
- Emit respawn:blocked SSE event with reason and details
- Show notification when respawn is blocked
- Visual blocked state with pulsing red indicator
Priority-based Todos (part of 2.3):
- Add RalphTodoPriority type (P0/P1/P2/null)
- Parse priority from todo content (P0:, Critical:, High Priority, etc.)
- Add priority field to RalphTodoItem interface
- Update frontend to display priority badges with colors
- Sort todos by priority (P0 > P1 > P2) then by status
- Add CSS for priority badges and highlighted cards
Bump version to 0.1391
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>
- Add getLightState() and getLightSessionsState() methods
- SSE init payload reduced from ~1.9MB to ~5KB (~400x smaller)
- Terminal buffers are fetched on-demand when switching tabs
- Fixes UI becoming unresponsive on SSE reconnect
chore: bump version to 0.1388
- 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>
Session Manager:
- Store event handlers for proper cleanup on session stop
- Add resetSessionManager() for test isolation
State Store:
- Use atomic write pattern (temp file + rename) to prevent corruption
- Add tokenStats to AppState interface
Subagent Watcher:
- Clean up pendingToolCalls on agent completion
- Add cleanupStaleAgents() for 24h+ old agents
- Clear all state maps on stop() for clean restart
Web Server:
- Remove listeners from transcript watcher before stopping
- Clean up respawn timers when session is deleted
- Use cleanupSession() in spawn orchestrator for proper resource cleanup
Frontend:
- Close existing EventSource before reconnecting to prevent duplicates
- Close failed connection before scheduling reconnect
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>
Instead of timing-based correlation between terminal output and subagent
files, now reads the Task tool's description parameter directly from the
parent session's transcript. This provides 100% reliable mapping between
agent IDs and their short descriptions, fixing issues where multiple
agents spawned in quick succession would get the same window title.
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>
- Extract short description from TaskTracker (params.description) for subagent windows
- Correlate subagents with sessions by working directory and timing
- Auto-minimize subagent windows when agents complete
- Persist minimized/open window states to server for cross-browser sync
- Restore window states on reconnection/page reload
- New API: GET/PUT /api/subagent-window-states
- State file: ~/.claudeman/subagent-window-states.json
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>
When sessions were restored after server restart, lastRecordedTokens
was not initialized, causing the periodic token recording to treat
the entire restored token count as new usage. This inflated daily
stats by re-counting tokens on every server restart.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Prevents false idle detection when server is rebuilt/restarted.
Previously, restored respawn controllers would start immediately
and trigger after 30s of "no output" because the session wasn't
fully connected yet.
Now waits 2 minutes from server startup before activating restored
respawn controllers, giving sessions time to reconnect and stabilize.
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>
The run summary tracker wasn't tracking respawn events for restored
sessions because the tracker didn't exist when setupRespawnListeners
was called during session restoration. Changed to lazy lookup so
the tracker is retrieved each time an event fires.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a "what happened while you were away" view for sessions:
- Track significant events: session start/stop, respawn cycles, state changes,
idle/working transitions, token milestones, auto-compact/clear, Ralph
completions, AI check results, hook events, errors/warnings
- Stats dashboard: respawn cycles, peak tokens, active/idle time, issue counts
- Timeline view with color-coded severity and emoji icons
- Filter events by type (all/errors/warnings/respawn/idle)
- State stuck detection (warns when state unchanged for 10+ minutes)
Click the chart icon on any session tab to open the Run Summary modal.
Files:
- src/run-summary.ts: RunSummaryTracker class with event tracking
- src/types.ts: RunSummary, RunSummaryEvent types
- src/web/server.ts: Integration with session/respawn events, API endpoint
- src/web/public/: Modal UI, timeline rendering, filter controls
- docs/run-summary-plan.md: Implementation plan
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement multi-phase improvement to respawn controller's idle detection:
Phase 1 - Stop Hook Detection:
- Add signalStopHook() method - definitive signal when Claude finishes
- 3s confirmation timer to handle race conditions
- Skip AI check when hook received (100% confidence)
Phase 2 - idle_prompt Detection:
- Add signalIdlePrompt() method - fires after 60s+ of idle
- Immediately confirms idle (no confirmation timer needed)
Phase 3 - Transcript File Monitoring:
- New TranscriptWatcher class watches session JSONL files
- Detects: completion, tool execution, plan mode, errors
- Signals respawn controller for supporting detection
Web UI Updates:
- Hook indicator with purple styling and pulse animation
- Shows "Stop hook received" or "idle_prompt hook received"
- 100% confidence displayed with hook-confirmed style
This significantly improves idle detection reliability by using
definitive signals from Claude Code rather than parsing terminal output.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add TokenUsageEntry and TokenStats types for daily tracking
- Add state-store methods for recording and retrieving daily usage
- Add /api/token-stats endpoint with daily breakdown and totals
- Add token stats modal with summary cards, 7-day bar chart, and table
- Record tokens periodically (5min) and on session delete
- Make header tokens clickable to open stats modal
- Fix subagents panel toggle icon direction (down when open)
- Increase subagents panel height when expanded
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 100ms debounce for new file detection to allow content to be written
- Add subagent:updated event for retroactive description updates
- Extract description in processEntry when first user message is processed
- Add extractDescriptionFromFile helper with retry in file change handler
- Update SubagentTranscriptEntry.content type to support string | array
- Add test coverage for subagent:updated event
Fixes 43% failure rate where subagents displayed raw IDs instead of descriptions
due to race condition when files were discovered before first line was written.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move COM shorthand to prominent position after safety warning
- Add version sync note (must match package.json)
- Consolidate Key Files into 4 logical categories
- Clarify next available test port (3128)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extract better titles from task description (first line/sentence)
- Make subagent window text white for better readability
- Expand monitor panel to 700px when subagents tab is active
- Add smooth width transition when switching tabs
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SubagentWatcher service that discovers and tails Claude Code's subagent
transcript files (~/.claude/projects/.../subagents/agent-*.jsonl)
- Track tool calls, progress events, and messages in real-time via file watching
- Add SSE events for subagent:discovered, subagent:tool_call, subagent:progress,
subagent:message, subagent:completed
- Add REST API endpoints: GET /api/subagents, /api/subagents/:id,
/api/subagents/:id/transcript
- Add subagent panel in Monitor section showing active agents and their activity
- Add floating draggable windows that auto-open for each active agent
- Add standalone CLI tool: scripts/watch-subagents.ts for terminal monitoring
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AiCheckerBase abstract class to eliminate ~700 lines of duplication
between AiIdleChecker and AiPlanChecker
- Fix missing persistence fields (completionConfirmMs, noOutputTimeoutMs)
that caused custom timing values to be lost on server restart
- Extract restoreRespawnController() helper to dedupe session restoration
logic between state.json and screens.json paths
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When /respawn/stop was called, the controller was stopped but remained
in the respawnControllers map. This caused persistSessionState() to
still read config.enabled=true and save respawnEnabled=true to state.json.
On server restart, the respawn controller would be re-enabled because
state.json had respawnEnabled=true.
Fix: Remove controller from map and clear any timed respawn when
/respawn/stop is called, so persistSessionState() correctly sets
respawnEnabled=false.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- persistSessionState() now saves respawnEnabled based on config.enabled
(user intent) instead of controller.state (running state)
- cleanupSession() saves respawn config BEFORE removing controller
- AiIdleChecker and AiPlanChecker constructors filter undefined values
to prevent overwriting defaults (fixes "timed out after undefinedms")
- updateConfig() methods also filter undefined values
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add restoreTokens() method to Session class for recovery after restart
- Add GlobalStats type for cumulative usage tracking across all sessions
- Accumulate tokens from deleted sessions into global stats
- Track lifetime session count with incrementSessionsCreated()
- Add /api/stats endpoint for global stats
- Include globalStats in /api/status response
- Frontend shows aggregate tokens + cost in header
- Fix respawn controller config to filter undefined values
- Add 7 new tests for global stats functionality (v0.1343)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Display version number in center of bottom toolbar
- Load version from package.json via server's /api/status
- Version shown on initial load and SSE reconnect
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix "enable twice" bug: add enabled:true to getModalRespawnConfig()
- Add timer tracking with countdown display in respawn banner
- New events: timerStarted, timerCancelled, timerCompleted, actionLog
- Show active timers with progress bars and recent action log
- Skip remaining timeouts after AI check returns IDLE/WORKING verdict
- Enhanced DetectionStatus with activeTimers, recentActions, currentPhase
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds a two-stage gate before auto-accepting plan mode prompts:
1. Strict regex pre-filter - checks for numbered options + selector
2. AI confirmation - spawns Opus to classify as PLAN_MODE or NOT_PLAN_MODE
This prevents spurious Enter key presses when Claude is paused mid-thought
or experiencing network lag, rather than showing a plan approval prompt.
New files:
- src/ai-plan-checker.ts: AI checker following ai-idle-checker.ts pattern
Config fields added to RespawnConfig:
- aiPlanCheckEnabled (default: true)
- aiPlanCheckModel (default: claude-opus-4-5-20251101)
- aiPlanCheckMaxContext (default: 8000)
- aiPlanCheckTimeoutMs (default: 60000)
- aiPlanCheckCooldownMs (default: 30000)
New events: planCheckStarted, planCheckCompleted, planCheckFailed
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace the "Worked for Xm Xs" pattern as the sole primary idle
detection signal with a final AI-powered check. When pre-filter
conditions are met (output silence, no working patterns, tokens
stable), a fresh Claude CLI session is spawned in a screen to
analyze terminal output and provide a definitive IDLE/WORKING
verdict before proceeding with the respawn cycle.
New state in state machine: `ai_checking` (between pre-filter
confirmation and `sending_update`). WORKING verdict triggers a
3-minute cooldown. Errors auto-disable after 3 consecutive
failures, falling back to the existing noOutputTimeoutMs safety net.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The server was dropping the `data` field from hook-event POST requests,
so notifications always showed generic messages. Now forwards tool name,
command, question text, and reason to the frontend.
Notifications now show:
- permission_prompt: "Bash: docker push prod:latest"
- elicitation_dialog: "Merge PR #42 to main?"
- idle_prompt: custom message if provided
- stop: reason if provided
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The auto-accept feature was too aggressive - it would press Enter for any
silence without a completion message, including AskUserQuestion prompts.
Now uses the elicitation_dialog notification hook to detect when Claude is
asking a question, and blocks auto-accept in that case. Only plan mode
approvals (silence with no completion message AND no elicitation signal)
trigger auto-accept.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wire Claude Code's official hooks system (Notification, Stop) to POST
back to Claudeman's new /api/hook-event endpoint, which broadcasts SSE
events consumed by the existing NotificationManager for desktop alerts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Notification prefs are now included in the PUT /api/settings payload
and stored in ~/.claudeman/settings.json. On page load, server-stored
prefs are loaded as fallback when localStorage is empty (e.g. new
browser or cleared cache).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enables the Web Notifications API when accessing via SSH tunnel or
non-localhost URLs. Self-signed cert is auto-generated with openssl
and stored in ~/.claudeman/certs/ for reuse across restarts.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Instead of parsing terminal output for <spawn1337> tags, spawn capabilities
are now exposed as native MCP tools that Claude Code can call directly.
The MCP server (stdio transport) proxies requests to the existing REST API.
- Add src/mcp-server.ts with 6 tools: spawn_agent, list_agents,
get_agent_status, get_agent_result, send_agent_message, cancel_agent
- Remove src/spawn-detector.ts and all references in session.ts/server.ts
- Add CLAUDEMAN_API_URL env var propagation to sessions and screens
- Write .mcp.json to case directories during creation
- Remove spawn1337 tag documentation from case-template.md
- Add claudeman-mcp bin entry to package.json
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Ralph tracker no longer auto-enables on pattern detection. It must be
explicitly enabled per-session (via API) or globally via the new
`ralphEnabled` AppConfig setting. Adds GET/PUT /api/config endpoints
for runtime configuration. Spawn agent ralph enable is unchanged.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When Claude enters plan mode or asks a question (AskUserQuestion), output
stops without a completion message. The new autoAcceptPrompts feature
detects this state and sends Enter after a configurable delay (default 8s)
to accept the plan or select the default option, keeping Claude working
autonomously.
Enabled by default. Adds UI checkbox in the respawn config panel.
Safety: only fires once per silence period, requires prior output,
and won't fire during active respawn cycles.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaces the ~400-line inline template string in claude-md.ts with a
file read from src/templates/case-template.md. Removes the hardcoded
/home/arkon/default/CLAUDE.md path from server.ts. The build script
now copies the template to dist/templates/ for production use.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
state.json is now the primary source for session recovery, but
screens.json is used as a fallback for respawn config since it was
the proven working path before. This provides double-redundancy:
both files would need to be lost for respawn state to disappear.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
cleanupSession() always called store.removeSession() which deleted the
session from state.json. On server stop, cleanupSession(id, false) was
called for all sessions - preserving screens but deleting their saved
state. On next restart, state.json was empty so nothing was restored.
Now only removes from state.json when killScreen=true (user explicitly
deleting a session), preserving state for recovery on restart.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All session settings (auto-compact, auto-clear, ralph, respawn) are now
restored from state.json on server restart. Previously settings were
split across state.json, screens.json, and state-inner.json which was
fragile. state-inner.json is kept as a fallback for ralph state only.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
persistSessionState was called before the respawn controller was restored,
so respawnEnabled was always saved as false during recovery. Moved the
persist call to after all restorations (auto-compact, auto-clear, ralph,
respawn) are applied.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Session recovery from screens created fresh Session objects with default
values, losing the auto-compact and auto-clear settings that were saved
to state.json. Now reads them back during recovery.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The respawn controller's enabled/disabled state was not being saved,
so CLI status couldn't show whether respawn was active.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add GET /api/sessions/:id/respawn/config endpoint for reading saved config
- PUT /api/sessions/:id/respawn/config now works without running controller
(saves pre-config to screens.json for when respawn starts)
- Respawn start/enable merges pre-saved config from screens.json
- Frontend auto-saves respawn config, auto-compact, auto-clear on field change
- Frontend loads saved config when opening session options modal
- Updated CLAUDE.md with state persistence docs, new API endpoint,
SessionState fields table, state lifecycle, and session setting guide
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The web server now persists all per-session settings (name, mode,
auto-compact, auto-clear, respawn config, ralph state, tokens, cost)
to state.json so the CLI status/session commands can display them.
Also removes unused pendingStepConfirm property from respawn controller.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>