Skip to main content
Glama
artifact-discovery.test.ts13.3 kB
/** * Artifact Discovery Live Test * * Tests real artifact discovery functionality with actual VibeCoderOutput directory scanning */ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { PRDIntegrationService } from '../../integrations/prd-integration.js'; import { TaskListIntegrationService } from '../../integrations/task-list-integration.js'; import type { PRDInfo, TaskListInfo } from '../../types/artifact-types.js'; import * as fs from 'fs/promises'; import * as path from 'path'; // Extended timeout for real file operations const LIVE_TEST_TIMEOUT = 60000; // 60 seconds describe('Artifact Discovery Live Test', () => { let prdIntegration: PRDIntegrationService; let taskListIntegration: TaskListIntegrationService; let testOutputDir: string; let createdTestFiles: string[] = []; beforeEach(async () => { // Initialize services prdIntegration = PRDIntegrationService.getInstance(); taskListIntegration = TaskListIntegrationService.getInstance(); // Setup test output directory const baseOutputDir = process.env.VIBE_CODER_OUTPUT_DIR || path.join(process.cwd(), 'VibeCoderOutput'); testOutputDir = baseOutputDir; console.log(`🔍 Testing artifact discovery in: ${testOutputDir}`); // Create test artifacts for discovery await createTestArtifacts(); }); afterEach(async () => { // Cleanup test files await cleanupTestArtifacts(); }); describe('PRD Discovery Live Tests', () => { it('should discover existing PRD files in VibeCoderOutput/prd-generator', async () => { console.log('🔍 Starting PRD file discovery...'); const startTime = Date.now(); const discoveredPRDs: PRDInfo[] = await prdIntegration.findPRDFiles(); const duration = Date.now() - startTime; console.log(`✅ PRD discovery completed in ${duration}ms`); console.log(`📄 Found ${discoveredPRDs.length} PRD files`); // Verify discovery results expect(discoveredPRDs).toBeDefined(); expect(Array.isArray(discoveredPRDs)).toBe(true); expect(duration).toBeLessThan(10000); // Should complete within 10 seconds // Log discovered PRDs discoveredPRDs.forEach((prd, index) => { console.log(` ${index + 1}. ${prd.fileName} (${prd.projectName})`); console.log(` Path: ${prd.filePath}`); console.log(` Size: ${prd.fileSize} bytes`); console.log(` Created: ${prd.createdAt.toISOString()}`); console.log(` Accessible: ${prd.isAccessible}`); }); // Verify test PRD is found const testPRD = discoveredPRDs.find(prd => prd.projectName.includes('Live Test')); if (testPRD) { console.log(`✅ Test PRD found: ${testPRD.fileName}`); expect(testPRD.isAccessible).toBe(true); expect(testPRD.fileSize).toBeGreaterThan(0); } else { console.log(`⚠️ Test PRD not found, but discovery is working`); } // Verify PRD structure discoveredPRDs.forEach(prd => { expect(prd.filePath).toBeDefined(); expect(prd.fileName).toBeDefined(); expect(prd.projectName).toBeDefined(); expect(prd.createdAt).toBeInstanceOf(Date); expect(prd.fileSize).toBeGreaterThanOrEqual(0); expect(typeof prd.isAccessible).toBe('boolean'); }); console.log(`🎯 PRD discovery test completed successfully!`); }, LIVE_TEST_TIMEOUT); it('should detect most recent PRD for a specific project', async () => { console.log('🔍 Testing PRD detection for specific project...'); const startTime = Date.now(); const detectedPRD = await prdIntegration.detectExistingPRD('Live Test Project'); const duration = Date.now() - startTime; console.log(`✅ PRD detection completed in ${duration}ms`); if (detectedPRD) { console.log(`📄 Detected PRD: ${detectedPRD.fileName}`); console.log(` Project: ${detectedPRD.projectName}`); console.log(` Path: ${detectedPRD.filePath}`); console.log(` Size: ${detectedPRD.fileSize} bytes`); expect(detectedPRD.projectName).toContain('Live Test'); expect(detectedPRD.isAccessible).toBe(true); } else { console.log(`ℹ️ No PRD detected for 'Live Test Project' - this is expected if no matching files exist`); } expect(duration).toBeLessThan(5000); // Should complete within 5 seconds console.log(`🎯 PRD detection test completed!`); }, LIVE_TEST_TIMEOUT); }); describe('Task List Discovery Live Tests', () => { it('should discover existing task list files in VibeCoderOutput/generated_task_lists', async () => { console.log('🔍 Starting task list file discovery...'); const startTime = Date.now(); const discoveredTaskLists: TaskListInfo[] = await taskListIntegration.findTaskListFiles(); const duration = Date.now() - startTime; console.log(`✅ Task list discovery completed in ${duration}ms`); console.log(`📋 Found ${discoveredTaskLists.length} task list files`); // Verify discovery results expect(discoveredTaskLists).toBeDefined(); expect(Array.isArray(discoveredTaskLists)).toBe(true); expect(duration).toBeLessThan(10000); // Should complete within 10 seconds // Log discovered task lists discoveredTaskLists.forEach((taskList, index) => { console.log(` ${index + 1}. ${taskList.fileName} (${taskList.projectName})`); console.log(` Path: ${taskList.filePath}`); console.log(` Size: ${taskList.fileSize} bytes`); console.log(` Created: ${taskList.createdAt.toISOString()}`); console.log(` Accessible: ${taskList.isAccessible}`); }); // Verify test task list is found const testTaskList = discoveredTaskLists.find(tl => tl.projectName.includes('Live Test')); if (testTaskList) { console.log(`✅ Test task list found: ${testTaskList.fileName}`); expect(testTaskList.isAccessible).toBe(true); expect(testTaskList.fileSize).toBeGreaterThan(0); } else { console.log(`⚠️ Test task list not found, but discovery is working`); } // Verify task list structure discoveredTaskLists.forEach(taskList => { expect(taskList.filePath).toBeDefined(); expect(taskList.fileName).toBeDefined(); expect(taskList.projectName).toBeDefined(); expect(taskList.createdAt).toBeInstanceOf(Date); expect(taskList.fileSize).toBeGreaterThanOrEqual(0); expect(typeof taskList.isAccessible).toBe('boolean'); }); console.log(`🎯 Task list discovery test completed successfully!`); }, LIVE_TEST_TIMEOUT); it('should detect most recent task list for a specific project', async () => { console.log('🔍 Testing task list detection for specific project...'); const startTime = Date.now(); const detectedTaskList = await taskListIntegration.detectExistingTaskList('Live Test Project'); const duration = Date.now() - startTime; console.log(`✅ Task list detection completed in ${duration}ms`); if (detectedTaskList) { console.log(`📋 Detected task list: ${detectedTaskList.fileName}`); console.log(` Project: ${detectedTaskList.projectName}`); console.log(` Path: ${detectedTaskList.filePath}`); console.log(` Size: ${detectedTaskList.fileSize} bytes`); expect(detectedTaskList.projectName).toContain('Live Test'); expect(detectedTaskList.isAccessible).toBe(true); } else { console.log(`ℹ️ No task list detected for 'Live Test Project' - this is expected if no matching files exist`); } expect(duration).toBeLessThan(5000); // Should complete within 5 seconds console.log(`🎯 Task list detection test completed!`); }, LIVE_TEST_TIMEOUT); }); describe('Cross-Artifact Discovery Tests', () => { it('should discover both PRDs and task lists and correlate by project', async () => { console.log('🔍 Testing cross-artifact discovery correlation...'); const startTime = Date.now(); const [discoveredPRDs, discoveredTaskLists] = await Promise.all([ prdIntegration.findPRDFiles(), taskListIntegration.findTaskListFiles() ]); const duration = Date.now() - startTime; console.log(`✅ Cross-artifact discovery completed in ${duration}ms`); console.log(`📊 Found ${discoveredPRDs.length} PRDs and ${discoveredTaskLists.length} task lists`); // Find projects that have both PRDs and task lists const prdProjects = new Set(discoveredPRDs.map(prd => prd.projectName.toLowerCase())); const taskListProjects = new Set(discoveredTaskLists.map(tl => tl.projectName.toLowerCase())); const commonProjects = [...prdProjects].filter(project => taskListProjects.has(project)); console.log(`🔗 Projects with both PRDs and task lists: ${commonProjects.length}`); commonProjects.forEach(project => { console.log(` - ${project}`); }); // Verify discovery performance expect(duration).toBeLessThan(15000); // Should complete within 15 seconds expect(discoveredPRDs.length + discoveredTaskLists.length).toBeGreaterThanOrEqual(0); // Log summary console.log(`📈 Discovery Summary:`); console.log(` Total PRDs: ${discoveredPRDs.length}`); console.log(` Total Task Lists: ${discoveredTaskLists.length}`); console.log(` Common Projects: ${commonProjects.length}`); console.log(` Discovery Time: ${duration}ms`); console.log(`🎯 Cross-artifact discovery test completed successfully!`); }, LIVE_TEST_TIMEOUT); it('should validate VibeCoderOutput directory structure', async () => { console.log('🔍 Validating VibeCoderOutput directory structure...'); const baseOutputDir = process.env.VIBE_CODER_OUTPUT_DIR || path.join(process.cwd(), 'VibeCoderOutput'); // Check main directory const mainDirExists = await checkDirectoryExists(baseOutputDir); console.log(`📁 VibeCoderOutput directory: ${mainDirExists ? '✅ EXISTS' : '❌ MISSING'}`); expect(mainDirExists).toBe(true); // Check PRD directory const prdDir = path.join(baseOutputDir, 'prd-generator'); const prdDirExists = await checkDirectoryExists(prdDir); console.log(`📁 prd-generator directory: ${prdDirExists ? '✅ EXISTS' : '❌ MISSING'}`); // Check task list directory const taskListDir = path.join(baseOutputDir, 'generated_task_lists'); const taskListDirExists = await checkDirectoryExists(taskListDir); console.log(`📁 generated_task_lists directory: ${taskListDirExists ? '✅ EXISTS' : '❌ MISSING'}`); // Log directory structure console.log(`📊 Directory Structure:`); console.log(` Base: ${baseOutputDir}`); console.log(` PRD: ${prdDir} (${prdDirExists ? 'exists' : 'missing'})`); console.log(` Tasks: ${taskListDir} (${taskListDirExists ? 'exists' : 'missing'})`); console.log(`🎯 Directory structure validation completed!`); }, LIVE_TEST_TIMEOUT); }); // Helper function to create test artifacts async function createTestArtifacts(): Promise<void> { try { const prdDir = path.join(testOutputDir, 'prd-generator'); const taskListDir = path.join(testOutputDir, 'generated_task_lists'); // Ensure directories exist await fs.mkdir(prdDir, { recursive: true }); await fs.mkdir(taskListDir, { recursive: true }); // Create test PRD const testPRDContent = `# Live Test Project - PRD\n\n## Overview\nTest PRD for live discovery testing\n\n## Features\n- Feature 1\n- Feature 2\n`; const prdPath = path.join(prdDir, 'live-test-project-prd.md'); await fs.writeFile(prdPath, testPRDContent); createdTestFiles.push(prdPath); // Create test task list const testTaskListContent = `# Live Test Project - Tasks\n\n## Overview\nTest task list for live discovery testing\n\n## Tasks\n- Task 1\n- Task 2\n`; const taskListPath = path.join(taskListDir, 'live-test-project-tasks.md'); await fs.writeFile(taskListPath, testTaskListContent); createdTestFiles.push(taskListPath); console.log(`📁 Created test artifacts: ${createdTestFiles.length} files`); } catch (error) { console.warn(`⚠️ Failed to create test artifacts:`, error); } } // Helper function to cleanup test artifacts async function cleanupTestArtifacts(): Promise<void> { for (const filePath of createdTestFiles) { try { await fs.unlink(filePath); } catch (error) { console.warn(`⚠️ Failed to cleanup ${filePath}:`, error); } } createdTestFiles = []; console.log(`🧹 Cleaned up test artifacts`); } // Helper function to check if directory exists async function checkDirectoryExists(dirPath: string): Promise<boolean> { try { const stats = await fs.stat(dirPath); return stats.isDirectory(); } catch { return false; } } });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/freshtechbro/vibe-coder-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server