Skip to main content
Glama

WebSee MCP Server

by 1AQuantum
build-artifact-manager.js7.04 kB
/** * Build Analyzer Agent * Parses and analyzes webpack/vite build artifacts for source intelligence * Part of the WebSee Source Intelligence Layer */ import { readFile } from 'fs/promises'; import { existsSync } from 'fs'; import { join, resolve } from 'path'; export class BuildArtifactManager { manifest = null; projectRoot; moduleMap = new Map(); constructor(projectRoot = process.cwd()) { this.projectRoot = resolve(projectRoot); } /** * Load build artifacts from webpack stats or vite manifest */ async loadBuildArtifacts() { // Try webpack stats.json first const webpackStats = join(this.projectRoot, 'dist', 'stats.json'); if (existsSync(webpackStats)) { await this.loadWebpackStats(webpackStats); return; } // Try vite manifest.json const viteManifest = join(this.projectRoot, 'dist', '.vite', 'manifest.json'); if (existsSync(viteManifest)) { await this.loadViteManifest(viteManifest); return; } // Try common alternate locations const alternateLocations = [ 'build/stats.json', '.next/build-manifest.json', 'public/build/manifest.json', ]; for (const location of alternateLocations) { const path = join(this.projectRoot, location); if (existsSync(path)) { const content = await readFile(path, 'utf-8'); const data = JSON.parse(content); this.processGenericManifest(data); return; } } throw new Error('No build artifacts found. Please run build first.'); } /** * Load and parse webpack stats.json */ async loadWebpackStats(statsPath) { const content = await readFile(statsPath, 'utf-8'); const stats = JSON.parse(content); this.manifest = { type: 'webpack', version: stats.version || 'unknown', chunks: this.parseWebpackChunks(stats.chunks || []), modules: this.parseWebpackModules(stats.modules || []), assets: stats.assets || [], entrypoints: stats.entrypoints || {}, }; this.buildModuleMap(); } /** * Load and parse vite manifest.json */ async loadViteManifest(manifestPath) { const content = await readFile(manifestPath, 'utf-8'); const manifest = JSON.parse(content); const modules = []; const chunks = []; // Parse vite manifest format Object.entries(manifest).forEach(([file, info]) => { if (info.isEntry) { chunks.push({ id: file, files: [info.file, ...(info.css || [])], size: 0, // Vite doesn't provide size in manifest modules: [], entry: true, initial: true, }); } modules.push({ id: file, name: file, size: 0, chunks: [file], source: info.src, }); }); this.manifest = { type: 'vite', version: 'unknown', chunks, modules, assets: Object.values(manifest).map((info) => ({ name: info.file, size: 0, chunks: [], })), entrypoints: {}, }; this.buildModuleMap(); } /** * Parse webpack chunks */ parseWebpackChunks(chunks) { return chunks.map(chunk => ({ id: chunk.id, files: chunk.files || [], size: chunk.size || 0, modules: chunk.modules || [], entry: chunk.entry, initial: chunk.initial, })); } /** * Parse webpack modules */ parseWebpackModules(modules) { return modules.map(module => ({ id: module.id, name: module.name || module.identifier || String(module.id), size: module.size || 0, chunks: module.chunks || [], source: module.source, originalSource: module.originalSource, })); } /** * Process generic manifest format */ processGenericManifest(data) { this.manifest = { type: 'unknown', version: data.version || 'unknown', chunks: data.chunks || [], modules: data.modules || [], assets: data.assets || [], entrypoints: data.entrypoints || {}, }; this.buildModuleMap(); } /** * Build module lookup map */ buildModuleMap() { if (!this.manifest) return; this.moduleMap.clear(); this.manifest.modules.forEach(module => { this.moduleMap.set(String(module.name), module); if (module.id !== module.name) { this.moduleMap.set(String(module.id), module); } }); } /** * Find module by file path */ findModule(filePath) { // Try exact match let module = this.moduleMap.get(filePath); if (module) return module; // Try relative path const relativePath = filePath.replace(this.projectRoot, '').replace(/^\//, ''); module = this.moduleMap.get(relativePath); if (module) return module; // Try partial match for (const [key, mod] of this.moduleMap.entries()) { if (key.includes(filePath) || filePath.includes(key)) { return mod; } } return undefined; } /** * Get chunk containing a module */ getChunkForModule(moduleId) { if (!this.manifest) return undefined; return this.manifest.chunks.find(chunk => chunk.modules.some(m => m.id === moduleId || m.name === moduleId)); } /** * Get build summary */ getSummary() { if (!this.manifest) { throw new Error('No manifest loaded'); } const totalSize = this.manifest.modules.reduce((sum, m) => sum + m.size, 0); const largestModules = [...this.manifest.modules].sort((a, b) => b.size - a.size).slice(0, 10); return { type: this.manifest.type, totalModules: this.manifest.modules.length, totalChunks: this.manifest.chunks.length, totalSize, largestModules, }; } /** * Get entrypoints */ getEntrypoints() { return this.manifest?.entrypoints || {}; } /** * Check if manifest is loaded */ isLoaded() { return this.manifest !== null; } /** * Clear loaded manifest */ clear() { this.manifest = null; this.moduleMap.clear(); } } //# sourceMappingURL=build-artifact-manager.js.map

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/1AQuantum/websee-mcp-server'

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