Skip to main content
Glama

Context Pods

by conorluddy
path-resolution.tsโ€ข4.97 kB
/** * Consolidated path resolution utilities for Context-Pods * * Provides consistent template path resolution across CLI and server packages */ import { existsSync, readFileSync } from 'fs'; import { createRequire } from 'module'; import { homedir } from 'os'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; /** * Get the directory containing this module (works in both CJS and ESM) */ function getModuleDir(): string { // Handle both CommonJS and ES modules if (typeof __dirname !== 'undefined') { return __dirname; } // ES module fallback const __filename = fileURLToPath(import.meta.url); return dirname(__filename); } /** * Find the Context-Pods project root by looking for package.json with the correct name */ function findProjectRoot(startDir: string): string { let current = startDir; while (current !== dirname(current)) { const packageJsonPath = join(current, 'package.json'); if (existsSync(packageJsonPath)) { try { const packageContent = readFileSync(packageJsonPath, 'utf8'); const pkg = JSON.parse(packageContent) as { name?: string; workspaces?: unknown }; // Look for the Context-Pods root package if (pkg.name === 'context-pods' && pkg.workspaces) { return current; } } catch { // Continue searching if package.json is malformed } } current = dirname(current); } throw new Error( 'Could not find Context-Pods project root (package.json with name "context-pods")', ); } /** * Template path resolution options */ export interface TemplatePathOptions { /** Environment variable to check for override */ envVar?: string; /** Additional paths to try */ additionalPaths?: string[]; /** Skip bundled template check */ skipBundled?: boolean; /** Skip user home directory check */ skipUserHome?: boolean; } /** * Get template paths in priority order following the consolidated strategy: * 1. Environment variable (highest priority) * 2. Bundled templates in npm package * 3. User home directory (~/.context-pods/templates) * 4. Development/workspace templates * 5. Additional paths provided */ export function getTemplatePaths(options: TemplatePathOptions = {}): string[] { const { envVar = 'CONTEXT_PODS_TEMPLATES_PATH', additionalPaths = [], skipBundled = false, skipUserHome = false, } = options; const paths: string[] = []; // 1. Environment variable (highest priority) if (process.env[envVar]) { paths.push(process.env[envVar]); } if (!skipBundled) { // 2. Bundled templates (npm package distribution) try { // Create require function for ES modules const require = createRequire(import.meta.url); // Try to resolve @context-pods/templates package location const templatesModulePath = require.resolve('@context-pods/templates/package.json'); const templatesPackageDir = dirname(templatesModulePath); const templatesPath = join(templatesPackageDir, 'templates'); paths.push(templatesPath); } catch { // Fallback to old method if templates package not available const moduleDir = getModuleDir(); const bundledPath = join(moduleDir, '../templates'); paths.push(bundledPath); } } if (!skipUserHome) { // 3. User home directory const userTemplatesPath = join(homedir(), '.context-pods', 'templates'); paths.push(userTemplatesPath); } // 4. Development/workspace templates try { const moduleDir = getModuleDir(); const projectRoot = findProjectRoot(moduleDir); const workspaceTemplatesPath = join(projectRoot, 'templates'); paths.push(workspaceTemplatesPath); } catch { // Project root not found, skip workspace templates } // 5. Additional paths paths.push(...additionalPaths); return paths; } /** * Get the first existing template path from the priority list */ export function getFirstExistingTemplatePath(options: TemplatePathOptions = {}): string | null { const paths = getTemplatePaths(options); for (const path of paths) { if (existsSync(path)) { return path; } } return null; } /** * Get all existing template paths from the priority list */ export function getAllExistingTemplatePaths(options: TemplatePathOptions = {}): string[] { const paths = getTemplatePaths(options); return paths.filter((path) => existsSync(path)); } /** * Get template path with fallback to default if none exist * This is the main function that packages should use */ export function resolveTemplatePath(options: TemplatePathOptions = {}): string { const existingPath = getFirstExistingTemplatePath(options); if (existingPath) { return existingPath; } // Return the most likely path for npm package distribution const paths = getTemplatePaths(options); return paths[1] || paths[0] || './templates'; // Prefer bundled path, then env var, then fallback }

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/conorluddy/ContextPods'

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