UNPKG

@vibeship/devtools

Version:

Comprehensive markdown-based project management system with AI capabilities for Next.js applications

1 lines 59.9 kB
{"version":3,"sources":["../src/config/defaults.ts","../src/config/schema.ts","../src/config/loader.ts","../src/config/merger.ts","../src/config/migration.ts","../src/config/index.ts"],"sourcesContent":["import { VibeshipConfig } from './types';\n\n/**\n * Default configuration for Vibeship DevTools\n */\nexport const defaultConfig: VibeshipConfig = {\n // File scanning\n scanPaths: ['./docs', './README.md'],\n include: ['**/*.md', '**/*.mdx'],\n exclude: ['**/node_modules/**', '**/.next/**', '**/.git/**', '**/dist/**', '**/build/**'],\n\n // Features\n features: {\n tasks: true,\n ai: false,\n realtime: true,\n commandPalette: true,\n fileEditing: false,\n markdownPreview: true,\n },\n\n // Security\n security: {\n authentication: false,\n rateLimit: true,\n cors: true,\n blockedPatterns: [\n '**/.env*',\n '**/*.key',\n '**/*.pem',\n '**/*.p12',\n '**/*.pfx',\n '**/secrets/**',\n '**/credentials/**',\n ],\n },\n\n // Task patterns\n taskPatterns: {\n todo: true,\n fixme: true,\n hack: true,\n note: true,\n },\n\n // UI configuration\n ui: {\n theme: 'system',\n position: 'bottom-right',\n defaultSize: {\n width: '400px',\n height: '600px',\n },\n hotkey: 'cmd+shift+k',\n showInProduction: false,\n },\n\n // API configuration\n api: {\n basePath: '/api/vibeship',\n version: 'v1',\n documentation: true,\n timeout: 30000, // 30 seconds\n },\n\n // Cache configuration\n cache: {\n enabled: true,\n directory: '.vibeship/cache',\n maxSize: 52428800, // 50MB\n ttl: 3600000, // 1 hour\n strategy: 'lru',\n },\n};\n\n/**\n * Development-specific configuration overrides\n */\nexport const developmentConfig: Partial<VibeshipConfig> = {\n features: {\n ...defaultConfig.features,\n fileEditing: true,\n },\n security: {\n ...defaultConfig.security,\n authentication: false,\n rateLimitConfig: {\n windowMs: 60000,\n maxRequests: 1000, // More lenient in development\n },\n },\n ui: {\n ...defaultConfig.ui,\n showInProduction: true, // Allow in dev mode\n },\n cache: {\n ...defaultConfig.cache,\n ttl: 300000, // 5 minutes in dev\n },\n};\n\n/**\n * Production-specific configuration overrides\n */\nexport const productionConfig: Partial<VibeshipConfig> = {\n features: {\n ...defaultConfig.features,\n fileEditing: false, // Never allow file editing in production\n },\n security: {\n ...defaultConfig.security,\n authentication: true,\n rateLimit: true,\n rateLimitConfig: {\n windowMs: 60000,\n maxRequests: 100,\n tiers: {\n anonymous: { windowMs: 60000, maxRequests: 20 },\n authenticated: { windowMs: 60000, maxRequests: 100 },\n premium: { windowMs: 60000, maxRequests: 1000 },\n },\n },\n corsConfig: {\n allowedOrigins: (origin: string) => {\n // In production, validate against allowed domains\n const allowedDomains = process.env.ALLOWED_DOMAINS?.split(',') || [];\n return allowedDomains.some(domain => origin.includes(domain));\n },\n credentials: true,\n maxAge: 86400,\n },\n },\n ui: {\n ...defaultConfig.ui,\n showInProduction: false,\n },\n cache: {\n ...defaultConfig.cache,\n maxSize: 104857600, // 100MB in production\n ttl: 7200000, // 2 hours in production\n },\n};\n\n/**\n * Test-specific configuration overrides\n */\nexport const testConfig: Partial<VibeshipConfig> = {\n scanPaths: ['./test-docs'],\n security: {\n ...defaultConfig.security,\n authentication: false,\n rateLimit: false,\n },\n cache: {\n ...defaultConfig.cache,\n enabled: false, // Disable cache in tests\n },\n ui: {\n ...defaultConfig.ui,\n showInProduction: true,\n },\n};\n\n/**\n * Get environment-specific defaults\n */\nexport function getEnvironmentDefaults(): Partial<VibeshipConfig> {\n const env = process.env.NODE_ENV || 'development';\n \n switch (env) {\n case 'production':\n return productionConfig;\n case 'test':\n return testConfig;\n case 'development':\n default:\n return developmentConfig;\n }\n}","import { z } from 'zod';\n\n/**\n * Zod schemas for configuration validation\n */\n\n// Custom task pattern schema\nconst CustomTaskPatternSchema = z.object({\n name: z.string().min(1, 'Pattern name is required'),\n pattern: z.union([z.string(), z.instanceof(RegExp)]),\n priority: z.enum(['low', 'medium', 'high']).optional(),\n color: z.string().optional(),\n});\n\n// Task patterns schema\nconst TaskPatternsSchema = z.object({\n todo: z.boolean(),\n fixme: z.boolean(),\n hack: z.boolean(),\n note: z.boolean(),\n warning: z.boolean().optional(),\n optimize: z.boolean().optional(),\n custom: z.array(CustomTaskPatternSchema).optional(),\n});\n\n// Feature flags schema\nconst FeatureFlagsSchema = z.object({\n tasks: z.boolean(),\n ai: z.boolean(),\n realtime: z.boolean(),\n commandPalette: z.boolean(),\n fileEditing: z.boolean(),\n markdownPreview: z.boolean(),\n});\n\n// Auth provider schema\nconst AuthProviderSchema = z.object({\n id: z.string(),\n type: z.enum(['oauth', 'oidc', 'saml']),\n clientId: z.string(),\n clientSecret: z.string().optional(),\n issuer: z.string().optional(),\n});\n\n// Auth configuration schema\nconst AuthConfigSchema = z.object({\n jwtSecret: z.string().optional(),\n apiKey: z.string().optional(),\n session: z.object({\n secret: z.string(),\n maxAge: z.number().optional(),\n }).optional(),\n providers: z.array(AuthProviderSchema).optional(),\n});\n\n// Rate limit configuration schema\nconst RateLimitConfigSchema = z.object({\n windowMs: z.number().positive(),\n maxRequests: z.number().positive(),\n skipSuccessfulRequests: z.boolean().optional(),\n skipFailedRequests: z.boolean().optional(),\n tiers: z.object({\n anonymous: z.object({\n windowMs: z.number().positive(),\n maxRequests: z.number().positive(),\n }).optional(),\n authenticated: z.object({\n windowMs: z.number().positive(),\n maxRequests: z.number().positive(),\n }).optional(),\n premium: z.object({\n windowMs: z.number().positive(),\n maxRequests: z.number().positive(),\n }).optional(),\n }).optional(),\n});\n\n// CORS configuration schema\nconst CORSConfigSchema = z.object({\n allowedOrigins: z.union([\n z.array(z.string()),\n z.string(),\n z.function().args(z.string()).returns(z.boolean()),\n ]),\n allowedMethods: z.array(z.string()).optional(),\n allowedHeaders: z.array(z.string()).optional(),\n exposedHeaders: z.array(z.string()).optional(),\n credentials: z.boolean().optional(),\n maxAge: z.number().optional(),\n});\n\n// Security configuration schema\nconst SecurityConfigSchema = z.object({\n authentication: z.boolean(),\n auth: AuthConfigSchema.optional(),\n rateLimit: z.boolean(),\n rateLimitConfig: RateLimitConfigSchema.optional(),\n cors: z.boolean(),\n corsConfig: CORSConfigSchema.optional(),\n allowedPaths: z.array(z.string()).optional(),\n blockedPatterns: z.array(z.string()).optional(),\n});\n\n// UI configuration schema\nconst UIConfigSchema = z.object({\n theme: z.enum(['light', 'dark', 'system']).optional(),\n position: z.enum(['top-left', 'top-right', 'bottom-left', 'bottom-right']).optional(),\n defaultSize: z.object({\n width: z.union([z.number(), z.string()]).optional(),\n height: z.union([z.number(), z.string()]).optional(),\n }).optional(),\n hotkey: z.string().optional(),\n showInProduction: z.boolean().optional(),\n customCSS: z.string().optional(),\n});\n\n// API configuration schema\nconst APIConfigSchema = z.object({\n basePath: z.string(),\n version: z.string().optional(),\n documentation: z.boolean().optional(),\n middleware: z.array(z.string()).optional(),\n timeout: z.number().positive().optional(),\n});\n\n// Cache configuration schema\nconst CacheConfigSchema = z.object({\n enabled: z.boolean(),\n directory: z.string(),\n maxSize: z.number().positive(),\n ttl: z.number().positive(),\n strategy: z.enum(['lru', 'fifo', 'lfu']),\n});\n\n// Experimental configuration schema\nconst ExperimentalConfigSchema = z.object({\n markdownExtensions: z.boolean().optional(),\n customTaskProviders: z.boolean().optional(),\n plugins: z.boolean().optional(),\n pluginConfigs: z.record(z.any()).optional(),\n});\n\n// Main configuration schema\nexport const VibeshipConfigSchema = z.object({\n scanPaths: z.array(z.string()).min(1, 'At least one scan path is required'),\n include: z.array(z.string()).min(1, 'At least one include pattern is required'),\n exclude: z.array(z.string()),\n features: FeatureFlagsSchema,\n security: SecurityConfigSchema,\n taskPatterns: TaskPatternsSchema,\n ui: UIConfigSchema,\n api: APIConfigSchema,\n cache: CacheConfigSchema,\n experimental: ExperimentalConfigSchema.optional(),\n});\n\n// Partial configuration schema (for user input)\nexport const PartialVibeshipConfigSchema = VibeshipConfigSchema.deepPartial();\n\n/**\n * Validate configuration with helpful error messages\n */\nexport function validateConfig(config: unknown): {\n success: boolean;\n data?: z.infer<typeof VibeshipConfigSchema>;\n errors?: string[];\n} {\n try {\n const result = VibeshipConfigSchema.parse(config);\n return { success: true, data: result };\n } catch (error) {\n if (error instanceof z.ZodError) {\n const errors = error.errors.map(err => {\n const path = err.path.join('.');\n const message = err.message;\n return `${path}: ${message}`;\n });\n return { success: false, errors };\n }\n return { \n success: false, \n errors: ['Invalid configuration format'] \n };\n }\n}\n\n/**\n * Validate partial configuration\n */\nexport function validatePartialConfig(config: unknown): {\n success: boolean;\n data?: z.infer<typeof PartialVibeshipConfigSchema>;\n errors?: string[];\n} {\n try {\n const result = PartialVibeshipConfigSchema.parse(config);\n return { success: true, data: result };\n } catch (error) {\n if (error instanceof z.ZodError) {\n const errors = error.errors.map(err => {\n const path = err.path.join('.');\n const message = err.message;\n return `${path}: ${message}`;\n });\n return { success: false, errors };\n }\n return { \n success: false, \n errors: ['Invalid configuration format'] \n };\n }\n}\n\n/**\n * Type guard for valid configuration\n */\nexport function isValidConfig(config: unknown): config is z.infer<typeof VibeshipConfigSchema> {\n return VibeshipConfigSchema.safeParse(config).success;\n}\n\n/**\n * Get configuration type from schema\n */\nexport type VibeshipConfigFromSchema = z.infer<typeof VibeshipConfigSchema>;","import { existsSync, readFileSync } from 'fs';\nimport { join, resolve, extname } from 'path';\nimport { pathToFileURL } from 'url';\nimport { VibeshipConfig, PartialVibeshipConfig } from './types';\nimport { defaultConfig, getEnvironmentDefaults } from './defaults';\nimport { mergeConfigurations, applyEnvironmentOverrides, freezeConfig } from './merger';\nimport { validateConfig, validatePartialConfig } from './schema';\n\n/**\n * Configuration file names to search for\n */\nconst CONFIG_FILE_NAMES = [\n 'vibeship.config.ts',\n 'vibeship.config.js',\n 'vibeship.config.mjs',\n 'vibeship.config.cjs',\n 'vibeship.config.json',\n '.vibeshiprc.json',\n '.vibeshiprc',\n];\n\n/**\n * Configuration loader options\n */\nexport interface LoadConfigOptions {\n /**\n * Custom config path\n */\n configPath?: string;\n\n /**\n * Root directory to search for config\n */\n rootDir?: string;\n\n /**\n * Whether to apply environment overrides\n */\n applyEnvOverrides?: boolean;\n\n /**\n * Whether to validate the configuration\n */\n validate?: boolean;\n\n /**\n * Whether to freeze the configuration\n */\n freeze?: boolean;\n}\n\n/**\n * Load configuration from various sources\n */\nexport async function loadConfig(options: LoadConfigOptions = {}): Promise<VibeshipConfig> {\n const {\n configPath,\n rootDir = process.cwd(),\n applyEnvOverrides = true,\n validate = true,\n freeze = true,\n } = options;\n\n // 1. Find configuration file\n const configFile = configPath || findConfigFile(rootDir);\n \n // 2. Load user configuration\n let userConfig: PartialVibeshipConfig = {};\n if (configFile) {\n userConfig = await loadConfigFile(configFile);\n \n // Validate partial config if requested\n if (validate) {\n const validation = validatePartialConfig(userConfig);\n if (!validation.success) {\n throw new Error(\n `Invalid configuration in ${configFile}:\\n${validation.errors?.join('\\n')}`\n );\n }\n }\n }\n\n // 3. Get environment-specific defaults\n const environmentDefaults = getEnvironmentDefaults();\n\n // 4. Merge configurations\n let config = mergeConfigurations(\n defaultConfig,\n environmentDefaults,\n {}, // Environment overrides will be applied separately\n userConfig\n );\n\n // 5. Apply environment variable overrides\n if (applyEnvOverrides) {\n config = applyEnvironmentOverrides(config);\n }\n\n // 6. Validate final configuration\n if (validate) {\n const validation = validateConfig(config);\n if (!validation.success) {\n throw new Error(\n `Invalid final configuration:\\n${validation.errors?.join('\\n')}`\n );\n }\n config = validation.data!;\n }\n\n // 7. Freeze configuration to prevent mutations\n if (freeze) {\n config = freezeConfig(config);\n }\n\n return config;\n}\n\n/**\n * Find configuration file in the project\n */\nfunction findConfigFile(rootDir: string): string | undefined {\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = join(rootDir, fileName);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n\n // Check parent directories up to 3 levels\n let currentDir = rootDir;\n for (let i = 0; i < 3; i++) {\n const parentDir = resolve(currentDir, '..');\n if (parentDir === currentDir) break; // Reached root\n\n for (const fileName of CONFIG_FILE_NAMES) {\n const filePath = join(parentDir, fileName);\n if (existsSync(filePath)) {\n return filePath;\n }\n }\n currentDir = parentDir;\n }\n\n return undefined;\n}\n\n/**\n * Load configuration from a file\n */\nasync function loadConfigFile(filePath: string): Promise<PartialVibeshipConfig> {\n const ext = extname(filePath);\n\n switch (ext) {\n case '.ts':\n case '.mjs':\n return loadTypeScriptConfig(filePath);\n \n case '.js':\n case '.cjs':\n return loadJavaScriptConfig(filePath);\n \n case '.json':\n case '':\n return loadJsonConfig(filePath);\n \n default:\n throw new Error(`Unsupported configuration file format: ${ext}`);\n }\n}\n\n/**\n * Load TypeScript configuration file\n */\nasync function loadTypeScriptConfig(filePath: string): Promise<PartialVibeshipConfig> {\n // Check if we can use native TypeScript loading\n const supportsTS = await checkTypeScriptSupport();\n \n if (supportsTS) {\n // Use dynamic import with TypeScript support\n const fileUrl = pathToFileURL(filePath).href;\n const module = await import(fileUrl);\n return extractConfigFromModule(module);\n }\n\n // Fallback: Try to use ts-node or tsx if available\n try {\n // Try tsx first (faster)\n await tryRegisterLoader('tsx/cjs');\n } catch {\n try {\n // Fallback to ts-node\n await tryRegisterLoader('ts-node/register');\n } catch {\n throw new Error(\n 'TypeScript configuration files require either:\\n' +\n '1. Running with --loader tsx or --loader ts-node/esm\\n' +\n '2. Having tsx or ts-node installed\\n' +\n '3. Using a .js configuration file instead'\n );\n }\n }\n\n // Now try loading again\n const fileUrl = pathToFileURL(filePath).href;\n const module = await import(fileUrl);\n return extractConfigFromModule(module);\n}\n\n/**\n * Load JavaScript configuration file\n */\nasync function loadJavaScriptConfig(filePath: string): Promise<PartialVibeshipConfig> {\n const fileUrl = pathToFileURL(filePath).href;\n const module = await import(fileUrl);\n return extractConfigFromModule(module);\n}\n\n/**\n * Load JSON configuration file\n */\nfunction loadJsonConfig(filePath: string): PartialVibeshipConfig {\n const content = readFileSync(filePath, 'utf-8');\n try {\n return JSON.parse(content);\n } catch (error) {\n throw new Error(`Invalid JSON in configuration file ${filePath}: ${error}`);\n }\n}\n\n/**\n * Extract configuration from module\n */\nfunction extractConfigFromModule(module: any): PartialVibeshipConfig {\n // Support various export formats\n if (module.default) {\n // ES modules default export\n if (typeof module.default === 'function') {\n return module.default();\n }\n return module.default;\n }\n\n if (module.config) {\n // Named export\n if (typeof module.config === 'function') {\n return module.config();\n }\n return module.config;\n }\n\n if (typeof module === 'function') {\n // Direct function export\n return module();\n }\n\n if (typeof module === 'object' && module !== null) {\n // Direct object export\n return module;\n }\n\n throw new Error('Configuration file must export a configuration object');\n}\n\n/**\n * Check if TypeScript is natively supported\n */\nasync function checkTypeScriptSupport(): Promise<boolean> {\n // Check if running with tsx or ts-node loader\n if (process.env.TSX || process.env.TS_NODE_DEV) {\n return true;\n }\n\n // Check Node.js version for native TypeScript support\n const nodeVersion = process.version;\n const major = parseInt(nodeVersion.split('.')[0].substring(1));\n \n // Node.js 20+ with --experimental-strip-types\n if (major >= 20 && process.execArgv.includes('--experimental-strip-types')) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Try to register a TypeScript loader\n */\nasync function tryRegisterLoader(loader: string): Promise<void> {\n try {\n await import(loader);\n } catch (error) {\n throw new Error(`Failed to load ${loader}`);\n }\n}\n\n/**\n * Create a configuration helper function for use in config files\n */\nexport function defineConfig<T extends PartialVibeshipConfig = PartialVibeshipConfig>(config: T): T {\n return config;\n}\n\n/**\n * Watch configuration file for changes\n */\nexport async function watchConfig(\n options: LoadConfigOptions & { onChange: (config: VibeshipConfig) => void }\n): Promise<() => void> {\n const { onChange, ...loadOptions } = options;\n const configFile = options.configPath || findConfigFile(options.rootDir || process.cwd());\n\n if (!configFile) {\n // No config file, just return current config\n const config = await loadConfig(loadOptions);\n onChange(config);\n return () => {}; // No-op cleanup\n }\n\n // Initial load\n let currentConfig = await loadConfig(loadOptions);\n onChange(currentConfig);\n\n // Watch for changes\n const { watch } = await import('fs');\n const watcher = watch(configFile, async (eventType) => {\n if (eventType === 'change') {\n try {\n // Clear module cache for the config file\n delete require.cache[require.resolve(configFile)];\n \n // Reload configuration\n const newConfig = await loadConfig(loadOptions);\n \n // Only notify if config actually changed\n if (JSON.stringify(newConfig) !== JSON.stringify(currentConfig)) {\n currentConfig = newConfig;\n onChange(newConfig);\n }\n } catch (error) {\n console.error('Error reloading configuration:', error);\n }\n }\n });\n\n // Return cleanup function\n return () => {\n watcher.close();\n };\n}\n\n/**\n * Get configuration with caching\n */\nlet cachedConfig: VibeshipConfig | null = null;\nlet cacheKey: string | null = null;\n\nexport async function getConfig(options: LoadConfigOptions = {}): Promise<VibeshipConfig> {\n const key = JSON.stringify(options);\n \n if (cachedConfig && cacheKey === key) {\n return cachedConfig;\n }\n\n cachedConfig = await loadConfig(options);\n cacheKey = key;\n \n return cachedConfig;\n}\n\n/**\n * Clear configuration cache\n */\nexport function clearConfigCache(): void {\n cachedConfig = null;\n cacheKey = null;\n}","import { VibeshipConfig, PartialVibeshipConfig, DeepPartial } from './types';\n\n/**\n * Deep merge utility for configuration objects\n */\nexport function deepMerge<T extends object>(\n target: T,\n ...sources: DeepPartial<T>[]\n): T {\n if (!sources.length) return target;\n\n const source = sources.shift();\n if (!source) return target;\n\n const output = { ...target };\n\n Object.keys(source).forEach((key) => {\n const targetValue = output[key as keyof T];\n const sourceValue = source[key as keyof T];\n\n if (sourceValue === undefined) {\n return;\n }\n\n if (sourceValue === null) {\n output[key as keyof T] = null as any;\n return;\n }\n\n if (isObject(targetValue) && isObject(sourceValue)) {\n output[key as keyof T] = deepMerge(\n targetValue as any,\n sourceValue as any\n );\n } else if (Array.isArray(sourceValue)) {\n // For arrays, replace entirely rather than merge\n output[key as keyof T] = [...sourceValue] as any;\n } else {\n output[key as keyof T] = sourceValue as any;\n }\n });\n\n return deepMerge(output, ...sources);\n}\n\n/**\n * Check if value is a plain object\n */\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return (\n value !== null &&\n typeof value === 'object' &&\n !Array.isArray(value) &&\n !(value instanceof Date) &&\n !(value instanceof RegExp)\n );\n}\n\n/**\n * Merge configurations with proper precedence\n * Priority (highest to lowest):\n * 1. User configuration\n * 2. Environment overrides\n * 3. Environment defaults\n * 4. Base defaults\n * \n * @param defaultConfig - Base default configuration\n * @param environmentDefaults - Environment-specific defaults\n * @param environmentOverrides - Environment variable overrides\n * @param userConfig - User-provided configuration\n * @returns Merged configuration\n * \n * @example\n * ```ts\n * const config = mergeConfigurations(\n * defaultConfig,\n * developmentConfig,\n * envOverrides,\n * userConfig\n * );\n * ```\n * \n * @public\n */\nexport function mergeConfigurations(\n defaultConfig: VibeshipConfig,\n environmentDefaults: PartialVibeshipConfig,\n environmentOverrides: PartialVibeshipConfig,\n userConfig: PartialVibeshipConfig\n): VibeshipConfig {\n return deepMerge(\n defaultConfig,\n environmentDefaults,\n environmentOverrides,\n userConfig\n );\n}\n\n/**\n * Apply environment variable overrides to configuration\n */\nexport function applyEnvironmentOverrides(\n config: VibeshipConfig\n): VibeshipConfig {\n const overrides: PartialVibeshipConfig = {};\n\n // Authentication overrides\n if (process.env.VIBECODE_AUTH_SECRET) {\n overrides.security = {\n ...overrides.security,\n auth: {\n ...overrides.security?.auth,\n jwtSecret: process.env.VIBECODE_AUTH_SECRET,\n },\n };\n }\n\n if (process.env.VIBECODE_API_KEY) {\n overrides.security = {\n ...overrides.security,\n auth: {\n ...overrides.security?.auth,\n apiKey: process.env.VIBECODE_API_KEY,\n },\n };\n }\n\n // CORS overrides\n if (process.env.VIBECODE_ALLOWED_ORIGINS) {\n const origins = process.env.VIBECODE_ALLOWED_ORIGINS.split(',').map(s => s.trim());\n overrides.security = {\n ...overrides.security,\n corsConfig: {\n ...overrides.security?.corsConfig,\n allowedOrigins: origins,\n },\n };\n }\n\n // Rate limit overrides\n if (process.env.VIBECODE_RATE_LIMIT) {\n const [windowMs, maxRequests] = process.env.VIBECODE_RATE_LIMIT.split(',').map(Number);\n if (windowMs && maxRequests) {\n overrides.security = {\n ...overrides.security,\n rateLimitConfig: {\n ...overrides.security?.rateLimitConfig,\n windowMs,\n maxRequests,\n },\n };\n }\n }\n\n // Cache overrides\n if (process.env.VIBECODE_CACHE_ENABLED !== undefined) {\n overrides.cache = {\n ...overrides.cache,\n enabled: process.env.VIBECODE_CACHE_ENABLED === 'true',\n };\n }\n\n // AI provider overrides\n if (process.env.VIBECODE_AI_PROVIDER) {\n overrides.features = {\n ...overrides.features,\n ai: true,\n };\n }\n\n // Apply feature flags from environment\n const featureFlags = [\n 'VIBECODE_FEATURE_TASKS',\n 'VIBECODE_FEATURE_AI',\n 'VIBECODE_FEATURE_REALTIME',\n 'VIBECODE_FEATURE_COMMAND_PALETTE',\n 'VIBECODE_FEATURE_FILE_EDITING',\n 'VIBECODE_FEATURE_MARKDOWN_PREVIEW',\n ];\n\n featureFlags.forEach((flag) => {\n if (process.env[flag] !== undefined) {\n const featureName = flag\n .replace('VIBECODE_FEATURE_', '')\n .toLowerCase()\n .replace(/_([a-z])/g, (_, letter) => letter.toUpperCase()) as keyof typeof config.features;\n\n overrides.features = {\n ...overrides.features,\n [featureName]: process.env[flag] === 'true',\n };\n }\n });\n\n return deepMerge(config, overrides);\n}\n\n/**\n * Freeze configuration to prevent mutations\n */\nexport function freezeConfig<T extends object>(config: T): Readonly<T> {\n return deepFreeze(config);\n}\n\n/**\n * Deep freeze utility\n */\nfunction deepFreeze<T extends object>(obj: T): Readonly<T> {\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach((prop) => {\n const value = obj[prop as keyof T];\n if (value && typeof value === 'object' && !Object.isFrozen(value)) {\n deepFreeze(value);\n }\n });\n\n return obj;\n}\n\n/**\n * Create a configuration patch that can be applied later\n */\nexport function createConfigPatch(\n baseConfig: VibeshipConfig,\n newConfig: VibeshipConfig\n): PartialVibeshipConfig {\n const patch: PartialVibeshipConfig = {};\n\n Object.keys(newConfig).forEach((key) => {\n const baseValue = baseConfig[key as keyof VibeshipConfig];\n const newValue = newConfig[key as keyof VibeshipConfig];\n\n if (JSON.stringify(baseValue) !== JSON.stringify(newValue)) {\n patch[key as keyof PartialVibeshipConfig] = newValue as any;\n }\n });\n\n return patch;\n}\n\n/**\n * Validate that a configuration patch is safe to apply\n */\nexport function isPatchSafe(patch: PartialVibeshipConfig): boolean {\n // Check for dangerous patterns in file paths\n const dangerousPaths = ['/', '..', '~', '$HOME'];\n \n // Check scanPaths\n if (patch.scanPaths && Array.isArray(patch.scanPaths)) {\n for (const path of patch.scanPaths) {\n if (path && dangerousPaths.some(dangerous => path.includes(dangerous))) {\n return false;\n }\n }\n }\n\n // Check security.allowedPaths\n if (patch.security?.allowedPaths && Array.isArray(patch.security.allowedPaths)) {\n for (const path of patch.security.allowedPaths) {\n if (path && dangerousPaths.some(dangerous => path.includes(dangerous))) {\n return false;\n }\n }\n }\n\n // Check for unsafe patterns in blocked patterns\n if (patch.security?.blockedPatterns) {\n // Ensure critical patterns are not removed\n const criticalPatterns = ['**/.env*', '**/*.key', '**/*.pem'];\n for (const pattern of criticalPatterns) {\n if (!patch.security.blockedPatterns.includes(pattern)) {\n return false;\n }\n }\n }\n\n return true;\n}","import { PartialVibeshipConfig, VibeshipConfig } from './types';\nimport { validatePartialConfig } from './schema';\n\n/**\n * Configuration migration interface\n */\nexport interface ConfigMigration {\n /**\n * Migration version\n */\n version: string;\n\n /**\n * Migration description\n */\n description: string;\n\n /**\n * Check if migration should be applied\n */\n shouldApply: (config: any) => boolean;\n\n /**\n * Apply the migration\n */\n migrate: (config: any) => PartialVibeshipConfig;\n\n /**\n * Validate the migration result\n */\n validate?: (config: PartialVibeshipConfig) => boolean;\n}\n\n/**\n * Available migrations\n */\nconst MIGRATIONS: ConfigMigration[] = [\n {\n version: '1.0.0',\n description: 'Migrate legacy devtools config to vibecode config',\n shouldApply: (config: any) => {\n return config.devtools && !config.scanPaths;\n },\n migrate: (config: any) => {\n const { devtools, ...rest } = config;\n return {\n ...rest,\n scanPaths: devtools.scanPaths || ['./docs'],\n features: {\n tasks: devtools.enableTasks !== false,\n ai: devtools.enableAI === true,\n realtime: devtools.enableRealtime !== false,\n commandPalette: devtools.enableCommandPalette !== false,\n fileEditing: devtools.enableFileEditing === true,\n markdownPreview: devtools.enableMarkdownPreview !== false,\n },\n ui: {\n theme: devtools.theme || 'system',\n position: devtools.position || 'bottom-right',\n hotkey: devtools.hotkey || 'ctrl+shift+d',\n showInProduction: devtools.showInProduction === true,\n },\n };\n },\n },\n {\n version: '1.1.0',\n description: 'Migrate old security config structure',\n shouldApply: (config: any) => {\n return config.auth && !config.security?.auth;\n },\n migrate: (config: any) => {\n const { auth, cors, rateLimit, ...rest } = config;\n return {\n ...rest,\n security: {\n ...rest.security,\n authentication: !!auth,\n auth: auth ? {\n jwtSecret: auth.jwtSecret,\n apiKey: auth.apiKey,\n session: auth.session,\n providers: auth.providers,\n } : undefined,\n cors: cors !== false,\n corsConfig: cors && typeof cors === 'object' ? cors : undefined,\n rateLimit: rateLimit !== false,\n rateLimitConfig: rateLimit && typeof rateLimit === 'object' ? rateLimit : undefined,\n },\n };\n },\n },\n {\n version: '1.2.0',\n description: 'Migrate task patterns from arrays to objects',\n shouldApply: (config: any) => {\n return config.taskPatterns && Array.isArray(config.taskPatterns);\n },\n migrate: (config: any) => {\n const patterns = config.taskPatterns as string[];\n return {\n ...config,\n taskPatterns: {\n todo: patterns.includes('TODO') || patterns.includes('todo'),\n fixme: patterns.includes('FIXME') || patterns.includes('fixme'),\n hack: patterns.includes('HACK') || patterns.includes('hack'),\n note: patterns.includes('NOTE') || patterns.includes('note'),\n warning: patterns.includes('WARNING') || patterns.includes('warning'),\n optimize: patterns.includes('OPTIMIZE') || patterns.includes('optimize'),\n },\n };\n },\n },\n {\n version: '1.3.0',\n description: 'Migrate cache config from string to object',\n shouldApply: (config: any) => {\n return typeof config.cache === 'string' || typeof config.cache === 'boolean';\n },\n migrate: (config: any) => {\n const cacheValue = config.cache;\n return {\n ...config,\n cache: {\n enabled: cacheValue !== false && cacheValue !== 'false',\n directory: typeof cacheValue === 'string' ? cacheValue : '.vibecode/cache',\n maxSize: 52428800, // 50MB\n ttl: 3600000, // 1 hour\n strategy: 'lru' as const,\n },\n };\n },\n },\n {\n version: '1.4.0',\n description: 'Migrate API config from string to object',\n shouldApply: (config: any) => {\n return typeof config.api === 'string';\n },\n migrate: (config: any) => {\n const apiValue = config.api as string;\n return {\n ...config,\n api: {\n basePath: apiValue.startsWith('/') ? apiValue : `/api/${apiValue}`,\n version: 'v1',\n documentation: true,\n timeout: 30000,\n },\n };\n },\n },\n];\n\n/**\n * Migration result\n */\nexport interface MigrationResult {\n /**\n * Whether any migrations were applied\n */\n migrated: boolean;\n\n /**\n * Applied migrations\n */\n appliedMigrations: string[];\n\n /**\n * Migration warnings\n */\n warnings: string[];\n\n /**\n * Migrated configuration\n */\n config: PartialVibeshipConfig;\n}\n\n/**\n * Apply migrations to configuration\n */\nexport function migrateConfig(config: any): MigrationResult {\n const result: MigrationResult = {\n migrated: false,\n appliedMigrations: [],\n warnings: [],\n config: { ...config },\n };\n\n // Apply migrations in order\n for (const migration of MIGRATIONS) {\n if (migration.shouldApply(result.config)) {\n try {\n const migratedConfig = migration.migrate(result.config);\n \n // Validate migration result if validator is provided\n if (migration.validate && !migration.validate(migratedConfig)) {\n result.warnings.push(\n `Migration ${migration.version} validation failed: ${migration.description}`\n );\n continue;\n }\n\n // Validate with schema\n const validation = validatePartialConfig(migratedConfig);\n if (!validation.success) {\n result.warnings.push(\n `Migration ${migration.version} produced invalid config: ${validation.errors?.join(', ')}`\n );\n continue;\n }\n\n result.config = migratedConfig;\n result.migrated = true;\n result.appliedMigrations.push(migration.version);\n \n console.log(`Applied migration ${migration.version}: ${migration.description}`);\n } catch (error) {\n result.warnings.push(\n `Migration ${migration.version} failed: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n return result;\n}\n\n/**\n * Check if configuration needs migration\n */\nexport function needsMigration(config: any): boolean {\n return MIGRATIONS.some(migration => migration.shouldApply(config));\n}\n\n/**\n * Get available migrations for a configuration\n */\nexport function getAvailableMigrations(config: any): ConfigMigration[] {\n return MIGRATIONS.filter(migration => migration.shouldApply(config));\n}\n\n/**\n * Create a backup of the configuration before migration\n */\nexport function createConfigBackup(config: any, backupPath?: string): string {\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const backupName = backupPath || `vibecode.config.backup.${timestamp}.json`;\n \n const { writeFileSync } = require('fs');\n writeFileSync(backupName, JSON.stringify(config, null, 2));\n \n return backupName;\n}\n\n/**\n * Interactive migration helper\n */\nexport async function interactiveMigration(\n config: any,\n options: {\n prompt?: (message: string) => Promise<boolean>;\n createBackup?: boolean;\n backupPath?: string;\n } = {}\n): Promise<MigrationResult> {\n const { prompt, createBackup = true, backupPath } = options;\n \n const availableMigrations = getAvailableMigrations(config);\n \n if (availableMigrations.length === 0) {\n return {\n migrated: false,\n appliedMigrations: [],\n warnings: [],\n config,\n };\n }\n\n // Show available migrations\n console.log('\\nAvailable migrations:');\n for (const migration of availableMigrations) {\n console.log(` ${migration.version}: ${migration.description}`);\n }\n\n // Ask for confirmation\n const shouldMigrate = prompt \n ? await prompt(`Apply ${availableMigrations.length} migration(s)?`)\n : true;\n\n if (!shouldMigrate) {\n return {\n migrated: false,\n appliedMigrations: [],\n warnings: ['Migration cancelled by user'],\n config,\n };\n }\n\n // Create backup\n if (createBackup) {\n const backupFile = createConfigBackup(config, backupPath);\n console.log(`Configuration backup created: ${backupFile}`);\n }\n\n // Apply migrations\n return migrateConfig(config);\n}\n\n/**\n * Rollback to a previous configuration\n */\nexport function rollbackConfig(backupPath: string): any {\n const { readFileSync, existsSync } = require('fs');\n \n if (!existsSync(backupPath)) {\n throw new Error(`Backup file not found: ${backupPath}`);\n }\n\n const backupContent = readFileSync(backupPath, 'utf-8');\n return JSON.parse(backupContent);\n}\n\n/**\n * Clean up old backup files\n */\nexport function cleanupBackups(maxAge: number = 30 * 24 * 60 * 60 * 1000): void {\n const { readdirSync, statSync, unlinkSync } = require('fs');\n const { join } = require('path');\n \n const currentDir = process.cwd();\n const files = readdirSync(currentDir);\n const backupFiles = files.filter((file: string) => file.startsWith('vibecode.config.backup.'));\n \n const now = Date.now();\n \n for (const file of backupFiles) {\n const filePath = join(currentDir, file);\n const stats = statSync(filePath);\n \n if (now - stats.mtime.getTime() > maxAge) {\n unlinkSync(filePath);\n console.log(`Cleaned up old backup: ${file}`);\n }\n }\n}","/**\n * Vibeship DevTools Configuration System\n * \n * A comprehensive configuration system with:\n * - TypeScript support and autocomplete\n * - Schema validation with Zod\n * - Environment variable overrides\n * - Multiple configuration file formats\n * - Configuration merging and defaults\n * - Runtime configuration updates\n * - Migration system for backwards compatibility\n */\n\n// Types\nexport type {\n VibeshipConfig,\n PartialVibeshipConfig,\n DeepPartial,\n DefineConfigFunction,\n FeatureFlags,\n SecurityConfig,\n AuthConfig,\n AuthProvider,\n RateLimitConfig,\n CORSConfig,\n TaskPatterns,\n CustomTaskPattern,\n UIConfig,\n APIConfig,\n CacheConfig,\n ExperimentalConfig,\n EnvConfig,\n} from './types';\n\n// Default configurations\nexport {\n defaultConfig,\n developmentConfig,\n productionConfig,\n testConfig,\n getEnvironmentDefaults,\n} from './defaults';\n\n// Schema validation\nexport {\n VibeshipConfigSchema,\n PartialVibeshipConfigSchema,\n validateConfig,\n validatePartialConfig,\n isValidConfig,\n} from './schema';\nexport type { VibeshipConfigFromSchema } from './schema';\n\n// Configuration loading and management\nexport {\n loadConfig,\n defineConfig,\n getConfig,\n clearConfigCache,\n watchConfig,\n} from './loader';\nexport type { LoadConfigOptions } from './loader';\n\n// Configuration merging utilities\nexport {\n deepMerge,\n mergeConfigurations,\n applyEnvironmentOverrides,\n freezeConfig,\n createConfigPatch,\n isPatchSafe,\n} from './merger';\n\n// Migration system\nexport {\n migrateConfig,\n needsMigration,\n getAvailableMigrations,\n createConfigBackup,\n interactiveMigration,\n rollbackConfig,\n cleanupBackups,\n} from './migration';\nexport type { ConfigMigration, MigrationResult } from './migration';\n\n// Convenience re-exports for common use cases\nexport { z } from 'zod';\n\n/**\n * Create a configuration with TypeScript support and validation\n * \n * @example\n * ```typescript\n * import { defineConfig } from '@vibeship/devtools/config';\n * \n * export default defineConfig({\n * scanPaths: ['./docs', './README.md'],\n * features: {\n * ai: true,\n * fileEditing: false,\n * },\n * security: {\n * authentication: true,\n * rateLimitConfig: {\n * windowMs: 60000,\n * maxRequests: 100,\n * },\n * },\n * });\n * ```\n */"],"mappings":"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