Tool-renderer registry (21 files, ~1.5k lines):
- src/lib/tool-renderers.ts — registry + getToolRenderer (exported, never
imported anywhere)
- src/lib/renderers/index.ts + 10 .ts registrars + 10 .svelte components
- main.ts: removed the requestAnimationFrame(() => import('./lib/renderers'))
that was the only thing keeping the dead subsystem alive
Dead components (never imported):
- ToolCallGroup, PlanProgress, GoalHeader, InlineApproval, SessionDigest
Dead store exports (written, never read):
- context.ts: pendingApprovals writable (+ Approval type import)
- events.ts: connectionState writable (+ its .set() calls)
Dead API surface:
- api.ts: SessionDigest interface + fetchSessionDigest (only caller was the
dead SessionDigest.svelte)
Dead npm deps:
- mode-watcher (0 imports; superseded by stores/theme.svelte.ts)
- @internationalized/date (0 imports)
Also: fix stale comments referencing deleted symbols, update plan R1/R2
status. Build clean (4683 modules, down from 4706; one Svelte 5 warning
gone — the dead HealthSummary.svelte was emitting state_referenced_locally).
56 lines
1.3 KiB
TypeScript
56 lines
1.3 KiB
TypeScript
import { writable } from 'svelte/store'
|
|
import { sseUrl } from '$lib/config'
|
|
|
|
export interface OikosEvent {
|
|
id: number
|
|
ts: string
|
|
type: string
|
|
entity_id?: string | null
|
|
severity: 'info' | 'warning' | 'critical'
|
|
source: string
|
|
data?: unknown
|
|
correlation_id?: string | null
|
|
}
|
|
|
|
const MAX_BUFFERED = 200
|
|
|
|
export const liveEvents = writable<OikosEvent[]>([])
|
|
|
|
let source: EventSource | null = null
|
|
let subscriberCount = 0
|
|
|
|
async function connect() {
|
|
if (source) return
|
|
// The browser's EventSource sends Last-event-ID automatically on reconnect.
|
|
// sseUrl is async so the OIDC access token is refreshed if expired.
|
|
source = new EventSource(await sseUrl('/api/v1/events/stream'))
|
|
|
|
source.onmessage = (ev) => {
|
|
try {
|
|
const parsed: OikosEvent = JSON.parse(ev.data)
|
|
liveEvents.update((events) => [parsed, ...events].slice(0, MAX_BUFFERED))
|
|
} catch {
|
|
// skip malformed
|
|
}
|
|
}
|
|
|
|
source.onerror = () => {
|
|
// browser will auto-reconnect; nothing to surface here
|
|
}
|
|
}
|
|
|
|
function disconnect() {
|
|
source?.close()
|
|
source = null
|
|
}
|
|
|
|
// Reference-counted: the stream stays open as long as at least one page subscribes.
|
|
export function subscribeEvents(): () => void {
|
|
subscriberCount++
|
|
if (subscriberCount === 1) connect()
|
|
return () => {
|
|
subscriberCount--
|
|
if (subscriberCount === 0) disconnect()
|
|
}
|
|
}
|