mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-04 14:39:42 +02:00
* refactor: extract SSE event handlers into named class methods Replace ~80 inline addListener closures in connectSSE() with a declarative _SSE_HANDLER_MAP array that drives registration in a single loop. Each handler is now a named _on* method on CodemanApp, making them individually addressable for LLM navigation. Add SSE_EVENTS constant object in constants.js to eliminate magic event-type strings scattered across the frontend. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: fix inaccuracies in CLAUDE.md - Fix types barrel path: src/types.ts → src/types/index.ts - Update app.js line count: ~12K → ~11.5K - Correct route handler counts (113 → 111, per-group fixes) - Add code style, ESM gotcha, env vars, route test, lifecycle log docs - Add Node 22 CI note, test teardown timeout, port range Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add mobile screenshots and QR auth security writeup to README Add 3 mobile screenshots (landing, idle, active) and expand the mobile section with QR auth security design details and a touch-optimized interface subsection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: bundle xterm-zerolag-input as vendor IIFE and add pre-commit hook Build and postinstall now bundle the local xterm-zerolag-input package as an IIFE at vendor/xterm-zerolag-input.js with global LocalEchoOverlay shim. Add git pre-commit hook that runs prettier --check on staged .ts files to catch format issues before CI. Also bump constants.js and app.js cache-bust versions to 0.3.0 and add tunnel upload URL display row in settings. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add cloudflared install support and interactive launch menu - Add optional cloudflared dependency detection and installation across 6 distro families (macOS, Debian, Fedora, Arch, Alpine, SUSE) - Add tunnel systemd service setup helper - Replace post-install instructions with interactive launch menu (run now / systemd service / skip) - Uninstall now cleans up both codeman-web and codeman-tunnel services Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: gitignore readme-preview.mjs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: WIP — SSE event constants, @fileoverview docs, CLAUDE.md compression - Migrate broadcast() string literals → SseEvent.* typed constants - Add @fileoverview with cross-domain references to all 13 type domain files - Add @fileoverview to frontend JS modules (constants, mobile, voice, etc.) - Add section dividers to route files for LLM scanability - Compress CLAUDE.md: flat file list → domain table, fix counts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: optimize codebase for LLM context window efficiency CLAUDE.md: 456 → 309 lines (32% reduction) - Merge Commands into compact table, remove redundant bash block - Convert Security section to dense table format - Merge Performance + Resource Limits, Debugging + Troubleshooting - Compress Tunnel, Memory Leak, Scripts, Screenshots sections - Remove Key Patterns that duplicate @fileoverview in source files Backend @fileoverview enhancements (10 priority files): - session.ts: key methods, events, cross-domain refs - respawn-controller.ts: state machine, idle detection layers - ralph-tracker.ts: exports, circuit breaker, events - ralph-loop.ts: lifecycle, persistence, events - subagent-watcher.ts: watched patterns, teammate detection - server.ts: coordination list, port interfaces - state-store.ts: dual-file persistence, migration - session-manager.ts: lifecycle methods, mutex guard - hooks-config.ts: hook events list, categories - sse-events.ts: category breakdown (~90 events, 17 categories) Frontend app.js: add 6 section dividers, update @fileoverview line refs Fix: escape glob `*/` in JSDoc that broke ESLint parser Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: address PR #29 review bugs - server.ts: replace hardcoded 'session:needsRefresh' with SseEvent constant - install.sh: fix Alpine cloudflared install for non-root (download to tmpfile first) - install.sh: replace Arch pacman (AUR-only) with direct binary download - index.html: bump all 8 remaining cache-bust versions from v0.2.9 to v0.3.0 - mobile-handlers.js: fix @dependency annotation (keyboard-accessory.js, not constants.js) - types/push.ts: fix layer number (4, not 5) - subagent-watcher.ts: fix watched pattern path to include {session} segment - constants.js: fix SSE_EVENTS count in @fileoverview (~73, not ~65) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
300 lines
10 KiB
TypeScript
300 lines
10 KiB
TypeScript
/**
|
|
* @fileoverview Respawn controller type definitions.
|
|
*
|
|
* Covers the autonomous session cycling system: configuration, presets,
|
|
* per-cycle metrics, aggregate health scoring, and adaptive timing.
|
|
*
|
|
* Key exports:
|
|
* - RespawnConfig — full respawn settings (idle timeout, AI checks, adaptive timing, skip-clear)
|
|
* - PersistedRespawnConfig — subset saved to disk for mux session recovery
|
|
* - RespawnPreset — named preset for quick setup (solo-work, team-lead, overnight-autonomous, etc.)
|
|
* - RespawnCycleMetrics — per-cycle outcome tracking (duration, idle reason, steps, tokens)
|
|
* - RespawnAggregateMetrics — aggregate stats across cycles (success rate, p90 duration)
|
|
* - RalphLoopHealthScore — composite 0-100 health score with 5 component scores
|
|
* - HealthStatus — 'excellent' | 'good' | 'degraded' | 'critical'
|
|
* - TimingHistory — rolling window of timing data for adaptive adjustments
|
|
* - CycleOutcome — 'success' | 'stuck_recovery' | 'blocked' | 'error' | 'cancelled'
|
|
*
|
|
* Cross-domain relationships:
|
|
* - RespawnConfig is embedded in AppConfig.respawn (app-state) and SessionState.respawnConfig (session)
|
|
* - RalphLoopHealthScore.components.circuitBreaker derives from CircuitBreakerStatus (ralph domain)
|
|
* - RespawnCycleMetrics.sessionId links to SessionState.id (session domain)
|
|
*
|
|
* Served at `GET /api/sessions/:id/respawn` (config + state).
|
|
*/
|
|
|
|
/**
|
|
* Configuration for the Respawn Controller
|
|
*
|
|
* The respawn controller keeps interactive sessions productive by
|
|
* automatically cycling through update prompts when Claude goes idle.
|
|
*/
|
|
export interface RespawnConfig {
|
|
/** How long to wait after seeing prompt before considering truly idle (ms) */
|
|
idleTimeoutMs: number;
|
|
/** The prompt to send for updating docs */
|
|
updatePrompt: string;
|
|
/** Delay between sending steps (ms) */
|
|
interStepDelayMs: number;
|
|
/** Whether to enable respawn loop */
|
|
enabled: boolean;
|
|
/** Whether to send /clear after update prompt */
|
|
sendClear: boolean;
|
|
/** Whether to send /init after /clear */
|
|
sendInit: boolean;
|
|
/** Optional prompt to send if /init doesn't trigger work */
|
|
kickstartPrompt?: string;
|
|
/** Time to wait after completion message before confirming idle (ms) */
|
|
completionConfirmMs?: number;
|
|
/** Fallback timeout when no output received at all (ms) */
|
|
noOutputTimeoutMs?: number;
|
|
/** Whether to auto-accept plan mode prompts by pressing Enter (not questions) */
|
|
autoAcceptPrompts?: boolean;
|
|
/** Delay before auto-accepting plan mode prompts when no output and no completion message (ms) */
|
|
autoAcceptDelayMs?: number;
|
|
/** Whether AI idle check is enabled */
|
|
aiIdleCheckEnabled?: boolean;
|
|
/** Model to use for AI idle check */
|
|
aiIdleCheckModel?: string;
|
|
/** Maximum characters of terminal buffer for AI check */
|
|
aiIdleCheckMaxContext?: number;
|
|
/** Timeout for AI check in ms */
|
|
aiIdleCheckTimeoutMs?: number;
|
|
/** Cooldown after WORKING verdict in ms */
|
|
aiIdleCheckCooldownMs?: number;
|
|
/** Whether AI plan mode check is enabled for auto-accept */
|
|
aiPlanCheckEnabled?: boolean;
|
|
/** Model to use for AI plan mode check */
|
|
aiPlanCheckModel?: string;
|
|
/** Maximum characters of terminal buffer for plan check */
|
|
aiPlanCheckMaxContext?: number;
|
|
/** Timeout for AI plan check in ms */
|
|
aiPlanCheckTimeoutMs?: number;
|
|
/** Cooldown after NOT_PLAN_MODE verdict in ms */
|
|
aiPlanCheckCooldownMs?: number;
|
|
|
|
// ========== P2-001: Adaptive Timing ==========
|
|
|
|
/** Whether to use adaptive timing based on historical patterns */
|
|
adaptiveTimingEnabled?: boolean;
|
|
/** Minimum value for adaptive completion confirm (ms) */
|
|
adaptiveMinConfirmMs?: number;
|
|
/** Maximum value for adaptive completion confirm (ms) */
|
|
adaptiveMaxConfirmMs?: number;
|
|
|
|
// ========== P2-002: Skip-Clear Optimization ==========
|
|
|
|
/** Whether to skip /clear when context is below threshold */
|
|
skipClearWhenLowContext?: boolean;
|
|
/** Token percentage threshold below which /clear is skipped (0-100) */
|
|
skipClearThresholdPercent?: number;
|
|
|
|
// ========== P2-004: Cycle Metrics ==========
|
|
|
|
/** Whether to track and persist cycle metrics */
|
|
trackCycleMetrics?: boolean;
|
|
}
|
|
|
|
// ========== P2-004: Respawn Cycle Metrics ==========
|
|
|
|
/**
|
|
* Outcome of a respawn cycle
|
|
*/
|
|
export type CycleOutcome =
|
|
| 'success' // Cycle completed normally
|
|
| 'stuck_recovery' // Stuck-state recovery triggered
|
|
| 'blocked' // Blocked by circuit breaker or exit signal
|
|
| 'error' // Error during cycle
|
|
| 'cancelled'; // Cancelled (e.g., controller stopped)
|
|
|
|
/**
|
|
* Metrics for a single respawn cycle.
|
|
* Persisted for post-mortem analysis of long-running loops.
|
|
*/
|
|
export interface RespawnCycleMetrics {
|
|
/** Unique cycle ID (session-id:cycle-number) */
|
|
cycleId: string;
|
|
/** Session ID this cycle belongs to */
|
|
sessionId: string;
|
|
/** Cycle number within the session */
|
|
cycleNumber: number;
|
|
/** Timestamp when cycle started */
|
|
startedAt: number;
|
|
/** Timestamp when cycle completed */
|
|
completedAt: number;
|
|
/** Total duration of cycle (ms) */
|
|
durationMs: number;
|
|
/** What triggered idle detection */
|
|
idleReason: string;
|
|
/** Time spent detecting idle (from start of watching to idle confirmed) */
|
|
idleDetectionMs: number;
|
|
/** Steps completed in this cycle */
|
|
stepsCompleted: string[];
|
|
/** Whether /clear was skipped (P2-002) */
|
|
clearSkipped: boolean;
|
|
/** Outcome of the cycle */
|
|
outcome: CycleOutcome;
|
|
/** Error message if outcome is 'error' */
|
|
errorMessage?: string;
|
|
/** Token count at start of cycle */
|
|
tokenCountAtStart?: number;
|
|
/** Token count at end of cycle */
|
|
tokenCountAtEnd?: number;
|
|
/** Completion confirm time used (may be adaptive) */
|
|
completionConfirmMsUsed: number;
|
|
}
|
|
|
|
/**
|
|
* Aggregate metrics across multiple cycles for health scoring.
|
|
*/
|
|
export interface RespawnAggregateMetrics {
|
|
/** Total cycles tracked */
|
|
totalCycles: number;
|
|
/** Successful cycles */
|
|
successfulCycles: number;
|
|
/** Cycles that required stuck-state recovery */
|
|
stuckRecoveryCycles: number;
|
|
/** Blocked cycles */
|
|
blockedCycles: number;
|
|
/** Error cycles */
|
|
errorCycles: number;
|
|
/** Average cycle duration (ms) */
|
|
avgCycleDurationMs: number;
|
|
/** Average idle detection time (ms) */
|
|
avgIdleDetectionMs: number;
|
|
/** 90th percentile cycle duration (ms) */
|
|
p90CycleDurationMs: number;
|
|
/** Success rate (0-100) */
|
|
successRate: number;
|
|
/** Last updated timestamp */
|
|
lastUpdatedAt: number;
|
|
}
|
|
|
|
// ========== P2-005: Ralph Loop Health Score ==========
|
|
|
|
/**
|
|
* Health status levels for the Ralph Loop system.
|
|
*/
|
|
export type HealthStatus = 'excellent' | 'good' | 'degraded' | 'critical';
|
|
|
|
/**
|
|
* Comprehensive health score for a Ralph Loop session.
|
|
* Aggregates multiple health signals into a single score.
|
|
*/
|
|
export interface RalphLoopHealthScore {
|
|
/** Overall health score (0-100) */
|
|
score: number;
|
|
/** Health status based on score thresholds */
|
|
status: HealthStatus;
|
|
/** Individual component scores (0-100 each) */
|
|
components: {
|
|
/** Based on recent cycle success rate */
|
|
cycleSuccess: number;
|
|
/** Based on circuit breaker state */
|
|
circuitBreaker: number;
|
|
/** Based on iteration stall metrics */
|
|
iterationProgress: number;
|
|
/** Based on AI checker error rate */
|
|
aiChecker: number;
|
|
/** Based on stuck-state recovery count */
|
|
stuckRecovery: number;
|
|
};
|
|
/** Human-readable summary of health */
|
|
summary: string;
|
|
/** Recommendations for improvement */
|
|
recommendations: string[];
|
|
/** Timestamp when score was calculated */
|
|
calculatedAt: number;
|
|
}
|
|
|
|
// ========== Timing History for Adaptive Timing ==========
|
|
|
|
/**
|
|
* Historical timing data for adaptive adjustments.
|
|
*/
|
|
export interface TimingHistory {
|
|
/** Rolling window of recent idle detection durations (ms) */
|
|
recentIdleDetectionMs: number[];
|
|
/** Rolling window of recent cycle durations (ms) */
|
|
recentCycleDurationMs: number[];
|
|
/** Calculated adaptive completion confirm value (ms) */
|
|
adaptiveCompletionConfirmMs: number;
|
|
/** Number of samples in rolling windows */
|
|
sampleCount: number;
|
|
/** Maximum samples to keep */
|
|
maxSamples: number;
|
|
/** Last updated timestamp */
|
|
lastUpdatedAt: number;
|
|
}
|
|
|
|
/**
|
|
* Named respawn configuration preset for quick setup
|
|
*/
|
|
export interface RespawnPreset {
|
|
/** Unique preset identifier */
|
|
id: string;
|
|
/** User-friendly preset name */
|
|
name: string;
|
|
/** Description of when to use this preset */
|
|
description?: string;
|
|
/** The respawn configuration (without enabled flag) */
|
|
config: Omit<RespawnConfig, 'enabled'>;
|
|
/** Duration in minutes (optional default) */
|
|
durationMinutes?: number;
|
|
/** Whether this is a built-in preset */
|
|
builtIn?: boolean;
|
|
/** Timestamp when created */
|
|
createdAt: number;
|
|
}
|
|
|
|
/**
|
|
* Persisted respawn configuration for mux sessions.
|
|
* Subset of RespawnConfig that gets saved to disk.
|
|
*/
|
|
export interface PersistedRespawnConfig {
|
|
/** Whether respawn was enabled */
|
|
enabled: boolean;
|
|
/** How long to wait after seeing prompt before considering truly idle (ms) */
|
|
idleTimeoutMs: number;
|
|
/** The prompt to send for updating docs */
|
|
updatePrompt: string;
|
|
/** Delay between sending steps (ms) */
|
|
interStepDelayMs: number;
|
|
/** Whether to send /clear after update prompt */
|
|
sendClear: boolean;
|
|
/** Whether to send /init after /clear */
|
|
sendInit: boolean;
|
|
/** Optional prompt to send if /init doesn't trigger work */
|
|
kickstartPrompt?: string;
|
|
/** Whether to auto-accept plan mode prompts by pressing Enter (not questions) */
|
|
autoAcceptPrompts?: boolean;
|
|
/** Delay before auto-accepting prompts (ms) */
|
|
autoAcceptDelayMs?: number;
|
|
/** Time to wait after completion message before confirming idle (ms) */
|
|
completionConfirmMs?: number;
|
|
/** Fallback timeout when no output received at all (ms) */
|
|
noOutputTimeoutMs?: number;
|
|
/** Whether AI idle check is enabled */
|
|
aiIdleCheckEnabled?: boolean;
|
|
/** Model to use for AI idle check */
|
|
aiIdleCheckModel?: string;
|
|
/** Maximum characters of terminal buffer for AI check */
|
|
aiIdleCheckMaxContext?: number;
|
|
/** Timeout for AI check in ms */
|
|
aiIdleCheckTimeoutMs?: number;
|
|
/** Cooldown after WORKING verdict in ms */
|
|
aiIdleCheckCooldownMs?: number;
|
|
/** Whether AI plan mode check is enabled for auto-accept */
|
|
aiPlanCheckEnabled?: boolean;
|
|
/** Model to use for AI plan mode check */
|
|
aiPlanCheckModel?: string;
|
|
/** Maximum characters of terminal buffer for plan check */
|
|
aiPlanCheckMaxContext?: number;
|
|
/** Timeout for AI plan check in ms */
|
|
aiPlanCheckTimeoutMs?: number;
|
|
/** Cooldown after NOT_PLAN_MODE verdict in ms */
|
|
aiPlanCheckCooldownMs?: number;
|
|
/** Duration in minutes if timed respawn was set */
|
|
durationMinutes?: number;
|
|
}
|