import { describe, expect, it, vi } from 'vitest'; import type { AgentRuntimeProvider, RuntimeScope } from '@mosaicstack/types'; import { MatrixNativeRuntimeProvider, type MatrixRuntimeTransport, } from './matrix-native-runtime-provider.js'; import { TmuxFleetRuntimeProvider, type FleetRuntimeTransport, } from './tmux-fleet-runtime-provider.js'; const scope: RuntimeScope = { actorId: 'operator-1', tenantId: 'tenant-a', channelId: 'cli', correlationId: 'corr-1', }; interface ProviderFixture { name: string; provider: AgentRuntimeProvider; providerId: string; verifySession: unknown; send: unknown; } function fixtures(): ProviderFixture[] { const fleetTransport: FleetRuntimeTransport = { verifySession: vi.fn(async () => ({ id: 'session-1', runtimeId: 'native-1', socketName: 'fleet', })), listSessions: vi.fn(async () => [ { id: 'session-1', runtimeId: 'native-1', socketName: 'fleet' }, ]), sendMessage: vi.fn(async () => undefined), terminate: vi.fn(async () => undefined), }; const fleet = new TmuxFleetRuntimeProvider({ transport: fleetTransport, readAuthority: { canRead: vi.fn(async () => true) }, writeAuthority: { canWrite: vi.fn(async () => true), assertAuthorized: vi.fn(async () => undefined), }, attachmentIdFactory: () => 'attachment-1', now: () => new Date('2026-07-13T00:00:00.000Z'), }); const matrixTransport: MatrixRuntimeTransport = { health: vi.fn(async () => ({ status: 'healthy' as const, checkedAt: '2026-07-13T00:00:00.000Z', })), verifySession: vi.fn(async () => ({ id: 'session-1', runtimeId: 'native-1', state: 'active' as const, createdAt: '2026-07-13T00:00:00.000Z', updatedAt: '2026-07-13T00:00:00.000Z', })), listSessions: vi.fn(async () => [ { id: 'session-1', runtimeId: 'native-1', state: 'active' as const, createdAt: '2026-07-13T00:00:00.000Z', updatedAt: '2026-07-13T00:00:00.000Z', }, ]), stream: async function* () {}, send: vi.fn(async () => undefined), terminate: vi.fn(async () => undefined), }; const matrix = new MatrixNativeRuntimeProvider({ transport: matrixTransport, readAuthority: { canRead: vi.fn(async () => true) }, writeAuthority: { canWrite: vi.fn(async () => true), assertAuthorized: vi.fn(async () => undefined), }, attachmentIdFactory: () => 'attachment-1', now: () => new Date('2026-07-13T00:00:00.000Z'), }); return [ { name: 'tmux/fleet', provider: fleet, providerId: 'fleet.tmux', verifySession: fleetTransport.verifySession, send: fleetTransport.sendMessage, }, { name: 'Matrix/native', provider: matrix, providerId: 'runtime.matrix', verifySession: matrixTransport.verifySession, send: matrixTransport.send, }, ]; } /** Shared contract tests for the migration-safe provider intersection. */ describe('tmux/fleet and Matrix/native provider parity', (): void => { it.each(fixtures())( '%s exposes the shared runtime operations', async (fixture): Promise => { await expect(fixture.provider.capabilities(scope)).resolves.toEqual( expect.objectContaining({ supported: expect.arrayContaining([ 'session.list', 'session.tree', 'session.send', 'session.attach', 'session.terminate', ]), }), ); await expect(fixture.provider.listSessions(scope)).resolves.toEqual([ expect.objectContaining({ id: 'session-1', providerId: fixture.providerId, runtimeId: 'native-1', }), ]); }, ); it.each(fixtures())( '%s rejects empty messages before touching its transport', async (fixture): Promise => { await expect( fixture.provider.sendMessage( 'session-1', { content: '', idempotencyKey: 'message-1' }, scope, ), ).rejects.toMatchObject({ code: 'invalid_request' }); expect(fixture.verifySession).not.toHaveBeenCalled(); expect(fixture.send).not.toHaveBeenCalled(); }, ); it.each(fixtures())( '%s rejects an empty termination approval before touching its transport', async (fixture): Promise => { await expect(fixture.provider.terminate('session-1', '', scope)).rejects.toMatchObject({ code: 'invalid_request', }); expect(fixture.verifySession).not.toHaveBeenCalled(); }, ); it.each(fixtures())( '%s creates a read-only handle bound to immutable scope', async (fixture): Promise => { await expect(fixture.provider.attach('session-1', 'control', scope)).rejects.toMatchObject({ code: 'forbidden', }); expect(fixture.verifySession).not.toHaveBeenCalled(); await expect(fixture.provider.attach('session-1', 'read', scope)).resolves.toEqual( expect.objectContaining({ attachmentId: 'attachment-1', sessionId: 'session-1', mode: 'read', }), ); await expect( fixture.provider.detach('attachment-1', { ...scope, actorId: 'operator-2' }), ).rejects.toMatchObject({ code: 'forbidden' }); }, ); });