Skip to main content
Glama

VyOS MCP Server

by danielbodnar
watch-docs.ts•4.33 kB
#!/usr/bin/env bun import { spawn } from 'node:child_process'; import { watch } from 'node:fs'; import { debounce } from 'lodash-es'; /** * @fileoverview Watch mode for documentation development. * Automatically rebuilds TypeDoc documentation when source files change. * * @author VyOS MCP Server * @version 1.0.0 * @since 2025-01-13 */ const SRC_DIR = './src'; const DOCS_DIR = './docs'; let isBuilding = false; /** * Build documentation */ async function buildDocs(): Promise<void> { if (isBuilding) { console.log('ā³ Build already in progress, skipping...'); return; } isBuilding = true; console.log('šŸ“š Rebuilding documentation...'); const startTime = Date.now(); try { const result = await new Promise<void>((resolve, reject) => { const child = spawn( 'bun', [ 'run', 'docs', ], { stdio: 'pipe', shell: true, }, ); let output = ''; let errorOutput = ''; child.stdout?.on('data', (data) => { output += data.toString(); }); child.stderr?.on('data', (data) => { errorOutput += data.toString(); }); child.on('close', (code) => { if (code === 0) { resolve(); } else { reject( new Error( `Documentation build failed with code ${code}\n${errorOutput}`, ), ); } }); child.on('error', reject); }); const duration = Date.now() - startTime; console.log(`āœ… Documentation rebuilt in ${duration}ms`); } catch (error) { console.error('āŒ Documentation build failed:', error.message); } finally { isBuilding = false; } } /** * Debounced build function to avoid excessive rebuilds */ const debouncedBuild = debounce(buildDocs, 500); /** * Start watching for file changes */ function startWatching(): void { console.log('šŸ‘€ Watching for changes in:', SRC_DIR); console.log('šŸ“ Documentation output:', DOCS_DIR); console.log('šŸ”„ Press Ctrl+C to stop\n'); // Initial build buildDocs(); // Watch for changes const watcher = watch( SRC_DIR, { recursive: true, }, (eventType, filename) => { if (!filename) return; // Only watch TypeScript files if (!filename.endsWith('.ts')) return; console.log(`šŸ“ ${eventType}: ${filename}`); debouncedBuild(); }, ); // Graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ‘‹ Stopping documentation watcher...'); watcher.close(); process.exit(0); }); process.on('SIGTERM', () => { console.log('\nšŸ‘‹ Stopping documentation watcher...'); watcher.close(); process.exit(0); }); } // Check if lodash-es is available, if not use a simple debounce if (!Bun.which('lodash-es')) { // Simple debounce implementation function simpleDebounce<T extends (...args: any[]) => any>( func: T, wait: number, ): (...args: Parameters<T>) => void { let timeout: Timer | null = null; return (...args: Parameters<T>) => { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { func(...args); }, wait); }; } const debouncedBuildSimple = simpleDebounce(buildDocs, 500); // Replace the lodash debounce with our simple implementation console.log('šŸ“¦ Using built-in debounce (lodash-es not available)'); console.log('šŸ‘€ Watching for changes in:', SRC_DIR); console.log('šŸ“ Documentation output:', DOCS_DIR); console.log('šŸ”„ Press Ctrl+C to stop\n'); // Initial build buildDocs(); // Watch for changes const watcher = watch( SRC_DIR, { recursive: true, }, (eventType, filename) => { if (!filename) return; // Only watch TypeScript files if (!filename.endsWith('.ts')) return; console.log(`šŸ“ ${eventType}: ${filename}`); debouncedBuildSimple(); }, ); // Graceful shutdown process.on('SIGINT', () => { console.log('\nšŸ‘‹ Stopping documentation watcher...'); watcher.close(); process.exit(0); }); process.on('SIGTERM', () => { console.log('\nšŸ‘‹ Stopping documentation watcher...'); watcher.close(); process.exit(0); }); } else { startWatching(); }

Latest Blog Posts

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/danielbodnar/vyos-mcp'

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