/** * Smoke tests: Prompt section drill-down. * * Verifies that large prompts served via prompts/get are section-split * and that subsequent calls with _resultId + _section return cached sections. * * Requires: mcplocal running on localhost:3200, mcpd on 10.0.0.194:3100 */ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { SmokeMcpSession, isMcplocalRunning } from './mcp-client.js'; const PROJECT_NAME = 'smoke-data'; describe('Smoke: Prompt section drill-down', () => { let available = false; let session: SmokeMcpSession; beforeAll(async () => { available = await isMcplocalRunning(); if (!available) return; session = new SmokeMcpSession(PROJECT_NAME); await session.initialize(); await session.sendNotification('notifications/initialized'); }); afterAll(async () => { if (session) await session.close(); }); it('prompts/list returns available prompts', async () => { if (!available) return; const result = await session.send('prompts/list') as { prompts: Array<{ name: string; description?: string }> }; expect(result.prompts).toBeDefined(); expect(Array.isArray(result.prompts)).toBe(true); // Should have at least mcpctl-managed prompts const mcpctlPrompts = result.prompts.filter((p) => p.name.startsWith('mcpctl/')); console.log(` Found ${result.prompts.length} prompts (${mcpctlPrompts.length} mcpctl-managed)`); }); it('prompts/get returns prompt content', async () => { if (!available) return; const listResult = await session.send('prompts/list') as { prompts: Array<{ name: string }> }; if (listResult.prompts.length === 0) { console.log(' No prompts available — skipping'); return; } const promptName = listResult.prompts[0].name; const getResult = await session.send('prompts/get', { name: promptName }) as { messages?: Array<{ role: string; content: unknown }>; }; expect(getResult.messages).toBeDefined(); expect(getResult.messages!.length).toBeGreaterThan(0); console.log(` prompts/get "${promptName}": ${getResult.messages!.length} message(s)`); }); it('large prompt response includes section TOC with _resultId', async () => { if (!available) return; // Find a mcpctl-managed prompt (these tend to be large system prompts) const listResult = await session.send('prompts/list') as { prompts: Array<{ name: string }> }; const mcpctlPrompts = listResult.prompts.filter((p) => p.name.startsWith('mcpctl/')); if (mcpctlPrompts.length === 0) { console.log(' No mcpctl prompts — skipping section drill-down test'); return; } // Try each prompt to find one large enough to be section-split let foundSections = false; for (const prompt of mcpctlPrompts) { const getResult = await session.send('prompts/get', { name: prompt.name }) as { messages?: Array<{ role: string; content: unknown }>; }; if (!getResult.messages || getResult.messages.length === 0) continue; const msg = getResult.messages[0]; const text = typeof msg.content === 'string' ? msg.content : (msg.content as { text?: string }).text ?? ''; if (text.includes('_resultId')) { foundSections = true; console.log(` "${prompt.name}": section-split TOC detected (${text.length} chars)`); console.log(` TOC preview: ${text.slice(0, 200)}...`); // Extract _resultId const match = /_resultId:\s*(pm-[a-z0-9]+)/.exec(text); if (match) { const resultId = match[1]; // Extract first section id from TOC const sectionMatch = /\[([^\]]+)\]/.exec(text); if (sectionMatch) { const sectionId = sectionMatch[1]; console.log(` Drilling into section "${sectionId}" with resultId "${resultId}"...`); // Drill down const drillResult = await session.send('prompts/get', { name: prompt.name, arguments: { _resultId: resultId, _section: sectionId }, }) as { content?: Array<{ text: string }> }; expect(drillResult).toBeDefined(); console.log(` Drill-down returned: ${JSON.stringify(drillResult).length} chars`); } } break; } else { console.log(` "${prompt.name}": ${text.length} chars (not section-split — likely too small)`); } } if (!foundSections) { console.log(' No prompts large enough for section-split — test inconclusive but not failing'); } }); });