Skip to main content
Glama
fileSelector.ts3.37 kB
import { readdirSync, statSync, mkdirSync, existsSync } from 'fs'; import { join, relative, basename, dirname } from 'path'; export function slugifyForFilename(text: string): string { return text .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/(^-|-$)/g, '') .slice(0, 48) || 'generated'; } export function findCandidateFiles(promptText: string, maxResults = 10): string[] { const cwd = process.cwd(); const stopwords = new Set(['the', 'a', 'an', 'and', 'or', 'to', 'for', 'with', 'by', 'on', 'in', 'of', 'from', 'left', 'right', 'nav', 'navbar', 'menu']); const words = (promptText || '') .toLowerCase() .replace(/[^a-z0-9\s]/g, ' ') .split(/\s+/) .filter(w => w.length > 2 && !stopwords.has(w)); const candidates: { path: string; score: number }[] = []; function walk(dir: string) { let list: string[] = []; try { list = readdirSync(dir); } catch { return; } for (const name of list) { const full = join(dir, name); try { const s = statSync(full); if (s.isDirectory()) { if (name === 'node_modules' || name === '.git' || name === 'dist' || name === 'build') continue; walk(full); } else if (s.isFile()) { const rel = relative(cwd, full).replace(/\\/g, '/'); const lname = rel.toLowerCase(); let score = 0; for (const w of words) { if (lname.includes(w)) score += 2; const base = basename(lname); if (base.includes(w)) score += 3; } if (lname.endsWith('.svelte') || lname.endsWith('.tsx') || lname.endsWith('.jsx') || lname.endsWith('.ts') || lname.endsWith('.js') || lname.endsWith('.html')) { score += 1; } if (score > 0) candidates.push({ path: rel, score }); } } catch { /* ignore */ } } } walk(cwd); candidates.sort((a, b) => b.score - a.score); return candidates.slice(0, maxResults).map(c => c.path); } export function chooseOutputForCreate(promptText: string, language: string | undefined): string { const candidates = findCandidateFiles(promptText, 8); let chosen: string | null = null; for (const c of candidates) { if (!existsSync(c)) { chosen = c; break; } } if (!chosen && candidates.length > 0) { const first = candidates[0]; const extMatch = first.match(/\.([0-9a-z]+)$/i); const ext = extMatch ? extMatch[1] : (language === 'typescript' ? 'ts' : 'js'); const slug = slugifyForFilename((promptText || '').split('\n')[0] || 'generated'); chosen = `generated/${slug}.${ext}`; } if (!chosen) { const ext = language === 'typescript' ? 'ts' : 'js'; const slug = slugifyForFilename((promptText || '').split('\n')[0] || 'generated'); chosen = `generated/${slug}.${ext}`; } // Ensure parent exists try { const parent = dirname(chosen); if (parent && parent !== '.' && !existsSync(parent)) mkdirSync(parent, { recursive: true }); } catch { /* ignore */ } return chosen; }

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/babasida246/ai-mcp-gateway'

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