/** * Fixture commands/skills domains: contract-shape conformance for the two * domains added to ApiProxy — rpcId echo, session-addressed catalogs, execute * parse/dispatch, skill.list session resolution, and the FixtureApiClient * dispatch rows. */ import { describe, expect, it } from 'vitest' import type { SessionId } from '../src/client/api.ts' import { RpcId } from '../src/client/api.ts' import type { RpcRequest } from '../src/client/api.ts' import { FixtureApiClient, createFixtureApi } from '../src/client/fixture.ts' const sid = (id: string): SessionId => id as SessionId let reqCount = 0 const req =

(payload: P): RpcRequest

=> ({ rpcId: RpcId(`t-${reqCount++}`), payload }) const signal = new AbortController().signal describe('createFixtureApi commands/skills', () => { it('serves the addressed session catalog with rpcId echo', async () => { const api = createFixtureApi() const request = req({ sessionId: sid('fx-alpha') }) const response = await api.commands.list(request) expect(response.rpcId).toBe(request.rpcId) if (!response.result.ok) throw new Error('list failed') const commands = response.result.value.commands expect(commands.map(c => c.name)).toEqual(['compact', 'echo', 'goal-fixture']) // input hint rides only the commands declaring it. const echo = commands.find(c => c.name === 'echo') expect(echo?.input?.hint).toBeTruthy() expect(commands.find(c => c.name === 'compact')?.input).toBeUndefined() }) it('rejects a catalog request for an unknown session', async () => { const api = createFixtureApi() const response = await api.commands.list(req({ sessionId: sid('fx-nope') })) expect(response.result).toMatchObject({ ok: false, error: { code: 'session-not-found' } }) }) it('executes a known command line and reports matched with a result', async () => { const api = createFixtureApi() const response = await api.commands.execute(req({ sessionId: sid('fx-alpha'), line: '/echo hello world' }), signal) if (!response.result.ok) throw new Error('execute failed') expect(response.result.value.matched).toBe(true) expect(response.result.value.result).toEqual({ kind: 'success', text: 'hello world' }) }) it('addresses execute to the session (result text carries the id)', async () => { const api = createFixtureApi() const hit = await api.commands.execute(req({ sessionId: sid('fx-alpha'), line: '/goal-fixture ship' }), signal) if (!hit.result.ok) throw new Error('execute failed') expect(hit.result.value.matched).toBe(true) expect(hit.result.value.result?.text).toContain('fx-alpha') const missing = await api.commands.execute(req({ sessionId: sid('fx-nope'), line: '/goal-fixture ship' }), signal) expect(missing.result).toMatchObject({ ok: false, error: { code: 'session-not-found' } }) }) it('falls to matched:false on unknown names and non-command lines', async () => { const api = createFixtureApi() for (const line of ['/nope', 'plain text', '/']) { const response = await api.commands.execute(req({ sessionId: sid('fx-alpha'), line }), signal) if (!response.result.ok) throw new Error('execute failed') expect(response.result.value.matched).toBe(false) expect(response.result.value.result).toBeUndefined() } }) it('serves the skill catalog for the addressed session and rejects unknown sessions', async () => { const api = createFixtureApi() const response = await api.skills.list(req({ sessionId: sid('fx-alpha') })) if (!response.result.ok) throw new Error('skill list failed') expect(response.result.value.skills[0]?.name).toBe('fixture-demo') const missingSession = await api.skills.list(req({ sessionId: sid('fx-nope') })) expect(missingSession.result).toMatchObject({ ok: false, error: { code: 'session-not-found' } }) }) }) describe('FixtureApiClient command/skill dispatch', () => { it('routes the three method keys through the in-memory dispatch table', async () => { const client = new FixtureApiClient() const list = await client.commands.list({ sessionId: sid('fx-alpha') }) if (!list.result.ok) throw new Error('command.list failed') expect(list.result.value.commands.length).toBeGreaterThan(0) const executed = await client.commands.execute({ sessionId: sid('fx-alpha'), line: '/compact' }) if (!executed.result.ok) throw new Error('command.execute failed') expect(executed.result.value.matched).toBe(true) const skills = await client.skills.list({ sessionId: sid('fx-alpha') }) if (!skills.result.ok) throw new Error('skill.list failed') expect(skills.result.value.skills.length).toBeGreaterThan(0) }) })