A cross-session insight surface: the sidebar-foot entry (stacked above Settings by the harness's own foot layout, with a running-sessions badge) opens a frame-wide overlay through the shared module store. The panel reads the root-scope useSessions/useWorkspaces standard kit — every list row's host-cached projection values — so no session log needs opening: - KPI band over the picked range (7d / 30d / all): active sessions, billed tokens, estimated cost (models.dev book), cache-hit rate. - Activity heatmap (GitHub-style, 12 weeks, square cells filling the card): a day click pins the session grid to that day. - Aggregate composition donut over the range's sessions. - Session cards with a mini composition ring, billed/turns/cost figures and a workspace-group / project breadcrumb (deduped when both names match); grid filters by range, pinned day, group chips (incl. Ungrouped), and search; sorts by recency, tokens, or context size; a card click opens the session through the harness's own sessions.open and closes the panel. Subagent-origin rows are excluded, mirroring the workspace browser's own predicate (plain open() cannot address them). Every row is sanitized in isolation — a hostile row degrades to a metadata-only card, never an error.
56 lines
1.6 KiB
TypeScript
56 lines
1.6 KiB
TypeScript
// The Context Dashboard's open-state store (src/client/overviewStore.ts):
|
|
// subscribe/notify semantics, idempotent sets, unsubscribe.
|
|
|
|
import assert from 'node:assert/strict'
|
|
import { afterEach, describe, test } from 'vitest'
|
|
import { overviewStore } from '../../src/client/overviewStore'
|
|
|
|
afterEach(() => {
|
|
overviewStore.set(false)
|
|
})
|
|
|
|
describe('overviewStore', () => {
|
|
test('closed by default; set flips and notifies', () => {
|
|
assert.equal(overviewStore.getSnapshot(), false)
|
|
const seen: boolean[] = []
|
|
const unsubscribe = overviewStore.subscribe(() => { seen.push(overviewStore.getSnapshot()) })
|
|
overviewStore.set(true)
|
|
assert.equal(overviewStore.getSnapshot(), true)
|
|
assert.deepEqual(seen, [true])
|
|
overviewStore.set(false)
|
|
assert.deepEqual(seen, [true, false])
|
|
unsubscribe()
|
|
})
|
|
|
|
test('an idempotent set notifies nobody', () => {
|
|
overviewStore.set(true)
|
|
let calls = 0
|
|
const unsubscribe = overviewStore.subscribe(() => { calls++ })
|
|
overviewStore.set(true)
|
|
assert.equal(calls, 0)
|
|
overviewStore.set(false)
|
|
assert.equal(calls, 1)
|
|
unsubscribe()
|
|
})
|
|
|
|
test('unsubscribe detaches the listener', () => {
|
|
let calls = 0
|
|
const unsubscribe = overviewStore.subscribe(() => { calls++ })
|
|
unsubscribe()
|
|
overviewStore.set(true)
|
|
assert.equal(calls, 0)
|
|
})
|
|
|
|
test('several listeners all hear a flip', () => {
|
|
let a = 0
|
|
let b = 0
|
|
const unA = overviewStore.subscribe(() => { a++ })
|
|
const unB = overviewStore.subscribe(() => { b++ })
|
|
overviewStore.set(true)
|
|
assert.equal(a, 1)
|
|
assert.equal(b, 1)
|
|
unA()
|
|
unB()
|
|
})
|
|
})
|