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
+50
View File
@@ -469,6 +469,56 @@
</div>
</div>
<!-- Run Summary Modal -->
<div class="modal" id="runSummaryModal">
<div class="modal-backdrop" onclick="app.closeRunSummary()"></div>
<div class="modal-content modal-lg">
<div class="modal-header">
<h3>Run Summary</h3>
<button class="modal-close" onclick="app.closeRunSummary()">&times;</button>
</div>
<div class="modal-body">
<!-- Stats Cards -->
<div class="run-summary-stats" id="runSummaryStats">
<div class="stat-card">
<div class="stat-value" id="rsStat-cycles">0</div>
<div class="stat-label">Respawn Cycles</div>
</div>
<div class="stat-card">
<div class="stat-value" id="rsStat-tokens">0</div>
<div class="stat-label">Tokens Used</div>
</div>
<div class="stat-card">
<div class="stat-value" id="rsStat-active">0m</div>
<div class="stat-label">Active Time</div>
</div>
<div class="stat-card">
<div class="stat-value" id="rsStat-issues">0</div>
<div class="stat-label">Issues</div>
</div>
</div>
<!-- Filter Buttons -->
<div class="run-summary-filters">
<button class="filter-btn active" data-filter="all" onclick="app.filterRunSummary('all')">All</button>
<button class="filter-btn" data-filter="errors" onclick="app.filterRunSummary('errors')">Errors</button>
<button class="filter-btn" data-filter="warnings" onclick="app.filterRunSummary('warnings')">Warnings</button>
<button class="filter-btn" data-filter="respawn" onclick="app.filterRunSummary('respawn')">Respawn</button>
<button class="filter-btn" data-filter="idle" onclick="app.filterRunSummary('idle')">Idle/Working</button>
</div>
<!-- Timeline -->
<div class="run-summary-timeline" id="runSummaryTimeline">
<p class="empty-message">Loading summary...</p>
</div>
</div>
<div class="modal-footer">
<span class="run-summary-session-info" id="runSummarySessionInfo"></span>
<button class="btn-toolbar btn-sm" onclick="app.closeRunSummary()">Close</button>
</div>
</div>
</div>
<!-- Close Session Confirmation Modal -->
<div class="modal" id="closeConfirmModal">
<div class="modal-backdrop" onclick="app.cancelCloseSession()"></div>