feat: add Run Summary feature for session activity tracking

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>
This commit is contained in:
arkon
2026-01-25 22:05:28 +01:00
co-authored by Claude Opus 4.5
parent 8b0577d8aa
commit b811c8dc80
9 changed files with 1210 additions and 7 deletions
+115
View File
@@ -859,6 +859,121 @@ export function getErrorMessage(error: unknown): string {
return 'An unknown error occurred';
}
// ========== Run Summary Types ==========
/**
* Types of events tracked in the run summary.
* These provide a historical view of what happened during a session.
*/
export type RunSummaryEventType =
| 'session_started'
| 'session_stopped'
| 'respawn_cycle_started'
| 'respawn_cycle_completed'
| 'respawn_state_change'
| 'error'
| 'warning'
| 'token_milestone'
| 'auto_compact'
| 'auto_clear'
| 'idle_detected'
| 'working_detected'
| 'ralph_completion'
| 'ai_check_result'
| 'hook_event'
| 'state_stuck';
/**
* Severity levels for run summary events.
*/
export type RunSummaryEventSeverity = 'info' | 'warning' | 'error' | 'success';
/**
* A single event in the run summary timeline.
*/
export interface RunSummaryEvent {
/** Unique event identifier */
id: string;
/** Timestamp when event occurred */
timestamp: number;
/** Type of event */
type: RunSummaryEventType;
/** Severity level for display */
severity: RunSummaryEventSeverity;
/** Short title for the event */
title: string;
/** Optional detailed description */
details?: string;
/** Optional additional metadata */
metadata?: Record<string, unknown>;
}
/**
* Statistics aggregated from run summary events.
*/
export interface RunSummaryStats {
/** Number of respawn cycles completed */
totalRespawnCycles: number;
/** Total tokens used during this run */
totalTokensUsed: number;
/** Peak token count observed */
peakTokens: number;
/** Total time Claude was actively working (ms) */
totalTimeActiveMs: number;
/** Total time Claude was idle (ms) */
totalTimeIdleMs: number;
/** Number of errors encountered */
errorCount: number;
/** Number of warnings encountered */
warningCount: number;
/** Number of AI idle checks performed */
aiCheckCount: number;
/** Timestamp when last became idle */
lastIdleAt: number | null;
/** Timestamp when last started working */
lastWorkingAt: number | null;
/** Total number of state transitions */
stateTransitions: number;
}
/**
* Complete run summary for a session.
* Provides a historical view of session activity for users returning after absence.
*/
export interface RunSummary {
/** Session ID this summary belongs to */
sessionId: string;
/** Session display name */
sessionName: string;
/** Timestamp when tracking started */
startedAt: number;
/** Timestamp of last update */
lastUpdatedAt: number;
/** Timeline of events (most recent last) */
events: RunSummaryEvent[];
/** Aggregated statistics */
stats: RunSummaryStats;
}
/**
* Creates initial run summary stats.
*/
export function createInitialRunSummaryStats(): RunSummaryStats {
return {
totalRespawnCycles: 0,
totalTokensUsed: 0,
peakTokens: 0,
totalTimeActiveMs: 0,
totalTimeIdleMs: 0,
errorCount: 0,
warningCount: 0,
aiCheckCount: 0,
lastIdleAt: null,
lastWorkingAt: null,
stateTransitions: 0,
};
}
// ========== Spawn1337 Protocol Re-exports ==========
export type {