Processing Indicator: Complete Code Reference
This document provides a line-by-line breakdown of every piece of code related to the processing/activity indicator (the spinning logomark in the top left corner of the viewer UI).Overview
The processing indicator is a visual cue that shows when the worker service is actively processing memories (observations or summaries). It consists of:- Logomark Image:
claude-mem-logomark.webpin the header - Spinning Animation: Applied via CSS class when processing is active
- State Management: Tracked via Server-Sent Events (SSE) from the worker
- Processing Sessions Set: Maintains active session IDs being processed
Data Flow
1. TypeScript Types
File: src/ui/viewer/types.ts
Lines 45-58: StreamEvent interface with processing_status type
processing_status type includes a processing object that indicates whether a session is currently being processed.
2. Worker Service (Backend)
File: src/services/worker-service.ts
Lines 247-272: broadcastSSE() - Core SSE broadcasting
Lines 274-285: broadcastProcessingStatus() - Processing indicator control
Line 817: Summarize request triggers processing start
handleSummarize() method - when a summary request is queued, processing starts.
File location: src/services/worker-service.ts:817
Line 1153: Summary generation complete - processing stops
processSummarizeMessage() after successfully generating and saving a summary.
File location: src/services/worker-service.ts:1153
Line 1183: No summary generated - still mark processing complete
processSummarizeMessage() when no summary tags are found in the AI response.
File location: src/services/worker-service.ts:1183
3. React Hook: SSE Connection
File: src/ui/viewer/hooks/useSSE.ts
Line 12: processingSessions state initialization
Lines 90-104: processing_status event handler
processing_status SSE events and updates the processingSessions Set:
is_processing: true→ Adds session ID to Setis_processing: false→ Removes session ID from Set
src/ui/viewer/hooks/useSSE.ts:90-104
Lines 73-78: Summary completion also clears processing status
new_summary event arrives, remove the session from processingSessions (defensive cleanup in case the processing_status event was missed).
File location: src/ui/viewer/hooks/useSSE.ts:73-78
Line 125: Hook return value includes processingSessions
4. React Component: App
File: src/ui/viewer/App.tsx
Line 20: Destructure processingSessions from useSSE
Line 92: Convert Set to boolean for Header component
true to Header if ANY session is being processed (Set has items), false otherwise.
File location: src/ui/viewer/App.tsx:92
5. React Component: Header
File: src/ui/viewer/components/Header.tsx
Line 12: isProcessing prop definition
Line 24: isProcessing destructured from props
Line 31: Logomark with conditional spinning class
isProcessing is true, adds the spinning CSS class to the logomark image, triggering the rotation animation.
File location: src/ui/viewer/components/Header.tsx:31
Rendered HTML Examples:
- Not processing:
<img src="claude-mem-logomark.webp" alt="" className="logomark" /> - Processing:
<img src="claude-mem-logomark.webp" alt="" className="logomark spinning" />
6. CSS Styling & Animation
File: plugin/ui/viewer.html (compiled output)
Lines 342-349: Logomark and spinning class styles
.logomark: Base styles for the logo image (32px height, auto width).logomark.spinning: Applies the spin animation when processing is active- Duration: 1.5 seconds per rotation
- Timing: Linear (constant speed)
- Iteration: Infinite (continues until class is removed)
plugin/ui/viewer.html:342-349
Lines 701-705: Spin animation keyframes
plugin/ui/viewer.html:701-705
7. API Endpoint: Stream
File: src/ui/viewer/constants/api.ts
Line 11: SSE stream endpoint
/stream endpoint is used by useSSE.ts to establish the EventSource connection.
Bonus: Feed Skeleton Processing Indicator
While not part of the logomark spinner, the feed also shows processing state with skeleton cards and a smaller spinner.File: src/ui/viewer/components/Feed.tsx
Lines 66-80: Create skeleton items for processing sessions
processingSessions Set).
Line 104: Render SummarySkeleton component
File: src/ui/viewer/components/SummarySkeleton.tsx
Lines 14-17: Processing indicator in skeleton card
CSS for Feed Spinner
Lines 682-690: Processing indicator containerLines 692-700: Small spinner for skeleton cards
@keyframes spin animation.
Lines 711-715: Skeleton card opacity
Lines 715-740: Skeleton line animations (shimmer effect)
Summary: Complete Processing Flow
- User submits prompt → Claude Code session starts
- Worker receives summarize request →
worker-service.ts:817callsbroadcastProcessingStatus(sessionId, true) - SSE broadcasts →
{ type: 'processing_status', processing: { session_id: '...', is_processing: true } } - React receives event →
useSSE.ts:90-104adds sessionId toprocessingSessionsSet - State flows down →
App.tsx:92converts Set size to boolean →Header.tsx:31receivesisProcessing={true} - CSS class applied →
className="logomark spinning"triggers animation - Logomark spins → CSS animation
@keyframes spinrotates 360° every 1.5s - Feed shows skeleton →
Feed.tsx:66-80creates skeleton cards for processing sessions - Summary completes →
worker-service.ts:1153callsbroadcastProcessingStatus(sessionId, false) - SSE broadcasts →
{ type: 'processing_status', processing: { session_id: '...', is_processing: false } } - React clears state →
useSSE.ts:90-104removes sessionId from Set - Animation stops →
isProcessing={false}removesspinningclass, logomark stops rotating
File Summary
| File | Lines | Purpose |
|---|---|---|
src/ui/viewer/types.ts | 45-58 | Defines StreamEvent interface with processing_status type |
src/services/worker-service.ts | 247-285, 817, 1153, 1183 | Broadcasts processing status via SSE |
src/ui/viewer/hooks/useSSE.ts | 12, 73-78, 90-104, 125 | Manages processingSessions Set from SSE events |
src/ui/viewer/App.tsx | 20, 92 | Converts Set to boolean, passes to Header |
src/ui/viewer/components/Header.tsx | 12, 24, 31 | Applies spinning class to logomark |
plugin/ui/viewer.html (CSS) | 342-349, 701-705 | Styles logomark and defines spin animation |
src/ui/viewer/components/Feed.tsx | 66-80, 104 | Creates skeleton cards for processing sessions |
src/ui/viewer/components/SummarySkeleton.tsx | 14-17 | Renders inline spinner in skeleton cards |
plugin/ui/viewer.html (CSS) | 682-740 | Styles for skeleton cards and inline spinner |
Key Design Decisions
-
Set vs Boolean: Using a
Set<string>forprocessingSessionsallows tracking multiple concurrent sessions. The UI shows spinning as long as any session is processing. -
Defensive Cleanup: Both
processing_statusevents ANDnew_summaryevents clear processing state, ensuring the spinner stops even if events arrive out of order. - CSS-Only Animation: No JavaScript animation loops - pure CSS transforms provide smooth, GPU-accelerated rotation with minimal performance impact.
- Dual Indicators: Header logomark (global processing state) + skeleton cards (per-session processing state) provide both overview and detail-level feedback.
- SSE Architecture: Server-Sent Events provide real-time updates without polling, keeping UI responsive with minimal network overhead.

