import { describe, it, expect, vi } from 'vitest'; import { createApproveCommand, createApprovalsCommand, createContextCommand, createDenyCommand, createElevateCommand, createModelCommand, createQueueCommand, createResearchCommand, createSkillCommand, createTransferCommand } from './index.js'; describe('builtin /model command', () => { it('passes through the full argument string', async () => { const cmd = createModelCommand(); const setModel = vi.fn(() => 'ok'); const result = await cmd.execute(['default', 'github/gpt-5-mini'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/model default github/gpt-5-mini', services: { setModel }, }); expect(setModel).toHaveBeenCalledWith('default github/gpt-5-mini'); expect(result).toEqual({ handled: true, text: 'ok' }); }); it('still works for single-argument tier switching', async () => { const cmd = createModelCommand(); const setModel = vi.fn(() => 'switched'); const result = await cmd.execute(['fast'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/model fast', services: { setModel }, }); expect(setModel).toHaveBeenCalledWith('fast'); expect(result).toEqual({ handled: true, text: 'switched' }); }); }); describe('builtin /research command', () => { it('delegates to the research agent with the full task string', async () => { const cmd = createResearchCommand(); const delegateAgent = vi.fn(() => 'research output'); const result = await cmd.execute(['compare', 'k0s', 'vs', 'k3s'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/research compare k0s vs k3s', services: { delegateAgent }, }); expect(delegateAgent).toHaveBeenCalledWith('research', 'compare k0s vs k3s'); expect(result).toEqual({ handled: true, text: 'research output' }); }); it('returns usage when no task is provided', async () => { const cmd = createResearchCommand(); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/research', services: {}, }); expect(result).toEqual({ handled: true, text: 'Usage: /research ' }); }); }); describe('builtin /elevate command', () => { it('passes through the full argument string', async () => { const cmd = createElevateCommand(); const setElevation = vi.fn(() => 'ok'); const result = await cmd.execute(['10m', 'reason', '--yes'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/elevate 10m reason --yes', services: { setElevation }, }); expect(setElevation).toHaveBeenCalledWith('10m reason --yes'); expect(result).toEqual({ handled: true, text: 'ok' }); }); it('shows status when no args are provided', async () => { const cmd = createElevateCommand(); const getElevation = vi.fn(() => 'status'); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/elevate', services: { getElevation }, }); expect(getElevation).toHaveBeenCalledOnce(); expect(result).toEqual({ handled: true, text: 'status' }); }); }); describe('builtin /queue command', () => { it('shows queue status with no args', async () => { const cmd = createQueueCommand(); const getQueue = vi.fn(() => 'queue status'); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/queue', services: { getQueue }, }); expect(getQueue).toHaveBeenCalledOnce(); expect(result).toEqual({ handled: true, text: 'queue status' }); }); it('passes through set operations', async () => { const cmd = createQueueCommand(); const setQueue = vi.fn(() => 'updated'); const result = await cmd.execute(['set', 'mode', 'followup'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/queue set mode followup', services: { setQueue }, }); expect(setQueue).toHaveBeenCalledWith('mode followup'); expect(result).toEqual({ handled: true, text: 'updated' }); }); it('calls reset operation', async () => { const cmd = createQueueCommand(); const resetQueue = vi.fn(() => 'reset'); const result = await cmd.execute(['reset'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/queue reset', services: { resetQueue }, }); expect(resetQueue).toHaveBeenCalledOnce(); expect(result).toEqual({ handled: true, text: 'reset' }); }); }); describe('builtin /context command', () => { it('returns context usage text from services', async () => { const cmd = createContextCommand(); const getContext = vi.fn(() => 'Context Usage\n\n75.0%'); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/context', services: { getContext }, }); expect(getContext).toHaveBeenCalledOnce(); expect(result).toEqual({ handled: true, text: 'Context Usage\n\n75.0%' }); }); it('returns not-available when service is missing', async () => { const cmd = createContextCommand(); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/context', services: {}, }); expect(result).toEqual({ handled: true, text: 'Context command is not available in this session.' }); }); }); describe('builtin /transfer command', () => { it('passes through the full target argument string', async () => { const cmd = createTransferCommand(); const transferSession = vi.fn(() => 'Session transferred'); const result = await cmd.execute(['telegram'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/transfer telegram', services: { transferSession }, }); expect(transferSession).toHaveBeenCalledWith('telegram'); expect(result).toEqual({ handled: true, text: 'Session transferred' }); }); it('returns not-available when service is missing', async () => { const cmd = createTransferCommand(); const result = await cmd.execute(['tui'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/transfer tui', services: {}, }); expect(result).toEqual({ handled: true, text: 'Transfer command is not available in this session.' }); }); }); describe('builtin approval commands', () => { it('calls getApprovals for /approvals', async () => { const cmd = createApprovalsCommand(); const getApprovals = vi.fn(() => '1 pending'); const result = await cmd.execute([], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/approvals', services: { getApprovals }, }); expect(getApprovals).toHaveBeenCalledOnce(); expect(result).toEqual({ handled: true, text: '1 pending' }); }); it('passes raw input to approvePending for /approve', async () => { const cmd = createApproveCommand(); const approvePending = vi.fn(() => 'approved'); const result = await cmd.execute(['abc-123'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/approve abc-123', services: { approvePending }, }); expect(approvePending).toHaveBeenCalledWith('abc-123'); expect(result).toEqual({ handled: true, text: 'approved' }); }); it('passes raw input to denyPending for /deny', async () => { const cmd = createDenyCommand(); const denyPending = vi.fn(() => 'denied'); const result = await cmd.execute(['abc-123', 'too', 'risky'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/deny abc-123 too risky', services: { denyPending }, }); expect(denyPending).toHaveBeenCalledWith('abc-123 too risky'); expect(result).toEqual({ handled: true, text: 'denied' }); }); }); describe('builtin /skill command', () => { it('passes subcommand text to skillCommand service', async () => { const cmd = createSkillCommand(); const skillCommand = vi.fn(() => 'ok'); const result = await cmd.execute(['search', 'calendar'], { channel: 'test', senderId: 'user', sessionId: 's1', rawInput: '/skill search calendar', services: { skillCommand }, }); expect(skillCommand).toHaveBeenCalledWith('search calendar'); expect(result).toEqual({ handled: true, text: 'ok' }); }); });