STORY: The session backend needed to aggregate agent health from a live telemetry stream rather than static bead metadata. This refactor makes liveness signals real-time and accurate. COLLABORATION: We extended the ActivityEvent model with a native 'heartbeat' kind, updated extendActivityLease() to emit through the activity bus, and refactored getAgentLivenessMap() to prioritize heartbeat activity history over stale bead metadata. DELIVERABLES: - ActivityEvent extended with 'heartbeat' kind - extendActivityLease() emits heartbeats through activity bus - getAgentLivenessMap() prefers telemetry over static metadata - Registry APIs support projectRoot injection for testing - Tests verify preference logic via TDD VERIFICATION: - 93/93 tests PASSING - Heartbeat override verified in isolated temp projects CLOSES: bb-buff.1.3 BLOCKS: bb-buff.3.2, bb-buff.3.3, bb-buff.2.1
38 lines
1.2 KiB
TypeScript
38 lines
1.2 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
|
|
import { GET as eventsGet } from '../../src/app/api/events/route';
|
|
import { getIssuesWatchManager } from '../../src/lib/watcher';
|
|
|
|
test.afterEach(async () => {
|
|
await getIssuesWatchManager().stopAll();
|
|
});
|
|
|
|
test.after(async () => {
|
|
await getIssuesWatchManager().stopAll();
|
|
});
|
|
|
|
test('events route returns SSE response with expected headers', async () => {
|
|
const response = await eventsGet(new Request('http://localhost/api/events?projectRoot=C:/Repo/Test'));
|
|
|
|
assert.equal(response.status, 200);
|
|
assert.equal(response.headers.get('content-type')?.includes('text/event-stream'), true);
|
|
assert.equal(response.headers.get('cache-control')?.includes('no-cache'), true);
|
|
|
|
const reader = response.body?.getReader();
|
|
if (reader) {
|
|
await reader.cancel();
|
|
}
|
|
});
|
|
|
|
test('events route emits initial connected frame', async () => {
|
|
const response = await eventsGet(new Request('http://localhost/api/events?projectRoot=C:/Repo/Test'));
|
|
const reader = response.body?.getReader();
|
|
assert.equal(Boolean(reader), true);
|
|
|
|
const first = await reader!.read();
|
|
const chunk = new TextDecoder().decode(first.value);
|
|
assert.equal(chunk.includes(': connected'), true);
|
|
|
|
await reader!.cancel();
|
|
});
|