UNPKG

create-ai-chat-context-experimental

Version:

Phase 2: TypeScript rewrite - AI Chat Context & Memory System with conversation extraction and AICF format support (powered by aicf-core v2.1.0).

134 lines 4.63 kB
/** * This file is part of create-ai-chat-context-experimental. * Licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). * See LICENSE file for details. */ /** * Package Root Utility * * Finds the package root directory in both development and production environments. * Works with both ESM and CJS builds. */ import { dirname, join } from 'path'; import { fileURLToPath } from 'url'; import { existsSync, readFileSync } from 'fs'; /** * Get the current file's directory * This function uses a trick: new Error().stack to get the file path * Works in both ESM and CJS without using import.meta or __dirname */ function getCurrentFileDir() { try { // Create an error to get the stack trace const error = new Error(); const stack = error.stack; if (!stack) return undefined; // Parse the stack to find this file's path // Stack format varies, but typically includes file:// URLs or absolute paths const lines = stack.split('\n'); for (const line of lines) { // Look for file:// URLs (ESM) const fileMatch = line.match(/file:\/\/([^:)]+)/); if (fileMatch && fileMatch[1]) { const filePath = fileURLToPath(`file://${fileMatch[1]}`); if (filePath && filePath.includes('PackageRoot')) { return dirname(filePath); } } // Look for absolute paths (CJS) const pathMatch = line.match(/\(([^:)]+):\d+:\d+\)/); if (pathMatch && pathMatch[1]) { const filePath = pathMatch[1]; if (filePath && filePath.includes('PackageRoot')) { return dirname(filePath); } } } return undefined; } catch { return undefined; } } /** * Get the package root directory * * Strategy: Find this file's location, then search up for package.json * This works in both ESM and CJS, both development and production * * @returns Absolute path to package root directory */ export function getPackageRoot() { // Strategy 1: Use stack trace to find this file's location const currentDir = getCurrentFileDir(); if (currentDir) { // Search up from this file's location to find package.json let searchDir = currentDir; for (let i = 0; i < 10; i++) { const packageJsonPath = join(searchDir, 'package.json'); if (existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); if (packageJson.name === 'create-ai-chat-context-experimental') { return searchDir; } } catch { // Invalid package.json, continue searching } } // Go up one level const parentDir = dirname(searchDir); if (parentDir === searchDir) { break; // Hit root } searchDir = parentDir; } } // Strategy 2: Search up from cwd (fallback for development) let searchDir = process.cwd(); for (let i = 0; i < 10; i++) { const packageJsonPath = join(searchDir, 'package.json'); if (existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8')); if (packageJson.name === 'create-ai-chat-context-experimental') { return searchDir; } } catch { // Invalid package.json, continue searching } } // Go up one level const parentDir = dirname(searchDir); if (parentDir === searchDir) { break; // Hit root } searchDir = parentDir; } // Last resort: assume we're in the package directory return process.cwd(); } /** * Get the templates directory * * Templates are at: dist/templates/ relative to package root * * @returns Absolute path to templates directory */ export function getTemplatesDir() { const packageRoot = getPackageRoot(); return join(packageRoot, 'dist', 'templates'); } /** * Verify that the templates directory exists * * @returns true if templates directory exists, false otherwise */ export function templatesExist() { const templatesDir = getTemplatesDir(); return existsSync(templatesDir); } //# sourceMappingURL=PackageRoot.js.map