Cleanup:
- Removed 109 stale asset files from static/assets/ (was 122, now 13)
- Removed static/v2/ entirely (was duplicate of root assets)
- Removed dead dashboard code: DashboardView, Layout, GlobalStats,
CharacterCard, CharacterGrid, VitalBar, TabContainer, CombatTab,
RaresTab, MapTab, InventoryTab, global.css, MapTransformContext
- Removed recharts dependency (425KB chunk eliminated)
- CSS reduced from 17KB to 10KB
- Added deploy-frontend.sh script for one-command build+deploy
- Updated CLAUDE.md with combat_stats, share_*, dungeon_map events
and React frontend architecture
Death alerts (frontend + backend):
- Frontend: DeathNotification component with red banner + sawtooth
sound when vitae goes from 0 to >0
- Backend: detects vitae transition in vitals handler, sends Discord
webhook to #aclog with "☠️ CHARACTER died! (vitae: X%)"
- Rate-limited: max 1 Discord alert per character per 5 minutes
Idle detection (backend):
- Background task runs every 60 seconds
- Detects: vt_state "default"/"idle" OR kph=0 while in combat/hunt
- Sends Discord webhook: "⚠️ CHARACTER appears idle (state: X, KPH: 0)"
- Auto-clears alert when character becomes active again
- No duplicate alerts for same idle period
Discord integration:
- DISCORD_ACLOG_WEBHOOK env var for webhook URL
- Used by both death alerts and idle detection
- Graceful fallback when not configured
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The CharacterWindow only fetched once from API on mount and never
updated. Now:
- character_stats WS messages are tracked in useLiveData via ref
- Passed through WindowRenderer to CharacterWindow as liveStats prop
- Window uses live WS data when available, falls back to API fetch
- Attributes, skills, vitals base values, properties (augmentations,
ratings, etc.), allegiance all update in real-time
Also: vitals bars in the character window use live WS vitals data
(health_percentage etc.) for real-time HP/Stamina/Mana display.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>